diff options
Diffstat (limited to 'nss/lib/freebl/mpi')
67 files changed, 12713 insertions, 12624 deletions
diff --git a/nss/lib/freebl/mpi/README b/nss/lib/freebl/mpi/README index fc6c5e1..475549b 100644 --- a/nss/lib/freebl/mpi/README +++ b/nss/lib/freebl/mpi/README @@ -234,7 +234,6 @@ mp_div(a, b, q, r) - computes q, r such that a = bq + r mp_div_2d(a, d, q, r) - computes q = a / 2^d, r = a % 2^d mp_expt(a, b, c) - computes c = a ** b mp_2expt(a, k) - computes a = 2^k -mp_sqrt(a, c) - computes c = floor(sqrt(a)) The mp_div_2d() function efficiently computes division by powers of two. Either the q or r parameter may be NULL, in which case that @@ -282,7 +281,6 @@ mp_cmp_z(a) - compare a <=> 0 mp_cmp_d(a, d) - compare a <=> d, d is a single digit mp_cmp(a, b) - compare a <=> b mp_cmp_mag(a, b) - compare |a| <=> |b| -mp_cmp_int(a, z) - compare a <=> z, z is a signed long integer mp_isodd(a) - return nonzero if odd, zero otherwise mp_iseven(a) - return nonzero if even, zero otherwise @@ -523,13 +521,6 @@ MP_MEMCPY - If true, use memcpy() to copy buffers. If you run into weird alignment bugs, set this to zero and an explicit loop will be used. -MP_CRYPTO - If true, whenever arrays of digits are free'd, they - are zeroed first. This is useful if you're using - the library in a cryptographic environment; however, - it does add overhead to each free operation. For - performance, if you don't care about zeroing your - buffers, set this to false. - MP_ARGCHK - Set to 0, 1, or 2. This defines how the argument checking macro, ARGCHK(), gets expanded. If this is set to zero, ARGCHK() expands to nothing; no diff --git a/nss/lib/freebl/mpi/logtab.h b/nss/lib/freebl/mpi/logtab.h index 1f2660e..24cb13c 100644 --- a/nss/lib/freebl/mpi/logtab.h +++ b/nss/lib/freebl/mpi/logtab.h @@ -8,22 +8,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ const float s_logv_2[] = { - 0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f, /* 0 1 2 3 */ - 0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f, /* 4 5 6 7 */ - 0.333333333f, 0.315464877f, 0.301029996f, 0.289064826f, /* 8 9 10 11 */ - 0.278942946f, 0.270238154f, 0.262649535f, 0.255958025f, /* 12 13 14 15 */ - 0.250000000f, 0.244650542f, 0.239812467f, 0.235408913f, /* 16 17 18 19 */ - 0.231378213f, 0.227670249f, 0.224243824f, 0.221064729f, /* 20 21 22 23 */ - 0.218104292f, 0.215338279f, 0.212746054f, 0.210309918f, /* 24 25 26 27 */ - 0.208014598f, 0.205846832f, 0.203795047f, 0.201849087f, /* 28 29 30 31 */ - 0.200000000f, 0.198239863f, 0.196561632f, 0.194959022f, /* 32 33 34 35 */ - 0.193426404f, 0.191958720f, 0.190551412f, 0.189200360f, /* 36 37 38 39 */ - 0.187901825f, 0.186652411f, 0.185449023f, 0.184288833f, /* 40 41 42 43 */ - 0.183169251f, 0.182087900f, 0.181042597f, 0.180031327f, /* 44 45 46 47 */ - 0.179052232f, 0.178103594f, 0.177183820f, 0.176291434f, /* 48 49 50 51 */ - 0.175425064f, 0.174583430f, 0.173765343f, 0.172969690f, /* 52 53 54 55 */ - 0.172195434f, 0.171441601f, 0.170707280f, 0.169991616f, /* 56 57 58 59 */ - 0.169293808f, 0.168613099f, 0.167948779f, 0.167300179f, /* 60 61 62 63 */ - 0.166666667f + 0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f, /* 0 1 2 3 */ + 0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f, /* 4 5 6 7 */ + 0.333333333f, 0.315464877f, 0.301029996f, 0.289064826f, /* 8 9 10 11 */ + 0.278942946f, 0.270238154f, 0.262649535f, 0.255958025f, /* 12 13 14 15 */ + 0.250000000f, 0.244650542f, 0.239812467f, 0.235408913f, /* 16 17 18 19 */ + 0.231378213f, 0.227670249f, 0.224243824f, 0.221064729f, /* 20 21 22 23 */ + 0.218104292f, 0.215338279f, 0.212746054f, 0.210309918f, /* 24 25 26 27 */ + 0.208014598f, 0.205846832f, 0.203795047f, 0.201849087f, /* 28 29 30 31 */ + 0.200000000f, 0.198239863f, 0.196561632f, 0.194959022f, /* 32 33 34 35 */ + 0.193426404f, 0.191958720f, 0.190551412f, 0.189200360f, /* 36 37 38 39 */ + 0.187901825f, 0.186652411f, 0.185449023f, 0.184288833f, /* 40 41 42 43 */ + 0.183169251f, 0.182087900f, 0.181042597f, 0.180031327f, /* 44 45 46 47 */ + 0.179052232f, 0.178103594f, 0.177183820f, 0.176291434f, /* 48 49 50 51 */ + 0.175425064f, 0.174583430f, 0.173765343f, 0.172969690f, /* 52 53 54 55 */ + 0.172195434f, 0.171441601f, 0.170707280f, 0.169991616f, /* 56 57 58 59 */ + 0.169293808f, 0.168613099f, 0.167948779f, 0.167300179f, /* 60 61 62 63 */ + 0.166666667f }; - diff --git a/nss/lib/freebl/mpi/mdxptest.c b/nss/lib/freebl/mpi/mdxptest.c index 28b05f0..adbcfc3 100644 --- a/nss/lib/freebl/mpi/mdxptest.c +++ b/nss/lib/freebl/mpi/mdxptest.c @@ -5,42 +5,40 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <malloc.h> #include <time.h> #include "mpi.h" #include "mpi-priv.h" /* #define OLD_WAY 1 */ -/* This key is the 1024-bit test key used for speed testing of RSA private +/* This key is the 1024-bit test key used for speed testing of RSA private ** key ops. */ #define CONST const static CONST unsigned char default_n[128] = { -0xc2,0xae,0x96,0x89,0xaf,0xce,0xd0,0x7b,0x3b,0x35,0xfd,0x0f,0xb1,0xf4,0x7a,0xd1, -0x3c,0x7d,0xb5,0x86,0xf2,0x68,0x36,0xc9,0x97,0xe6,0x82,0x94,0x86,0xaa,0x05,0x39, -0xec,0x11,0x51,0xcc,0x5c,0xa1,0x59,0xba,0x29,0x18,0xf3,0x28,0xf1,0x9d,0xe3,0xae, -0x96,0x5d,0x6d,0x87,0x73,0xf6,0xf6,0x1f,0xd0,0x2d,0xfb,0x2f,0x7a,0x13,0x7f,0xc8, -0x0c,0x7a,0xe9,0x85,0xfb,0xce,0x74,0x86,0xf8,0xef,0x2f,0x85,0x37,0x73,0x0f,0x62, -0x4e,0x93,0x17,0xb7,0x7e,0x84,0x9a,0x94,0x11,0x05,0xca,0x0d,0x31,0x4b,0x2a,0xc8, -0xdf,0xfe,0xe9,0x0c,0x13,0xc7,0xf2,0xad,0x19,0x64,0x28,0x3c,0xb5,0x6a,0xc8,0x4b, -0x79,0xea,0x7c,0xce,0x75,0x92,0x45,0x3e,0xa3,0x9d,0x64,0x6f,0x04,0x69,0x19,0x17 + 0xc2, 0xae, 0x96, 0x89, 0xaf, 0xce, 0xd0, 0x7b, 0x3b, 0x35, 0xfd, 0x0f, 0xb1, 0xf4, 0x7a, 0xd1, + 0x3c, 0x7d, 0xb5, 0x86, 0xf2, 0x68, 0x36, 0xc9, 0x97, 0xe6, 0x82, 0x94, 0x86, 0xaa, 0x05, 0x39, + 0xec, 0x11, 0x51, 0xcc, 0x5c, 0xa1, 0x59, 0xba, 0x29, 0x18, 0xf3, 0x28, 0xf1, 0x9d, 0xe3, 0xae, + 0x96, 0x5d, 0x6d, 0x87, 0x73, 0xf6, 0xf6, 0x1f, 0xd0, 0x2d, 0xfb, 0x2f, 0x7a, 0x13, 0x7f, 0xc8, + 0x0c, 0x7a, 0xe9, 0x85, 0xfb, 0xce, 0x74, 0x86, 0xf8, 0xef, 0x2f, 0x85, 0x37, 0x73, 0x0f, 0x62, + 0x4e, 0x93, 0x17, 0xb7, 0x7e, 0x84, 0x9a, 0x94, 0x11, 0x05, 0xca, 0x0d, 0x31, 0x4b, 0x2a, 0xc8, + 0xdf, 0xfe, 0xe9, 0x0c, 0x13, 0xc7, 0xf2, 0xad, 0x19, 0x64, 0x28, 0x3c, 0xb5, 0x6a, 0xc8, 0x4b, + 0x79, 0xea, 0x7c, 0xce, 0x75, 0x92, 0x45, 0x3e, 0xa3, 0x9d, 0x64, 0x6f, 0x04, 0x69, 0x19, 0x17 }; static CONST unsigned char default_d[128] = { -0x13,0xcb,0xbc,0xf2,0xf3,0x35,0x8c,0x6d,0x7b,0x6f,0xd9,0xf3,0xa6,0x9c,0xbd,0x80, -0x59,0x2e,0x4f,0x2f,0x11,0xa7,0x17,0x2b,0x18,0x8f,0x0f,0xe8,0x1a,0x69,0x5f,0x6e, -0xac,0x5a,0x76,0x7e,0xd9,0x4c,0x6e,0xdb,0x47,0x22,0x8a,0x57,0x37,0x7a,0x5e,0x94, -0x7a,0x25,0xb5,0xe5,0x78,0x1d,0x3c,0x99,0xaf,0x89,0x7d,0x69,0x2e,0x78,0x9d,0x1d, -0x84,0xc8,0xc1,0xd7,0x1a,0xb2,0x6d,0x2d,0x8a,0xd9,0xab,0x6b,0xce,0xae,0xb0,0xa0, -0x58,0x55,0xad,0x5c,0x40,0x8a,0xd6,0x96,0x08,0x8a,0xe8,0x63,0xe6,0x3d,0x6c,0x20, -0x49,0xc7,0xaf,0x0f,0x25,0x73,0xd3,0x69,0x43,0x3b,0xf2,0x32,0xf8,0x3d,0x5e,0xee, -0x7a,0xca,0xd6,0x94,0x55,0xe5,0xbd,0x25,0x34,0x8d,0x63,0x40,0xb5,0x8a,0xc3,0x01 + 0x13, 0xcb, 0xbc, 0xf2, 0xf3, 0x35, 0x8c, 0x6d, 0x7b, 0x6f, 0xd9, 0xf3, 0xa6, 0x9c, 0xbd, 0x80, + 0x59, 0x2e, 0x4f, 0x2f, 0x11, 0xa7, 0x17, 0x2b, 0x18, 0x8f, 0x0f, 0xe8, 0x1a, 0x69, 0x5f, 0x6e, + 0xac, 0x5a, 0x76, 0x7e, 0xd9, 0x4c, 0x6e, 0xdb, 0x47, 0x22, 0x8a, 0x57, 0x37, 0x7a, 0x5e, 0x94, + 0x7a, 0x25, 0xb5, 0xe5, 0x78, 0x1d, 0x3c, 0x99, 0xaf, 0x89, 0x7d, 0x69, 0x2e, 0x78, 0x9d, 0x1d, + 0x84, 0xc8, 0xc1, 0xd7, 0x1a, 0xb2, 0x6d, 0x2d, 0x8a, 0xd9, 0xab, 0x6b, 0xce, 0xae, 0xb0, 0xa0, + 0x58, 0x55, 0xad, 0x5c, 0x40, 0x8a, 0xd6, 0x96, 0x08, 0x8a, 0xe8, 0x63, 0xe6, 0x3d, 0x6c, 0x20, + 0x49, 0xc7, 0xaf, 0x0f, 0x25, 0x73, 0xd3, 0x69, 0x43, 0x3b, 0xf2, 0x32, 0xf8, 0x3d, 0x5e, 0xee, + 0x7a, 0xca, 0xd6, 0x94, 0x55, 0xe5, 0xbd, 0x25, 0x34, 0x8d, 0x63, 0x40, 0xb5, 0x8a, 0xc3, 0x01 }; - #define DEFAULT_ITERS 50 typedef clock_t timetype; @@ -54,39 +52,43 @@ struct TimingContextStr { timetype end; timetype interval; - int minutes; - int seconds; - int millisecs; + int minutes; + int seconds; + int millisecs; }; typedef struct TimingContextStr TimingContext; -TimingContext *CreateTimingContext(void) +TimingContext * +CreateTimingContext(void) { return (TimingContext *)malloc(sizeof(TimingContext)); } -void DestroyTimingContext(TimingContext *ctx) +void +DestroyTimingContext(TimingContext *ctx) { free(ctx); } -void TimingBegin(TimingContext *ctx) +void +TimingBegin(TimingContext *ctx) { gettime(&ctx->start); } -static void timingUpdate(TimingContext *ctx) +static void +timingUpdate(TimingContext *ctx) { ctx->millisecs = msec(ctx->interval) % 1000; - ctx->seconds = sec(ctx->interval); - ctx->minutes = ctx->seconds / 60; - ctx->seconds %= 60; - + ctx->seconds = sec(ctx->interval); + ctx->minutes = ctx->seconds / 60; + ctx->seconds %= 60; } -void TimingEnd(TimingContext *ctx) +void +TimingEnd(TimingContext *ctx) { gettime(&ctx->end); ctx->interval = ctx->end; @@ -94,17 +96,18 @@ void TimingEnd(TimingContext *ctx) timingUpdate(ctx); } -char *TimingGenerateString(TimingContext *ctx) +char * +TimingGenerateString(TimingContext *ctx) { static char sBuf[4096]; sprintf(sBuf, "%d minutes, %d.%03d seconds", ctx->minutes, - ctx->seconds, ctx->millisecs); + ctx->seconds, ctx->millisecs); return sBuf; } static void -dumpBytes( unsigned char * b, int l) +dumpBytes(unsigned char *b, int l) { int i; if (l <= 0) @@ -122,17 +125,17 @@ dumpBytes( unsigned char * b, int l) } static mp_err -testNewFuncs(const unsigned char * modulusBytes, int modulus_len) +testNewFuncs(const unsigned char *modulusBytes, int modulus_len) { - mp_err mperr = MP_OKAY; + mp_err mperr = MP_OKAY; mp_int modulus; unsigned char buf[512]; mperr = mp_init(&modulus); - mperr = mp_read_unsigned_octets(&modulus, modulusBytes, modulus_len ); + mperr = mp_read_unsigned_octets(&modulus, modulusBytes, modulus_len); mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len); - mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+1); - mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+4); + mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len + 1); + mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len + 4); mperr = mp_to_unsigned_octets(&modulus, buf, modulus_len); mperr = mp_to_signed_octets(&modulus, buf, modulus_len + 1); mp_clear(&modulus); @@ -140,41 +143,41 @@ testNewFuncs(const unsigned char * modulusBytes, int modulus_len) } int -testModExp( const unsigned char * modulusBytes, - const unsigned int expo, - const unsigned char * input, - unsigned char * output, - int modulus_len) +testModExp(const unsigned char *modulusBytes, + const unsigned int expo, + const unsigned char *input, + unsigned char *output, + int modulus_len) { - mp_err mperr = MP_OKAY; + mp_err mperr = MP_OKAY; mp_int modulus; mp_int base; mp_int exponent; mp_int result; - mperr = mp_init(&modulus); + mperr = mp_init(&modulus); mperr += mp_init(&base); mperr += mp_init(&exponent); mperr += mp_init(&result); /* we initialize all mp_ints unconditionally, even if some fail. ** This guarantees that the DIGITS pointer is valid (even if null). - ** So, mp_clear will do the right thing below. + ** So, mp_clear will do the right thing below. */ if (mperr == MP_OKAY) { - mperr = mp_read_unsigned_octets(&modulus, - modulusBytes + (sizeof default_n - modulus_len), modulus_len ); - mperr += mp_read_unsigned_octets(&base, input, modulus_len ); - mp_set(&exponent, expo); - if (mperr == MP_OKAY) { + mperr = mp_read_unsigned_octets(&modulus, + modulusBytes + (sizeof default_n - modulus_len), modulus_len); + mperr += mp_read_unsigned_octets(&base, input, modulus_len); + mp_set(&exponent, expo); + if (mperr == MP_OKAY) { #if OLD_WAY - mperr = s_mp_exptmod(&base, &exponent, &modulus, &result); + mperr = s_mp_exptmod(&base, &exponent, &modulus, &result); #else - mperr = mp_exptmod(&base, &exponent, &modulus, &result); + mperr = mp_exptmod(&base, &exponent, &modulus, &result); #endif - if (mperr == MP_OKAY) { - mperr = mp_to_fixlen_octets(&result, output, modulus_len); - } - } + if (mperr == MP_OKAY) { + mperr = mp_to_fixlen_octets(&result, output, modulus_len); + } + } } mp_clear(&base); mp_clear(&result); @@ -186,41 +189,41 @@ testModExp( const unsigned char * modulusBytes, } int -doModExp( const unsigned char * modulusBytes, - const unsigned char * exponentBytes, - const unsigned char * input, - unsigned char * output, - int modulus_len) +doModExp(const unsigned char *modulusBytes, + const unsigned char *exponentBytes, + const unsigned char *input, + unsigned char *output, + int modulus_len) { - mp_err mperr = MP_OKAY; + mp_err mperr = MP_OKAY; mp_int modulus; mp_int base; mp_int exponent; mp_int result; - mperr = mp_init(&modulus); + mperr = mp_init(&modulus); mperr += mp_init(&base); mperr += mp_init(&exponent); mperr += mp_init(&result); /* we initialize all mp_ints unconditionally, even if some fail. ** This guarantees that the DIGITS pointer is valid (even if null). - ** So, mp_clear will do the right thing below. + ** So, mp_clear will do the right thing below. */ if (mperr == MP_OKAY) { - mperr = mp_read_unsigned_octets(&modulus, - modulusBytes + (sizeof default_n - modulus_len), modulus_len ); - mperr += mp_read_unsigned_octets(&exponent, exponentBytes, modulus_len ); - mperr += mp_read_unsigned_octets(&base, input, modulus_len ); - if (mperr == MP_OKAY) { + mperr = mp_read_unsigned_octets(&modulus, + modulusBytes + (sizeof default_n - modulus_len), modulus_len); + mperr += mp_read_unsigned_octets(&exponent, exponentBytes, modulus_len); + mperr += mp_read_unsigned_octets(&base, input, modulus_len); + if (mperr == MP_OKAY) { #if OLD_WAY - mperr = s_mp_exptmod(&base, &exponent, &modulus, &result); + mperr = s_mp_exptmod(&base, &exponent, &modulus, &result); #else - mperr = mp_exptmod(&base, &exponent, &modulus, &result); + mperr = mp_exptmod(&base, &exponent, &modulus, &result); #endif - if (mperr == MP_OKAY) { - mperr = mp_to_fixlen_octets(&result, output, modulus_len); - } - } + if (mperr == MP_OKAY) { + mperr = mp_to_fixlen_octets(&result, output, modulus_len); + } + } } mp_clear(&base); mp_clear(&result); @@ -234,77 +237,70 @@ doModExp( const unsigned char * modulusBytes, int main(int argc, char **argv) { - TimingContext * timeCtx; - char * progName; - long iters = DEFAULT_ITERS; - unsigned int modulus_len; - int i; - int rv; - unsigned char buf [1024]; - unsigned char buf2[1024]; + TimingContext *timeCtx; + char *progName; + long iters = DEFAULT_ITERS; + unsigned int modulus_len; + int i; + int rv; + unsigned char buf[1024]; + unsigned char buf2[1024]; progName = strrchr(argv[0], '/'); if (!progName) - progName = strrchr(argv[0], '\\'); - progName = progName ? progName+1 : argv[0]; + progName = strrchr(argv[0], '\\'); + progName = progName ? progName + 1 : argv[0]; if (argc >= 2) { - iters = atol(argv[1]); + iters = atol(argv[1]); } if (argc >= 3) { - modulus_len = atol(argv[2]); - } else - modulus_len = sizeof default_n; + modulus_len = atol(argv[2]); + } else + modulus_len = sizeof default_n; /* no library init function !? */ memset(buf, 0x41, sizeof buf); - if (iters < 2) { - testNewFuncs( default_n, modulus_len); - testNewFuncs( default_n+1, modulus_len - 1); - testNewFuncs( default_n+2, modulus_len - 2); - testNewFuncs( default_n+3, modulus_len - 3); + if (iters < 2) { + testNewFuncs(default_n, modulus_len); + testNewFuncs(default_n + 1, modulus_len - 1); + testNewFuncs(default_n + 2, modulus_len - 2); + testNewFuncs(default_n + 3, modulus_len - 3); - printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); - rv = testModExp(default_n, 0, buf, buf2, modulus_len); - dumpBytes((unsigned char *)buf2, modulus_len); + rv = testModExp(default_n, 0, buf, buf2, modulus_len); + dumpBytes((unsigned char *)buf2, modulus_len); - printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); - rv = testModExp(default_n, 1, buf, buf2, modulus_len); - dumpBytes((unsigned char *)buf2, modulus_len); + rv = testModExp(default_n, 1, buf, buf2, modulus_len); + dumpBytes((unsigned char *)buf2, modulus_len); - printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); - rv = testModExp(default_n, 2, buf, buf2, modulus_len); - dumpBytes((unsigned char *)buf2, modulus_len); + rv = testModExp(default_n, 2, buf, buf2, modulus_len); + dumpBytes((unsigned char *)buf2, modulus_len); - printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); - rv = testModExp(default_n, 3, buf, buf2, modulus_len); - dumpBytes((unsigned char *)buf2, modulus_len); - } - printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); + rv = testModExp(default_n, 3, buf, buf2, modulus_len); + dumpBytes((unsigned char *)buf2, modulus_len); + } rv = doModExp(default_n, default_d, buf, buf2, modulus_len); if (rv != 0) { - fprintf(stderr, "Error in modexp operation:\n"); - exit(1); + fprintf(stderr, "Error in modexp operation:\n"); + exit(1); } dumpBytes((unsigned char *)buf2, modulus_len); - printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); timeCtx = CreateTimingContext(); TimingBegin(timeCtx); i = iters; while (i--) { - rv = doModExp(default_n, default_d, buf, buf2, modulus_len); - if (rv != 0) { - fprintf(stderr, "Error in modexp operation\n"); - exit(1); - } + rv = doModExp(default_n, default_d, buf, buf2, modulus_len); + if (rv != 0) { + fprintf(stderr, "Error in modexp operation\n"); + exit(1); + } } TimingEnd(timeCtx); printf("%ld iterations in %s\n", iters, TimingGenerateString(timeCtx)); - printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); return 0; } diff --git a/nss/lib/freebl/mpi/montmulf.c b/nss/lib/freebl/mpi/montmulf.c index 3f93d3e..ce8fbc3 100644 --- a/nss/lib/freebl/mpi/montmulf.c +++ b/nss/lib/freebl/mpi/montmulf.c @@ -6,11 +6,11 @@ #define RF_INLINE_MACROS 1 #endif -static const double TwoTo16=65536.0; -static const double TwoToMinus16=1.0/65536.0; -static const double Zero=0.0; -static const double TwoTo32=65536.0*65536.0; -static const double TwoToMinus32=1.0/(65536.0*65536.0); +static const double TwoTo16 = 65536.0; +static const double TwoToMinus16 = 1.0 / 65536.0; +static const double Zero = 0.0; +static const double TwoTo32 = 65536.0 * 65536.0; +static const double TwoToMinus32 = 1.0 / (65536.0 * 65536.0); #ifdef RF_INLINE_MACROS @@ -18,13 +18,12 @@ double upper32(double); double lower32(double, double); double mod(double, double, double); -void i16_to_d16_and_d32x4(const double * /*1/(2^16)*/, - const double * /* 2^16*/, - const double * /* 0 */, - double * /*result16*/, - double * /* result32 */, - float * /*source - should be unsigned int* - converted to float* */); +void i16_to_d16_and_d32x4(const double * /*1/(2^16)*/, + const double * /* 2^16*/, + const double * /* 0 */, + double * /*result16*/, + double * /* result32 */, + float * /*source - should be unsigned int* converted to float* */); #else #ifdef MP_USE_FLOOR @@ -33,263 +32,255 @@ void i16_to_d16_and_d32x4(const double * /*1/(2^16)*/, #define floor(d) ((double)((unsigned long long)(d))) #endif -static double upper32(double x) +static double +upper32(double x) { - return floor(x*TwoToMinus32); + return floor(x * TwoToMinus32); } -static double lower32(double x, double y) +static double +lower32(double x, double y) { - return x-TwoTo32*floor(x*TwoToMinus32); + return x - TwoTo32 * floor(x * TwoToMinus32); } -static double mod(double x, double oneoverm, double m) +static double +mod(double x, double oneoverm, double m) { - return x-m*floor(x*oneoverm); + return x - m * floor(x * oneoverm); } #endif - -static void cleanup(double *dt, int from, int tlen) +static void +cleanup(double *dt, int from, int tlen) { - int i; - double tmp,tmp1,x,x1; - - tmp=tmp1=Zero; - /* original code ** - for(i=2*from;i<2*tlen-2;i++) - { - x=dt[i]; - dt[i]=lower32(x,Zero)+tmp1; - tmp1=tmp; - tmp=upper32(x); - } - dt[tlen-2]+=tmp1; - dt[tlen-1]+=tmp; - **end original code ***/ - /* new code ***/ - for(i=2*from;i<2*tlen;i+=2) - { - x=dt[i]; - x1=dt[i+1]; - dt[i]=lower32(x,Zero)+tmp; - dt[i+1]=lower32(x1,Zero)+tmp1; - tmp=upper32(x); - tmp1=upper32(x1); - } - /** end new code **/ -} + int i; + double tmp, tmp1, x, x1; + tmp = tmp1 = Zero; + /* original code ** + for(i=2*from;i<2*tlen-2;i++) + { + x=dt[i]; + dt[i]=lower32(x,Zero)+tmp1; + tmp1=tmp; + tmp=upper32(x); + } + dt[tlen-2]+=tmp1; + dt[tlen-1]+=tmp; + **end original code ***/ + /* new code ***/ + for (i = 2 * from; i < 2 * tlen; i += 2) { + x = dt[i]; + x1 = dt[i + 1]; + dt[i] = lower32(x, Zero) + tmp; + dt[i + 1] = lower32(x1, Zero) + tmp1; + tmp = upper32(x); + tmp1 = upper32(x1); + } + /** end new code **/ +} -void conv_d16_to_i32(unsigned int *i32, double *d16, long long *tmp, int ilen) +void +conv_d16_to_i32(unsigned int *i32, double *d16, long long *tmp, int ilen) { -int i; -long long t, t1, a, b, c, d; - - t1=0; - a=(long long)d16[0]; - b=(long long)d16[1]; - for(i=0; i<ilen-1; i++) - { - c=(long long)d16[2*i+2]; - t1+=(unsigned int)a; - t=(a>>32); - d=(long long)d16[2*i+3]; - t1+=(b&0xffff)<<16; - t+=(b>>16)+(t1>>32); - i32[i]=(unsigned int)t1; - t1=t; - a=c; - b=d; - } - t1+=(unsigned int)a; - t=(a>>32); - t1+=(b&0xffff)<<16; - i32[i]=(unsigned int)t1; + int i; + long long t, t1, a, b, c, d; + + t1 = 0; + a = (long long)d16[0]; + b = (long long)d16[1]; + for (i = 0; i < ilen - 1; i++) { + c = (long long)d16[2 * i + 2]; + t1 += (unsigned int)a; + t = (a >> 32); + d = (long long)d16[2 * i + 3]; + t1 += (b & 0xffff) << 16; + t += (b >> 16) + (t1 >> 32); + i32[i] = (unsigned int)t1; + t1 = t; + a = c; + b = d; + } + t1 += (unsigned int)a; + t = (a >> 32); + t1 += (b & 0xffff) << 16; + i32[i] = (unsigned int)t1; } -void conv_i32_to_d32(double *d32, unsigned int *i32, int len) +void +conv_i32_to_d32(double *d32, unsigned int *i32, int len) { -int i; + int i; #pragma pipeloop(0) - for(i=0;i<len;i++) d32[i]=(double)(i32[i]); + for (i = 0; i < len; i++) + d32[i] = (double)(i32[i]); } - -void conv_i32_to_d16(double *d16, unsigned int *i32, int len) +void +conv_i32_to_d16(double *d16, unsigned int *i32, int len) { -int i; -unsigned int a; + int i; + unsigned int a; #pragma pipeloop(0) - for(i=0;i<len;i++) - { - a=i32[i]; - d16[2*i]=(double)(a&0xffff); - d16[2*i+1]=(double)(a>>16); - } + for (i = 0; i < len; i++) { + a = i32[i]; + d16[2 * i] = (double)(a & 0xffff); + d16[2 * i + 1] = (double)(a >> 16); + } } - -void conv_i32_to_d32_and_d16(double *d32, double *d16, - unsigned int *i32, int len) +void +conv_i32_to_d32_and_d16(double *d32, double *d16, + unsigned int *i32, int len) { -int i = 0; -unsigned int a; + int i = 0; + unsigned int a; #pragma pipeloop(0) #ifdef RF_INLINE_MACROS - for(;i<len-3;i+=4) - { - i16_to_d16_and_d32x4(&TwoToMinus16, &TwoTo16, &Zero, - &(d16[2*i]), &(d32[i]), (float *)(&(i32[i]))); - } + for (; i < len - 3; i += 4) { + i16_to_d16_and_d32x4(&TwoToMinus16, &TwoTo16, &Zero, + &(d16[2 * i]), &(d32[i]), (float *)(&(i32[i]))); + } #endif - for(;i<len;i++) - { - a=i32[i]; - d32[i]=(double)(i32[i]); - d16[2*i]=(double)(a&0xffff); - d16[2*i+1]=(double)(a>>16); - } + for (; i < len; i++) { + a = i32[i]; + d32[i] = (double)(i32[i]); + d16[2 * i] = (double)(a & 0xffff); + d16[2 * i + 1] = (double)(a >> 16); + } } - -void adjust_montf_result(unsigned int *i32, unsigned int *nint, int len) +void +adjust_montf_result(unsigned int *i32, unsigned int *nint, int len) { -long long acc; -int i; - - if(i32[len]>0) i=-1; - else - { - for(i=len-1; i>=0; i--) - { - if(i32[i]!=nint[i]) break; - } - } - if((i<0)||(i32[i]>nint[i])) - { - acc=0; - for(i=0;i<len;i++) - { - acc=acc+(unsigned long long)(i32[i])-(unsigned long long)(nint[i]); - i32[i]=(unsigned int)acc; - acc=acc>>32; - } - } + long long acc; + int i; + + if (i32[len] > 0) + i = -1; + else { + for (i = len - 1; i >= 0; i--) { + if (i32[i] != nint[i]) + break; + } + } + if ((i < 0) || (i32[i] > nint[i])) { + acc = 0; + for (i = 0; i < len; i++) { + acc = acc + (unsigned long long)(i32[i]) - (unsigned long long)(nint[i]); + i32[i] = (unsigned int)acc; + acc = acc >> 32; + } + } } - - - /* ** the lengths of the input arrays should be at least the following: ** result[nlen+1], dm1[nlen], dm2[2*nlen+1], dt[4*nlen+2], dn[nlen], nint[nlen] ** all of them should be different from one another ** */ -void mont_mulf_noconv(unsigned int *result, - double *dm1, double *dm2, double *dt, - double *dn, unsigned int *nint, - int nlen, double dn0) +void +mont_mulf_noconv(unsigned int *result, + double *dm1, double *dm2, double *dt, + double *dn, unsigned int *nint, + int nlen, double dn0) { - int i, j, jj; - int tmp; - double digit, m2j, nextm2j, a, b; - double *dptmp, *pdm1, *pdm2, *pdn, *pdtj, pdn_0, pdm1_0; - - pdm1=&(dm1[0]); - pdm2=&(dm2[0]); - pdn=&(dn[0]); - pdm2[2*nlen]=Zero; - - if (nlen!=16) - { - for(i=0;i<4*nlen+2;i++) dt[i]=Zero; - - a=dt[0]=pdm1[0]*pdm2[0]; - digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16); - - pdtj=&(dt[0]); - for(j=jj=0;j<2*nlen;j++,jj++,pdtj++) - { - m2j=pdm2[j]; - a=pdtj[0]+pdn[0]*digit; - b=pdtj[1]+pdm1[0]*pdm2[j+1]+a*TwoToMinus16; - pdtj[1]=b; + int i, j, jj; + int tmp; + double digit, m2j, nextm2j, a, b; + double *dptmp, *pdm1, *pdm2, *pdn, *pdtj, pdn_0, pdm1_0; + + pdm1 = &(dm1[0]); + pdm2 = &(dm2[0]); + pdn = &(dn[0]); + pdm2[2 * nlen] = Zero; + + if (nlen != 16) { + for (i = 0; i < 4 * nlen + 2; i++) + dt[i] = Zero; + + a = dt[0] = pdm1[0] * pdm2[0]; + digit = mod(lower32(a, Zero) * dn0, TwoToMinus16, TwoTo16); + + pdtj = &(dt[0]); + for (j = jj = 0; j < 2 * nlen; j++, jj++, pdtj++) { + m2j = pdm2[j]; + a = pdtj[0] + pdn[0] * digit; + b = pdtj[1] + pdm1[0] * pdm2[j + 1] + a * TwoToMinus16; + pdtj[1] = b; #pragma pipeloop(0) - for(i=1;i<nlen;i++) - { - pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit; - } - if((jj==30)) {cleanup(dt,j/2+1,2*nlen+1); jj=0;} - - digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16); - } - } - else - { - a=dt[0]=pdm1[0]*pdm2[0]; - - dt[65]= dt[64]= dt[63]= dt[62]= dt[61]= dt[60]= - dt[59]= dt[58]= dt[57]= dt[56]= dt[55]= dt[54]= - dt[53]= dt[52]= dt[51]= dt[50]= dt[49]= dt[48]= - dt[47]= dt[46]= dt[45]= dt[44]= dt[43]= dt[42]= - dt[41]= dt[40]= dt[39]= dt[38]= dt[37]= dt[36]= - dt[35]= dt[34]= dt[33]= dt[32]= dt[31]= dt[30]= - dt[29]= dt[28]= dt[27]= dt[26]= dt[25]= dt[24]= - dt[23]= dt[22]= dt[21]= dt[20]= dt[19]= dt[18]= - dt[17]= dt[16]= dt[15]= dt[14]= dt[13]= dt[12]= - dt[11]= dt[10]= dt[ 9]= dt[ 8]= dt[ 7]= dt[ 6]= - dt[ 5]= dt[ 4]= dt[ 3]= dt[ 2]= dt[ 1]=Zero; - - pdn_0=pdn[0]; - pdm1_0=pdm1[0]; - - digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16); - pdtj=&(dt[0]); - - for(j=0;j<32;j++,pdtj++) - { - - m2j=pdm2[j]; - a=pdtj[0]+pdn_0*digit; - b=pdtj[1]+pdm1_0*pdm2[j+1]+a*TwoToMinus16; - pdtj[1]=b; - - /**** this loop will be fully unrolled: - for(i=1;i<16;i++) - { - pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit; - } - *************************************/ - pdtj[2]+=pdm1[1]*m2j+pdn[1]*digit; - pdtj[4]+=pdm1[2]*m2j+pdn[2]*digit; - pdtj[6]+=pdm1[3]*m2j+pdn[3]*digit; - pdtj[8]+=pdm1[4]*m2j+pdn[4]*digit; - pdtj[10]+=pdm1[5]*m2j+pdn[5]*digit; - pdtj[12]+=pdm1[6]*m2j+pdn[6]*digit; - pdtj[14]+=pdm1[7]*m2j+pdn[7]*digit; - pdtj[16]+=pdm1[8]*m2j+pdn[8]*digit; - pdtj[18]+=pdm1[9]*m2j+pdn[9]*digit; - pdtj[20]+=pdm1[10]*m2j+pdn[10]*digit; - pdtj[22]+=pdm1[11]*m2j+pdn[11]*digit; - pdtj[24]+=pdm1[12]*m2j+pdn[12]*digit; - pdtj[26]+=pdm1[13]*m2j+pdn[13]*digit; - pdtj[28]+=pdm1[14]*m2j+pdn[14]*digit; - pdtj[30]+=pdm1[15]*m2j+pdn[15]*digit; - /* no need for cleenup, cannot overflow */ - digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16); - } - } - - conv_d16_to_i32(result,dt+2*nlen,(long long *)dt,nlen+1); - - adjust_montf_result(result,nint,nlen); - + for (i = 1; i < nlen; i++) { + pdtj[2 * i] += pdm1[i] * m2j + pdn[i] * digit; + } + if ((jj == 30)) { + cleanup(dt, j / 2 + 1, 2 * nlen + 1); + jj = 0; + } + + digit = mod(lower32(b, Zero) * dn0, TwoToMinus16, TwoTo16); + } + } else { + a = dt[0] = pdm1[0] * pdm2[0]; + + dt[65] = dt[64] = dt[63] = dt[62] = dt[61] = dt[60] = + dt[59] = dt[58] = dt[57] = dt[56] = dt[55] = dt[54] = + dt[53] = dt[52] = dt[51] = dt[50] = dt[49] = dt[48] = + dt[47] = dt[46] = dt[45] = dt[44] = dt[43] = dt[42] = + dt[41] = dt[40] = dt[39] = dt[38] = dt[37] = dt[36] = + dt[35] = dt[34] = dt[33] = dt[32] = dt[31] = dt[30] = + dt[29] = dt[28] = dt[27] = dt[26] = dt[25] = dt[24] = + dt[23] = dt[22] = dt[21] = dt[20] = dt[19] = dt[18] = + dt[17] = dt[16] = dt[15] = dt[14] = dt[13] = dt[12] = + dt[11] = dt[10] = dt[9] = dt[8] = dt[7] = dt[6] = + dt[5] = dt[4] = dt[3] = dt[2] = dt[1] = Zero; + + pdn_0 = pdn[0]; + pdm1_0 = pdm1[0]; + + digit = mod(lower32(a, Zero) * dn0, TwoToMinus16, TwoTo16); + pdtj = &(dt[0]); + + for (j = 0; j < 32; j++, pdtj++) { + + m2j = pdm2[j]; + a = pdtj[0] + pdn_0 * digit; + b = pdtj[1] + pdm1_0 * pdm2[j + 1] + a * TwoToMinus16; + pdtj[1] = b; + + /**** this loop will be fully unrolled: + for(i=1;i<16;i++) + { + pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit; + } + *************************************/ + pdtj[2] += pdm1[1] * m2j + pdn[1] * digit; + pdtj[4] += pdm1[2] * m2j + pdn[2] * digit; + pdtj[6] += pdm1[3] * m2j + pdn[3] * digit; + pdtj[8] += pdm1[4] * m2j + pdn[4] * digit; + pdtj[10] += pdm1[5] * m2j + pdn[5] * digit; + pdtj[12] += pdm1[6] * m2j + pdn[6] * digit; + pdtj[14] += pdm1[7] * m2j + pdn[7] * digit; + pdtj[16] += pdm1[8] * m2j + pdn[8] * digit; + pdtj[18] += pdm1[9] * m2j + pdn[9] * digit; + pdtj[20] += pdm1[10] * m2j + pdn[10] * digit; + pdtj[22] += pdm1[11] * m2j + pdn[11] * digit; + pdtj[24] += pdm1[12] * m2j + pdn[12] * digit; + pdtj[26] += pdm1[13] * m2j + pdn[13] * digit; + pdtj[28] += pdm1[14] * m2j + pdn[14] * digit; + pdtj[30] += pdm1[15] * m2j + pdn[15] * digit; + /* no need for cleenup, cannot overflow */ + digit = mod(lower32(b, Zero) * dn0, TwoToMinus16, TwoTo16); + } + } + + conv_d16_to_i32(result, dt + 2 * nlen, (long long *)dt, nlen + 1); + + adjust_montf_result(result, nint, nlen); } - diff --git a/nss/lib/freebl/mpi/montmulf.h b/nss/lib/freebl/mpi/montmulf.h index 7039c0b..69bed4a 100644 --- a/nss/lib/freebl/mpi/montmulf.h +++ b/nss/lib/freebl/mpi/montmulf.h @@ -6,7 +6,6 @@ * following interfaces and array size requirements: */ - void conv_i32_to_d32(double *d32, unsigned int *i32, int len); /* Converts an array of int's to an array of doubles, so that each double @@ -16,7 +15,6 @@ void conv_i32_to_d32(double *d32, unsigned int *i32, int len); * (doubles and unsigned ints, respectively) */ - void conv_i32_to_d16(double *d16, unsigned int *i32, int len); /* Converts an array of int's to an array of doubles so that each element @@ -29,24 +27,22 @@ void conv_i32_to_d16(double *d16, unsigned int *i32, int len); * 2*len and i32 should point an array of ints of size at least len */ - -void conv_i32_to_d32_and_d16(double *d32, double *d16, - unsigned int *i32, int len); +void conv_i32_to_d32_and_d16(double *d32, double *d16, + unsigned int *i32, int len); /* Does the above two conversions together, it is much faster than doing * both of those in succession */ - void mont_mulf_noconv(unsigned int *result, - double *dm1, double *dm2, double *dt, - double *dn, unsigned int *nint, - int nlen, double dn0); + double *dm1, double *dm2, double *dt, + double *dn, unsigned int *nint, + int nlen, double dn0); /* Does the Montgomery multiplication of the numbers stored in the arrays * pointed to by dm1 and dm2, writing the result to the array pointed to by * result. It uses the array pointed to by dt as a temporary work area. - * nint should point to the modulus in the array-of-integers representation, + * nint should point to the modulus in the array-of-integers representation, * dn should point to its array-of-doubles as obtained as a result of the * function call conv_i32_to_d32(dn, nint, nlen); * nlen is the length of the array containing the modulus. @@ -54,10 +50,10 @@ void mont_mulf_noconv(unsigned int *result, * call conv_i32_to_d32(dm1, m1, nlen), the representation for dm2 is the * result of the function call conv_i32_to_d16(dm2, m2, nlen). * Note that m1 and m2 should both be of length nlen, so they should be - * padded with 0's if necessary before the conversion. The result comes in + * padded with 0's if necessary before the conversion. The result comes in * this form (int representation, padded with 0's). * dn0 is the value of the 16 least significant bits of n0'. - * The function does not allocate memory for any of the arrays, so the + * The function does not allocate memory for any of the arrays, so the * pointers should point to arrays with the following minimal sizes: * result - nlen+1 * dm1 - nlen @@ -66,4 +62,4 @@ void mont_mulf_noconv(unsigned int *result, * dn - nlen * nint - nlen * No two arrays should point to overlapping areas of memory. - */ + */ diff --git a/nss/lib/freebl/mpi/mp_comba.c b/nss/lib/freebl/mpi/mp_comba.c index f12f454..3b4937b 100644 --- a/nss/lib/freebl/mpi/mp_comba.c +++ b/nss/lib/freebl/mpi/mp_comba.c @@ -10,1289 +10,3226 @@ */ /* TomsFastMath, a fast ISO C bignum library. - * + * * This project is meant to fill in where LibTomMath * falls short. That is speed ;-) * * This project is public domain and free for all purposes. - * + * * Tom St Denis, tomstdenis@iahu.ca */ - #include "mpi-priv.h" - - /* clamp digits */ -#define mp_clamp(a) { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : ZPOS; } +#define mp_clamp(a) \ + { \ + while ((a)->used && (a)->dp[(a)->used - 1] == 0) \ + --((a)->used); \ + (a)->sign = (a)->used ? (a)->sign : ZPOS; \ + } /* anything you need at the start */ #define COMBA_START /* clear the chaining variables */ #define COMBA_CLEAR \ - c0 = c1 = c2 = 0; + c0 = c1 = c2 = 0; /* forward the carry to the next digit */ #define COMBA_FORWARD \ - do { c0 = c1; c1 = c2; c2 = 0; } while (0); + do { \ + c0 = c1; \ + c1 = c2; \ + c2 = 0; \ + } while (0); /* anything you need at the end */ #define COMBA_FINI /* this should multiply i and j */ -#define MULADD(i, j) \ -__asm__ ( \ - "movq %6,%%rax \n\t" \ - "mulq %7 \n\t" \ - "addq %%rax,%0 \n\t" \ - "adcq %%rdx,%1 \n\t" \ - "adcq $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","cc"); - - - +#define MULADD(i, j) \ + __asm__( \ + "movq %6,%%rax \n\t" \ + "mulq %7 \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + : "=r"(c0), "=r"(c1), "=r"(c2) \ + : "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) \ + : "%rax", "%rdx", "cc"); /* sqr macros only */ #define CLEAR_CARRY \ - c0 = c1 = c2 = 0; + c0 = c1 = c2 = 0; #define COMBA_STORE(x) \ - x = c0; + x = c0; #define COMBA_STORE2(x) \ - x = c1; + x = c1; #define CARRY_FORWARD \ - do { c0 = c1; c1 = c2; c2 = 0; } while (0); + do { \ + c0 = c1; \ + c1 = c2; \ + c2 = 0; \ + } while (0); #define COMBA_FINI -#define SQRADD(i, j) \ -__asm__ ( \ - "movq %6,%%rax \n\t" \ - "mulq %%rax \n\t" \ - "addq %%rax,%0 \n\t" \ - "adcq %%rdx,%1 \n\t" \ - "adcq $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","cc"); - -#define SQRADD2(i, j) \ -__asm__ ( \ - "movq %6,%%rax \n\t" \ - "mulq %7 \n\t" \ - "addq %%rax,%0 \n\t" \ - "adcq %%rdx,%1 \n\t" \ - "adcq $0,%2 \n\t" \ - "addq %%rax,%0 \n\t" \ - "adcq %%rdx,%1 \n\t" \ - "adcq $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","cc"); - -#define SQRADDSC(i, j) \ -__asm__ ( \ - "movq %3,%%rax \n\t" \ - "mulq %4 \n\t" \ - "movq %%rax,%0 \n\t" \ - "movq %%rdx,%1 \n\t" \ - "xorq %2,%2 \n\t" \ - :"=r"(sc0), "=r"(sc1), "=r"(sc2): "g"(i), "g"(j) :"%rax","%rdx","cc"); - -#define SQRADDAC(i, j) \ -__asm__ ( \ - "movq %6,%%rax \n\t" \ - "mulq %7 \n\t" \ - "addq %%rax,%0 \n\t" \ - "adcq %%rdx,%1 \n\t" \ - "adcq $0,%2 \n\t" \ - :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","cc"); - -#define SQRADDDB \ -__asm__ ( \ - "addq %6,%0 \n\t" \ - "adcq %7,%1 \n\t" \ - "adcq %8,%2 \n\t" \ - "addq %6,%0 \n\t" \ - "adcq %7,%1 \n\t" \ - "adcq %8,%2 \n\t" \ - :"=&r"(c0), "=&r"(c1), "=&r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "cc"); - - - - - -void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C) +#define SQRADD(i, j) \ + __asm__( \ + "movq %6,%%rax \n\t" \ + "mulq %%rax \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + : "=r"(c0), "=r"(c1), "=r"(c2) \ + : "0"(c0), "1"(c1), "2"(c2), "g"(i) \ + : "%rax", "%rdx", "cc"); + +#define SQRADD2(i, j) \ + __asm__( \ + "movq %6,%%rax \n\t" \ + "mulq %7 \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + : "=r"(c0), "=r"(c1), "=r"(c2) \ + : "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) \ + : "%rax", "%rdx", "cc"); + +#define SQRADDSC(i, j) \ + __asm__( \ + "movq %3,%%rax \n\t" \ + "mulq %4 \n\t" \ + "movq %%rax,%0 \n\t" \ + "movq %%rdx,%1 \n\t" \ + "xorq %2,%2 \n\t" \ + : "=r"(sc0), "=r"(sc1), "=r"(sc2) \ + : "g"(i), "g"(j) \ + : "%rax", "%rdx", "cc"); + +#define SQRADDAC(i, j) \ + __asm__( \ + "movq %6,%%rax \n\t" \ + "mulq %7 \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + : "=r"(sc0), "=r"(sc1), "=r"(sc2) \ + : "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) \ + : "%rax", "%rdx", "cc"); + +#define SQRADDDB \ + __asm__( \ + "addq %6,%0 \n\t" \ + "adcq %7,%1 \n\t" \ + "adcq %8,%2 \n\t" \ + "addq %6,%0 \n\t" \ + "adcq %7,%1 \n\t" \ + "adcq %8,%2 \n\t" \ + : "=&r"(c0), "=&r"(c1), "=&r"(c2) \ + : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) \ + : "cc"); + +void +s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C) { - mp_digit c0, c1, c2, at[8]; - - memcpy(at, A->dp, 4 * sizeof(mp_digit)); - memcpy(at+4, B->dp, 4 * sizeof(mp_digit)); - COMBA_START; - - COMBA_CLEAR; - /* 0 */ - MULADD(at[0], at[4]); - COMBA_STORE(C->dp[0]); - /* 1 */ - COMBA_FORWARD; - MULADD(at[0], at[5]); MULADD(at[1], at[4]); - COMBA_STORE(C->dp[1]); - /* 2 */ - COMBA_FORWARD; - MULADD(at[0], at[6]); MULADD(at[1], at[5]); MULADD(at[2], at[4]); - COMBA_STORE(C->dp[2]); - /* 3 */ - COMBA_FORWARD; - MULADD(at[0], at[7]); MULADD(at[1], at[6]); MULADD(at[2], at[5]); MULADD(at[3], at[4]); - COMBA_STORE(C->dp[3]); - /* 4 */ - COMBA_FORWARD; - MULADD(at[1], at[7]); MULADD(at[2], at[6]); MULADD(at[3], at[5]); - COMBA_STORE(C->dp[4]); - /* 5 */ - COMBA_FORWARD; - MULADD(at[2], at[7]); MULADD(at[3], at[6]); - COMBA_STORE(C->dp[5]); - /* 6 */ - COMBA_FORWARD; - MULADD(at[3], at[7]); - COMBA_STORE(C->dp[6]); - COMBA_STORE2(C->dp[7]); - C->used = 8; - C->sign = A->sign ^ B->sign; - mp_clamp(C); - COMBA_FINI; + mp_digit c0, c1, c2, at[8]; + + memcpy(at, A->dp, 4 * sizeof(mp_digit)); + memcpy(at + 4, B->dp, 4 * sizeof(mp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[4]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[5]); + MULADD(at[1], at[4]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[6]); + MULADD(at[1], at[5]); + MULADD(at[2], at[4]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[7]); + MULADD(at[1], at[6]); + MULADD(at[2], at[5]); + MULADD(at[3], at[4]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[1], at[7]); + MULADD(at[2], at[6]); + MULADD(at[3], at[5]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[2], at[7]); + MULADD(at[3], at[6]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[3], at[7]); + COMBA_STORE(C->dp[6]); + COMBA_STORE2(C->dp[7]); + C->used = 8; + C->sign = A->sign ^ B->sign; + mp_clamp(C); + COMBA_FINI; } -void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C) +void +s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C) { - mp_digit c0, c1, c2, at[16]; - - memcpy(at, A->dp, 8 * sizeof(mp_digit)); - memcpy(at+8, B->dp, 8 * sizeof(mp_digit)); - COMBA_START; - - COMBA_CLEAR; - /* 0 */ - MULADD(at[0], at[8]); - COMBA_STORE(C->dp[0]); - /* 1 */ - COMBA_FORWARD; - MULADD(at[0], at[9]); MULADD(at[1], at[8]); - COMBA_STORE(C->dp[1]); - /* 2 */ - COMBA_FORWARD; - MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]); - COMBA_STORE(C->dp[2]); - /* 3 */ - COMBA_FORWARD; - MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]); - COMBA_STORE(C->dp[3]); - /* 4 */ - COMBA_FORWARD; - MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]); - COMBA_STORE(C->dp[4]); - /* 5 */ - COMBA_FORWARD; - MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]); - COMBA_STORE(C->dp[5]); - /* 6 */ - COMBA_FORWARD; - MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); MULADD(at[6], at[8]); - COMBA_STORE(C->dp[6]); - /* 7 */ - COMBA_FORWARD; - MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); MULADD(at[6], at[9]); MULADD(at[7], at[8]); - COMBA_STORE(C->dp[7]); - /* 8 */ - COMBA_FORWARD; - MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); MULADD(at[7], at[9]); - COMBA_STORE(C->dp[8]); - /* 9 */ - COMBA_FORWARD; - MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); MULADD(at[7], at[10]); - COMBA_STORE(C->dp[9]); - /* 10 */ - COMBA_FORWARD; - MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); MULADD(at[7], at[11]); - COMBA_STORE(C->dp[10]); - /* 11 */ - COMBA_FORWARD; - MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]); - COMBA_STORE(C->dp[11]); - /* 12 */ - COMBA_FORWARD; - MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); - COMBA_STORE(C->dp[12]); - /* 13 */ - COMBA_FORWARD; - MULADD(at[6], at[15]); MULADD(at[7], at[14]); - COMBA_STORE(C->dp[13]); - /* 14 */ - COMBA_FORWARD; - MULADD(at[7], at[15]); - COMBA_STORE(C->dp[14]); - COMBA_STORE2(C->dp[15]); - C->used = 16; - C->sign = A->sign ^ B->sign; - mp_clamp(C); - COMBA_FINI; + mp_digit c0, c1, c2, at[16]; + + memcpy(at, A->dp, 8 * sizeof(mp_digit)); + memcpy(at + 8, B->dp, 8 * sizeof(mp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[8]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[9]); + MULADD(at[1], at[8]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[10]); + MULADD(at[1], at[9]); + MULADD(at[2], at[8]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); + MULADD(at[1], at[10]); + MULADD(at[2], at[9]); + MULADD(at[3], at[8]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[12]); + MULADD(at[1], at[11]); + MULADD(at[2], at[10]); + MULADD(at[3], at[9]); + MULADD(at[4], at[8]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); + MULADD(at[1], at[12]); + MULADD(at[2], at[11]); + MULADD(at[3], at[10]); + MULADD(at[4], at[9]); + MULADD(at[5], at[8]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); + MULADD(at[1], at[13]); + MULADD(at[2], at[12]); + MULADD(at[3], at[11]); + MULADD(at[4], at[10]); + MULADD(at[5], at[9]); + MULADD(at[6], at[8]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); + MULADD(at[1], at[14]); + MULADD(at[2], at[13]); + MULADD(at[3], at[12]); + MULADD(at[4], at[11]); + MULADD(at[5], at[10]); + MULADD(at[6], at[9]); + MULADD(at[7], at[8]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[1], at[15]); + MULADD(at[2], at[14]); + MULADD(at[3], at[13]); + MULADD(at[4], at[12]); + MULADD(at[5], at[11]); + MULADD(at[6], at[10]); + MULADD(at[7], at[9]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[2], at[15]); + MULADD(at[3], at[14]); + MULADD(at[4], at[13]); + MULADD(at[5], at[12]); + MULADD(at[6], at[11]); + MULADD(at[7], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[3], at[15]); + MULADD(at[4], at[14]); + MULADD(at[5], at[13]); + MULADD(at[6], at[12]); + MULADD(at[7], at[11]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[4], at[15]); + MULADD(at[5], at[14]); + MULADD(at[6], at[13]); + MULADD(at[7], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[5], at[15]); + MULADD(at[6], at[14]); + MULADD(at[7], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[6], at[15]); + MULADD(at[7], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[7], at[15]); + COMBA_STORE(C->dp[14]); + COMBA_STORE2(C->dp[15]); + C->used = 16; + C->sign = A->sign ^ B->sign; + mp_clamp(C); + COMBA_FINI; } -void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C) +void +s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C) { - mp_digit c0, c1, c2, at[32]; - - memcpy(at, A->dp, 16 * sizeof(mp_digit)); - memcpy(at+16, B->dp, 16 * sizeof(mp_digit)); - COMBA_START; - - COMBA_CLEAR; - /* 0 */ - MULADD(at[0], at[16]); - COMBA_STORE(C->dp[0]); - /* 1 */ - COMBA_FORWARD; - MULADD(at[0], at[17]); MULADD(at[1], at[16]); - COMBA_STORE(C->dp[1]); - /* 2 */ - COMBA_FORWARD; - MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); - COMBA_STORE(C->dp[2]); - /* 3 */ - COMBA_FORWARD; - MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); - COMBA_STORE(C->dp[3]); - /* 4 */ - COMBA_FORWARD; - MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); - COMBA_STORE(C->dp[4]); - /* 5 */ - COMBA_FORWARD; - MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); - COMBA_STORE(C->dp[5]); - /* 6 */ - COMBA_FORWARD; - MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); - COMBA_STORE(C->dp[6]); - /* 7 */ - COMBA_FORWARD; - MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); - COMBA_STORE(C->dp[7]); - /* 8 */ - COMBA_FORWARD; - MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); - COMBA_STORE(C->dp[8]); - /* 9 */ - COMBA_FORWARD; - MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); - COMBA_STORE(C->dp[9]); - /* 10 */ - COMBA_FORWARD; - MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]); - COMBA_STORE(C->dp[10]); - /* 11 */ - COMBA_FORWARD; - MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]); - COMBA_STORE(C->dp[11]); - /* 12 */ - COMBA_FORWARD; - MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]); - COMBA_STORE(C->dp[12]); - /* 13 */ - COMBA_FORWARD; - MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); MULADD(at[13], at[16]); - COMBA_STORE(C->dp[13]); - /* 14 */ - COMBA_FORWARD; - MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); MULADD(at[14], at[16]); - COMBA_STORE(C->dp[14]); - /* 15 */ - COMBA_FORWARD; - MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); MULADD(at[14], at[17]); MULADD(at[15], at[16]); - COMBA_STORE(C->dp[15]); - /* 16 */ - COMBA_FORWARD; - MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); MULADD(at[14], at[18]); MULADD(at[15], at[17]); - COMBA_STORE(C->dp[16]); - /* 17 */ - COMBA_FORWARD; - MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); MULADD(at[14], at[19]); MULADD(at[15], at[18]); - COMBA_STORE(C->dp[17]); - /* 18 */ - COMBA_FORWARD; - MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); MULADD(at[15], at[19]); - COMBA_STORE(C->dp[18]); - /* 19 */ - COMBA_FORWARD; - MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); MULADD(at[15], at[20]); - COMBA_STORE(C->dp[19]); - /* 20 */ - COMBA_FORWARD; - MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); MULADD(at[15], at[21]); - COMBA_STORE(C->dp[20]); - /* 21 */ - COMBA_FORWARD; - MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); MULADD(at[15], at[22]); - COMBA_STORE(C->dp[21]); - /* 22 */ - COMBA_FORWARD; - MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); MULADD(at[15], at[23]); - COMBA_STORE(C->dp[22]); - /* 23 */ - COMBA_FORWARD; - MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]); - COMBA_STORE(C->dp[23]); - /* 24 */ - COMBA_FORWARD; - MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]); - COMBA_STORE(C->dp[24]); - /* 25 */ - COMBA_FORWARD; - MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]); - COMBA_STORE(C->dp[25]); - /* 26 */ - COMBA_FORWARD; - MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]); - COMBA_STORE(C->dp[26]); - /* 27 */ - COMBA_FORWARD; - MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]); - COMBA_STORE(C->dp[27]); - /* 28 */ - COMBA_FORWARD; - MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]); - COMBA_STORE(C->dp[28]); - /* 29 */ - COMBA_FORWARD; - MULADD(at[14], at[31]); MULADD(at[15], at[30]); - COMBA_STORE(C->dp[29]); - /* 30 */ - COMBA_FORWARD; - MULADD(at[15], at[31]); - COMBA_STORE(C->dp[30]); - COMBA_STORE2(C->dp[31]); - C->used = 32; - C->sign = A->sign ^ B->sign; - mp_clamp(C); - COMBA_FINI; + mp_digit c0, c1, c2, at[32]; + + memcpy(at, A->dp, 16 * sizeof(mp_digit)); + memcpy(at + 16, B->dp, 16 * sizeof(mp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[16]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); + MULADD(at[1], at[16]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); + MULADD(at[1], at[17]); + MULADD(at[2], at[16]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); + MULADD(at[1], at[18]); + MULADD(at[2], at[17]); + MULADD(at[3], at[16]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[20]); + MULADD(at[1], at[19]); + MULADD(at[2], at[18]); + MULADD(at[3], at[17]); + MULADD(at[4], at[16]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); + MULADD(at[1], at[20]); + MULADD(at[2], at[19]); + MULADD(at[3], at[18]); + MULADD(at[4], at[17]); + MULADD(at[5], at[16]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[22]); + MULADD(at[1], at[21]); + MULADD(at[2], at[20]); + MULADD(at[3], at[19]); + MULADD(at[4], at[18]); + MULADD(at[5], at[17]); + MULADD(at[6], at[16]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[23]); + MULADD(at[1], at[22]); + MULADD(at[2], at[21]); + MULADD(at[3], at[20]); + MULADD(at[4], at[19]); + MULADD(at[5], at[18]); + MULADD(at[6], at[17]); + MULADD(at[7], at[16]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[24]); + MULADD(at[1], at[23]); + MULADD(at[2], at[22]); + MULADD(at[3], at[21]); + MULADD(at[4], at[20]); + MULADD(at[5], at[19]); + MULADD(at[6], at[18]); + MULADD(at[7], at[17]); + MULADD(at[8], at[16]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[25]); + MULADD(at[1], at[24]); + MULADD(at[2], at[23]); + MULADD(at[3], at[22]); + MULADD(at[4], at[21]); + MULADD(at[5], at[20]); + MULADD(at[6], at[19]); + MULADD(at[7], at[18]); + MULADD(at[8], at[17]); + MULADD(at[9], at[16]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[26]); + MULADD(at[1], at[25]); + MULADD(at[2], at[24]); + MULADD(at[3], at[23]); + MULADD(at[4], at[22]); + MULADD(at[5], at[21]); + MULADD(at[6], at[20]); + MULADD(at[7], at[19]); + MULADD(at[8], at[18]); + MULADD(at[9], at[17]); + MULADD(at[10], at[16]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[27]); + MULADD(at[1], at[26]); + MULADD(at[2], at[25]); + MULADD(at[3], at[24]); + MULADD(at[4], at[23]); + MULADD(at[5], at[22]); + MULADD(at[6], at[21]); + MULADD(at[7], at[20]); + MULADD(at[8], at[19]); + MULADD(at[9], at[18]); + MULADD(at[10], at[17]); + MULADD(at[11], at[16]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[28]); + MULADD(at[1], at[27]); + MULADD(at[2], at[26]); + MULADD(at[3], at[25]); + MULADD(at[4], at[24]); + MULADD(at[5], at[23]); + MULADD(at[6], at[22]); + MULADD(at[7], at[21]); + MULADD(at[8], at[20]); + MULADD(at[9], at[19]); + MULADD(at[10], at[18]); + MULADD(at[11], at[17]); + MULADD(at[12], at[16]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[29]); + MULADD(at[1], at[28]); + MULADD(at[2], at[27]); + MULADD(at[3], at[26]); + MULADD(at[4], at[25]); + MULADD(at[5], at[24]); + MULADD(at[6], at[23]); + MULADD(at[7], at[22]); + MULADD(at[8], at[21]); + MULADD(at[9], at[20]); + MULADD(at[10], at[19]); + MULADD(at[11], at[18]); + MULADD(at[12], at[17]); + MULADD(at[13], at[16]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[30]); + MULADD(at[1], at[29]); + MULADD(at[2], at[28]); + MULADD(at[3], at[27]); + MULADD(at[4], at[26]); + MULADD(at[5], at[25]); + MULADD(at[6], at[24]); + MULADD(at[7], at[23]); + MULADD(at[8], at[22]); + MULADD(at[9], at[21]); + MULADD(at[10], at[20]); + MULADD(at[11], at[19]); + MULADD(at[12], at[18]); + MULADD(at[13], at[17]); + MULADD(at[14], at[16]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[31]); + MULADD(at[1], at[30]); + MULADD(at[2], at[29]); + MULADD(at[3], at[28]); + MULADD(at[4], at[27]); + MULADD(at[5], at[26]); + MULADD(at[6], at[25]); + MULADD(at[7], at[24]); + MULADD(at[8], at[23]); + MULADD(at[9], at[22]); + MULADD(at[10], at[21]); + MULADD(at[11], at[20]); + MULADD(at[12], at[19]); + MULADD(at[13], at[18]); + MULADD(at[14], at[17]); + MULADD(at[15], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[1], at[31]); + MULADD(at[2], at[30]); + MULADD(at[3], at[29]); + MULADD(at[4], at[28]); + MULADD(at[5], at[27]); + MULADD(at[6], at[26]); + MULADD(at[7], at[25]); + MULADD(at[8], at[24]); + MULADD(at[9], at[23]); + MULADD(at[10], at[22]); + MULADD(at[11], at[21]); + MULADD(at[12], at[20]); + MULADD(at[13], at[19]); + MULADD(at[14], at[18]); + MULADD(at[15], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[2], at[31]); + MULADD(at[3], at[30]); + MULADD(at[4], at[29]); + MULADD(at[5], at[28]); + MULADD(at[6], at[27]); + MULADD(at[7], at[26]); + MULADD(at[8], at[25]); + MULADD(at[9], at[24]); + MULADD(at[10], at[23]); + MULADD(at[11], at[22]); + MULADD(at[12], at[21]); + MULADD(at[13], at[20]); + MULADD(at[14], at[19]); + MULADD(at[15], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[3], at[31]); + MULADD(at[4], at[30]); + MULADD(at[5], at[29]); + MULADD(at[6], at[28]); + MULADD(at[7], at[27]); + MULADD(at[8], at[26]); + MULADD(at[9], at[25]); + MULADD(at[10], at[24]); + MULADD(at[11], at[23]); + MULADD(at[12], at[22]); + MULADD(at[13], at[21]); + MULADD(at[14], at[20]); + MULADD(at[15], at[19]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[4], at[31]); + MULADD(at[5], at[30]); + MULADD(at[6], at[29]); + MULADD(at[7], at[28]); + MULADD(at[8], at[27]); + MULADD(at[9], at[26]); + MULADD(at[10], at[25]); + MULADD(at[11], at[24]); + MULADD(at[12], at[23]); + MULADD(at[13], at[22]); + MULADD(at[14], at[21]); + MULADD(at[15], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[5], at[31]); + MULADD(at[6], at[30]); + MULADD(at[7], at[29]); + MULADD(at[8], at[28]); + MULADD(at[9], at[27]); + MULADD(at[10], at[26]); + MULADD(at[11], at[25]); + MULADD(at[12], at[24]); + MULADD(at[13], at[23]); + MULADD(at[14], at[22]); + MULADD(at[15], at[21]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[6], at[31]); + MULADD(at[7], at[30]); + MULADD(at[8], at[29]); + MULADD(at[9], at[28]); + MULADD(at[10], at[27]); + MULADD(at[11], at[26]); + MULADD(at[12], at[25]); + MULADD(at[13], at[24]); + MULADD(at[14], at[23]); + MULADD(at[15], at[22]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[7], at[31]); + MULADD(at[8], at[30]); + MULADD(at[9], at[29]); + MULADD(at[10], at[28]); + MULADD(at[11], at[27]); + MULADD(at[12], at[26]); + MULADD(at[13], at[25]); + MULADD(at[14], at[24]); + MULADD(at[15], at[23]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[8], at[31]); + MULADD(at[9], at[30]); + MULADD(at[10], at[29]); + MULADD(at[11], at[28]); + MULADD(at[12], at[27]); + MULADD(at[13], at[26]); + MULADD(at[14], at[25]); + MULADD(at[15], at[24]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[9], at[31]); + MULADD(at[10], at[30]); + MULADD(at[11], at[29]); + MULADD(at[12], at[28]); + MULADD(at[13], at[27]); + MULADD(at[14], at[26]); + MULADD(at[15], at[25]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[10], at[31]); + MULADD(at[11], at[30]); + MULADD(at[12], at[29]); + MULADD(at[13], at[28]); + MULADD(at[14], at[27]); + MULADD(at[15], at[26]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[11], at[31]); + MULADD(at[12], at[30]); + MULADD(at[13], at[29]); + MULADD(at[14], at[28]); + MULADD(at[15], at[27]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[12], at[31]); + MULADD(at[13], at[30]); + MULADD(at[14], at[29]); + MULADD(at[15], at[28]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[13], at[31]); + MULADD(at[14], at[30]); + MULADD(at[15], at[29]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[14], at[31]); + MULADD(at[15], at[30]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[15], at[31]); + COMBA_STORE(C->dp[30]); + COMBA_STORE2(C->dp[31]); + C->used = 32; + C->sign = A->sign ^ B->sign; + mp_clamp(C); + COMBA_FINI; } -void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C) +void +s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C) { - mp_digit c0, c1, c2, at[64]; - - memcpy(at, A->dp, 32 * sizeof(mp_digit)); - memcpy(at+32, B->dp, 32 * sizeof(mp_digit)); - COMBA_START; - - COMBA_CLEAR; - /* 0 */ - MULADD(at[0], at[32]); - COMBA_STORE(C->dp[0]); - /* 1 */ - COMBA_FORWARD; - MULADD(at[0], at[33]); MULADD(at[1], at[32]); - COMBA_STORE(C->dp[1]); - /* 2 */ - COMBA_FORWARD; - MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]); - COMBA_STORE(C->dp[2]); - /* 3 */ - COMBA_FORWARD; - MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]); - COMBA_STORE(C->dp[3]); - /* 4 */ - COMBA_FORWARD; - MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]); - COMBA_STORE(C->dp[4]); - /* 5 */ - COMBA_FORWARD; - MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]); - COMBA_STORE(C->dp[5]); - /* 6 */ - COMBA_FORWARD; - MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]); - COMBA_STORE(C->dp[6]); - /* 7 */ - COMBA_FORWARD; - MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]); - COMBA_STORE(C->dp[7]); - /* 8 */ - COMBA_FORWARD; - MULADD(at[0], at[40]); MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]); - COMBA_STORE(C->dp[8]); - /* 9 */ - COMBA_FORWARD; - MULADD(at[0], at[41]); MULADD(at[1], at[40]); MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]); - COMBA_STORE(C->dp[9]); - /* 10 */ - COMBA_FORWARD; - MULADD(at[0], at[42]); MULADD(at[1], at[41]); MULADD(at[2], at[40]); MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]); - COMBA_STORE(C->dp[10]); - /* 11 */ - COMBA_FORWARD; - MULADD(at[0], at[43]); MULADD(at[1], at[42]); MULADD(at[2], at[41]); MULADD(at[3], at[40]); MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]); - COMBA_STORE(C->dp[11]); - /* 12 */ - COMBA_FORWARD; - MULADD(at[0], at[44]); MULADD(at[1], at[43]); MULADD(at[2], at[42]); MULADD(at[3], at[41]); MULADD(at[4], at[40]); MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]); - COMBA_STORE(C->dp[12]); - /* 13 */ - COMBA_FORWARD; - MULADD(at[0], at[45]); MULADD(at[1], at[44]); MULADD(at[2], at[43]); MULADD(at[3], at[42]); MULADD(at[4], at[41]); MULADD(at[5], at[40]); MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]); - COMBA_STORE(C->dp[13]); - /* 14 */ - COMBA_FORWARD; - MULADD(at[0], at[46]); MULADD(at[1], at[45]); MULADD(at[2], at[44]); MULADD(at[3], at[43]); MULADD(at[4], at[42]); MULADD(at[5], at[41]); MULADD(at[6], at[40]); MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]); - COMBA_STORE(C->dp[14]); - /* 15 */ - COMBA_FORWARD; - MULADD(at[0], at[47]); MULADD(at[1], at[46]); MULADD(at[2], at[45]); MULADD(at[3], at[44]); MULADD(at[4], at[43]); MULADD(at[5], at[42]); MULADD(at[6], at[41]); MULADD(at[7], at[40]); MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]); - COMBA_STORE(C->dp[15]); - /* 16 */ - COMBA_FORWARD; - MULADD(at[0], at[48]); MULADD(at[1], at[47]); MULADD(at[2], at[46]); MULADD(at[3], at[45]); MULADD(at[4], at[44]); MULADD(at[5], at[43]); MULADD(at[6], at[42]); MULADD(at[7], at[41]); MULADD(at[8], at[40]); MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]); - COMBA_STORE(C->dp[16]); - /* 17 */ - COMBA_FORWARD; - MULADD(at[0], at[49]); MULADD(at[1], at[48]); MULADD(at[2], at[47]); MULADD(at[3], at[46]); MULADD(at[4], at[45]); MULADD(at[5], at[44]); MULADD(at[6], at[43]); MULADD(at[7], at[42]); MULADD(at[8], at[41]); MULADD(at[9], at[40]); MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]); - COMBA_STORE(C->dp[17]); - /* 18 */ - COMBA_FORWARD; - MULADD(at[0], at[50]); MULADD(at[1], at[49]); MULADD(at[2], at[48]); MULADD(at[3], at[47]); MULADD(at[4], at[46]); MULADD(at[5], at[45]); MULADD(at[6], at[44]); MULADD(at[7], at[43]); MULADD(at[8], at[42]); MULADD(at[9], at[41]); MULADD(at[10], at[40]); MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]); - COMBA_STORE(C->dp[18]); - /* 19 */ - COMBA_FORWARD; - MULADD(at[0], at[51]); MULADD(at[1], at[50]); MULADD(at[2], at[49]); MULADD(at[3], at[48]); MULADD(at[4], at[47]); MULADD(at[5], at[46]); MULADD(at[6], at[45]); MULADD(at[7], at[44]); MULADD(at[8], at[43]); MULADD(at[9], at[42]); MULADD(at[10], at[41]); MULADD(at[11], at[40]); MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]); - COMBA_STORE(C->dp[19]); - /* 20 */ - COMBA_FORWARD; - MULADD(at[0], at[52]); MULADD(at[1], at[51]); MULADD(at[2], at[50]); MULADD(at[3], at[49]); MULADD(at[4], at[48]); MULADD(at[5], at[47]); MULADD(at[6], at[46]); MULADD(at[7], at[45]); MULADD(at[8], at[44]); MULADD(at[9], at[43]); MULADD(at[10], at[42]); MULADD(at[11], at[41]); MULADD(at[12], at[40]); MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); MULADD(at[20], at[32]); - COMBA_STORE(C->dp[20]); - /* 21 */ - COMBA_FORWARD; - MULADD(at[0], at[53]); MULADD(at[1], at[52]); MULADD(at[2], at[51]); MULADD(at[3], at[50]); MULADD(at[4], at[49]); MULADD(at[5], at[48]); MULADD(at[6], at[47]); MULADD(at[7], at[46]); MULADD(at[8], at[45]); MULADD(at[9], at[44]); MULADD(at[10], at[43]); MULADD(at[11], at[42]); MULADD(at[12], at[41]); MULADD(at[13], at[40]); MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); MULADD(at[20], at[33]); MULADD(at[21], at[32]); - COMBA_STORE(C->dp[21]); - /* 22 */ - COMBA_FORWARD; - MULADD(at[0], at[54]); MULADD(at[1], at[53]); MULADD(at[2], at[52]); MULADD(at[3], at[51]); MULADD(at[4], at[50]); MULADD(at[5], at[49]); MULADD(at[6], at[48]); MULADD(at[7], at[47]); MULADD(at[8], at[46]); MULADD(at[9], at[45]); MULADD(at[10], at[44]); MULADD(at[11], at[43]); MULADD(at[12], at[42]); MULADD(at[13], at[41]); MULADD(at[14], at[40]); MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); MULADD(at[20], at[34]); MULADD(at[21], at[33]); MULADD(at[22], at[32]); - COMBA_STORE(C->dp[22]); - /* 23 */ - COMBA_FORWARD; - MULADD(at[0], at[55]); MULADD(at[1], at[54]); MULADD(at[2], at[53]); MULADD(at[3], at[52]); MULADD(at[4], at[51]); MULADD(at[5], at[50]); MULADD(at[6], at[49]); MULADD(at[7], at[48]); MULADD(at[8], at[47]); MULADD(at[9], at[46]); MULADD(at[10], at[45]); MULADD(at[11], at[44]); MULADD(at[12], at[43]); MULADD(at[13], at[42]); MULADD(at[14], at[41]); MULADD(at[15], at[40]); MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); MULADD(at[20], at[35]); MULADD(at[21], at[34]); MULADD(at[22], at[33]); MULADD(at[23], at[32]); - COMBA_STORE(C->dp[23]); - /* 24 */ - COMBA_FORWARD; - MULADD(at[0], at[56]); MULADD(at[1], at[55]); MULADD(at[2], at[54]); MULADD(at[3], at[53]); MULADD(at[4], at[52]); MULADD(at[5], at[51]); MULADD(at[6], at[50]); MULADD(at[7], at[49]); MULADD(at[8], at[48]); MULADD(at[9], at[47]); MULADD(at[10], at[46]); MULADD(at[11], at[45]); MULADD(at[12], at[44]); MULADD(at[13], at[43]); MULADD(at[14], at[42]); MULADD(at[15], at[41]); MULADD(at[16], at[40]); MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); MULADD(at[20], at[36]); MULADD(at[21], at[35]); MULADD(at[22], at[34]); MULADD(at[23], at[33]); MULADD(at[24], at[32]); - COMBA_STORE(C->dp[24]); - /* 25 */ - COMBA_FORWARD; - MULADD(at[0], at[57]); MULADD(at[1], at[56]); MULADD(at[2], at[55]); MULADD(at[3], at[54]); MULADD(at[4], at[53]); MULADD(at[5], at[52]); MULADD(at[6], at[51]); MULADD(at[7], at[50]); MULADD(at[8], at[49]); MULADD(at[9], at[48]); MULADD(at[10], at[47]); MULADD(at[11], at[46]); MULADD(at[12], at[45]); MULADD(at[13], at[44]); MULADD(at[14], at[43]); MULADD(at[15], at[42]); MULADD(at[16], at[41]); MULADD(at[17], at[40]); MULADD(at[18], at[39]); MULADD(at[19], at[38]); MULADD(at[20], at[37]); MULADD(at[21], at[36]); MULADD(at[22], at[35]); MULADD(at[23], at[34]); MULADD(at[24], at[33]); MULADD(at[25], at[32]); - COMBA_STORE(C->dp[25]); - /* 26 */ - COMBA_FORWARD; - MULADD(at[0], at[58]); MULADD(at[1], at[57]); MULADD(at[2], at[56]); MULADD(at[3], at[55]); MULADD(at[4], at[54]); MULADD(at[5], at[53]); MULADD(at[6], at[52]); MULADD(at[7], at[51]); MULADD(at[8], at[50]); MULADD(at[9], at[49]); MULADD(at[10], at[48]); MULADD(at[11], at[47]); MULADD(at[12], at[46]); MULADD(at[13], at[45]); MULADD(at[14], at[44]); MULADD(at[15], at[43]); MULADD(at[16], at[42]); MULADD(at[17], at[41]); MULADD(at[18], at[40]); MULADD(at[19], at[39]); MULADD(at[20], at[38]); MULADD(at[21], at[37]); MULADD(at[22], at[36]); MULADD(at[23], at[35]); MULADD(at[24], at[34]); MULADD(at[25], at[33]); MULADD(at[26], at[32]); - COMBA_STORE(C->dp[26]); - /* 27 */ - COMBA_FORWARD; - MULADD(at[0], at[59]); MULADD(at[1], at[58]); MULADD(at[2], at[57]); MULADD(at[3], at[56]); MULADD(at[4], at[55]); MULADD(at[5], at[54]); MULADD(at[6], at[53]); MULADD(at[7], at[52]); MULADD(at[8], at[51]); MULADD(at[9], at[50]); MULADD(at[10], at[49]); MULADD(at[11], at[48]); MULADD(at[12], at[47]); MULADD(at[13], at[46]); MULADD(at[14], at[45]); MULADD(at[15], at[44]); MULADD(at[16], at[43]); MULADD(at[17], at[42]); MULADD(at[18], at[41]); MULADD(at[19], at[40]); MULADD(at[20], at[39]); MULADD(at[21], at[38]); MULADD(at[22], at[37]); MULADD(at[23], at[36]); MULADD(at[24], at[35]); MULADD(at[25], at[34]); MULADD(at[26], at[33]); MULADD(at[27], at[32]); - COMBA_STORE(C->dp[27]); - /* 28 */ - COMBA_FORWARD; - MULADD(at[0], at[60]); MULADD(at[1], at[59]); MULADD(at[2], at[58]); MULADD(at[3], at[57]); MULADD(at[4], at[56]); MULADD(at[5], at[55]); MULADD(at[6], at[54]); MULADD(at[7], at[53]); MULADD(at[8], at[52]); MULADD(at[9], at[51]); MULADD(at[10], at[50]); MULADD(at[11], at[49]); MULADD(at[12], at[48]); MULADD(at[13], at[47]); MULADD(at[14], at[46]); MULADD(at[15], at[45]); MULADD(at[16], at[44]); MULADD(at[17], at[43]); MULADD(at[18], at[42]); MULADD(at[19], at[41]); MULADD(at[20], at[40]); MULADD(at[21], at[39]); MULADD(at[22], at[38]); MULADD(at[23], at[37]); MULADD(at[24], at[36]); MULADD(at[25], at[35]); MULADD(at[26], at[34]); MULADD(at[27], at[33]); MULADD(at[28], at[32]); - COMBA_STORE(C->dp[28]); - /* 29 */ - COMBA_FORWARD; - MULADD(at[0], at[61]); MULADD(at[1], at[60]); MULADD(at[2], at[59]); MULADD(at[3], at[58]); MULADD(at[4], at[57]); MULADD(at[5], at[56]); MULADD(at[6], at[55]); MULADD(at[7], at[54]); MULADD(at[8], at[53]); MULADD(at[9], at[52]); MULADD(at[10], at[51]); MULADD(at[11], at[50]); MULADD(at[12], at[49]); MULADD(at[13], at[48]); MULADD(at[14], at[47]); MULADD(at[15], at[46]); MULADD(at[16], at[45]); MULADD(at[17], at[44]); MULADD(at[18], at[43]); MULADD(at[19], at[42]); MULADD(at[20], at[41]); MULADD(at[21], at[40]); MULADD(at[22], at[39]); MULADD(at[23], at[38]); MULADD(at[24], at[37]); MULADD(at[25], at[36]); MULADD(at[26], at[35]); MULADD(at[27], at[34]); MULADD(at[28], at[33]); MULADD(at[29], at[32]); - COMBA_STORE(C->dp[29]); - /* 30 */ - COMBA_FORWARD; - MULADD(at[0], at[62]); MULADD(at[1], at[61]); MULADD(at[2], at[60]); MULADD(at[3], at[59]); MULADD(at[4], at[58]); MULADD(at[5], at[57]); MULADD(at[6], at[56]); MULADD(at[7], at[55]); MULADD(at[8], at[54]); MULADD(at[9], at[53]); MULADD(at[10], at[52]); MULADD(at[11], at[51]); MULADD(at[12], at[50]); MULADD(at[13], at[49]); MULADD(at[14], at[48]); MULADD(at[15], at[47]); MULADD(at[16], at[46]); MULADD(at[17], at[45]); MULADD(at[18], at[44]); MULADD(at[19], at[43]); MULADD(at[20], at[42]); MULADD(at[21], at[41]); MULADD(at[22], at[40]); MULADD(at[23], at[39]); MULADD(at[24], at[38]); MULADD(at[25], at[37]); MULADD(at[26], at[36]); MULADD(at[27], at[35]); MULADD(at[28], at[34]); MULADD(at[29], at[33]); MULADD(at[30], at[32]); - COMBA_STORE(C->dp[30]); - /* 31 */ - COMBA_FORWARD; - MULADD(at[0], at[63]); MULADD(at[1], at[62]); MULADD(at[2], at[61]); MULADD(at[3], at[60]); MULADD(at[4], at[59]); MULADD(at[5], at[58]); MULADD(at[6], at[57]); MULADD(at[7], at[56]); MULADD(at[8], at[55]); MULADD(at[9], at[54]); MULADD(at[10], at[53]); MULADD(at[11], at[52]); MULADD(at[12], at[51]); MULADD(at[13], at[50]); MULADD(at[14], at[49]); MULADD(at[15], at[48]); MULADD(at[16], at[47]); MULADD(at[17], at[46]); MULADD(at[18], at[45]); MULADD(at[19], at[44]); MULADD(at[20], at[43]); MULADD(at[21], at[42]); MULADD(at[22], at[41]); MULADD(at[23], at[40]); MULADD(at[24], at[39]); MULADD(at[25], at[38]); MULADD(at[26], at[37]); MULADD(at[27], at[36]); MULADD(at[28], at[35]); MULADD(at[29], at[34]); MULADD(at[30], at[33]); MULADD(at[31], at[32]); - COMBA_STORE(C->dp[31]); - /* 32 */ - COMBA_FORWARD; - MULADD(at[1], at[63]); MULADD(at[2], at[62]); MULADD(at[3], at[61]); MULADD(at[4], at[60]); MULADD(at[5], at[59]); MULADD(at[6], at[58]); MULADD(at[7], at[57]); MULADD(at[8], at[56]); MULADD(at[9], at[55]); MULADD(at[10], at[54]); MULADD(at[11], at[53]); MULADD(at[12], at[52]); MULADD(at[13], at[51]); MULADD(at[14], at[50]); MULADD(at[15], at[49]); MULADD(at[16], at[48]); MULADD(at[17], at[47]); MULADD(at[18], at[46]); MULADD(at[19], at[45]); MULADD(at[20], at[44]); MULADD(at[21], at[43]); MULADD(at[22], at[42]); MULADD(at[23], at[41]); MULADD(at[24], at[40]); MULADD(at[25], at[39]); MULADD(at[26], at[38]); MULADD(at[27], at[37]); MULADD(at[28], at[36]); MULADD(at[29], at[35]); MULADD(at[30], at[34]); MULADD(at[31], at[33]); - COMBA_STORE(C->dp[32]); - /* 33 */ - COMBA_FORWARD; - MULADD(at[2], at[63]); MULADD(at[3], at[62]); MULADD(at[4], at[61]); MULADD(at[5], at[60]); MULADD(at[6], at[59]); MULADD(at[7], at[58]); MULADD(at[8], at[57]); MULADD(at[9], at[56]); MULADD(at[10], at[55]); MULADD(at[11], at[54]); MULADD(at[12], at[53]); MULADD(at[13], at[52]); MULADD(at[14], at[51]); MULADD(at[15], at[50]); MULADD(at[16], at[49]); MULADD(at[17], at[48]); MULADD(at[18], at[47]); MULADD(at[19], at[46]); MULADD(at[20], at[45]); MULADD(at[21], at[44]); MULADD(at[22], at[43]); MULADD(at[23], at[42]); MULADD(at[24], at[41]); MULADD(at[25], at[40]); MULADD(at[26], at[39]); MULADD(at[27], at[38]); MULADD(at[28], at[37]); MULADD(at[29], at[36]); MULADD(at[30], at[35]); MULADD(at[31], at[34]); - COMBA_STORE(C->dp[33]); - /* 34 */ - COMBA_FORWARD; - MULADD(at[3], at[63]); MULADD(at[4], at[62]); MULADD(at[5], at[61]); MULADD(at[6], at[60]); MULADD(at[7], at[59]); MULADD(at[8], at[58]); MULADD(at[9], at[57]); MULADD(at[10], at[56]); MULADD(at[11], at[55]); MULADD(at[12], at[54]); MULADD(at[13], at[53]); MULADD(at[14], at[52]); MULADD(at[15], at[51]); MULADD(at[16], at[50]); MULADD(at[17], at[49]); MULADD(at[18], at[48]); MULADD(at[19], at[47]); MULADD(at[20], at[46]); MULADD(at[21], at[45]); MULADD(at[22], at[44]); MULADD(at[23], at[43]); MULADD(at[24], at[42]); MULADD(at[25], at[41]); MULADD(at[26], at[40]); MULADD(at[27], at[39]); MULADD(at[28], at[38]); MULADD(at[29], at[37]); MULADD(at[30], at[36]); MULADD(at[31], at[35]); - COMBA_STORE(C->dp[34]); - /* 35 */ - COMBA_FORWARD; - MULADD(at[4], at[63]); MULADD(at[5], at[62]); MULADD(at[6], at[61]); MULADD(at[7], at[60]); MULADD(at[8], at[59]); MULADD(at[9], at[58]); MULADD(at[10], at[57]); MULADD(at[11], at[56]); MULADD(at[12], at[55]); MULADD(at[13], at[54]); MULADD(at[14], at[53]); MULADD(at[15], at[52]); MULADD(at[16], at[51]); MULADD(at[17], at[50]); MULADD(at[18], at[49]); MULADD(at[19], at[48]); MULADD(at[20], at[47]); MULADD(at[21], at[46]); MULADD(at[22], at[45]); MULADD(at[23], at[44]); MULADD(at[24], at[43]); MULADD(at[25], at[42]); MULADD(at[26], at[41]); MULADD(at[27], at[40]); MULADD(at[28], at[39]); MULADD(at[29], at[38]); MULADD(at[30], at[37]); MULADD(at[31], at[36]); - COMBA_STORE(C->dp[35]); - /* 36 */ - COMBA_FORWARD; - MULADD(at[5], at[63]); MULADD(at[6], at[62]); MULADD(at[7], at[61]); MULADD(at[8], at[60]); MULADD(at[9], at[59]); MULADD(at[10], at[58]); MULADD(at[11], at[57]); MULADD(at[12], at[56]); MULADD(at[13], at[55]); MULADD(at[14], at[54]); MULADD(at[15], at[53]); MULADD(at[16], at[52]); MULADD(at[17], at[51]); MULADD(at[18], at[50]); MULADD(at[19], at[49]); MULADD(at[20], at[48]); MULADD(at[21], at[47]); MULADD(at[22], at[46]); MULADD(at[23], at[45]); MULADD(at[24], at[44]); MULADD(at[25], at[43]); MULADD(at[26], at[42]); MULADD(at[27], at[41]); MULADD(at[28], at[40]); MULADD(at[29], at[39]); MULADD(at[30], at[38]); MULADD(at[31], at[37]); - COMBA_STORE(C->dp[36]); - /* 37 */ - COMBA_FORWARD; - MULADD(at[6], at[63]); MULADD(at[7], at[62]); MULADD(at[8], at[61]); MULADD(at[9], at[60]); MULADD(at[10], at[59]); MULADD(at[11], at[58]); MULADD(at[12], at[57]); MULADD(at[13], at[56]); MULADD(at[14], at[55]); MULADD(at[15], at[54]); MULADD(at[16], at[53]); MULADD(at[17], at[52]); MULADD(at[18], at[51]); MULADD(at[19], at[50]); MULADD(at[20], at[49]); MULADD(at[21], at[48]); MULADD(at[22], at[47]); MULADD(at[23], at[46]); MULADD(at[24], at[45]); MULADD(at[25], at[44]); MULADD(at[26], at[43]); MULADD(at[27], at[42]); MULADD(at[28], at[41]); MULADD(at[29], at[40]); MULADD(at[30], at[39]); MULADD(at[31], at[38]); - COMBA_STORE(C->dp[37]); - /* 38 */ - COMBA_FORWARD; - MULADD(at[7], at[63]); MULADD(at[8], at[62]); MULADD(at[9], at[61]); MULADD(at[10], at[60]); MULADD(at[11], at[59]); MULADD(at[12], at[58]); MULADD(at[13], at[57]); MULADD(at[14], at[56]); MULADD(at[15], at[55]); MULADD(at[16], at[54]); MULADD(at[17], at[53]); MULADD(at[18], at[52]); MULADD(at[19], at[51]); MULADD(at[20], at[50]); MULADD(at[21], at[49]); MULADD(at[22], at[48]); MULADD(at[23], at[47]); MULADD(at[24], at[46]); MULADD(at[25], at[45]); MULADD(at[26], at[44]); MULADD(at[27], at[43]); MULADD(at[28], at[42]); MULADD(at[29], at[41]); MULADD(at[30], at[40]); MULADD(at[31], at[39]); - COMBA_STORE(C->dp[38]); - /* 39 */ - COMBA_FORWARD; - MULADD(at[8], at[63]); MULADD(at[9], at[62]); MULADD(at[10], at[61]); MULADD(at[11], at[60]); MULADD(at[12], at[59]); MULADD(at[13], at[58]); MULADD(at[14], at[57]); MULADD(at[15], at[56]); MULADD(at[16], at[55]); MULADD(at[17], at[54]); MULADD(at[18], at[53]); MULADD(at[19], at[52]); MULADD(at[20], at[51]); MULADD(at[21], at[50]); MULADD(at[22], at[49]); MULADD(at[23], at[48]); MULADD(at[24], at[47]); MULADD(at[25], at[46]); MULADD(at[26], at[45]); MULADD(at[27], at[44]); MULADD(at[28], at[43]); MULADD(at[29], at[42]); MULADD(at[30], at[41]); MULADD(at[31], at[40]); - COMBA_STORE(C->dp[39]); - /* 40 */ - COMBA_FORWARD; - MULADD(at[9], at[63]); MULADD(at[10], at[62]); MULADD(at[11], at[61]); MULADD(at[12], at[60]); MULADD(at[13], at[59]); MULADD(at[14], at[58]); MULADD(at[15], at[57]); MULADD(at[16], at[56]); MULADD(at[17], at[55]); MULADD(at[18], at[54]); MULADD(at[19], at[53]); MULADD(at[20], at[52]); MULADD(at[21], at[51]); MULADD(at[22], at[50]); MULADD(at[23], at[49]); MULADD(at[24], at[48]); MULADD(at[25], at[47]); MULADD(at[26], at[46]); MULADD(at[27], at[45]); MULADD(at[28], at[44]); MULADD(at[29], at[43]); MULADD(at[30], at[42]); MULADD(at[31], at[41]); - COMBA_STORE(C->dp[40]); - /* 41 */ - COMBA_FORWARD; - MULADD(at[10], at[63]); MULADD(at[11], at[62]); MULADD(at[12], at[61]); MULADD(at[13], at[60]); MULADD(at[14], at[59]); MULADD(at[15], at[58]); MULADD(at[16], at[57]); MULADD(at[17], at[56]); MULADD(at[18], at[55]); MULADD(at[19], at[54]); MULADD(at[20], at[53]); MULADD(at[21], at[52]); MULADD(at[22], at[51]); MULADD(at[23], at[50]); MULADD(at[24], at[49]); MULADD(at[25], at[48]); MULADD(at[26], at[47]); MULADD(at[27], at[46]); MULADD(at[28], at[45]); MULADD(at[29], at[44]); MULADD(at[30], at[43]); MULADD(at[31], at[42]); - COMBA_STORE(C->dp[41]); - /* 42 */ - COMBA_FORWARD; - MULADD(at[11], at[63]); MULADD(at[12], at[62]); MULADD(at[13], at[61]); MULADD(at[14], at[60]); MULADD(at[15], at[59]); MULADD(at[16], at[58]); MULADD(at[17], at[57]); MULADD(at[18], at[56]); MULADD(at[19], at[55]); MULADD(at[20], at[54]); MULADD(at[21], at[53]); MULADD(at[22], at[52]); MULADD(at[23], at[51]); MULADD(at[24], at[50]); MULADD(at[25], at[49]); MULADD(at[26], at[48]); MULADD(at[27], at[47]); MULADD(at[28], at[46]); MULADD(at[29], at[45]); MULADD(at[30], at[44]); MULADD(at[31], at[43]); - COMBA_STORE(C->dp[42]); - /* 43 */ - COMBA_FORWARD; - MULADD(at[12], at[63]); MULADD(at[13], at[62]); MULADD(at[14], at[61]); MULADD(at[15], at[60]); MULADD(at[16], at[59]); MULADD(at[17], at[58]); MULADD(at[18], at[57]); MULADD(at[19], at[56]); MULADD(at[20], at[55]); MULADD(at[21], at[54]); MULADD(at[22], at[53]); MULADD(at[23], at[52]); MULADD(at[24], at[51]); MULADD(at[25], at[50]); MULADD(at[26], at[49]); MULADD(at[27], at[48]); MULADD(at[28], at[47]); MULADD(at[29], at[46]); MULADD(at[30], at[45]); MULADD(at[31], at[44]); - COMBA_STORE(C->dp[43]); - /* 44 */ - COMBA_FORWARD; - MULADD(at[13], at[63]); MULADD(at[14], at[62]); MULADD(at[15], at[61]); MULADD(at[16], at[60]); MULADD(at[17], at[59]); MULADD(at[18], at[58]); MULADD(at[19], at[57]); MULADD(at[20], at[56]); MULADD(at[21], at[55]); MULADD(at[22], at[54]); MULADD(at[23], at[53]); MULADD(at[24], at[52]); MULADD(at[25], at[51]); MULADD(at[26], at[50]); MULADD(at[27], at[49]); MULADD(at[28], at[48]); MULADD(at[29], at[47]); MULADD(at[30], at[46]); MULADD(at[31], at[45]); - COMBA_STORE(C->dp[44]); - /* 45 */ - COMBA_FORWARD; - MULADD(at[14], at[63]); MULADD(at[15], at[62]); MULADD(at[16], at[61]); MULADD(at[17], at[60]); MULADD(at[18], at[59]); MULADD(at[19], at[58]); MULADD(at[20], at[57]); MULADD(at[21], at[56]); MULADD(at[22], at[55]); MULADD(at[23], at[54]); MULADD(at[24], at[53]); MULADD(at[25], at[52]); MULADD(at[26], at[51]); MULADD(at[27], at[50]); MULADD(at[28], at[49]); MULADD(at[29], at[48]); MULADD(at[30], at[47]); MULADD(at[31], at[46]); - COMBA_STORE(C->dp[45]); - /* 46 */ - COMBA_FORWARD; - MULADD(at[15], at[63]); MULADD(at[16], at[62]); MULADD(at[17], at[61]); MULADD(at[18], at[60]); MULADD(at[19], at[59]); MULADD(at[20], at[58]); MULADD(at[21], at[57]); MULADD(at[22], at[56]); MULADD(at[23], at[55]); MULADD(at[24], at[54]); MULADD(at[25], at[53]); MULADD(at[26], at[52]); MULADD(at[27], at[51]); MULADD(at[28], at[50]); MULADD(at[29], at[49]); MULADD(at[30], at[48]); MULADD(at[31], at[47]); - COMBA_STORE(C->dp[46]); - /* 47 */ - COMBA_FORWARD; - MULADD(at[16], at[63]); MULADD(at[17], at[62]); MULADD(at[18], at[61]); MULADD(at[19], at[60]); MULADD(at[20], at[59]); MULADD(at[21], at[58]); MULADD(at[22], at[57]); MULADD(at[23], at[56]); MULADD(at[24], at[55]); MULADD(at[25], at[54]); MULADD(at[26], at[53]); MULADD(at[27], at[52]); MULADD(at[28], at[51]); MULADD(at[29], at[50]); MULADD(at[30], at[49]); MULADD(at[31], at[48]); - COMBA_STORE(C->dp[47]); - /* 48 */ - COMBA_FORWARD; - MULADD(at[17], at[63]); MULADD(at[18], at[62]); MULADD(at[19], at[61]); MULADD(at[20], at[60]); MULADD(at[21], at[59]); MULADD(at[22], at[58]); MULADD(at[23], at[57]); MULADD(at[24], at[56]); MULADD(at[25], at[55]); MULADD(at[26], at[54]); MULADD(at[27], at[53]); MULADD(at[28], at[52]); MULADD(at[29], at[51]); MULADD(at[30], at[50]); MULADD(at[31], at[49]); - COMBA_STORE(C->dp[48]); - /* 49 */ - COMBA_FORWARD; - MULADD(at[18], at[63]); MULADD(at[19], at[62]); MULADD(at[20], at[61]); MULADD(at[21], at[60]); MULADD(at[22], at[59]); MULADD(at[23], at[58]); MULADD(at[24], at[57]); MULADD(at[25], at[56]); MULADD(at[26], at[55]); MULADD(at[27], at[54]); MULADD(at[28], at[53]); MULADD(at[29], at[52]); MULADD(at[30], at[51]); MULADD(at[31], at[50]); - COMBA_STORE(C->dp[49]); - /* 50 */ - COMBA_FORWARD; - MULADD(at[19], at[63]); MULADD(at[20], at[62]); MULADD(at[21], at[61]); MULADD(at[22], at[60]); MULADD(at[23], at[59]); MULADD(at[24], at[58]); MULADD(at[25], at[57]); MULADD(at[26], at[56]); MULADD(at[27], at[55]); MULADD(at[28], at[54]); MULADD(at[29], at[53]); MULADD(at[30], at[52]); MULADD(at[31], at[51]); - COMBA_STORE(C->dp[50]); - /* 51 */ - COMBA_FORWARD; - MULADD(at[20], at[63]); MULADD(at[21], at[62]); MULADD(at[22], at[61]); MULADD(at[23], at[60]); MULADD(at[24], at[59]); MULADD(at[25], at[58]); MULADD(at[26], at[57]); MULADD(at[27], at[56]); MULADD(at[28], at[55]); MULADD(at[29], at[54]); MULADD(at[30], at[53]); MULADD(at[31], at[52]); - COMBA_STORE(C->dp[51]); - /* 52 */ - COMBA_FORWARD; - MULADD(at[21], at[63]); MULADD(at[22], at[62]); MULADD(at[23], at[61]); MULADD(at[24], at[60]); MULADD(at[25], at[59]); MULADD(at[26], at[58]); MULADD(at[27], at[57]); MULADD(at[28], at[56]); MULADD(at[29], at[55]); MULADD(at[30], at[54]); MULADD(at[31], at[53]); - COMBA_STORE(C->dp[52]); - /* 53 */ - COMBA_FORWARD; - MULADD(at[22], at[63]); MULADD(at[23], at[62]); MULADD(at[24], at[61]); MULADD(at[25], at[60]); MULADD(at[26], at[59]); MULADD(at[27], at[58]); MULADD(at[28], at[57]); MULADD(at[29], at[56]); MULADD(at[30], at[55]); MULADD(at[31], at[54]); - COMBA_STORE(C->dp[53]); - /* 54 */ - COMBA_FORWARD; - MULADD(at[23], at[63]); MULADD(at[24], at[62]); MULADD(at[25], at[61]); MULADD(at[26], at[60]); MULADD(at[27], at[59]); MULADD(at[28], at[58]); MULADD(at[29], at[57]); MULADD(at[30], at[56]); MULADD(at[31], at[55]); - COMBA_STORE(C->dp[54]); - /* 55 */ - COMBA_FORWARD; - MULADD(at[24], at[63]); MULADD(at[25], at[62]); MULADD(at[26], at[61]); MULADD(at[27], at[60]); MULADD(at[28], at[59]); MULADD(at[29], at[58]); MULADD(at[30], at[57]); MULADD(at[31], at[56]); - COMBA_STORE(C->dp[55]); - /* 56 */ - COMBA_FORWARD; - MULADD(at[25], at[63]); MULADD(at[26], at[62]); MULADD(at[27], at[61]); MULADD(at[28], at[60]); MULADD(at[29], at[59]); MULADD(at[30], at[58]); MULADD(at[31], at[57]); - COMBA_STORE(C->dp[56]); - /* 57 */ - COMBA_FORWARD; - MULADD(at[26], at[63]); MULADD(at[27], at[62]); MULADD(at[28], at[61]); MULADD(at[29], at[60]); MULADD(at[30], at[59]); MULADD(at[31], at[58]); - COMBA_STORE(C->dp[57]); - /* 58 */ - COMBA_FORWARD; - MULADD(at[27], at[63]); MULADD(at[28], at[62]); MULADD(at[29], at[61]); MULADD(at[30], at[60]); MULADD(at[31], at[59]); - COMBA_STORE(C->dp[58]); - /* 59 */ - COMBA_FORWARD; - MULADD(at[28], at[63]); MULADD(at[29], at[62]); MULADD(at[30], at[61]); MULADD(at[31], at[60]); - COMBA_STORE(C->dp[59]); - /* 60 */ - COMBA_FORWARD; - MULADD(at[29], at[63]); MULADD(at[30], at[62]); MULADD(at[31], at[61]); - COMBA_STORE(C->dp[60]); - /* 61 */ - COMBA_FORWARD; - MULADD(at[30], at[63]); MULADD(at[31], at[62]); - COMBA_STORE(C->dp[61]); - /* 62 */ - COMBA_FORWARD; - MULADD(at[31], at[63]); - COMBA_STORE(C->dp[62]); - COMBA_STORE2(C->dp[63]); - C->used = 64; - C->sign = A->sign ^ B->sign; - mp_clamp(C); - COMBA_FINI; + mp_digit c0, c1, c2, at[64]; + + memcpy(at, A->dp, 32 * sizeof(mp_digit)); + memcpy(at + 32, B->dp, 32 * sizeof(mp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[32]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[33]); + MULADD(at[1], at[32]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[34]); + MULADD(at[1], at[33]); + MULADD(at[2], at[32]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[35]); + MULADD(at[1], at[34]); + MULADD(at[2], at[33]); + MULADD(at[3], at[32]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[36]); + MULADD(at[1], at[35]); + MULADD(at[2], at[34]); + MULADD(at[3], at[33]); + MULADD(at[4], at[32]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[37]); + MULADD(at[1], at[36]); + MULADD(at[2], at[35]); + MULADD(at[3], at[34]); + MULADD(at[4], at[33]); + MULADD(at[5], at[32]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[38]); + MULADD(at[1], at[37]); + MULADD(at[2], at[36]); + MULADD(at[3], at[35]); + MULADD(at[4], at[34]); + MULADD(at[5], at[33]); + MULADD(at[6], at[32]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[39]); + MULADD(at[1], at[38]); + MULADD(at[2], at[37]); + MULADD(at[3], at[36]); + MULADD(at[4], at[35]); + MULADD(at[5], at[34]); + MULADD(at[6], at[33]); + MULADD(at[7], at[32]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[40]); + MULADD(at[1], at[39]); + MULADD(at[2], at[38]); + MULADD(at[3], at[37]); + MULADD(at[4], at[36]); + MULADD(at[5], at[35]); + MULADD(at[6], at[34]); + MULADD(at[7], at[33]); + MULADD(at[8], at[32]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[41]); + MULADD(at[1], at[40]); + MULADD(at[2], at[39]); + MULADD(at[3], at[38]); + MULADD(at[4], at[37]); + MULADD(at[5], at[36]); + MULADD(at[6], at[35]); + MULADD(at[7], at[34]); + MULADD(at[8], at[33]); + MULADD(at[9], at[32]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[42]); + MULADD(at[1], at[41]); + MULADD(at[2], at[40]); + MULADD(at[3], at[39]); + MULADD(at[4], at[38]); + MULADD(at[5], at[37]); + MULADD(at[6], at[36]); + MULADD(at[7], at[35]); + MULADD(at[8], at[34]); + MULADD(at[9], at[33]); + MULADD(at[10], at[32]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[43]); + MULADD(at[1], at[42]); + MULADD(at[2], at[41]); + MULADD(at[3], at[40]); + MULADD(at[4], at[39]); + MULADD(at[5], at[38]); + MULADD(at[6], at[37]); + MULADD(at[7], at[36]); + MULADD(at[8], at[35]); + MULADD(at[9], at[34]); + MULADD(at[10], at[33]); + MULADD(at[11], at[32]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[44]); + MULADD(at[1], at[43]); + MULADD(at[2], at[42]); + MULADD(at[3], at[41]); + MULADD(at[4], at[40]); + MULADD(at[5], at[39]); + MULADD(at[6], at[38]); + MULADD(at[7], at[37]); + MULADD(at[8], at[36]); + MULADD(at[9], at[35]); + MULADD(at[10], at[34]); + MULADD(at[11], at[33]); + MULADD(at[12], at[32]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[45]); + MULADD(at[1], at[44]); + MULADD(at[2], at[43]); + MULADD(at[3], at[42]); + MULADD(at[4], at[41]); + MULADD(at[5], at[40]); + MULADD(at[6], at[39]); + MULADD(at[7], at[38]); + MULADD(at[8], at[37]); + MULADD(at[9], at[36]); + MULADD(at[10], at[35]); + MULADD(at[11], at[34]); + MULADD(at[12], at[33]); + MULADD(at[13], at[32]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[46]); + MULADD(at[1], at[45]); + MULADD(at[2], at[44]); + MULADD(at[3], at[43]); + MULADD(at[4], at[42]); + MULADD(at[5], at[41]); + MULADD(at[6], at[40]); + MULADD(at[7], at[39]); + MULADD(at[8], at[38]); + MULADD(at[9], at[37]); + MULADD(at[10], at[36]); + MULADD(at[11], at[35]); + MULADD(at[12], at[34]); + MULADD(at[13], at[33]); + MULADD(at[14], at[32]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[47]); + MULADD(at[1], at[46]); + MULADD(at[2], at[45]); + MULADD(at[3], at[44]); + MULADD(at[4], at[43]); + MULADD(at[5], at[42]); + MULADD(at[6], at[41]); + MULADD(at[7], at[40]); + MULADD(at[8], at[39]); + MULADD(at[9], at[38]); + MULADD(at[10], at[37]); + MULADD(at[11], at[36]); + MULADD(at[12], at[35]); + MULADD(at[13], at[34]); + MULADD(at[14], at[33]); + MULADD(at[15], at[32]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[0], at[48]); + MULADD(at[1], at[47]); + MULADD(at[2], at[46]); + MULADD(at[3], at[45]); + MULADD(at[4], at[44]); + MULADD(at[5], at[43]); + MULADD(at[6], at[42]); + MULADD(at[7], at[41]); + MULADD(at[8], at[40]); + MULADD(at[9], at[39]); + MULADD(at[10], at[38]); + MULADD(at[11], at[37]); + MULADD(at[12], at[36]); + MULADD(at[13], at[35]); + MULADD(at[14], at[34]); + MULADD(at[15], at[33]); + MULADD(at[16], at[32]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[0], at[49]); + MULADD(at[1], at[48]); + MULADD(at[2], at[47]); + MULADD(at[3], at[46]); + MULADD(at[4], at[45]); + MULADD(at[5], at[44]); + MULADD(at[6], at[43]); + MULADD(at[7], at[42]); + MULADD(at[8], at[41]); + MULADD(at[9], at[40]); + MULADD(at[10], at[39]); + MULADD(at[11], at[38]); + MULADD(at[12], at[37]); + MULADD(at[13], at[36]); + MULADD(at[14], at[35]); + MULADD(at[15], at[34]); + MULADD(at[16], at[33]); + MULADD(at[17], at[32]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[0], at[50]); + MULADD(at[1], at[49]); + MULADD(at[2], at[48]); + MULADD(at[3], at[47]); + MULADD(at[4], at[46]); + MULADD(at[5], at[45]); + MULADD(at[6], at[44]); + MULADD(at[7], at[43]); + MULADD(at[8], at[42]); + MULADD(at[9], at[41]); + MULADD(at[10], at[40]); + MULADD(at[11], at[39]); + MULADD(at[12], at[38]); + MULADD(at[13], at[37]); + MULADD(at[14], at[36]); + MULADD(at[15], at[35]); + MULADD(at[16], at[34]); + MULADD(at[17], at[33]); + MULADD(at[18], at[32]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[0], at[51]); + MULADD(at[1], at[50]); + MULADD(at[2], at[49]); + MULADD(at[3], at[48]); + MULADD(at[4], at[47]); + MULADD(at[5], at[46]); + MULADD(at[6], at[45]); + MULADD(at[7], at[44]); + MULADD(at[8], at[43]); + MULADD(at[9], at[42]); + MULADD(at[10], at[41]); + MULADD(at[11], at[40]); + MULADD(at[12], at[39]); + MULADD(at[13], at[38]); + MULADD(at[14], at[37]); + MULADD(at[15], at[36]); + MULADD(at[16], at[35]); + MULADD(at[17], at[34]); + MULADD(at[18], at[33]); + MULADD(at[19], at[32]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[0], at[52]); + MULADD(at[1], at[51]); + MULADD(at[2], at[50]); + MULADD(at[3], at[49]); + MULADD(at[4], at[48]); + MULADD(at[5], at[47]); + MULADD(at[6], at[46]); + MULADD(at[7], at[45]); + MULADD(at[8], at[44]); + MULADD(at[9], at[43]); + MULADD(at[10], at[42]); + MULADD(at[11], at[41]); + MULADD(at[12], at[40]); + MULADD(at[13], at[39]); + MULADD(at[14], at[38]); + MULADD(at[15], at[37]); + MULADD(at[16], at[36]); + MULADD(at[17], at[35]); + MULADD(at[18], at[34]); + MULADD(at[19], at[33]); + MULADD(at[20], at[32]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[0], at[53]); + MULADD(at[1], at[52]); + MULADD(at[2], at[51]); + MULADD(at[3], at[50]); + MULADD(at[4], at[49]); + MULADD(at[5], at[48]); + MULADD(at[6], at[47]); + MULADD(at[7], at[46]); + MULADD(at[8], at[45]); + MULADD(at[9], at[44]); + MULADD(at[10], at[43]); + MULADD(at[11], at[42]); + MULADD(at[12], at[41]); + MULADD(at[13], at[40]); + MULADD(at[14], at[39]); + MULADD(at[15], at[38]); + MULADD(at[16], at[37]); + MULADD(at[17], at[36]); + MULADD(at[18], at[35]); + MULADD(at[19], at[34]); + MULADD(at[20], at[33]); + MULADD(at[21], at[32]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[0], at[54]); + MULADD(at[1], at[53]); + MULADD(at[2], at[52]); + MULADD(at[3], at[51]); + MULADD(at[4], at[50]); + MULADD(at[5], at[49]); + MULADD(at[6], at[48]); + MULADD(at[7], at[47]); + MULADD(at[8], at[46]); + MULADD(at[9], at[45]); + MULADD(at[10], at[44]); + MULADD(at[11], at[43]); + MULADD(at[12], at[42]); + MULADD(at[13], at[41]); + MULADD(at[14], at[40]); + MULADD(at[15], at[39]); + MULADD(at[16], at[38]); + MULADD(at[17], at[37]); + MULADD(at[18], at[36]); + MULADD(at[19], at[35]); + MULADD(at[20], at[34]); + MULADD(at[21], at[33]); + MULADD(at[22], at[32]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[0], at[55]); + MULADD(at[1], at[54]); + MULADD(at[2], at[53]); + MULADD(at[3], at[52]); + MULADD(at[4], at[51]); + MULADD(at[5], at[50]); + MULADD(at[6], at[49]); + MULADD(at[7], at[48]); + MULADD(at[8], at[47]); + MULADD(at[9], at[46]); + MULADD(at[10], at[45]); + MULADD(at[11], at[44]); + MULADD(at[12], at[43]); + MULADD(at[13], at[42]); + MULADD(at[14], at[41]); + MULADD(at[15], at[40]); + MULADD(at[16], at[39]); + MULADD(at[17], at[38]); + MULADD(at[18], at[37]); + MULADD(at[19], at[36]); + MULADD(at[20], at[35]); + MULADD(at[21], at[34]); + MULADD(at[22], at[33]); + MULADD(at[23], at[32]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[0], at[56]); + MULADD(at[1], at[55]); + MULADD(at[2], at[54]); + MULADD(at[3], at[53]); + MULADD(at[4], at[52]); + MULADD(at[5], at[51]); + MULADD(at[6], at[50]); + MULADD(at[7], at[49]); + MULADD(at[8], at[48]); + MULADD(at[9], at[47]); + MULADD(at[10], at[46]); + MULADD(at[11], at[45]); + MULADD(at[12], at[44]); + MULADD(at[13], at[43]); + MULADD(at[14], at[42]); + MULADD(at[15], at[41]); + MULADD(at[16], at[40]); + MULADD(at[17], at[39]); + MULADD(at[18], at[38]); + MULADD(at[19], at[37]); + MULADD(at[20], at[36]); + MULADD(at[21], at[35]); + MULADD(at[22], at[34]); + MULADD(at[23], at[33]); + MULADD(at[24], at[32]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[0], at[57]); + MULADD(at[1], at[56]); + MULADD(at[2], at[55]); + MULADD(at[3], at[54]); + MULADD(at[4], at[53]); + MULADD(at[5], at[52]); + MULADD(at[6], at[51]); + MULADD(at[7], at[50]); + MULADD(at[8], at[49]); + MULADD(at[9], at[48]); + MULADD(at[10], at[47]); + MULADD(at[11], at[46]); + MULADD(at[12], at[45]); + MULADD(at[13], at[44]); + MULADD(at[14], at[43]); + MULADD(at[15], at[42]); + MULADD(at[16], at[41]); + MULADD(at[17], at[40]); + MULADD(at[18], at[39]); + MULADD(at[19], at[38]); + MULADD(at[20], at[37]); + MULADD(at[21], at[36]); + MULADD(at[22], at[35]); + MULADD(at[23], at[34]); + MULADD(at[24], at[33]); + MULADD(at[25], at[32]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[0], at[58]); + MULADD(at[1], at[57]); + MULADD(at[2], at[56]); + MULADD(at[3], at[55]); + MULADD(at[4], at[54]); + MULADD(at[5], at[53]); + MULADD(at[6], at[52]); + MULADD(at[7], at[51]); + MULADD(at[8], at[50]); + MULADD(at[9], at[49]); + MULADD(at[10], at[48]); + MULADD(at[11], at[47]); + MULADD(at[12], at[46]); + MULADD(at[13], at[45]); + MULADD(at[14], at[44]); + MULADD(at[15], at[43]); + MULADD(at[16], at[42]); + MULADD(at[17], at[41]); + MULADD(at[18], at[40]); + MULADD(at[19], at[39]); + MULADD(at[20], at[38]); + MULADD(at[21], at[37]); + MULADD(at[22], at[36]); + MULADD(at[23], at[35]); + MULADD(at[24], at[34]); + MULADD(at[25], at[33]); + MULADD(at[26], at[32]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[0], at[59]); + MULADD(at[1], at[58]); + MULADD(at[2], at[57]); + MULADD(at[3], at[56]); + MULADD(at[4], at[55]); + MULADD(at[5], at[54]); + MULADD(at[6], at[53]); + MULADD(at[7], at[52]); + MULADD(at[8], at[51]); + MULADD(at[9], at[50]); + MULADD(at[10], at[49]); + MULADD(at[11], at[48]); + MULADD(at[12], at[47]); + MULADD(at[13], at[46]); + MULADD(at[14], at[45]); + MULADD(at[15], at[44]); + MULADD(at[16], at[43]); + MULADD(at[17], at[42]); + MULADD(at[18], at[41]); + MULADD(at[19], at[40]); + MULADD(at[20], at[39]); + MULADD(at[21], at[38]); + MULADD(at[22], at[37]); + MULADD(at[23], at[36]); + MULADD(at[24], at[35]); + MULADD(at[25], at[34]); + MULADD(at[26], at[33]); + MULADD(at[27], at[32]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[0], at[60]); + MULADD(at[1], at[59]); + MULADD(at[2], at[58]); + MULADD(at[3], at[57]); + MULADD(at[4], at[56]); + MULADD(at[5], at[55]); + MULADD(at[6], at[54]); + MULADD(at[7], at[53]); + MULADD(at[8], at[52]); + MULADD(at[9], at[51]); + MULADD(at[10], at[50]); + MULADD(at[11], at[49]); + MULADD(at[12], at[48]); + MULADD(at[13], at[47]); + MULADD(at[14], at[46]); + MULADD(at[15], at[45]); + MULADD(at[16], at[44]); + MULADD(at[17], at[43]); + MULADD(at[18], at[42]); + MULADD(at[19], at[41]); + MULADD(at[20], at[40]); + MULADD(at[21], at[39]); + MULADD(at[22], at[38]); + MULADD(at[23], at[37]); + MULADD(at[24], at[36]); + MULADD(at[25], at[35]); + MULADD(at[26], at[34]); + MULADD(at[27], at[33]); + MULADD(at[28], at[32]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[0], at[61]); + MULADD(at[1], at[60]); + MULADD(at[2], at[59]); + MULADD(at[3], at[58]); + MULADD(at[4], at[57]); + MULADD(at[5], at[56]); + MULADD(at[6], at[55]); + MULADD(at[7], at[54]); + MULADD(at[8], at[53]); + MULADD(at[9], at[52]); + MULADD(at[10], at[51]); + MULADD(at[11], at[50]); + MULADD(at[12], at[49]); + MULADD(at[13], at[48]); + MULADD(at[14], at[47]); + MULADD(at[15], at[46]); + MULADD(at[16], at[45]); + MULADD(at[17], at[44]); + MULADD(at[18], at[43]); + MULADD(at[19], at[42]); + MULADD(at[20], at[41]); + MULADD(at[21], at[40]); + MULADD(at[22], at[39]); + MULADD(at[23], at[38]); + MULADD(at[24], at[37]); + MULADD(at[25], at[36]); + MULADD(at[26], at[35]); + MULADD(at[27], at[34]); + MULADD(at[28], at[33]); + MULADD(at[29], at[32]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[0], at[62]); + MULADD(at[1], at[61]); + MULADD(at[2], at[60]); + MULADD(at[3], at[59]); + MULADD(at[4], at[58]); + MULADD(at[5], at[57]); + MULADD(at[6], at[56]); + MULADD(at[7], at[55]); + MULADD(at[8], at[54]); + MULADD(at[9], at[53]); + MULADD(at[10], at[52]); + MULADD(at[11], at[51]); + MULADD(at[12], at[50]); + MULADD(at[13], at[49]); + MULADD(at[14], at[48]); + MULADD(at[15], at[47]); + MULADD(at[16], at[46]); + MULADD(at[17], at[45]); + MULADD(at[18], at[44]); + MULADD(at[19], at[43]); + MULADD(at[20], at[42]); + MULADD(at[21], at[41]); + MULADD(at[22], at[40]); + MULADD(at[23], at[39]); + MULADD(at[24], at[38]); + MULADD(at[25], at[37]); + MULADD(at[26], at[36]); + MULADD(at[27], at[35]); + MULADD(at[28], at[34]); + MULADD(at[29], at[33]); + MULADD(at[30], at[32]); + COMBA_STORE(C->dp[30]); + /* 31 */ + COMBA_FORWARD; + MULADD(at[0], at[63]); + MULADD(at[1], at[62]); + MULADD(at[2], at[61]); + MULADD(at[3], at[60]); + MULADD(at[4], at[59]); + MULADD(at[5], at[58]); + MULADD(at[6], at[57]); + MULADD(at[7], at[56]); + MULADD(at[8], at[55]); + MULADD(at[9], at[54]); + MULADD(at[10], at[53]); + MULADD(at[11], at[52]); + MULADD(at[12], at[51]); + MULADD(at[13], at[50]); + MULADD(at[14], at[49]); + MULADD(at[15], at[48]); + MULADD(at[16], at[47]); + MULADD(at[17], at[46]); + MULADD(at[18], at[45]); + MULADD(at[19], at[44]); + MULADD(at[20], at[43]); + MULADD(at[21], at[42]); + MULADD(at[22], at[41]); + MULADD(at[23], at[40]); + MULADD(at[24], at[39]); + MULADD(at[25], at[38]); + MULADD(at[26], at[37]); + MULADD(at[27], at[36]); + MULADD(at[28], at[35]); + MULADD(at[29], at[34]); + MULADD(at[30], at[33]); + MULADD(at[31], at[32]); + COMBA_STORE(C->dp[31]); + /* 32 */ + COMBA_FORWARD; + MULADD(at[1], at[63]); + MULADD(at[2], at[62]); + MULADD(at[3], at[61]); + MULADD(at[4], at[60]); + MULADD(at[5], at[59]); + MULADD(at[6], at[58]); + MULADD(at[7], at[57]); + MULADD(at[8], at[56]); + MULADD(at[9], at[55]); + MULADD(at[10], at[54]); + MULADD(at[11], at[53]); + MULADD(at[12], at[52]); + MULADD(at[13], at[51]); + MULADD(at[14], at[50]); + MULADD(at[15], at[49]); + MULADD(at[16], at[48]); + MULADD(at[17], at[47]); + MULADD(at[18], at[46]); + MULADD(at[19], at[45]); + MULADD(at[20], at[44]); + MULADD(at[21], at[43]); + MULADD(at[22], at[42]); + MULADD(at[23], at[41]); + MULADD(at[24], at[40]); + MULADD(at[25], at[39]); + MULADD(at[26], at[38]); + MULADD(at[27], at[37]); + MULADD(at[28], at[36]); + MULADD(at[29], at[35]); + MULADD(at[30], at[34]); + MULADD(at[31], at[33]); + COMBA_STORE(C->dp[32]); + /* 33 */ + COMBA_FORWARD; + MULADD(at[2], at[63]); + MULADD(at[3], at[62]); + MULADD(at[4], at[61]); + MULADD(at[5], at[60]); + MULADD(at[6], at[59]); + MULADD(at[7], at[58]); + MULADD(at[8], at[57]); + MULADD(at[9], at[56]); + MULADD(at[10], at[55]); + MULADD(at[11], at[54]); + MULADD(at[12], at[53]); + MULADD(at[13], at[52]); + MULADD(at[14], at[51]); + MULADD(at[15], at[50]); + MULADD(at[16], at[49]); + MULADD(at[17], at[48]); + MULADD(at[18], at[47]); + MULADD(at[19], at[46]); + MULADD(at[20], at[45]); + MULADD(at[21], at[44]); + MULADD(at[22], at[43]); + MULADD(at[23], at[42]); + MULADD(at[24], at[41]); + MULADD(at[25], at[40]); + MULADD(at[26], at[39]); + MULADD(at[27], at[38]); + MULADD(at[28], at[37]); + MULADD(at[29], at[36]); + MULADD(at[30], at[35]); + MULADD(at[31], at[34]); + COMBA_STORE(C->dp[33]); + /* 34 */ + COMBA_FORWARD; + MULADD(at[3], at[63]); + MULADD(at[4], at[62]); + MULADD(at[5], at[61]); + MULADD(at[6], at[60]); + MULADD(at[7], at[59]); + MULADD(at[8], at[58]); + MULADD(at[9], at[57]); + MULADD(at[10], at[56]); + MULADD(at[11], at[55]); + MULADD(at[12], at[54]); + MULADD(at[13], at[53]); + MULADD(at[14], at[52]); + MULADD(at[15], at[51]); + MULADD(at[16], at[50]); + MULADD(at[17], at[49]); + MULADD(at[18], at[48]); + MULADD(at[19], at[47]); + MULADD(at[20], at[46]); + MULADD(at[21], at[45]); + MULADD(at[22], at[44]); + MULADD(at[23], at[43]); + MULADD(at[24], at[42]); + MULADD(at[25], at[41]); + MULADD(at[26], at[40]); + MULADD(at[27], at[39]); + MULADD(at[28], at[38]); + MULADD(at[29], at[37]); + MULADD(at[30], at[36]); + MULADD(at[31], at[35]); + COMBA_STORE(C->dp[34]); + /* 35 */ + COMBA_FORWARD; + MULADD(at[4], at[63]); + MULADD(at[5], at[62]); + MULADD(at[6], at[61]); + MULADD(at[7], at[60]); + MULADD(at[8], at[59]); + MULADD(at[9], at[58]); + MULADD(at[10], at[57]); + MULADD(at[11], at[56]); + MULADD(at[12], at[55]); + MULADD(at[13], at[54]); + MULADD(at[14], at[53]); + MULADD(at[15], at[52]); + MULADD(at[16], at[51]); + MULADD(at[17], at[50]); + MULADD(at[18], at[49]); + MULADD(at[19], at[48]); + MULADD(at[20], at[47]); + MULADD(at[21], at[46]); + MULADD(at[22], at[45]); + MULADD(at[23], at[44]); + MULADD(at[24], at[43]); + MULADD(at[25], at[42]); + MULADD(at[26], at[41]); + MULADD(at[27], at[40]); + MULADD(at[28], at[39]); + MULADD(at[29], at[38]); + MULADD(at[30], at[37]); + MULADD(at[31], at[36]); + COMBA_STORE(C->dp[35]); + /* 36 */ + COMBA_FORWARD; + MULADD(at[5], at[63]); + MULADD(at[6], at[62]); + MULADD(at[7], at[61]); + MULADD(at[8], at[60]); + MULADD(at[9], at[59]); + MULADD(at[10], at[58]); + MULADD(at[11], at[57]); + MULADD(at[12], at[56]); + MULADD(at[13], at[55]); + MULADD(at[14], at[54]); + MULADD(at[15], at[53]); + MULADD(at[16], at[52]); + MULADD(at[17], at[51]); + MULADD(at[18], at[50]); + MULADD(at[19], at[49]); + MULADD(at[20], at[48]); + MULADD(at[21], at[47]); + MULADD(at[22], at[46]); + MULADD(at[23], at[45]); + MULADD(at[24], at[44]); + MULADD(at[25], at[43]); + MULADD(at[26], at[42]); + MULADD(at[27], at[41]); + MULADD(at[28], at[40]); + MULADD(at[29], at[39]); + MULADD(at[30], at[38]); + MULADD(at[31], at[37]); + COMBA_STORE(C->dp[36]); + /* 37 */ + COMBA_FORWARD; + MULADD(at[6], at[63]); + MULADD(at[7], at[62]); + MULADD(at[8], at[61]); + MULADD(at[9], at[60]); + MULADD(at[10], at[59]); + MULADD(at[11], at[58]); + MULADD(at[12], at[57]); + MULADD(at[13], at[56]); + MULADD(at[14], at[55]); + MULADD(at[15], at[54]); + MULADD(at[16], at[53]); + MULADD(at[17], at[52]); + MULADD(at[18], at[51]); + MULADD(at[19], at[50]); + MULADD(at[20], at[49]); + MULADD(at[21], at[48]); + MULADD(at[22], at[47]); + MULADD(at[23], at[46]); + MULADD(at[24], at[45]); + MULADD(at[25], at[44]); + MULADD(at[26], at[43]); + MULADD(at[27], at[42]); + MULADD(at[28], at[41]); + MULADD(at[29], at[40]); + MULADD(at[30], at[39]); + MULADD(at[31], at[38]); + COMBA_STORE(C->dp[37]); + /* 38 */ + COMBA_FORWARD; + MULADD(at[7], at[63]); + MULADD(at[8], at[62]); + MULADD(at[9], at[61]); + MULADD(at[10], at[60]); + MULADD(at[11], at[59]); + MULADD(at[12], at[58]); + MULADD(at[13], at[57]); + MULADD(at[14], at[56]); + MULADD(at[15], at[55]); + MULADD(at[16], at[54]); + MULADD(at[17], at[53]); + MULADD(at[18], at[52]); + MULADD(at[19], at[51]); + MULADD(at[20], at[50]); + MULADD(at[21], at[49]); + MULADD(at[22], at[48]); + MULADD(at[23], at[47]); + MULADD(at[24], at[46]); + MULADD(at[25], at[45]); + MULADD(at[26], at[44]); + MULADD(at[27], at[43]); + MULADD(at[28], at[42]); + MULADD(at[29], at[41]); + MULADD(at[30], at[40]); + MULADD(at[31], at[39]); + COMBA_STORE(C->dp[38]); + /* 39 */ + COMBA_FORWARD; + MULADD(at[8], at[63]); + MULADD(at[9], at[62]); + MULADD(at[10], at[61]); + MULADD(at[11], at[60]); + MULADD(at[12], at[59]); + MULADD(at[13], at[58]); + MULADD(at[14], at[57]); + MULADD(at[15], at[56]); + MULADD(at[16], at[55]); + MULADD(at[17], at[54]); + MULADD(at[18], at[53]); + MULADD(at[19], at[52]); + MULADD(at[20], at[51]); + MULADD(at[21], at[50]); + MULADD(at[22], at[49]); + MULADD(at[23], at[48]); + MULADD(at[24], at[47]); + MULADD(at[25], at[46]); + MULADD(at[26], at[45]); + MULADD(at[27], at[44]); + MULADD(at[28], at[43]); + MULADD(at[29], at[42]); + MULADD(at[30], at[41]); + MULADD(at[31], at[40]); + COMBA_STORE(C->dp[39]); + /* 40 */ + COMBA_FORWARD; + MULADD(at[9], at[63]); + MULADD(at[10], at[62]); + MULADD(at[11], at[61]); + MULADD(at[12], at[60]); + MULADD(at[13], at[59]); + MULADD(at[14], at[58]); + MULADD(at[15], at[57]); + MULADD(at[16], at[56]); + MULADD(at[17], at[55]); + MULADD(at[18], at[54]); + MULADD(at[19], at[53]); + MULADD(at[20], at[52]); + MULADD(at[21], at[51]); + MULADD(at[22], at[50]); + MULADD(at[23], at[49]); + MULADD(at[24], at[48]); + MULADD(at[25], at[47]); + MULADD(at[26], at[46]); + MULADD(at[27], at[45]); + MULADD(at[28], at[44]); + MULADD(at[29], at[43]); + MULADD(at[30], at[42]); + MULADD(at[31], at[41]); + COMBA_STORE(C->dp[40]); + /* 41 */ + COMBA_FORWARD; + MULADD(at[10], at[63]); + MULADD(at[11], at[62]); + MULADD(at[12], at[61]); + MULADD(at[13], at[60]); + MULADD(at[14], at[59]); + MULADD(at[15], at[58]); + MULADD(at[16], at[57]); + MULADD(at[17], at[56]); + MULADD(at[18], at[55]); + MULADD(at[19], at[54]); + MULADD(at[20], at[53]); + MULADD(at[21], at[52]); + MULADD(at[22], at[51]); + MULADD(at[23], at[50]); + MULADD(at[24], at[49]); + MULADD(at[25], at[48]); + MULADD(at[26], at[47]); + MULADD(at[27], at[46]); + MULADD(at[28], at[45]); + MULADD(at[29], at[44]); + MULADD(at[30], at[43]); + MULADD(at[31], at[42]); + COMBA_STORE(C->dp[41]); + /* 42 */ + COMBA_FORWARD; + MULADD(at[11], at[63]); + MULADD(at[12], at[62]); + MULADD(at[13], at[61]); + MULADD(at[14], at[60]); + MULADD(at[15], at[59]); + MULADD(at[16], at[58]); + MULADD(at[17], at[57]); + MULADD(at[18], at[56]); + MULADD(at[19], at[55]); + MULADD(at[20], at[54]); + MULADD(at[21], at[53]); + MULADD(at[22], at[52]); + MULADD(at[23], at[51]); + MULADD(at[24], at[50]); + MULADD(at[25], at[49]); + MULADD(at[26], at[48]); + MULADD(at[27], at[47]); + MULADD(at[28], at[46]); + MULADD(at[29], at[45]); + MULADD(at[30], at[44]); + MULADD(at[31], at[43]); + COMBA_STORE(C->dp[42]); + /* 43 */ + COMBA_FORWARD; + MULADD(at[12], at[63]); + MULADD(at[13], at[62]); + MULADD(at[14], at[61]); + MULADD(at[15], at[60]); + MULADD(at[16], at[59]); + MULADD(at[17], at[58]); + MULADD(at[18], at[57]); + MULADD(at[19], at[56]); + MULADD(at[20], at[55]); + MULADD(at[21], at[54]); + MULADD(at[22], at[53]); + MULADD(at[23], at[52]); + MULADD(at[24], at[51]); + MULADD(at[25], at[50]); + MULADD(at[26], at[49]); + MULADD(at[27], at[48]); + MULADD(at[28], at[47]); + MULADD(at[29], at[46]); + MULADD(at[30], at[45]); + MULADD(at[31], at[44]); + COMBA_STORE(C->dp[43]); + /* 44 */ + COMBA_FORWARD; + MULADD(at[13], at[63]); + MULADD(at[14], at[62]); + MULADD(at[15], at[61]); + MULADD(at[16], at[60]); + MULADD(at[17], at[59]); + MULADD(at[18], at[58]); + MULADD(at[19], at[57]); + MULADD(at[20], at[56]); + MULADD(at[21], at[55]); + MULADD(at[22], at[54]); + MULADD(at[23], at[53]); + MULADD(at[24], at[52]); + MULADD(at[25], at[51]); + MULADD(at[26], at[50]); + MULADD(at[27], at[49]); + MULADD(at[28], at[48]); + MULADD(at[29], at[47]); + MULADD(at[30], at[46]); + MULADD(at[31], at[45]); + COMBA_STORE(C->dp[44]); + /* 45 */ + COMBA_FORWARD; + MULADD(at[14], at[63]); + MULADD(at[15], at[62]); + MULADD(at[16], at[61]); + MULADD(at[17], at[60]); + MULADD(at[18], at[59]); + MULADD(at[19], at[58]); + MULADD(at[20], at[57]); + MULADD(at[21], at[56]); + MULADD(at[22], at[55]); + MULADD(at[23], at[54]); + MULADD(at[24], at[53]); + MULADD(at[25], at[52]); + MULADD(at[26], at[51]); + MULADD(at[27], at[50]); + MULADD(at[28], at[49]); + MULADD(at[29], at[48]); + MULADD(at[30], at[47]); + MULADD(at[31], at[46]); + COMBA_STORE(C->dp[45]); + /* 46 */ + COMBA_FORWARD; + MULADD(at[15], at[63]); + MULADD(at[16], at[62]); + MULADD(at[17], at[61]); + MULADD(at[18], at[60]); + MULADD(at[19], at[59]); + MULADD(at[20], at[58]); + MULADD(at[21], at[57]); + MULADD(at[22], at[56]); + MULADD(at[23], at[55]); + MULADD(at[24], at[54]); + MULADD(at[25], at[53]); + MULADD(at[26], at[52]); + MULADD(at[27], at[51]); + MULADD(at[28], at[50]); + MULADD(at[29], at[49]); + MULADD(at[30], at[48]); + MULADD(at[31], at[47]); + COMBA_STORE(C->dp[46]); + /* 47 */ + COMBA_FORWARD; + MULADD(at[16], at[63]); + MULADD(at[17], at[62]); + MULADD(at[18], at[61]); + MULADD(at[19], at[60]); + MULADD(at[20], at[59]); + MULADD(at[21], at[58]); + MULADD(at[22], at[57]); + MULADD(at[23], at[56]); + MULADD(at[24], at[55]); + MULADD(at[25], at[54]); + MULADD(at[26], at[53]); + MULADD(at[27], at[52]); + MULADD(at[28], at[51]); + MULADD(at[29], at[50]); + MULADD(at[30], at[49]); + MULADD(at[31], at[48]); + COMBA_STORE(C->dp[47]); + /* 48 */ + COMBA_FORWARD; + MULADD(at[17], at[63]); + MULADD(at[18], at[62]); + MULADD(at[19], at[61]); + MULADD(at[20], at[60]); + MULADD(at[21], at[59]); + MULADD(at[22], at[58]); + MULADD(at[23], at[57]); + MULADD(at[24], at[56]); + MULADD(at[25], at[55]); + MULADD(at[26], at[54]); + MULADD(at[27], at[53]); + MULADD(at[28], at[52]); + MULADD(at[29], at[51]); + MULADD(at[30], at[50]); + MULADD(at[31], at[49]); + COMBA_STORE(C->dp[48]); + /* 49 */ + COMBA_FORWARD; + MULADD(at[18], at[63]); + MULADD(at[19], at[62]); + MULADD(at[20], at[61]); + MULADD(at[21], at[60]); + MULADD(at[22], at[59]); + MULADD(at[23], at[58]); + MULADD(at[24], at[57]); + MULADD(at[25], at[56]); + MULADD(at[26], at[55]); + MULADD(at[27], at[54]); + MULADD(at[28], at[53]); + MULADD(at[29], at[52]); + MULADD(at[30], at[51]); + MULADD(at[31], at[50]); + COMBA_STORE(C->dp[49]); + /* 50 */ + COMBA_FORWARD; + MULADD(at[19], at[63]); + MULADD(at[20], at[62]); + MULADD(at[21], at[61]); + MULADD(at[22], at[60]); + MULADD(at[23], at[59]); + MULADD(at[24], at[58]); + MULADD(at[25], at[57]); + MULADD(at[26], at[56]); + MULADD(at[27], at[55]); + MULADD(at[28], at[54]); + MULADD(at[29], at[53]); + MULADD(at[30], at[52]); + MULADD(at[31], at[51]); + COMBA_STORE(C->dp[50]); + /* 51 */ + COMBA_FORWARD; + MULADD(at[20], at[63]); + MULADD(at[21], at[62]); + MULADD(at[22], at[61]); + MULADD(at[23], at[60]); + MULADD(at[24], at[59]); + MULADD(at[25], at[58]); + MULADD(at[26], at[57]); + MULADD(at[27], at[56]); + MULADD(at[28], at[55]); + MULADD(at[29], at[54]); + MULADD(at[30], at[53]); + MULADD(at[31], at[52]); + COMBA_STORE(C->dp[51]); + /* 52 */ + COMBA_FORWARD; + MULADD(at[21], at[63]); + MULADD(at[22], at[62]); + MULADD(at[23], at[61]); + MULADD(at[24], at[60]); + MULADD(at[25], at[59]); + MULADD(at[26], at[58]); + MULADD(at[27], at[57]); + MULADD(at[28], at[56]); + MULADD(at[29], at[55]); + MULADD(at[30], at[54]); + MULADD(at[31], at[53]); + COMBA_STORE(C->dp[52]); + /* 53 */ + COMBA_FORWARD; + MULADD(at[22], at[63]); + MULADD(at[23], at[62]); + MULADD(at[24], at[61]); + MULADD(at[25], at[60]); + MULADD(at[26], at[59]); + MULADD(at[27], at[58]); + MULADD(at[28], at[57]); + MULADD(at[29], at[56]); + MULADD(at[30], at[55]); + MULADD(at[31], at[54]); + COMBA_STORE(C->dp[53]); + /* 54 */ + COMBA_FORWARD; + MULADD(at[23], at[63]); + MULADD(at[24], at[62]); + MULADD(at[25], at[61]); + MULADD(at[26], at[60]); + MULADD(at[27], at[59]); + MULADD(at[28], at[58]); + MULADD(at[29], at[57]); + MULADD(at[30], at[56]); + MULADD(at[31], at[55]); + COMBA_STORE(C->dp[54]); + /* 55 */ + COMBA_FORWARD; + MULADD(at[24], at[63]); + MULADD(at[25], at[62]); + MULADD(at[26], at[61]); + MULADD(at[27], at[60]); + MULADD(at[28], at[59]); + MULADD(at[29], at[58]); + MULADD(at[30], at[57]); + MULADD(at[31], at[56]); + COMBA_STORE(C->dp[55]); + /* 56 */ + COMBA_FORWARD; + MULADD(at[25], at[63]); + MULADD(at[26], at[62]); + MULADD(at[27], at[61]); + MULADD(at[28], at[60]); + MULADD(at[29], at[59]); + MULADD(at[30], at[58]); + MULADD(at[31], at[57]); + COMBA_STORE(C->dp[56]); + /* 57 */ + COMBA_FORWARD; + MULADD(at[26], at[63]); + MULADD(at[27], at[62]); + MULADD(at[28], at[61]); + MULADD(at[29], at[60]); + MULADD(at[30], at[59]); + MULADD(at[31], at[58]); + COMBA_STORE(C->dp[57]); + /* 58 */ + COMBA_FORWARD; + MULADD(at[27], at[63]); + MULADD(at[28], at[62]); + MULADD(at[29], at[61]); + MULADD(at[30], at[60]); + MULADD(at[31], at[59]); + COMBA_STORE(C->dp[58]); + /* 59 */ + COMBA_FORWARD; + MULADD(at[28], at[63]); + MULADD(at[29], at[62]); + MULADD(at[30], at[61]); + MULADD(at[31], at[60]); + COMBA_STORE(C->dp[59]); + /* 60 */ + COMBA_FORWARD; + MULADD(at[29], at[63]); + MULADD(at[30], at[62]); + MULADD(at[31], at[61]); + COMBA_STORE(C->dp[60]); + /* 61 */ + COMBA_FORWARD; + MULADD(at[30], at[63]); + MULADD(at[31], at[62]); + COMBA_STORE(C->dp[61]); + /* 62 */ + COMBA_FORWARD; + MULADD(at[31], at[63]); + COMBA_STORE(C->dp[62]); + COMBA_STORE2(C->dp[63]); + C->used = 64; + C->sign = A->sign ^ B->sign; + mp_clamp(C); + COMBA_FINI; } - - -void s_mp_sqr_comba_4(const mp_int *A, mp_int *B) +void +s_mp_sqr_comba_4(const mp_int *A, mp_int *B) { - mp_digit *a, b[8], c0, c1, c2; - - a = A->dp; - COMBA_START; - - /* clear carries */ - CLEAR_CARRY; - - /* output 0 */ - SQRADD(a[0],a[0]); - COMBA_STORE(b[0]); - - /* output 1 */ - CARRY_FORWARD; - SQRADD2(a[0], a[1]); - COMBA_STORE(b[1]); - - /* output 2 */ - CARRY_FORWARD; - SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); - COMBA_STORE(b[2]); - - /* output 3 */ - CARRY_FORWARD; - SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); - COMBA_STORE(b[3]); - - /* output 4 */ - CARRY_FORWARD; - SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); - COMBA_STORE(b[4]); - - /* output 5 */ - CARRY_FORWARD; - SQRADD2(a[2], a[3]); - COMBA_STORE(b[5]); - - /* output 6 */ - CARRY_FORWARD; - SQRADD(a[3], a[3]); - COMBA_STORE(b[6]); - COMBA_STORE2(b[7]); - COMBA_FINI; - - B->used = 8; - B->sign = ZPOS; - memcpy(B->dp, b, 8 * sizeof(mp_digit)); - mp_clamp(B); + mp_digit *a, b[8], c0, c1, c2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0], a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); + SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); + SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[1], a[3]); + SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADD2(a[2], a[3]); + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + COMBA_STORE2(b[7]); + COMBA_FINI; + + B->used = 8; + B->sign = ZPOS; + memcpy(B->dp, b, 8 * sizeof(mp_digit)); + mp_clamp(B); } -void s_mp_sqr_comba_8(const mp_int *A, mp_int *B) +void +s_mp_sqr_comba_8(const mp_int *A, mp_int *B) { - mp_digit *a, b[16], c0, c1, c2, sc0, sc1, sc2; - - a = A->dp; - COMBA_START; - - /* clear carries */ - CLEAR_CARRY; - - /* output 0 */ - SQRADD(a[0],a[0]); - COMBA_STORE(b[0]); - - /* output 1 */ - CARRY_FORWARD; - SQRADD2(a[0], a[1]); - COMBA_STORE(b[1]); - - /* output 2 */ - CARRY_FORWARD; - SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); - COMBA_STORE(b[2]); - - /* output 3 */ - CARRY_FORWARD; - SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); - COMBA_STORE(b[3]); - - /* output 4 */ - CARRY_FORWARD; - SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); - COMBA_STORE(b[4]); - - /* output 5 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; - COMBA_STORE(b[5]); - - /* output 6 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); - COMBA_STORE(b[6]); - - /* output 7 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; - COMBA_STORE(b[7]); - - /* output 8 */ - CARRY_FORWARD; - SQRADDSC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); - COMBA_STORE(b[8]); - - /* output 9 */ - CARRY_FORWARD; - SQRADDSC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; - COMBA_STORE(b[9]); - - /* output 10 */ - CARRY_FORWARD; - SQRADD2(a[3], a[7]); SQRADD2(a[4], a[6]); SQRADD(a[5], a[5]); - COMBA_STORE(b[10]); - - /* output 11 */ - CARRY_FORWARD; - SQRADD2(a[4], a[7]); SQRADD2(a[5], a[6]); - COMBA_STORE(b[11]); - - /* output 12 */ - CARRY_FORWARD; - SQRADD2(a[5], a[7]); SQRADD(a[6], a[6]); - COMBA_STORE(b[12]); - - /* output 13 */ - CARRY_FORWARD; - SQRADD2(a[6], a[7]); - COMBA_STORE(b[13]); - - /* output 14 */ - CARRY_FORWARD; - SQRADD(a[7], a[7]); - COMBA_STORE(b[14]); - COMBA_STORE2(b[15]); - COMBA_FINI; - - B->used = 16; - B->sign = ZPOS; - memcpy(B->dp, b, 16 * sizeof(mp_digit)); - mp_clamp(B); + mp_digit *a, b[16], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0], a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); + SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); + SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); + SQRADD2(a[1], a[3]); + SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); + SQRADDAC(a[1], a[4]); + SQRADDAC(a[2], a[3]); + SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); + SQRADDAC(a[1], a[5]); + SQRADDAC(a[2], a[4]); + SQRADDDB; + SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); + SQRADDAC(a[1], a[6]); + SQRADDAC(a[2], a[5]); + SQRADDAC(a[3], a[4]); + SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[7]); + SQRADDAC(a[2], a[6]); + SQRADDAC(a[3], a[5]); + SQRADDDB; + SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[7]); + SQRADDAC(a[3], a[6]); + SQRADDAC(a[4], a[5]); + SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADD2(a[3], a[7]); + SQRADD2(a[4], a[6]); + SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADD2(a[4], a[7]); + SQRADD2(a[5], a[6]); + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADD2(a[5], a[7]); + SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADD2(a[6], a[7]); + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + COMBA_STORE2(b[15]); + COMBA_FINI; + + B->used = 16; + B->sign = ZPOS; + memcpy(B->dp, b, 16 * sizeof(mp_digit)); + mp_clamp(B); } -void s_mp_sqr_comba_16(const mp_int *A, mp_int *B) +void +s_mp_sqr_comba_16(const mp_int *A, mp_int *B) { - mp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2; - - a = A->dp; - COMBA_START; - - /* clear carries */ - CLEAR_CARRY; - - /* output 0 */ - SQRADD(a[0],a[0]); - COMBA_STORE(b[0]); - - /* output 1 */ - CARRY_FORWARD; - SQRADD2(a[0], a[1]); - COMBA_STORE(b[1]); - - /* output 2 */ - CARRY_FORWARD; - SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); - COMBA_STORE(b[2]); - - /* output 3 */ - CARRY_FORWARD; - SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); - COMBA_STORE(b[3]); - - /* output 4 */ - CARRY_FORWARD; - SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); - COMBA_STORE(b[4]); - - /* output 5 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; - COMBA_STORE(b[5]); - - /* output 6 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); - COMBA_STORE(b[6]); - - /* output 7 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; - COMBA_STORE(b[7]); - - /* output 8 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); - COMBA_STORE(b[8]); - - /* output 9 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; - COMBA_STORE(b[9]); - - /* output 10 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); - COMBA_STORE(b[10]); - - /* output 11 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; - COMBA_STORE(b[11]); - - /* output 12 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); - COMBA_STORE(b[12]); - - /* output 13 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; - COMBA_STORE(b[13]); - - /* output 14 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); - COMBA_STORE(b[14]); - - /* output 15 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; - COMBA_STORE(b[15]); - - /* output 16 */ - CARRY_FORWARD; - SQRADDSC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); - COMBA_STORE(b[16]); - - /* output 17 */ - CARRY_FORWARD; - SQRADDSC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; - COMBA_STORE(b[17]); - - /* output 18 */ - CARRY_FORWARD; - SQRADDSC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); - COMBA_STORE(b[18]); - - /* output 19 */ - CARRY_FORWARD; - SQRADDSC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; - COMBA_STORE(b[19]); - - /* output 20 */ - CARRY_FORWARD; - SQRADDSC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); - COMBA_STORE(b[20]); - - /* output 21 */ - CARRY_FORWARD; - SQRADDSC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; - COMBA_STORE(b[21]); - - /* output 22 */ - CARRY_FORWARD; - SQRADDSC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); - COMBA_STORE(b[22]); - - /* output 23 */ - CARRY_FORWARD; - SQRADDSC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; - COMBA_STORE(b[23]); - - /* output 24 */ - CARRY_FORWARD; - SQRADDSC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); - COMBA_STORE(b[24]); - - /* output 25 */ - CARRY_FORWARD; - SQRADDSC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; - COMBA_STORE(b[25]); - - /* output 26 */ - CARRY_FORWARD; - SQRADD2(a[11], a[15]); SQRADD2(a[12], a[14]); SQRADD(a[13], a[13]); - COMBA_STORE(b[26]); - - /* output 27 */ - CARRY_FORWARD; - SQRADD2(a[12], a[15]); SQRADD2(a[13], a[14]); - COMBA_STORE(b[27]); - - /* output 28 */ - CARRY_FORWARD; - SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]); - COMBA_STORE(b[28]); - - /* output 29 */ - CARRY_FORWARD; - SQRADD2(a[14], a[15]); - COMBA_STORE(b[29]); - - /* output 30 */ - CARRY_FORWARD; - SQRADD(a[15], a[15]); - COMBA_STORE(b[30]); - COMBA_STORE2(b[31]); - COMBA_FINI; - - B->used = 32; - B->sign = ZPOS; - memcpy(B->dp, b, 32 * sizeof(mp_digit)); - mp_clamp(B); + mp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0], a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); + SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); + SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); + SQRADD2(a[1], a[3]); + SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); + SQRADDAC(a[1], a[4]); + SQRADDAC(a[2], a[3]); + SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); + SQRADDAC(a[1], a[5]); + SQRADDAC(a[2], a[4]); + SQRADDDB; + SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); + SQRADDAC(a[1], a[6]); + SQRADDAC(a[2], a[5]); + SQRADDAC(a[3], a[4]); + SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); + SQRADDAC(a[1], a[7]); + SQRADDAC(a[2], a[6]); + SQRADDAC(a[3], a[5]); + SQRADDDB; + SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); + SQRADDAC(a[1], a[8]); + SQRADDAC(a[2], a[7]); + SQRADDAC(a[3], a[6]); + SQRADDAC(a[4], a[5]); + SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); + SQRADDAC(a[1], a[9]); + SQRADDAC(a[2], a[8]); + SQRADDAC(a[3], a[7]); + SQRADDAC(a[4], a[6]); + SQRADDDB; + SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); + SQRADDAC(a[1], a[10]); + SQRADDAC(a[2], a[9]); + SQRADDAC(a[3], a[8]); + SQRADDAC(a[4], a[7]); + SQRADDAC(a[5], a[6]); + SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); + SQRADDAC(a[1], a[11]); + SQRADDAC(a[2], a[10]); + SQRADDAC(a[3], a[9]); + SQRADDAC(a[4], a[8]); + SQRADDAC(a[5], a[7]); + SQRADDDB; + SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); + SQRADDAC(a[1], a[12]); + SQRADDAC(a[2], a[11]); + SQRADDAC(a[3], a[10]); + SQRADDAC(a[4], a[9]); + SQRADDAC(a[5], a[8]); + SQRADDAC(a[6], a[7]); + SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); + SQRADDAC(a[1], a[13]); + SQRADDAC(a[2], a[12]); + SQRADDAC(a[3], a[11]); + SQRADDAC(a[4], a[10]); + SQRADDAC(a[5], a[9]); + SQRADDAC(a[6], a[8]); + SQRADDDB; + SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); + SQRADDAC(a[1], a[14]); + SQRADDAC(a[2], a[13]); + SQRADDAC(a[3], a[12]); + SQRADDAC(a[4], a[11]); + SQRADDAC(a[5], a[10]); + SQRADDAC(a[6], a[9]); + SQRADDAC(a[7], a[8]); + SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[15]); + SQRADDAC(a[2], a[14]); + SQRADDAC(a[3], a[13]); + SQRADDAC(a[4], a[12]); + SQRADDAC(a[5], a[11]); + SQRADDAC(a[6], a[10]); + SQRADDAC(a[7], a[9]); + SQRADDDB; + SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[15]); + SQRADDAC(a[3], a[14]); + SQRADDAC(a[4], a[13]); + SQRADDAC(a[5], a[12]); + SQRADDAC(a[6], a[11]); + SQRADDAC(a[7], a[10]); + SQRADDAC(a[8], a[9]); + SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[15]); + SQRADDAC(a[4], a[14]); + SQRADDAC(a[5], a[13]); + SQRADDAC(a[6], a[12]); + SQRADDAC(a[7], a[11]); + SQRADDAC(a[8], a[10]); + SQRADDDB; + SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[15]); + SQRADDAC(a[5], a[14]); + SQRADDAC(a[6], a[13]); + SQRADDAC(a[7], a[12]); + SQRADDAC(a[8], a[11]); + SQRADDAC(a[9], a[10]); + SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[15]); + SQRADDAC(a[6], a[14]); + SQRADDAC(a[7], a[13]); + SQRADDAC(a[8], a[12]); + SQRADDAC(a[9], a[11]); + SQRADDDB; + SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[15]); + SQRADDAC(a[7], a[14]); + SQRADDAC(a[8], a[13]); + SQRADDAC(a[9], a[12]); + SQRADDAC(a[10], a[11]); + SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[15]); + SQRADDAC(a[8], a[14]); + SQRADDAC(a[9], a[13]); + SQRADDAC(a[10], a[12]); + SQRADDDB; + SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[15]); + SQRADDAC(a[9], a[14]); + SQRADDAC(a[10], a[13]); + SQRADDAC(a[11], a[12]); + SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[15]); + SQRADDAC(a[10], a[14]); + SQRADDAC(a[11], a[13]); + SQRADDDB; + SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[15]); + SQRADDAC(a[11], a[14]); + SQRADDAC(a[12], a[13]); + SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADD2(a[11], a[15]); + SQRADD2(a[12], a[14]); + SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADD2(a[12], a[15]); + SQRADD2(a[13], a[14]); + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADD2(a[13], a[15]); + SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADD2(a[14], a[15]); + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + COMBA_STORE2(b[31]); + COMBA_FINI; + + B->used = 32; + B->sign = ZPOS; + memcpy(B->dp, b, 32 * sizeof(mp_digit)); + mp_clamp(B); } - -void s_mp_sqr_comba_32(const mp_int *A, mp_int *B) +void +s_mp_sqr_comba_32(const mp_int *A, mp_int *B) { - mp_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2; - - a = A->dp; - COMBA_START; - - /* clear carries */ - CLEAR_CARRY; - - /* output 0 */ - SQRADD(a[0],a[0]); - COMBA_STORE(b[0]); - - /* output 1 */ - CARRY_FORWARD; - SQRADD2(a[0], a[1]); - COMBA_STORE(b[1]); - - /* output 2 */ - CARRY_FORWARD; - SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); - COMBA_STORE(b[2]); - - /* output 3 */ - CARRY_FORWARD; - SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); - COMBA_STORE(b[3]); - - /* output 4 */ - CARRY_FORWARD; - SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); - COMBA_STORE(b[4]); - - /* output 5 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; - COMBA_STORE(b[5]); - - /* output 6 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); - COMBA_STORE(b[6]); - - /* output 7 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; - COMBA_STORE(b[7]); - - /* output 8 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); - COMBA_STORE(b[8]); - - /* output 9 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; - COMBA_STORE(b[9]); - - /* output 10 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); - COMBA_STORE(b[10]); - - /* output 11 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; - COMBA_STORE(b[11]); - - /* output 12 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); - COMBA_STORE(b[12]); - - /* output 13 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; - COMBA_STORE(b[13]); - - /* output 14 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); - COMBA_STORE(b[14]); - - /* output 15 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; - COMBA_STORE(b[15]); - - /* output 16 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); - COMBA_STORE(b[16]); - - /* output 17 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; - COMBA_STORE(b[17]); - - /* output 18 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); - COMBA_STORE(b[18]); - - /* output 19 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; - COMBA_STORE(b[19]); - - /* output 20 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); - COMBA_STORE(b[20]); - - /* output 21 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; - COMBA_STORE(b[21]); - - /* output 22 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); - COMBA_STORE(b[22]); - - /* output 23 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; - COMBA_STORE(b[23]); - - /* output 24 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); - COMBA_STORE(b[24]); - - /* output 25 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; - COMBA_STORE(b[25]); - - /* output 26 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); - COMBA_STORE(b[26]); - - /* output 27 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; - COMBA_STORE(b[27]); - - /* output 28 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]); - COMBA_STORE(b[28]); - - /* output 29 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB; - COMBA_STORE(b[29]); - - /* output 30 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]); - COMBA_STORE(b[30]); - - /* output 31 */ - CARRY_FORWARD; - SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB; - COMBA_STORE(b[31]); - - /* output 32 */ - CARRY_FORWARD; - SQRADDSC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]); - COMBA_STORE(b[32]); - - /* output 33 */ - CARRY_FORWARD; - SQRADDSC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB; - COMBA_STORE(b[33]); - - /* output 34 */ - CARRY_FORWARD; - SQRADDSC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]); - COMBA_STORE(b[34]); - - /* output 35 */ - CARRY_FORWARD; - SQRADDSC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB; - COMBA_STORE(b[35]); - - /* output 36 */ - CARRY_FORWARD; - SQRADDSC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]); - COMBA_STORE(b[36]); - - /* output 37 */ - CARRY_FORWARD; - SQRADDSC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB; - COMBA_STORE(b[37]); - - /* output 38 */ - CARRY_FORWARD; - SQRADDSC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]); - COMBA_STORE(b[38]); - - /* output 39 */ - CARRY_FORWARD; - SQRADDSC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB; - COMBA_STORE(b[39]); - - /* output 40 */ - CARRY_FORWARD; - SQRADDSC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]); - COMBA_STORE(b[40]); - - /* output 41 */ - CARRY_FORWARD; - SQRADDSC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB; - COMBA_STORE(b[41]); - - /* output 42 */ - CARRY_FORWARD; - SQRADDSC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]); - COMBA_STORE(b[42]); - - /* output 43 */ - CARRY_FORWARD; - SQRADDSC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB; - COMBA_STORE(b[43]); - - /* output 44 */ - CARRY_FORWARD; - SQRADDSC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]); - COMBA_STORE(b[44]); - - /* output 45 */ - CARRY_FORWARD; - SQRADDSC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB; - COMBA_STORE(b[45]); - - /* output 46 */ - CARRY_FORWARD; - SQRADDSC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]); - COMBA_STORE(b[46]); - - /* output 47 */ - CARRY_FORWARD; - SQRADDSC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB; - COMBA_STORE(b[47]); - - /* output 48 */ - CARRY_FORWARD; - SQRADDSC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]); - COMBA_STORE(b[48]); - - /* output 49 */ - CARRY_FORWARD; - SQRADDSC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB; - COMBA_STORE(b[49]); - - /* output 50 */ - CARRY_FORWARD; - SQRADDSC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]); - COMBA_STORE(b[50]); - - /* output 51 */ - CARRY_FORWARD; - SQRADDSC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB; - COMBA_STORE(b[51]); - - /* output 52 */ - CARRY_FORWARD; - SQRADDSC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]); - COMBA_STORE(b[52]); - - /* output 53 */ - CARRY_FORWARD; - SQRADDSC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB; - COMBA_STORE(b[53]); - - /* output 54 */ - CARRY_FORWARD; - SQRADDSC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]); - COMBA_STORE(b[54]); - - /* output 55 */ - CARRY_FORWARD; - SQRADDSC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB; - COMBA_STORE(b[55]); - - /* output 56 */ - CARRY_FORWARD; - SQRADDSC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]); - COMBA_STORE(b[56]); - - /* output 57 */ - CARRY_FORWARD; - SQRADDSC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB; - COMBA_STORE(b[57]); - - /* output 58 */ - CARRY_FORWARD; - SQRADD2(a[27], a[31]); SQRADD2(a[28], a[30]); SQRADD(a[29], a[29]); - COMBA_STORE(b[58]); - - /* output 59 */ - CARRY_FORWARD; - SQRADD2(a[28], a[31]); SQRADD2(a[29], a[30]); - COMBA_STORE(b[59]); - - /* output 60 */ - CARRY_FORWARD; - SQRADD2(a[29], a[31]); SQRADD(a[30], a[30]); - COMBA_STORE(b[60]); - - /* output 61 */ - CARRY_FORWARD; - SQRADD2(a[30], a[31]); - COMBA_STORE(b[61]); - - /* output 62 */ - CARRY_FORWARD; - SQRADD(a[31], a[31]); - COMBA_STORE(b[62]); - COMBA_STORE2(b[63]); - COMBA_FINI; - - B->used = 64; - B->sign = ZPOS; - memcpy(B->dp, b, 64 * sizeof(mp_digit)); - mp_clamp(B); + mp_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0], a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); + SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); + SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); + SQRADD2(a[1], a[3]); + SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); + SQRADDAC(a[1], a[4]); + SQRADDAC(a[2], a[3]); + SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); + SQRADDAC(a[1], a[5]); + SQRADDAC(a[2], a[4]); + SQRADDDB; + SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); + SQRADDAC(a[1], a[6]); + SQRADDAC(a[2], a[5]); + SQRADDAC(a[3], a[4]); + SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); + SQRADDAC(a[1], a[7]); + SQRADDAC(a[2], a[6]); + SQRADDAC(a[3], a[5]); + SQRADDDB; + SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); + SQRADDAC(a[1], a[8]); + SQRADDAC(a[2], a[7]); + SQRADDAC(a[3], a[6]); + SQRADDAC(a[4], a[5]); + SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); + SQRADDAC(a[1], a[9]); + SQRADDAC(a[2], a[8]); + SQRADDAC(a[3], a[7]); + SQRADDAC(a[4], a[6]); + SQRADDDB; + SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); + SQRADDAC(a[1], a[10]); + SQRADDAC(a[2], a[9]); + SQRADDAC(a[3], a[8]); + SQRADDAC(a[4], a[7]); + SQRADDAC(a[5], a[6]); + SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); + SQRADDAC(a[1], a[11]); + SQRADDAC(a[2], a[10]); + SQRADDAC(a[3], a[9]); + SQRADDAC(a[4], a[8]); + SQRADDAC(a[5], a[7]); + SQRADDDB; + SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); + SQRADDAC(a[1], a[12]); + SQRADDAC(a[2], a[11]); + SQRADDAC(a[3], a[10]); + SQRADDAC(a[4], a[9]); + SQRADDAC(a[5], a[8]); + SQRADDAC(a[6], a[7]); + SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); + SQRADDAC(a[1], a[13]); + SQRADDAC(a[2], a[12]); + SQRADDAC(a[3], a[11]); + SQRADDAC(a[4], a[10]); + SQRADDAC(a[5], a[9]); + SQRADDAC(a[6], a[8]); + SQRADDDB; + SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); + SQRADDAC(a[1], a[14]); + SQRADDAC(a[2], a[13]); + SQRADDAC(a[3], a[12]); + SQRADDAC(a[4], a[11]); + SQRADDAC(a[5], a[10]); + SQRADDAC(a[6], a[9]); + SQRADDAC(a[7], a[8]); + SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[16]); + SQRADDAC(a[1], a[15]); + SQRADDAC(a[2], a[14]); + SQRADDAC(a[3], a[13]); + SQRADDAC(a[4], a[12]); + SQRADDAC(a[5], a[11]); + SQRADDAC(a[6], a[10]); + SQRADDAC(a[7], a[9]); + SQRADDDB; + SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[17]); + SQRADDAC(a[1], a[16]); + SQRADDAC(a[2], a[15]); + SQRADDAC(a[3], a[14]); + SQRADDAC(a[4], a[13]); + SQRADDAC(a[5], a[12]); + SQRADDAC(a[6], a[11]); + SQRADDAC(a[7], a[10]); + SQRADDAC(a[8], a[9]); + SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[18]); + SQRADDAC(a[1], a[17]); + SQRADDAC(a[2], a[16]); + SQRADDAC(a[3], a[15]); + SQRADDAC(a[4], a[14]); + SQRADDAC(a[5], a[13]); + SQRADDAC(a[6], a[12]); + SQRADDAC(a[7], a[11]); + SQRADDAC(a[8], a[10]); + SQRADDDB; + SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[19]); + SQRADDAC(a[1], a[18]); + SQRADDAC(a[2], a[17]); + SQRADDAC(a[3], a[16]); + SQRADDAC(a[4], a[15]); + SQRADDAC(a[5], a[14]); + SQRADDAC(a[6], a[13]); + SQRADDAC(a[7], a[12]); + SQRADDAC(a[8], a[11]); + SQRADDAC(a[9], a[10]); + SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[20]); + SQRADDAC(a[1], a[19]); + SQRADDAC(a[2], a[18]); + SQRADDAC(a[3], a[17]); + SQRADDAC(a[4], a[16]); + SQRADDAC(a[5], a[15]); + SQRADDAC(a[6], a[14]); + SQRADDAC(a[7], a[13]); + SQRADDAC(a[8], a[12]); + SQRADDAC(a[9], a[11]); + SQRADDDB; + SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[21]); + SQRADDAC(a[1], a[20]); + SQRADDAC(a[2], a[19]); + SQRADDAC(a[3], a[18]); + SQRADDAC(a[4], a[17]); + SQRADDAC(a[5], a[16]); + SQRADDAC(a[6], a[15]); + SQRADDAC(a[7], a[14]); + SQRADDAC(a[8], a[13]); + SQRADDAC(a[9], a[12]); + SQRADDAC(a[10], a[11]); + SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[22]); + SQRADDAC(a[1], a[21]); + SQRADDAC(a[2], a[20]); + SQRADDAC(a[3], a[19]); + SQRADDAC(a[4], a[18]); + SQRADDAC(a[5], a[17]); + SQRADDAC(a[6], a[16]); + SQRADDAC(a[7], a[15]); + SQRADDAC(a[8], a[14]); + SQRADDAC(a[9], a[13]); + SQRADDAC(a[10], a[12]); + SQRADDDB; + SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[23]); + SQRADDAC(a[1], a[22]); + SQRADDAC(a[2], a[21]); + SQRADDAC(a[3], a[20]); + SQRADDAC(a[4], a[19]); + SQRADDAC(a[5], a[18]); + SQRADDAC(a[6], a[17]); + SQRADDAC(a[7], a[16]); + SQRADDAC(a[8], a[15]); + SQRADDAC(a[9], a[14]); + SQRADDAC(a[10], a[13]); + SQRADDAC(a[11], a[12]); + SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[24]); + SQRADDAC(a[1], a[23]); + SQRADDAC(a[2], a[22]); + SQRADDAC(a[3], a[21]); + SQRADDAC(a[4], a[20]); + SQRADDAC(a[5], a[19]); + SQRADDAC(a[6], a[18]); + SQRADDAC(a[7], a[17]); + SQRADDAC(a[8], a[16]); + SQRADDAC(a[9], a[15]); + SQRADDAC(a[10], a[14]); + SQRADDAC(a[11], a[13]); + SQRADDDB; + SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[25]); + SQRADDAC(a[1], a[24]); + SQRADDAC(a[2], a[23]); + SQRADDAC(a[3], a[22]); + SQRADDAC(a[4], a[21]); + SQRADDAC(a[5], a[20]); + SQRADDAC(a[6], a[19]); + SQRADDAC(a[7], a[18]); + SQRADDAC(a[8], a[17]); + SQRADDAC(a[9], a[16]); + SQRADDAC(a[10], a[15]); + SQRADDAC(a[11], a[14]); + SQRADDAC(a[12], a[13]); + SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[26]); + SQRADDAC(a[1], a[25]); + SQRADDAC(a[2], a[24]); + SQRADDAC(a[3], a[23]); + SQRADDAC(a[4], a[22]); + SQRADDAC(a[5], a[21]); + SQRADDAC(a[6], a[20]); + SQRADDAC(a[7], a[19]); + SQRADDAC(a[8], a[18]); + SQRADDAC(a[9], a[17]); + SQRADDAC(a[10], a[16]); + SQRADDAC(a[11], a[15]); + SQRADDAC(a[12], a[14]); + SQRADDDB; + SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[27]); + SQRADDAC(a[1], a[26]); + SQRADDAC(a[2], a[25]); + SQRADDAC(a[3], a[24]); + SQRADDAC(a[4], a[23]); + SQRADDAC(a[5], a[22]); + SQRADDAC(a[6], a[21]); + SQRADDAC(a[7], a[20]); + SQRADDAC(a[8], a[19]); + SQRADDAC(a[9], a[18]); + SQRADDAC(a[10], a[17]); + SQRADDAC(a[11], a[16]); + SQRADDAC(a[12], a[15]); + SQRADDAC(a[13], a[14]); + SQRADDDB; + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[28]); + SQRADDAC(a[1], a[27]); + SQRADDAC(a[2], a[26]); + SQRADDAC(a[3], a[25]); + SQRADDAC(a[4], a[24]); + SQRADDAC(a[5], a[23]); + SQRADDAC(a[6], a[22]); + SQRADDAC(a[7], a[21]); + SQRADDAC(a[8], a[20]); + SQRADDAC(a[9], a[19]); + SQRADDAC(a[10], a[18]); + SQRADDAC(a[11], a[17]); + SQRADDAC(a[12], a[16]); + SQRADDAC(a[13], a[15]); + SQRADDDB; + SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[29]); + SQRADDAC(a[1], a[28]); + SQRADDAC(a[2], a[27]); + SQRADDAC(a[3], a[26]); + SQRADDAC(a[4], a[25]); + SQRADDAC(a[5], a[24]); + SQRADDAC(a[6], a[23]); + SQRADDAC(a[7], a[22]); + SQRADDAC(a[8], a[21]); + SQRADDAC(a[9], a[20]); + SQRADDAC(a[10], a[19]); + SQRADDAC(a[11], a[18]); + SQRADDAC(a[12], a[17]); + SQRADDAC(a[13], a[16]); + SQRADDAC(a[14], a[15]); + SQRADDDB; + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[30]); + SQRADDAC(a[1], a[29]); + SQRADDAC(a[2], a[28]); + SQRADDAC(a[3], a[27]); + SQRADDAC(a[4], a[26]); + SQRADDAC(a[5], a[25]); + SQRADDAC(a[6], a[24]); + SQRADDAC(a[7], a[23]); + SQRADDAC(a[8], a[22]); + SQRADDAC(a[9], a[21]); + SQRADDAC(a[10], a[20]); + SQRADDAC(a[11], a[19]); + SQRADDAC(a[12], a[18]); + SQRADDAC(a[13], a[17]); + SQRADDAC(a[14], a[16]); + SQRADDDB; + SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + + /* output 31 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[31]); + SQRADDAC(a[1], a[30]); + SQRADDAC(a[2], a[29]); + SQRADDAC(a[3], a[28]); + SQRADDAC(a[4], a[27]); + SQRADDAC(a[5], a[26]); + SQRADDAC(a[6], a[25]); + SQRADDAC(a[7], a[24]); + SQRADDAC(a[8], a[23]); + SQRADDAC(a[9], a[22]); + SQRADDAC(a[10], a[21]); + SQRADDAC(a[11], a[20]); + SQRADDAC(a[12], a[19]); + SQRADDAC(a[13], a[18]); + SQRADDAC(a[14], a[17]); + SQRADDAC(a[15], a[16]); + SQRADDDB; + COMBA_STORE(b[31]); + + /* output 32 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[31]); + SQRADDAC(a[2], a[30]); + SQRADDAC(a[3], a[29]); + SQRADDAC(a[4], a[28]); + SQRADDAC(a[5], a[27]); + SQRADDAC(a[6], a[26]); + SQRADDAC(a[7], a[25]); + SQRADDAC(a[8], a[24]); + SQRADDAC(a[9], a[23]); + SQRADDAC(a[10], a[22]); + SQRADDAC(a[11], a[21]); + SQRADDAC(a[12], a[20]); + SQRADDAC(a[13], a[19]); + SQRADDAC(a[14], a[18]); + SQRADDAC(a[15], a[17]); + SQRADDDB; + SQRADD(a[16], a[16]); + COMBA_STORE(b[32]); + + /* output 33 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[31]); + SQRADDAC(a[3], a[30]); + SQRADDAC(a[4], a[29]); + SQRADDAC(a[5], a[28]); + SQRADDAC(a[6], a[27]); + SQRADDAC(a[7], a[26]); + SQRADDAC(a[8], a[25]); + SQRADDAC(a[9], a[24]); + SQRADDAC(a[10], a[23]); + SQRADDAC(a[11], a[22]); + SQRADDAC(a[12], a[21]); + SQRADDAC(a[13], a[20]); + SQRADDAC(a[14], a[19]); + SQRADDAC(a[15], a[18]); + SQRADDAC(a[16], a[17]); + SQRADDDB; + COMBA_STORE(b[33]); + + /* output 34 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[31]); + SQRADDAC(a[4], a[30]); + SQRADDAC(a[5], a[29]); + SQRADDAC(a[6], a[28]); + SQRADDAC(a[7], a[27]); + SQRADDAC(a[8], a[26]); + SQRADDAC(a[9], a[25]); + SQRADDAC(a[10], a[24]); + SQRADDAC(a[11], a[23]); + SQRADDAC(a[12], a[22]); + SQRADDAC(a[13], a[21]); + SQRADDAC(a[14], a[20]); + SQRADDAC(a[15], a[19]); + SQRADDAC(a[16], a[18]); + SQRADDDB; + SQRADD(a[17], a[17]); + COMBA_STORE(b[34]); + + /* output 35 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[31]); + SQRADDAC(a[5], a[30]); + SQRADDAC(a[6], a[29]); + SQRADDAC(a[7], a[28]); + SQRADDAC(a[8], a[27]); + SQRADDAC(a[9], a[26]); + SQRADDAC(a[10], a[25]); + SQRADDAC(a[11], a[24]); + SQRADDAC(a[12], a[23]); + SQRADDAC(a[13], a[22]); + SQRADDAC(a[14], a[21]); + SQRADDAC(a[15], a[20]); + SQRADDAC(a[16], a[19]); + SQRADDAC(a[17], a[18]); + SQRADDDB; + COMBA_STORE(b[35]); + + /* output 36 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[31]); + SQRADDAC(a[6], a[30]); + SQRADDAC(a[7], a[29]); + SQRADDAC(a[8], a[28]); + SQRADDAC(a[9], a[27]); + SQRADDAC(a[10], a[26]); + SQRADDAC(a[11], a[25]); + SQRADDAC(a[12], a[24]); + SQRADDAC(a[13], a[23]); + SQRADDAC(a[14], a[22]); + SQRADDAC(a[15], a[21]); + SQRADDAC(a[16], a[20]); + SQRADDAC(a[17], a[19]); + SQRADDDB; + SQRADD(a[18], a[18]); + COMBA_STORE(b[36]); + + /* output 37 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[31]); + SQRADDAC(a[7], a[30]); + SQRADDAC(a[8], a[29]); + SQRADDAC(a[9], a[28]); + SQRADDAC(a[10], a[27]); + SQRADDAC(a[11], a[26]); + SQRADDAC(a[12], a[25]); + SQRADDAC(a[13], a[24]); + SQRADDAC(a[14], a[23]); + SQRADDAC(a[15], a[22]); + SQRADDAC(a[16], a[21]); + SQRADDAC(a[17], a[20]); + SQRADDAC(a[18], a[19]); + SQRADDDB; + COMBA_STORE(b[37]); + + /* output 38 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[31]); + SQRADDAC(a[8], a[30]); + SQRADDAC(a[9], a[29]); + SQRADDAC(a[10], a[28]); + SQRADDAC(a[11], a[27]); + SQRADDAC(a[12], a[26]); + SQRADDAC(a[13], a[25]); + SQRADDAC(a[14], a[24]); + SQRADDAC(a[15], a[23]); + SQRADDAC(a[16], a[22]); + SQRADDAC(a[17], a[21]); + SQRADDAC(a[18], a[20]); + SQRADDDB; + SQRADD(a[19], a[19]); + COMBA_STORE(b[38]); + + /* output 39 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[31]); + SQRADDAC(a[9], a[30]); + SQRADDAC(a[10], a[29]); + SQRADDAC(a[11], a[28]); + SQRADDAC(a[12], a[27]); + SQRADDAC(a[13], a[26]); + SQRADDAC(a[14], a[25]); + SQRADDAC(a[15], a[24]); + SQRADDAC(a[16], a[23]); + SQRADDAC(a[17], a[22]); + SQRADDAC(a[18], a[21]); + SQRADDAC(a[19], a[20]); + SQRADDDB; + COMBA_STORE(b[39]); + + /* output 40 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[31]); + SQRADDAC(a[10], a[30]); + SQRADDAC(a[11], a[29]); + SQRADDAC(a[12], a[28]); + SQRADDAC(a[13], a[27]); + SQRADDAC(a[14], a[26]); + SQRADDAC(a[15], a[25]); + SQRADDAC(a[16], a[24]); + SQRADDAC(a[17], a[23]); + SQRADDAC(a[18], a[22]); + SQRADDAC(a[19], a[21]); + SQRADDDB; + SQRADD(a[20], a[20]); + COMBA_STORE(b[40]); + + /* output 41 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[31]); + SQRADDAC(a[11], a[30]); + SQRADDAC(a[12], a[29]); + SQRADDAC(a[13], a[28]); + SQRADDAC(a[14], a[27]); + SQRADDAC(a[15], a[26]); + SQRADDAC(a[16], a[25]); + SQRADDAC(a[17], a[24]); + SQRADDAC(a[18], a[23]); + SQRADDAC(a[19], a[22]); + SQRADDAC(a[20], a[21]); + SQRADDDB; + COMBA_STORE(b[41]); + + /* output 42 */ + CARRY_FORWARD; + SQRADDSC(a[11], a[31]); + SQRADDAC(a[12], a[30]); + SQRADDAC(a[13], a[29]); + SQRADDAC(a[14], a[28]); + SQRADDAC(a[15], a[27]); + SQRADDAC(a[16], a[26]); + SQRADDAC(a[17], a[25]); + SQRADDAC(a[18], a[24]); + SQRADDAC(a[19], a[23]); + SQRADDAC(a[20], a[22]); + SQRADDDB; + SQRADD(a[21], a[21]); + COMBA_STORE(b[42]); + + /* output 43 */ + CARRY_FORWARD; + SQRADDSC(a[12], a[31]); + SQRADDAC(a[13], a[30]); + SQRADDAC(a[14], a[29]); + SQRADDAC(a[15], a[28]); + SQRADDAC(a[16], a[27]); + SQRADDAC(a[17], a[26]); + SQRADDAC(a[18], a[25]); + SQRADDAC(a[19], a[24]); + SQRADDAC(a[20], a[23]); + SQRADDAC(a[21], a[22]); + SQRADDDB; + COMBA_STORE(b[43]); + + /* output 44 */ + CARRY_FORWARD; + SQRADDSC(a[13], a[31]); + SQRADDAC(a[14], a[30]); + SQRADDAC(a[15], a[29]); + SQRADDAC(a[16], a[28]); + SQRADDAC(a[17], a[27]); + SQRADDAC(a[18], a[26]); + SQRADDAC(a[19], a[25]); + SQRADDAC(a[20], a[24]); + SQRADDAC(a[21], a[23]); + SQRADDDB; + SQRADD(a[22], a[22]); + COMBA_STORE(b[44]); + + /* output 45 */ + CARRY_FORWARD; + SQRADDSC(a[14], a[31]); + SQRADDAC(a[15], a[30]); + SQRADDAC(a[16], a[29]); + SQRADDAC(a[17], a[28]); + SQRADDAC(a[18], a[27]); + SQRADDAC(a[19], a[26]); + SQRADDAC(a[20], a[25]); + SQRADDAC(a[21], a[24]); + SQRADDAC(a[22], a[23]); + SQRADDDB; + COMBA_STORE(b[45]); + + /* output 46 */ + CARRY_FORWARD; + SQRADDSC(a[15], a[31]); + SQRADDAC(a[16], a[30]); + SQRADDAC(a[17], a[29]); + SQRADDAC(a[18], a[28]); + SQRADDAC(a[19], a[27]); + SQRADDAC(a[20], a[26]); + SQRADDAC(a[21], a[25]); + SQRADDAC(a[22], a[24]); + SQRADDDB; + SQRADD(a[23], a[23]); + COMBA_STORE(b[46]); + + /* output 47 */ + CARRY_FORWARD; + SQRADDSC(a[16], a[31]); + SQRADDAC(a[17], a[30]); + SQRADDAC(a[18], a[29]); + SQRADDAC(a[19], a[28]); + SQRADDAC(a[20], a[27]); + SQRADDAC(a[21], a[26]); + SQRADDAC(a[22], a[25]); + SQRADDAC(a[23], a[24]); + SQRADDDB; + COMBA_STORE(b[47]); + + /* output 48 */ + CARRY_FORWARD; + SQRADDSC(a[17], a[31]); + SQRADDAC(a[18], a[30]); + SQRADDAC(a[19], a[29]); + SQRADDAC(a[20], a[28]); + SQRADDAC(a[21], a[27]); + SQRADDAC(a[22], a[26]); + SQRADDAC(a[23], a[25]); + SQRADDDB; + SQRADD(a[24], a[24]); + COMBA_STORE(b[48]); + + /* output 49 */ + CARRY_FORWARD; + SQRADDSC(a[18], a[31]); + SQRADDAC(a[19], a[30]); + SQRADDAC(a[20], a[29]); + SQRADDAC(a[21], a[28]); + SQRADDAC(a[22], a[27]); + SQRADDAC(a[23], a[26]); + SQRADDAC(a[24], a[25]); + SQRADDDB; + COMBA_STORE(b[49]); + + /* output 50 */ + CARRY_FORWARD; + SQRADDSC(a[19], a[31]); + SQRADDAC(a[20], a[30]); + SQRADDAC(a[21], a[29]); + SQRADDAC(a[22], a[28]); + SQRADDAC(a[23], a[27]); + SQRADDAC(a[24], a[26]); + SQRADDDB; + SQRADD(a[25], a[25]); + COMBA_STORE(b[50]); + + /* output 51 */ + CARRY_FORWARD; + SQRADDSC(a[20], a[31]); + SQRADDAC(a[21], a[30]); + SQRADDAC(a[22], a[29]); + SQRADDAC(a[23], a[28]); + SQRADDAC(a[24], a[27]); + SQRADDAC(a[25], a[26]); + SQRADDDB; + COMBA_STORE(b[51]); + + /* output 52 */ + CARRY_FORWARD; + SQRADDSC(a[21], a[31]); + SQRADDAC(a[22], a[30]); + SQRADDAC(a[23], a[29]); + SQRADDAC(a[24], a[28]); + SQRADDAC(a[25], a[27]); + SQRADDDB; + SQRADD(a[26], a[26]); + COMBA_STORE(b[52]); + + /* output 53 */ + CARRY_FORWARD; + SQRADDSC(a[22], a[31]); + SQRADDAC(a[23], a[30]); + SQRADDAC(a[24], a[29]); + SQRADDAC(a[25], a[28]); + SQRADDAC(a[26], a[27]); + SQRADDDB; + COMBA_STORE(b[53]); + + /* output 54 */ + CARRY_FORWARD; + SQRADDSC(a[23], a[31]); + SQRADDAC(a[24], a[30]); + SQRADDAC(a[25], a[29]); + SQRADDAC(a[26], a[28]); + SQRADDDB; + SQRADD(a[27], a[27]); + COMBA_STORE(b[54]); + + /* output 55 */ + CARRY_FORWARD; + SQRADDSC(a[24], a[31]); + SQRADDAC(a[25], a[30]); + SQRADDAC(a[26], a[29]); + SQRADDAC(a[27], a[28]); + SQRADDDB; + COMBA_STORE(b[55]); + + /* output 56 */ + CARRY_FORWARD; + SQRADDSC(a[25], a[31]); + SQRADDAC(a[26], a[30]); + SQRADDAC(a[27], a[29]); + SQRADDDB; + SQRADD(a[28], a[28]); + COMBA_STORE(b[56]); + + /* output 57 */ + CARRY_FORWARD; + SQRADDSC(a[26], a[31]); + SQRADDAC(a[27], a[30]); + SQRADDAC(a[28], a[29]); + SQRADDDB; + COMBA_STORE(b[57]); + + /* output 58 */ + CARRY_FORWARD; + SQRADD2(a[27], a[31]); + SQRADD2(a[28], a[30]); + SQRADD(a[29], a[29]); + COMBA_STORE(b[58]); + + /* output 59 */ + CARRY_FORWARD; + SQRADD2(a[28], a[31]); + SQRADD2(a[29], a[30]); + COMBA_STORE(b[59]); + + /* output 60 */ + CARRY_FORWARD; + SQRADD2(a[29], a[31]); + SQRADD(a[30], a[30]); + COMBA_STORE(b[60]); + + /* output 61 */ + CARRY_FORWARD; + SQRADD2(a[30], a[31]); + COMBA_STORE(b[61]); + + /* output 62 */ + CARRY_FORWARD; + SQRADD(a[31], a[31]); + COMBA_STORE(b[62]); + COMBA_STORE2(b[63]); + COMBA_FINI; + + B->used = 64; + B->sign = ZPOS; + memcpy(B->dp, b, 64 * sizeof(mp_digit)); + mp_clamp(B); } diff --git a/nss/lib/freebl/mpi/mp_gf2m-priv.h b/nss/lib/freebl/mpi/mp_gf2m-priv.h index b9c2f3b..5be4da4 100644 --- a/nss/lib/freebl/mpi/mp_gf2m-priv.h +++ b/nss/lib/freebl/mpi/mp_gf2m-priv.h @@ -23,23 +23,23 @@ extern const mp_digit mp_gf2m_sqr_tb[16]; /* Platform-specific macros for fast binary polynomial squaring. */ #if MP_DIGIT_BITS == 32 -#define gf2m_SQR1(w) \ +#define gf2m_SQR1(w) \ mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 16 | \ - mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF] -#define gf2m_SQR0(w) \ - mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \ - mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) & 0xF] + mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF] +#define gf2m_SQR0(w) \ + mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \ + mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w)&0xF] #else -#define gf2m_SQR1(w) \ - mp_gf2m_sqr_tb[(w) >> 60 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 56 & 0xF] << 48 | \ - mp_gf2m_sqr_tb[(w) >> 52 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 48 & 0xF] << 32 | \ - mp_gf2m_sqr_tb[(w) >> 44 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 40 & 0xF] << 16 | \ - mp_gf2m_sqr_tb[(w) >> 36 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 32 & 0xF] -#define gf2m_SQR0(w) \ - mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 48 | \ - mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF] << 32 | \ - mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \ - mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) & 0xF] +#define gf2m_SQR1(w) \ + mp_gf2m_sqr_tb[(w) >> 60 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 56 & 0xF] << 48 | \ + mp_gf2m_sqr_tb[(w) >> 52 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 48 & 0xF] << 32 | \ + mp_gf2m_sqr_tb[(w) >> 44 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 40 & 0xF] << 16 | \ + mp_gf2m_sqr_tb[(w) >> 36 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 32 & 0xF] +#define gf2m_SQR0(w) \ + mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 48 | \ + mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF] << 32 | \ + mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \ + mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w)&0xF] #endif /* Multiply two binary polynomials mp_digits a, b. @@ -48,26 +48,26 @@ extern const mp_digit mp_gf2m_sqr_tb[16]; */ void s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b); -/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0) +/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0) * result is a binary polynomial in 4 mp_digits r[4]. * The caller MUST ensure that r has the right amount of space allocated. */ void s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1, - const mp_digit b0); + const mp_digit b0); -/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, b0) +/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, b0) * result is a binary polynomial in 6 mp_digits r[6]. * The caller MUST ensure that r has the right amount of space allocated. */ -void s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0, - const mp_digit b2, const mp_digit b1, const mp_digit b0); +void s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0, + const mp_digit b2, const mp_digit b1, const mp_digit b0); -/* Compute xor-multiply of two binary polynomials (a3, a2, a1, a0) x (b3, b2, b1, b0) +/* Compute xor-multiply of two binary polynomials (a3, a2, a1, a0) x (b3, b2, b1, b0) * result is a binary polynomial in 8 mp_digits r[8]. * The caller MUST ensure that r has the right amount of space allocated. */ -void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1, - const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1, - const mp_digit b0); +void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1, + const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1, + const mp_digit b0); #endif /* _MP_GF2M_PRIV_H_ */ diff --git a/nss/lib/freebl/mpi/mp_gf2m.c b/nss/lib/freebl/mpi/mp_gf2m.c index e84f3a0..5a096ad 100644 --- a/nss/lib/freebl/mpi/mp_gf2m.c +++ b/nss/lib/freebl/mpi/mp_gf2m.c @@ -8,159 +8,251 @@ #include "mpi-priv.h" const mp_digit mp_gf2m_sqr_tb[16] = -{ - 0, 1, 4, 5, 16, 17, 20, 21, - 64, 65, 68, 69, 80, 81, 84, 85 -}; + { + 0, 1, 4, 5, 16, 17, 20, 21, + 64, 65, 68, 69, 80, 81, 84, 85 + }; /* Multiply two binary polynomials mp_digits a, b. * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1. * Output in two mp_digits rh, rl. */ #if MP_DIGIT_BITS == 32 -void +void s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b) { register mp_digit h, l, s; - mp_digit tab[8], top2b = a >> 30; + mp_digit tab[8], top2b = a >> 30; register mp_digit a1, a2, a4; - a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1; - - tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2; - tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4; - - s = tab[b & 0x7]; l = s; - s = tab[b >> 3 & 0x7]; l ^= s << 3; h = s >> 29; - s = tab[b >> 6 & 0x7]; l ^= s << 6; h ^= s >> 26; - s = tab[b >> 9 & 0x7]; l ^= s << 9; h ^= s >> 23; - s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20; - s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17; - s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14; - s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11; - s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >> 8; - s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >> 5; - s = tab[b >> 30 ]; l ^= s << 30; h ^= s >> 2; + a1 = a & (0x3FFFFFFF); + a2 = a1 << 1; + a4 = a2 << 1; + + tab[0] = 0; + tab[1] = a1; + tab[2] = a2; + tab[3] = a1 ^ a2; + tab[4] = a4; + tab[5] = a1 ^ a4; + tab[6] = a2 ^ a4; + tab[7] = a1 ^ a2 ^ a4; + + s = tab[b & 0x7]; + l = s; + s = tab[b >> 3 & 0x7]; + l ^= s << 3; + h = s >> 29; + s = tab[b >> 6 & 0x7]; + l ^= s << 6; + h ^= s >> 26; + s = tab[b >> 9 & 0x7]; + l ^= s << 9; + h ^= s >> 23; + s = tab[b >> 12 & 0x7]; + l ^= s << 12; + h ^= s >> 20; + s = tab[b >> 15 & 0x7]; + l ^= s << 15; + h ^= s >> 17; + s = tab[b >> 18 & 0x7]; + l ^= s << 18; + h ^= s >> 14; + s = tab[b >> 21 & 0x7]; + l ^= s << 21; + h ^= s >> 11; + s = tab[b >> 24 & 0x7]; + l ^= s << 24; + h ^= s >> 8; + s = tab[b >> 27 & 0x7]; + l ^= s << 27; + h ^= s >> 5; + s = tab[b >> 30]; + l ^= s << 30; + h ^= s >> 2; /* compensate for the top two bits of a */ - if (top2b & 01) { l ^= b << 30; h ^= b >> 2; } - if (top2b & 02) { l ^= b << 31; h ^= b >> 1; } + if (top2b & 01) { + l ^= b << 30; + h ^= b >> 2; + } + if (top2b & 02) { + l ^= b << 31; + h ^= b >> 1; + } - *rh = h; *rl = l; -} + *rh = h; + *rl = l; +} #else -void +void s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b) { register mp_digit h, l, s; mp_digit tab[16], top3b = a >> 61; register mp_digit a1, a2, a4, a8; - a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1; - a4 = a2 << 1; a8 = a4 << 1; - tab[ 0] = 0; tab[ 1] = a1; tab[ 2] = a2; tab[ 3] = a1^a2; - tab[ 4] = a4; tab[ 5] = a1^a4; tab[ 6] = a2^a4; tab[ 7] = a1^a2^a4; - tab[ 8] = a8; tab[ 9] = a1^a8; tab[10] = a2^a8; tab[11] = a1^a2^a8; - tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8; - - s = tab[b & 0xF]; l = s; - s = tab[b >> 4 & 0xF]; l ^= s << 4; h = s >> 60; - s = tab[b >> 8 & 0xF]; l ^= s << 8; h ^= s >> 56; - s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52; - s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48; - s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44; - s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40; - s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36; - s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32; - s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28; - s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24; - s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20; - s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16; - s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12; - s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >> 8; - s = tab[b >> 60 ]; l ^= s << 60; h ^= s >> 4; + a1 = a & (0x1FFFFFFFFFFFFFFFULL); + a2 = a1 << 1; + a4 = a2 << 1; + a8 = a4 << 1; + tab[0] = 0; + tab[1] = a1; + tab[2] = a2; + tab[3] = a1 ^ a2; + tab[4] = a4; + tab[5] = a1 ^ a4; + tab[6] = a2 ^ a4; + tab[7] = a1 ^ a2 ^ a4; + tab[8] = a8; + tab[9] = a1 ^ a8; + tab[10] = a2 ^ a8; + tab[11] = a1 ^ a2 ^ a8; + tab[12] = a4 ^ a8; + tab[13] = a1 ^ a4 ^ a8; + tab[14] = a2 ^ a4 ^ a8; + tab[15] = a1 ^ a2 ^ a4 ^ a8; + + s = tab[b & 0xF]; + l = s; + s = tab[b >> 4 & 0xF]; + l ^= s << 4; + h = s >> 60; + s = tab[b >> 8 & 0xF]; + l ^= s << 8; + h ^= s >> 56; + s = tab[b >> 12 & 0xF]; + l ^= s << 12; + h ^= s >> 52; + s = tab[b >> 16 & 0xF]; + l ^= s << 16; + h ^= s >> 48; + s = tab[b >> 20 & 0xF]; + l ^= s << 20; + h ^= s >> 44; + s = tab[b >> 24 & 0xF]; + l ^= s << 24; + h ^= s >> 40; + s = tab[b >> 28 & 0xF]; + l ^= s << 28; + h ^= s >> 36; + s = tab[b >> 32 & 0xF]; + l ^= s << 32; + h ^= s >> 32; + s = tab[b >> 36 & 0xF]; + l ^= s << 36; + h ^= s >> 28; + s = tab[b >> 40 & 0xF]; + l ^= s << 40; + h ^= s >> 24; + s = tab[b >> 44 & 0xF]; + l ^= s << 44; + h ^= s >> 20; + s = tab[b >> 48 & 0xF]; + l ^= s << 48; + h ^= s >> 16; + s = tab[b >> 52 & 0xF]; + l ^= s << 52; + h ^= s >> 12; + s = tab[b >> 56 & 0xF]; + l ^= s << 56; + h ^= s >> 8; + s = tab[b >> 60]; + l ^= s << 60; + h ^= s >> 4; /* compensate for the top three bits of a */ - if (top3b & 01) { l ^= b << 61; h ^= b >> 3; } - if (top3b & 02) { l ^= b << 62; h ^= b >> 2; } - if (top3b & 04) { l ^= b << 63; h ^= b >> 1; } + if (top3b & 01) { + l ^= b << 61; + h ^= b >> 3; + } + if (top3b & 02) { + l ^= b << 62; + h ^= b >> 2; + } + if (top3b & 04) { + l ^= b << 63; + h ^= b >> 1; + } - *rh = h; *rl = l; -} + *rh = h; + *rl = l; +} #endif -/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0) +/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0) * result is a binary polynomial in 4 mp_digits r[4]. * The caller MUST ensure that r has the right amount of space allocated. */ -void +void s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1, const mp_digit b0) { mp_digit m1, m0; /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */ - s_bmul_1x1(r+3, r+2, a1, b1); - s_bmul_1x1(r+1, r, a0, b0); + s_bmul_1x1(r + 3, r + 2, a1, b1); + s_bmul_1x1(r + 1, r, a0, b0); s_bmul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1); /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */ - r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ - r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ + r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ + r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ } -/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, b0) +/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, b0) * result is a binary polynomial in 6 mp_digits r[6]. * The caller MUST ensure that r has the right amount of space allocated. */ -void -s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0, - const mp_digit b2, const mp_digit b1, const mp_digit b0) +void +s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0, + const mp_digit b2, const mp_digit b1, const mp_digit b0) { - mp_digit zm[4]; + mp_digit zm[4]; - s_bmul_1x1(r+5, r+4, a2, b2); /* fill top 2 words */ - s_bmul_2x2(zm, a1, a2^a0, b1, b2^b0); /* fill middle 4 words */ - s_bmul_2x2(r, a1, a0, b1, b0); /* fill bottom 4 words */ + s_bmul_1x1(r + 5, r + 4, a2, b2); /* fill top 2 words */ + s_bmul_2x2(zm, a1, a2 ^ a0, b1, b2 ^ b0); /* fill middle 4 words */ + s_bmul_2x2(r, a1, a0, b1, b0); /* fill bottom 4 words */ - zm[3] ^= r[3]; - zm[2] ^= r[2]; - zm[1] ^= r[1] ^ r[5]; - zm[0] ^= r[0] ^ r[4]; + zm[3] ^= r[3]; + zm[2] ^= r[2]; + zm[1] ^= r[1] ^ r[5]; + zm[0] ^= r[0] ^ r[4]; - r[5] ^= zm[3]; - r[4] ^= zm[2]; - r[3] ^= zm[1]; - r[2] ^= zm[0]; + r[5] ^= zm[3]; + r[4] ^= zm[2]; + r[3] ^= zm[1]; + r[2] ^= zm[0]; } -/* Compute xor-multiply of two binary polynomials (a3, a2, a1, a0) x (b3, b2, b1, b0) +/* Compute xor-multiply of two binary polynomials (a3, a2, a1, a0) x (b3, b2, b1, b0) * result is a binary polynomial in 8 mp_digits r[8]. * The caller MUST ensure that r has the right amount of space allocated. */ -void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1, - const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1, - const mp_digit b0) +void +s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1, + const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1, + const mp_digit b0) { - mp_digit zm[4]; + mp_digit zm[4]; - s_bmul_2x2(r+4, a3, a2, b3, b2); /* fill top 4 words */ - s_bmul_2x2(zm, a3^a1, a2^a0, b3^b1, b2^b0); /* fill middle 4 words */ - s_bmul_2x2(r, a1, a0, b1, b0); /* fill bottom 4 words */ + s_bmul_2x2(r + 4, a3, a2, b3, b2); /* fill top 4 words */ + s_bmul_2x2(zm, a3 ^ a1, a2 ^ a0, b3 ^ b1, b2 ^ b0); /* fill middle 4 words */ + s_bmul_2x2(r, a1, a0, b1, b0); /* fill bottom 4 words */ - zm[3] ^= r[3] ^ r[7]; - zm[2] ^= r[2] ^ r[6]; - zm[1] ^= r[1] ^ r[5]; - zm[0] ^= r[0] ^ r[4]; + zm[3] ^= r[3] ^ r[7]; + zm[2] ^= r[2] ^ r[6]; + zm[1] ^= r[1] ^ r[5]; + zm[0] ^= r[0] ^ r[4]; - r[5] ^= zm[3]; - r[4] ^= zm[2]; - r[3] ^= zm[1]; - r[2] ^= zm[0]; + r[5] ^= zm[3]; + r[4] ^= zm[2]; + r[3] ^= zm[1]; + r[2] ^= zm[0]; } /* Compute addition of two binary polynomials a and b, - * store result in c; c could be a or b, a and b could be equal; + * store result in c; c could be a or b, a and b could be equal; * c is the bitwise XOR of a and b. */ mp_err @@ -187,7 +279,7 @@ mp_badd(const mp_int *a, const mp_int *b, mp_int *c) } /* Make sure c has enough precision for the output value */ - MP_CHECKOK( s_mp_pad(c, used_pa) ); + MP_CHECKOK(s_mp_pad(c, used_pa)); /* Do word-by-word xor */ pc = MP_DIGITS(c); @@ -206,12 +298,12 @@ mp_badd(const mp_int *a, const mp_int *b, mp_int *c) CLEANUP: return res; -} +} -#define s_mp_div2(a) MP_CHECKOK( mpl_rsh((a), (a), 1) ); +#define s_mp_div2(a) MP_CHECKOK(mpl_rsh((a), (a), 1)); /* Compute binary polynomial multiply d = a * b */ -static void +static void s_bmul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d) { mp_digit a_i, a0b0, a1b1, carry = 0; @@ -225,7 +317,7 @@ s_bmul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d) } /* Compute binary polynomial xor multiply accumulate d ^= a * b */ -static void +static void s_bmul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d) { mp_digit a_i, a0b0, a1b1, carry = 0; @@ -238,10 +330,10 @@ s_bmul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d) *d ^= carry; } -/* Compute binary polynomial xor multiply c = a * b. +/* Compute binary polynomial xor multiply c = a * b. * All parameters may be identical. */ -mp_err +mp_err mp_bmul(const mp_int *a, const mp_int *b, mp_int *c) { mp_digit *pb, b_i; @@ -254,23 +346,24 @@ mp_bmul(const mp_int *a, const mp_int *b, mp_int *c) ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); if (a == c) { - MP_CHECKOK( mp_init_copy(&tmp, a) ); + MP_CHECKOK(mp_init_copy(&tmp, a)); if (a == b) b = &tmp; a = &tmp; } else if (b == c) { - MP_CHECKOK( mp_init_copy(&tmp, b) ); + MP_CHECKOK(mp_init_copy(&tmp, b)); b = &tmp; } if (MP_USED(a) < MP_USED(b)) { - const mp_int *xch = b; /* switch a and b if b longer */ + const mp_int *xch = b; /* switch a and b if b longer */ b = a; a = xch; } - MP_USED(c) = 1; MP_DIGIT(c, 0) = 0; - MP_CHECKOK( s_mp_pad(c, USED(a) + USED(b)) ); + MP_USED(c) = 1; + MP_DIGIT(c, 0) = 0; + MP_CHECKOK(s_mp_pad(c, USED(a) + USED(b))); pb = MP_DIGITS(b); s_bmul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c)); @@ -278,7 +371,7 @@ mp_bmul(const mp_int *a, const mp_int *b, mp_int *c) /* Outer loop: Digits of b */ a_used = MP_USED(a); b_used = MP_USED(b); - MP_USED(c) = a_used + b_used; + MP_USED(c) = a_used + b_used; for (ib = 1; ib < b_used; ib++) { b_i = *pb++; @@ -298,11 +391,10 @@ CLEANUP: return res; } - -/* Compute modular reduction of a and store result in r. - * r could be a. - * For modular arithmetic, the irreducible polynomial f(t) is represented - * as an array of int[], where f(t) is of the form: +/* Compute modular reduction of a and store result in r. + * r could be a. + * For modular arithmetic, the irreducible polynomial f(t) is represented + * as an array of int[], where f(t) is of the form: * f(t) = t^p[0] + t^p[1] + ... + t^p[k] * where m = p[0] > p[1] > ... > p[k] = 0. */ @@ -315,11 +407,11 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r) mp_size used; mp_err res = MP_OKAY; - /* The algorithm does the reduction in place in r, + /* The algorithm does the reduction in place in r, * if a != r, copy a into r first so reduction can be done in r */ if (a != r) { - MP_CHECKOK( mp_copy(a, r) ); + MP_CHECKOK(mp_copy(a, r)); } z = MP_DIGITS(r); @@ -332,7 +424,8 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r) zz = z[j]; if (zz == 0) { - j--; continue; + j--; + continue; } z[j] = 0; @@ -344,20 +437,19 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r) d1 = MP_DIGIT_BITS - d0; /*n /= MP_DIGIT_BITS; */ n >>= MP_DIGIT_BITS_LOG_2; - z[j-n] ^= (zz>>d0); - if (d0) - z[j-n-1] ^= (zz<<d1); + z[j - n] ^= (zz >> d0); + if (d0) + z[j - n - 1] ^= (zz << d1); } /* reducing component t^0 */ - n = dN; + n = dN; /*d0 = p[0] % MP_DIGIT_BITS;*/ d0 = p[0] & MP_DIGIT_BITS_MASK; d1 = MP_DIGIT_BITS - d0; - z[j-n] ^= (zz >> d0); - if (d0) - z[j-n-1] ^= (zz << d1); - + z[j - n] ^= (zz >> d0); + if (d0) + z[j - n - 1] ^= (zz << d1); } /* final round of reduction */ @@ -365,16 +457,17 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r) /* d0 = p[0] % MP_DIGIT_BITS; */ d0 = p[0] & MP_DIGIT_BITS_MASK; - zz = z[dN] >> d0; - if (zz == 0) break; + zz = z[dN] >> d0; + if (zz == 0) + break; d1 = MP_DIGIT_BITS - d0; /* clear up the top d1 bits */ if (d0) { - z[dN] = (z[dN] << d1) >> d1; - } else { - z[dN] = 0; - } + z[dN] = (z[dN] << d1) >> d1; + } else { + z[dN] = 0; + } *z ^= zz; /* reduction t^0 component */ for (k = 1; p[k] > 0; k++) { @@ -387,7 +480,7 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r) z[n] ^= (zz << d0); tmp = zz >> d1; if (d0 && tmp) - z[n+1] ^= tmp; + z[n + 1] ^= tmp; } } @@ -396,25 +489,26 @@ CLEANUP: return res; } -/* Compute the product of two polynomials a and b, reduce modulo p, +/* Compute the product of two polynomials a and b, reduce modulo p, * Store the result in r. r could be a or b; a could be b. */ -mp_err +mp_err mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[], mp_int *r) { mp_err res; - - if (a == b) return mp_bsqrmod(a, p, r); - if ((res = mp_bmul(a, b, r) ) != MP_OKAY) - return res; + + if (a == b) + return mp_bsqrmod(a, p, r); + if ((res = mp_bmul(a, b, r)) != MP_OKAY) + return res; return mp_bmod(r, p, r); } -/* Compute binary polynomial squaring c = a*a mod p . +/* Compute binary polynomial squaring c = a*a mod p . * Parameter r and a can be identical. */ -mp_err +mp_err mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r) { mp_digit *pa, *pr, a_i; @@ -426,17 +520,18 @@ mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r) MP_DIGITS(&tmp) = 0; if (a == r) { - MP_CHECKOK( mp_init_copy(&tmp, a) ); + MP_CHECKOK(mp_init_copy(&tmp, a)); a = &tmp; } - MP_USED(r) = 1; MP_DIGIT(r, 0) = 0; - MP_CHECKOK( s_mp_pad(r, 2*USED(a)) ); + MP_USED(r) = 1; + MP_DIGIT(r, 0) = 0; + MP_CHECKOK(s_mp_pad(r, 2 * USED(a))); pa = MP_DIGITS(a); pr = MP_DIGITS(r); a_used = MP_USED(a); - MP_USED(r) = 2 * a_used; + MP_USED(r) = 2 * a_used; for (ia = 0; ia < a_used; ia++) { a_i = *pa++; @@ -444,7 +539,7 @@ mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r) *pr++ = gf2m_SQR1(a_i); } - MP_CHECKOK( mp_bmod(r, p, r) ); + MP_CHECKOK(mp_bmod(r, p, r)); s_mp_clamp(r); SIGN(r) = ZPOS; @@ -455,13 +550,13 @@ CLEANUP: /* Compute binary polynomial y/x mod p, y divided by x, reduce modulo p. * Store the result in r. r could be x or y, and x could equal y. - * Uses algorithm Modular_Division_GF(2^m) from - * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to + * Uses algorithm Modular_Division_GF(2^m) from + * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to * the Great Divide". */ -int -mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp, - const unsigned int p[], mp_int *r) +int +mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp, + const unsigned int p[], mp_int *r) { mp_int aa, bb, uu; mp_int *a, *b, *u, *v; @@ -471,60 +566,62 @@ mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp, MP_DIGITS(&bb) = 0; MP_DIGITS(&uu) = 0; - MP_CHECKOK( mp_init_copy(&aa, x) ); - MP_CHECKOK( mp_init_copy(&uu, y) ); - MP_CHECKOK( mp_init_copy(&bb, pp) ); - MP_CHECKOK( s_mp_pad(r, USED(pp)) ); - MP_USED(r) = 1; MP_DIGIT(r, 0) = 0; - - a = &aa; b= &bb; u=&uu; v=r; + MP_CHECKOK(mp_init_copy(&aa, x)); + MP_CHECKOK(mp_init_copy(&uu, y)); + MP_CHECKOK(mp_init_copy(&bb, pp)); + MP_CHECKOK(s_mp_pad(r, USED(pp))); + MP_USED(r) = 1; + MP_DIGIT(r, 0) = 0; + + a = &aa; + b = &bb; + u = &uu; + v = r; /* reduce x and y mod p */ - MP_CHECKOK( mp_bmod(a, p, a) ); - MP_CHECKOK( mp_bmod(u, p, u) ); + MP_CHECKOK(mp_bmod(a, p, a)); + MP_CHECKOK(mp_bmod(u, p, u)); while (!mp_isodd(a)) { s_mp_div2(a); if (mp_isodd(u)) { - MP_CHECKOK( mp_badd(u, pp, u) ); + MP_CHECKOK(mp_badd(u, pp, u)); } s_mp_div2(u); } do { if (mp_cmp_mag(b, a) > 0) { - MP_CHECKOK( mp_badd(b, a, b) ); - MP_CHECKOK( mp_badd(v, u, v) ); + MP_CHECKOK(mp_badd(b, a, b)); + MP_CHECKOK(mp_badd(v, u, v)); do { s_mp_div2(b); if (mp_isodd(v)) { - MP_CHECKOK( mp_badd(v, pp, v) ); + MP_CHECKOK(mp_badd(v, pp, v)); } s_mp_div2(v); } while (!mp_isodd(b)); - } - else if ((MP_DIGIT(a,0) == 1) && (MP_USED(a) == 1)) + } else if ((MP_DIGIT(a, 0) == 1) && (MP_USED(a) == 1)) break; else { - MP_CHECKOK( mp_badd(a, b, a) ); - MP_CHECKOK( mp_badd(u, v, u) ); + MP_CHECKOK(mp_badd(a, b, a)); + MP_CHECKOK(mp_badd(u, v, u)); do { s_mp_div2(a); if (mp_isodd(u)) { - MP_CHECKOK( mp_badd(u, pp, u) ); + MP_CHECKOK(mp_badd(u, pp, u)); } s_mp_div2(u); } while (!mp_isodd(a)); } } while (1); - MP_CHECKOK( mp_copy(u, r) ); + MP_CHECKOK(mp_copy(u, r)); CLEANUP: mp_clear(&aa); mp_clear(&bb); mp_clear(&uu); return res; - } /* Convert the bit-string representation of a polynomial a into an array @@ -541,14 +638,16 @@ mp_bpoly2arr(const mp_int *a, unsigned int p[], int max) top_bit = 1; top_bit <<= MP_DIGIT_BIT - 1; - for (k = 0; k < max; k++) p[k] = 0; + for (k = 0; k < max; k++) + p[k] = 0; k = 0; for (i = MP_USED(a) - 1; i >= 0; i--) { mask = top_bit; for (j = MP_DIGIT_BIT - 1; j >= 0; j--) { if (MP_DIGITS(a)[i] & mask) { - if (k < max) p[k] = MP_DIGIT_BIT * i + j; + if (k < max) + p[k] = MP_DIGIT_BIT * i + j; k++; } mask >>= 1; @@ -558,7 +657,7 @@ mp_bpoly2arr(const mp_int *a, unsigned int p[], int max) return k; } -/* Convert the coefficient array representation of a polynomial to a +/* Convert the coefficient array representation of a polynomial to a * bit-string. The array must be terminated by 0. */ mp_err @@ -570,10 +669,10 @@ mp_barr2poly(const unsigned int p[], mp_int *a) mp_zero(a); for (i = 0; p[i] > 0; i++) { - MP_CHECKOK( mpl_set_bit(a, p[i], 1) ); + MP_CHECKOK(mpl_set_bit(a, p[i], 1)); } - MP_CHECKOK( mpl_set_bit(a, 0, 1) ); - + MP_CHECKOK(mpl_set_bit(a, 0, 1)); + CLEANUP: return res; } diff --git a/nss/lib/freebl/mpi/mp_gf2m.h b/nss/lib/freebl/mpi/mp_gf2m.h index 9faa026..ed2c854 100644 --- a/nss/lib/freebl/mpi/mp_gf2m.h +++ b/nss/lib/freebl/mpi/mp_gf2m.h @@ -10,17 +10,17 @@ mp_err mp_badd(const mp_int *a, const mp_int *b, mp_int *c); mp_err mp_bmul(const mp_int *a, const mp_int *b, mp_int *c); -/* For modular arithmetic, the irreducible polynomial f(t) is represented - * as an array of int[], where f(t) is of the form: +/* For modular arithmetic, the irreducible polynomial f(t) is represented + * as an array of int[], where f(t) is of the form: * f(t) = t^p[0] + t^p[1] + ... + t^p[k] * where m = p[0] > p[1] > ... > p[k] = 0. */ mp_err mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r); -mp_err mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[], - mp_int *r); +mp_err mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[], + mp_int *r); mp_err mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r); -mp_err mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp, - const unsigned int p[], mp_int *r); +mp_err mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp, + const unsigned int p[], mp_int *r); int mp_bpoly2arr(const mp_int *a, unsigned int p[], int max); mp_err mp_barr2poly(const unsigned int p[], mp_int *a); diff --git a/nss/lib/freebl/mpi/mpcpucache.c b/nss/lib/freebl/mpi/mpcpucache.c index 9250061..6fed352 100644 --- a/nss/lib/freebl/mpi/mpcpucache.c +++ b/nss/lib/freebl/mpi/mpcpucache.c @@ -9,7 +9,7 @@ * This file implements a single function: s_mpi_getProcessorLineSize(); * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line * if a cache exists, or zero if there is no cache. If more than one - * cache line exists, it should return the smallest line size (which is + * cache line exists, it should return the smallest line size (which is * usually the L1 cache). * * mp_modexp uses this information to make sure that private key information @@ -18,10 +18,10 @@ * Currently the file returns good data for most modern x86 processors, and * reasonable data on 64-bit ppc processors. All other processors are assumed * to have a cache line size of 32 bytes unless modified by target.mk. - * + * */ -#if defined(i386) || defined(__i386) || defined(__X86__) || defined (_M_IX86) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) +#if defined(i386) || defined(__i386) || defined(__X86__) || defined(_M_IX86) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) /* X86 processors have special instructions that tell us about the cache */ #include "string.h" @@ -34,25 +34,27 @@ #if defined(__GNUC__) -void freebl_cpuid(unsigned long op, unsigned long *eax, - unsigned long *ebx, unsigned long *ecx, - unsigned long *edx) +void +freebl_cpuid(unsigned long op, unsigned long *eax, + unsigned long *ebx, unsigned long *ecx, + unsigned long *edx) { - __asm__("cpuid\n\t" - : "=a" (*eax), - "=b" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (op)); + __asm__("cpuid\n\t" + : "=a"(*eax), + "=b"(*ebx), + "=c"(*ecx), + "=d"(*edx) + : "0"(op)); } #elif defined(_MSC_VER) #include <intrin.h> -void freebl_cpuid(unsigned long op, unsigned long *eax, - unsigned long *ebx, unsigned long *ecx, - unsigned long *edx) +void +freebl_cpuid(unsigned long op, unsigned long *eax, + unsigned long *ebx, unsigned long *ecx, + unsigned long *edx) { int intrinsic_out[4]; @@ -70,44 +72,50 @@ void freebl_cpuid(unsigned long op, unsigned long *eax, /* x86 */ #if defined(__GNUC__) -void freebl_cpuid(unsigned long op, unsigned long *eax, - unsigned long *ebx, unsigned long *ecx, - unsigned long *edx) +void +freebl_cpuid(unsigned long op, unsigned long *eax, + unsigned long *ebx, unsigned long *ecx, + unsigned long *edx) { -/* sigh GCC isn't smart enough to save the ebx PIC register on it's own - * in this case, so do it by hand. Use edi to store ebx and pass the - * value returned in ebx from cpuid through edi. */ - __asm__("mov %%ebx,%%edi\n\t" - "cpuid\n\t" - "xchgl %%ebx,%%edi\n\t" - : "=a" (*eax), - "=D" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (op)); + /* Some older processors don't fill the ecx register with cpuid, so clobber it + * before calling cpuid, so that there's no risk of picking random bits that + * erroneously indicate that absent CPU features are present. + * Also, GCC isn't smart enough to save the ebx PIC register on its own + * in this case, so do it by hand. Use edi to store ebx and pass the + * value returned in ebx from cpuid through edi. */ + __asm__("xor %%ecx, %%ecx\n\t" + "mov %%ebx,%%edi\n\t" + "cpuid\n\t" + "xchgl %%ebx,%%edi\n\t" + : "=a"(*eax), + "=D"(*ebx), + "=c"(*ecx), + "=d"(*edx) + : "0"(op)); } /* * try flipping a processor flag to determine CPU type */ -static unsigned long changeFlag(unsigned long flag) +static unsigned long +changeFlag(unsigned long flag) { - unsigned long changedFlags, originalFlags; - __asm__("pushfl\n\t" /* get the flags */ - "popl %0\n\t" - "movl %0,%1\n\t" /* save the original flags */ - "xorl %2,%0\n\t" /* flip the bit */ - "pushl %0\n\t" /* set the flags */ - "popfl\n\t" - "pushfl\n\t" /* get the flags again (for return) */ - "popl %0\n\t" - "pushl %1\n\t" /* restore the original flags */ - "popfl\n\t" - : "=r" (changedFlags), - "=r" (originalFlags), - "=r" (flag) - : "2" (flag)); - return changedFlags ^ originalFlags; + unsigned long changedFlags, originalFlags; + __asm__("pushfl\n\t" /* get the flags */ + "popl %0\n\t" + "movl %0,%1\n\t" /* save the original flags */ + "xorl %2,%0\n\t" /* flip the bit */ + "pushl %0\n\t" /* set the flags */ + "popfl\n\t" + "pushfl\n\t" /* get the flags again (for return) */ + "popl %0\n\t" + "pushl %1\n\t" /* restore the original flags */ + "popfl\n\t" + : "=r"(changedFlags), + "=r"(originalFlags), + "=r"(flag) + : "2"(flag)); + return changedFlags ^ originalFlags; } #elif defined(_MSC_VER) @@ -116,12 +124,14 @@ static unsigned long changeFlag(unsigned long flag) * windows versions of the above assembler */ #define wcpuid __asm __emit 0fh __asm __emit 0a2h -void freebl_cpuid(unsigned long op, unsigned long *Reax, - unsigned long *Rebx, unsigned long *Recx, unsigned long *Redx) +void +freebl_cpuid(unsigned long op, unsigned long *Reax, + unsigned long *Rebx, unsigned long *Recx, unsigned long *Redx) { - unsigned long Leax, Lebx, Lecx, Ledx; - __asm { + unsigned long Leax, Lebx, Lecx, Ledx; + __asm { pushad + xor ecx,ecx mov eax,op wcpuid mov Leax,eax @@ -129,35 +139,36 @@ void freebl_cpuid(unsigned long op, unsigned long *Reax, mov Lecx,ecx mov Ledx,edx popad - } - *Reax = Leax; - *Rebx = Lebx; - *Recx = Lecx; - *Redx = Ledx; + } + *Reax = Leax; + *Rebx = Lebx; + *Recx = Lecx; + *Redx = Ledx; } -static unsigned long changeFlag(unsigned long flag) +static unsigned long +changeFlag(unsigned long flag) { - unsigned long changedFlags, originalFlags; - __asm { - push eax - push ebx - pushfd /* get the flags */ - pop eax - push eax /* save the flags on the stack */ - mov originalFlags,eax /* save the original flags */ - mov ebx,flag - xor eax,ebx /* flip the bit */ - push eax /* set the flags */ - popfd - pushfd /* get the flags again (for return) */ - pop eax - popfd /* restore the original flags */ - mov changedFlags,eax - pop ebx - pop eax - } - return changedFlags ^ originalFlags; + unsigned long changedFlags, originalFlags; + __asm { + push eax + push ebx + pushfd /* get the flags */ + pop eax + push eax /* save the flags on the stack */ + mov originalFlags,eax /* save the original flags */ + mov ebx,flag + xor eax,ebx /* flip the bit */ + push eax /* set the flags */ + popfd + pushfd /* get the flags again (for return) */ + pop eax + popfd /* restore the original flags */ + mov changedFlags,eax + pop ebx + pop eax + } + return changedFlags ^ originalFlags; } #endif @@ -168,42 +179,43 @@ static unsigned long changeFlag(unsigned long flag) #define ID_FLAG 0x200000 /* 386 processors can't flip the AC_FLAG, intel AP Note AP-485 */ -static int is386() +static int +is386() { return changeFlag(AC_FLAG) == 0; } /* 486 processors can't flip the ID_FLAG, intel AP Note AP-485 */ -static int is486() +static int +is486() { return changeFlag(ID_FLAG) == 0; } #endif - /* * table for Intel Cache. - * See Intel Application Note AP-485 for more information + * See Intel Application Note AP-485 for more information */ typedef unsigned char CacheTypeEntry; typedef enum { - Cache_NONE = 0, + Cache_NONE = 0, Cache_UNKNOWN = 1, - Cache_TLB = 2, - Cache_TLBi = 3, - Cache_TLBd = 4, - Cache_Trace = 5, - Cache_L1 = 6, - Cache_L1i = 7, - Cache_L1d = 8, - Cache_L2 = 9 , - Cache_L2i = 10 , - Cache_L2d = 11 , - Cache_L3 = 12 , - Cache_L3i = 13, - Cache_L3d = 14 + Cache_TLB = 2, + Cache_TLBi = 3, + Cache_TLBd = 4, + Cache_Trace = 5, + Cache_L1 = 6, + Cache_L1i = 7, + Cache_L1d = 8, + Cache_L2 = 9, + Cache_L2i = 10, + Cache_L2d = 11, + Cache_L3 = 12, + Cache_L3i = 13, + Cache_L3d = 14 } CacheType; struct _cache { @@ -211,271 +223,272 @@ struct _cache { unsigned char lineSize; }; static const struct _cache CacheMap[256] = { -/* 00 */ {Cache_NONE, 0 }, -/* 01 */ {Cache_TLBi, 0 }, -/* 02 */ {Cache_TLBi, 0 }, -/* 03 */ {Cache_TLBd, 0 }, -/* 04 */ {Cache_TLBd, }, -/* 05 */ {Cache_UNKNOWN, 0 }, -/* 06 */ {Cache_L1i, 32 }, -/* 07 */ {Cache_UNKNOWN, 0 }, -/* 08 */ {Cache_L1i, 32 }, -/* 09 */ {Cache_UNKNOWN, 0 }, -/* 0a */ {Cache_L1d, 32 }, -/* 0b */ {Cache_UNKNOWN, 0 }, -/* 0c */ {Cache_L1d, 32 }, -/* 0d */ {Cache_UNKNOWN, 0 }, -/* 0e */ {Cache_UNKNOWN, 0 }, -/* 0f */ {Cache_UNKNOWN, 0 }, -/* 10 */ {Cache_UNKNOWN, 0 }, -/* 11 */ {Cache_UNKNOWN, 0 }, -/* 12 */ {Cache_UNKNOWN, 0 }, -/* 13 */ {Cache_UNKNOWN, 0 }, -/* 14 */ {Cache_UNKNOWN, 0 }, -/* 15 */ {Cache_UNKNOWN, 0 }, -/* 16 */ {Cache_UNKNOWN, 0 }, -/* 17 */ {Cache_UNKNOWN, 0 }, -/* 18 */ {Cache_UNKNOWN, 0 }, -/* 19 */ {Cache_UNKNOWN, 0 }, -/* 1a */ {Cache_UNKNOWN, 0 }, -/* 1b */ {Cache_UNKNOWN, 0 }, -/* 1c */ {Cache_UNKNOWN, 0 }, -/* 1d */ {Cache_UNKNOWN, 0 }, -/* 1e */ {Cache_UNKNOWN, 0 }, -/* 1f */ {Cache_UNKNOWN, 0 }, -/* 20 */ {Cache_UNKNOWN, 0 }, -/* 21 */ {Cache_UNKNOWN, 0 }, -/* 22 */ {Cache_L3, 64 }, -/* 23 */ {Cache_L3, 64 }, -/* 24 */ {Cache_UNKNOWN, 0 }, -/* 25 */ {Cache_L3, 64 }, -/* 26 */ {Cache_UNKNOWN, 0 }, -/* 27 */ {Cache_UNKNOWN, 0 }, -/* 28 */ {Cache_UNKNOWN, 0 }, -/* 29 */ {Cache_L3, 64 }, -/* 2a */ {Cache_UNKNOWN, 0 }, -/* 2b */ {Cache_UNKNOWN, 0 }, -/* 2c */ {Cache_L1d, 64 }, -/* 2d */ {Cache_UNKNOWN, 0 }, -/* 2e */ {Cache_UNKNOWN, 0 }, -/* 2f */ {Cache_UNKNOWN, 0 }, -/* 30 */ {Cache_L1i, 64 }, -/* 31 */ {Cache_UNKNOWN, 0 }, -/* 32 */ {Cache_UNKNOWN, 0 }, -/* 33 */ {Cache_UNKNOWN, 0 }, -/* 34 */ {Cache_UNKNOWN, 0 }, -/* 35 */ {Cache_UNKNOWN, 0 }, -/* 36 */ {Cache_UNKNOWN, 0 }, -/* 37 */ {Cache_UNKNOWN, 0 }, -/* 38 */ {Cache_UNKNOWN, 0 }, -/* 39 */ {Cache_L2, 64 }, -/* 3a */ {Cache_UNKNOWN, 0 }, -/* 3b */ {Cache_L2, 64 }, -/* 3c */ {Cache_L2, 64 }, -/* 3d */ {Cache_UNKNOWN, 0 }, -/* 3e */ {Cache_UNKNOWN, 0 }, -/* 3f */ {Cache_UNKNOWN, 0 }, -/* 40 */ {Cache_L2, 0 }, -/* 41 */ {Cache_L2, 32 }, -/* 42 */ {Cache_L2, 32 }, -/* 43 */ {Cache_L2, 32 }, -/* 44 */ {Cache_L2, 32 }, -/* 45 */ {Cache_L2, 32 }, -/* 46 */ {Cache_UNKNOWN, 0 }, -/* 47 */ {Cache_UNKNOWN, 0 }, -/* 48 */ {Cache_UNKNOWN, 0 }, -/* 49 */ {Cache_UNKNOWN, 0 }, -/* 4a */ {Cache_UNKNOWN, 0 }, -/* 4b */ {Cache_UNKNOWN, 0 }, -/* 4c */ {Cache_UNKNOWN, 0 }, -/* 4d */ {Cache_UNKNOWN, 0 }, -/* 4e */ {Cache_UNKNOWN, 0 }, -/* 4f */ {Cache_UNKNOWN, 0 }, -/* 50 */ {Cache_TLBi, 0 }, -/* 51 */ {Cache_TLBi, 0 }, -/* 52 */ {Cache_TLBi, 0 }, -/* 53 */ {Cache_UNKNOWN, 0 }, -/* 54 */ {Cache_UNKNOWN, 0 }, -/* 55 */ {Cache_UNKNOWN, 0 }, -/* 56 */ {Cache_UNKNOWN, 0 }, -/* 57 */ {Cache_UNKNOWN, 0 }, -/* 58 */ {Cache_UNKNOWN, 0 }, -/* 59 */ {Cache_UNKNOWN, 0 }, -/* 5a */ {Cache_UNKNOWN, 0 }, -/* 5b */ {Cache_TLBd, 0 }, -/* 5c */ {Cache_TLBd, 0 }, -/* 5d */ {Cache_TLBd, 0 }, -/* 5e */ {Cache_UNKNOWN, 0 }, -/* 5f */ {Cache_UNKNOWN, 0 }, -/* 60 */ {Cache_UNKNOWN, 0 }, -/* 61 */ {Cache_UNKNOWN, 0 }, -/* 62 */ {Cache_UNKNOWN, 0 }, -/* 63 */ {Cache_UNKNOWN, 0 }, -/* 64 */ {Cache_UNKNOWN, 0 }, -/* 65 */ {Cache_UNKNOWN, 0 }, -/* 66 */ {Cache_L1d, 64 }, -/* 67 */ {Cache_L1d, 64 }, -/* 68 */ {Cache_L1d, 64 }, -/* 69 */ {Cache_UNKNOWN, 0 }, -/* 6a */ {Cache_UNKNOWN, 0 }, -/* 6b */ {Cache_UNKNOWN, 0 }, -/* 6c */ {Cache_UNKNOWN, 0 }, -/* 6d */ {Cache_UNKNOWN, 0 }, -/* 6e */ {Cache_UNKNOWN, 0 }, -/* 6f */ {Cache_UNKNOWN, 0 }, -/* 70 */ {Cache_Trace, 1 }, -/* 71 */ {Cache_Trace, 1 }, -/* 72 */ {Cache_Trace, 1 }, -/* 73 */ {Cache_UNKNOWN, 0 }, -/* 74 */ {Cache_UNKNOWN, 0 }, -/* 75 */ {Cache_UNKNOWN, 0 }, -/* 76 */ {Cache_UNKNOWN, 0 }, -/* 77 */ {Cache_UNKNOWN, 0 }, -/* 78 */ {Cache_UNKNOWN, 0 }, -/* 79 */ {Cache_L2, 64 }, -/* 7a */ {Cache_L2, 64 }, -/* 7b */ {Cache_L2, 64 }, -/* 7c */ {Cache_L2, 64 }, -/* 7d */ {Cache_UNKNOWN, 0 }, -/* 7e */ {Cache_UNKNOWN, 0 }, -/* 7f */ {Cache_UNKNOWN, 0 }, -/* 80 */ {Cache_UNKNOWN, 0 }, -/* 81 */ {Cache_UNKNOWN, 0 }, -/* 82 */ {Cache_L2, 32 }, -/* 83 */ {Cache_L2, 32 }, -/* 84 */ {Cache_L2, 32 }, -/* 85 */ {Cache_L2, 32 }, -/* 86 */ {Cache_L2, 64 }, -/* 87 */ {Cache_L2, 64 }, -/* 88 */ {Cache_UNKNOWN, 0 }, -/* 89 */ {Cache_UNKNOWN, 0 }, -/* 8a */ {Cache_UNKNOWN, 0 }, -/* 8b */ {Cache_UNKNOWN, 0 }, -/* 8c */ {Cache_UNKNOWN, 0 }, -/* 8d */ {Cache_UNKNOWN, 0 }, -/* 8e */ {Cache_UNKNOWN, 0 }, -/* 8f */ {Cache_UNKNOWN, 0 }, -/* 90 */ {Cache_UNKNOWN, 0 }, -/* 91 */ {Cache_UNKNOWN, 0 }, -/* 92 */ {Cache_UNKNOWN, 0 }, -/* 93 */ {Cache_UNKNOWN, 0 }, -/* 94 */ {Cache_UNKNOWN, 0 }, -/* 95 */ {Cache_UNKNOWN, 0 }, -/* 96 */ {Cache_UNKNOWN, 0 }, -/* 97 */ {Cache_UNKNOWN, 0 }, -/* 98 */ {Cache_UNKNOWN, 0 }, -/* 99 */ {Cache_UNKNOWN, 0 }, -/* 9a */ {Cache_UNKNOWN, 0 }, -/* 9b */ {Cache_UNKNOWN, 0 }, -/* 9c */ {Cache_UNKNOWN, 0 }, -/* 9d */ {Cache_UNKNOWN, 0 }, -/* 9e */ {Cache_UNKNOWN, 0 }, -/* 9f */ {Cache_UNKNOWN, 0 }, -/* a0 */ {Cache_UNKNOWN, 0 }, -/* a1 */ {Cache_UNKNOWN, 0 }, -/* a2 */ {Cache_UNKNOWN, 0 }, -/* a3 */ {Cache_UNKNOWN, 0 }, -/* a4 */ {Cache_UNKNOWN, 0 }, -/* a5 */ {Cache_UNKNOWN, 0 }, -/* a6 */ {Cache_UNKNOWN, 0 }, -/* a7 */ {Cache_UNKNOWN, 0 }, -/* a8 */ {Cache_UNKNOWN, 0 }, -/* a9 */ {Cache_UNKNOWN, 0 }, -/* aa */ {Cache_UNKNOWN, 0 }, -/* ab */ {Cache_UNKNOWN, 0 }, -/* ac */ {Cache_UNKNOWN, 0 }, -/* ad */ {Cache_UNKNOWN, 0 }, -/* ae */ {Cache_UNKNOWN, 0 }, -/* af */ {Cache_UNKNOWN, 0 }, -/* b0 */ {Cache_TLBi, 0 }, -/* b1 */ {Cache_UNKNOWN, 0 }, -/* b2 */ {Cache_UNKNOWN, 0 }, -/* b3 */ {Cache_TLBd, 0 }, -/* b4 */ {Cache_UNKNOWN, 0 }, -/* b5 */ {Cache_UNKNOWN, 0 }, -/* b6 */ {Cache_UNKNOWN, 0 }, -/* b7 */ {Cache_UNKNOWN, 0 }, -/* b8 */ {Cache_UNKNOWN, 0 }, -/* b9 */ {Cache_UNKNOWN, 0 }, -/* ba */ {Cache_UNKNOWN, 0 }, -/* bb */ {Cache_UNKNOWN, 0 }, -/* bc */ {Cache_UNKNOWN, 0 }, -/* bd */ {Cache_UNKNOWN, 0 }, -/* be */ {Cache_UNKNOWN, 0 }, -/* bf */ {Cache_UNKNOWN, 0 }, -/* c0 */ {Cache_UNKNOWN, 0 }, -/* c1 */ {Cache_UNKNOWN, 0 }, -/* c2 */ {Cache_UNKNOWN, 0 }, -/* c3 */ {Cache_UNKNOWN, 0 }, -/* c4 */ {Cache_UNKNOWN, 0 }, -/* c5 */ {Cache_UNKNOWN, 0 }, -/* c6 */ {Cache_UNKNOWN, 0 }, -/* c7 */ {Cache_UNKNOWN, 0 }, -/* c8 */ {Cache_UNKNOWN, 0 }, -/* c9 */ {Cache_UNKNOWN, 0 }, -/* ca */ {Cache_UNKNOWN, 0 }, -/* cb */ {Cache_UNKNOWN, 0 }, -/* cc */ {Cache_UNKNOWN, 0 }, -/* cd */ {Cache_UNKNOWN, 0 }, -/* ce */ {Cache_UNKNOWN, 0 }, -/* cf */ {Cache_UNKNOWN, 0 }, -/* d0 */ {Cache_UNKNOWN, 0 }, -/* d1 */ {Cache_UNKNOWN, 0 }, -/* d2 */ {Cache_UNKNOWN, 0 }, -/* d3 */ {Cache_UNKNOWN, 0 }, -/* d4 */ {Cache_UNKNOWN, 0 }, -/* d5 */ {Cache_UNKNOWN, 0 }, -/* d6 */ {Cache_UNKNOWN, 0 }, -/* d7 */ {Cache_UNKNOWN, 0 }, -/* d8 */ {Cache_UNKNOWN, 0 }, -/* d9 */ {Cache_UNKNOWN, 0 }, -/* da */ {Cache_UNKNOWN, 0 }, -/* db */ {Cache_UNKNOWN, 0 }, -/* dc */ {Cache_UNKNOWN, 0 }, -/* dd */ {Cache_UNKNOWN, 0 }, -/* de */ {Cache_UNKNOWN, 0 }, -/* df */ {Cache_UNKNOWN, 0 }, -/* e0 */ {Cache_UNKNOWN, 0 }, -/* e1 */ {Cache_UNKNOWN, 0 }, -/* e2 */ {Cache_UNKNOWN, 0 }, -/* e3 */ {Cache_UNKNOWN, 0 }, -/* e4 */ {Cache_UNKNOWN, 0 }, -/* e5 */ {Cache_UNKNOWN, 0 }, -/* e6 */ {Cache_UNKNOWN, 0 }, -/* e7 */ {Cache_UNKNOWN, 0 }, -/* e8 */ {Cache_UNKNOWN, 0 }, -/* e9 */ {Cache_UNKNOWN, 0 }, -/* ea */ {Cache_UNKNOWN, 0 }, -/* eb */ {Cache_UNKNOWN, 0 }, -/* ec */ {Cache_UNKNOWN, 0 }, -/* ed */ {Cache_UNKNOWN, 0 }, -/* ee */ {Cache_UNKNOWN, 0 }, -/* ef */ {Cache_UNKNOWN, 0 }, -/* f0 */ {Cache_UNKNOWN, 0 }, -/* f1 */ {Cache_UNKNOWN, 0 }, -/* f2 */ {Cache_UNKNOWN, 0 }, -/* f3 */ {Cache_UNKNOWN, 0 }, -/* f4 */ {Cache_UNKNOWN, 0 }, -/* f5 */ {Cache_UNKNOWN, 0 }, -/* f6 */ {Cache_UNKNOWN, 0 }, -/* f7 */ {Cache_UNKNOWN, 0 }, -/* f8 */ {Cache_UNKNOWN, 0 }, -/* f9 */ {Cache_UNKNOWN, 0 }, -/* fa */ {Cache_UNKNOWN, 0 }, -/* fb */ {Cache_UNKNOWN, 0 }, -/* fc */ {Cache_UNKNOWN, 0 }, -/* fd */ {Cache_UNKNOWN, 0 }, -/* fe */ {Cache_UNKNOWN, 0 }, -/* ff */ {Cache_UNKNOWN, 0 } + /* 00 */ { Cache_NONE, 0 }, + /* 01 */ { Cache_TLBi, 0 }, + /* 02 */ { Cache_TLBi, 0 }, + /* 03 */ { Cache_TLBd, 0 }, + /* 04 */ { + Cache_TLBd, + }, + /* 05 */ { Cache_UNKNOWN, 0 }, + /* 06 */ { Cache_L1i, 32 }, + /* 07 */ { Cache_UNKNOWN, 0 }, + /* 08 */ { Cache_L1i, 32 }, + /* 09 */ { Cache_UNKNOWN, 0 }, + /* 0a */ { Cache_L1d, 32 }, + /* 0b */ { Cache_UNKNOWN, 0 }, + /* 0c */ { Cache_L1d, 32 }, + /* 0d */ { Cache_UNKNOWN, 0 }, + /* 0e */ { Cache_UNKNOWN, 0 }, + /* 0f */ { Cache_UNKNOWN, 0 }, + /* 10 */ { Cache_UNKNOWN, 0 }, + /* 11 */ { Cache_UNKNOWN, 0 }, + /* 12 */ { Cache_UNKNOWN, 0 }, + /* 13 */ { Cache_UNKNOWN, 0 }, + /* 14 */ { Cache_UNKNOWN, 0 }, + /* 15 */ { Cache_UNKNOWN, 0 }, + /* 16 */ { Cache_UNKNOWN, 0 }, + /* 17 */ { Cache_UNKNOWN, 0 }, + /* 18 */ { Cache_UNKNOWN, 0 }, + /* 19 */ { Cache_UNKNOWN, 0 }, + /* 1a */ { Cache_UNKNOWN, 0 }, + /* 1b */ { Cache_UNKNOWN, 0 }, + /* 1c */ { Cache_UNKNOWN, 0 }, + /* 1d */ { Cache_UNKNOWN, 0 }, + /* 1e */ { Cache_UNKNOWN, 0 }, + /* 1f */ { Cache_UNKNOWN, 0 }, + /* 20 */ { Cache_UNKNOWN, 0 }, + /* 21 */ { Cache_UNKNOWN, 0 }, + /* 22 */ { Cache_L3, 64 }, + /* 23 */ { Cache_L3, 64 }, + /* 24 */ { Cache_UNKNOWN, 0 }, + /* 25 */ { Cache_L3, 64 }, + /* 26 */ { Cache_UNKNOWN, 0 }, + /* 27 */ { Cache_UNKNOWN, 0 }, + /* 28 */ { Cache_UNKNOWN, 0 }, + /* 29 */ { Cache_L3, 64 }, + /* 2a */ { Cache_UNKNOWN, 0 }, + /* 2b */ { Cache_UNKNOWN, 0 }, + /* 2c */ { Cache_L1d, 64 }, + /* 2d */ { Cache_UNKNOWN, 0 }, + /* 2e */ { Cache_UNKNOWN, 0 }, + /* 2f */ { Cache_UNKNOWN, 0 }, + /* 30 */ { Cache_L1i, 64 }, + /* 31 */ { Cache_UNKNOWN, 0 }, + /* 32 */ { Cache_UNKNOWN, 0 }, + /* 33 */ { Cache_UNKNOWN, 0 }, + /* 34 */ { Cache_UNKNOWN, 0 }, + /* 35 */ { Cache_UNKNOWN, 0 }, + /* 36 */ { Cache_UNKNOWN, 0 }, + /* 37 */ { Cache_UNKNOWN, 0 }, + /* 38 */ { Cache_UNKNOWN, 0 }, + /* 39 */ { Cache_L2, 64 }, + /* 3a */ { Cache_UNKNOWN, 0 }, + /* 3b */ { Cache_L2, 64 }, + /* 3c */ { Cache_L2, 64 }, + /* 3d */ { Cache_UNKNOWN, 0 }, + /* 3e */ { Cache_UNKNOWN, 0 }, + /* 3f */ { Cache_UNKNOWN, 0 }, + /* 40 */ { Cache_L2, 0 }, + /* 41 */ { Cache_L2, 32 }, + /* 42 */ { Cache_L2, 32 }, + /* 43 */ { Cache_L2, 32 }, + /* 44 */ { Cache_L2, 32 }, + /* 45 */ { Cache_L2, 32 }, + /* 46 */ { Cache_UNKNOWN, 0 }, + /* 47 */ { Cache_UNKNOWN, 0 }, + /* 48 */ { Cache_UNKNOWN, 0 }, + /* 49 */ { Cache_UNKNOWN, 0 }, + /* 4a */ { Cache_UNKNOWN, 0 }, + /* 4b */ { Cache_UNKNOWN, 0 }, + /* 4c */ { Cache_UNKNOWN, 0 }, + /* 4d */ { Cache_UNKNOWN, 0 }, + /* 4e */ { Cache_UNKNOWN, 0 }, + /* 4f */ { Cache_UNKNOWN, 0 }, + /* 50 */ { Cache_TLBi, 0 }, + /* 51 */ { Cache_TLBi, 0 }, + /* 52 */ { Cache_TLBi, 0 }, + /* 53 */ { Cache_UNKNOWN, 0 }, + /* 54 */ { Cache_UNKNOWN, 0 }, + /* 55 */ { Cache_UNKNOWN, 0 }, + /* 56 */ { Cache_UNKNOWN, 0 }, + /* 57 */ { Cache_UNKNOWN, 0 }, + /* 58 */ { Cache_UNKNOWN, 0 }, + /* 59 */ { Cache_UNKNOWN, 0 }, + /* 5a */ { Cache_UNKNOWN, 0 }, + /* 5b */ { Cache_TLBd, 0 }, + /* 5c */ { Cache_TLBd, 0 }, + /* 5d */ { Cache_TLBd, 0 }, + /* 5e */ { Cache_UNKNOWN, 0 }, + /* 5f */ { Cache_UNKNOWN, 0 }, + /* 60 */ { Cache_UNKNOWN, 0 }, + /* 61 */ { Cache_UNKNOWN, 0 }, + /* 62 */ { Cache_UNKNOWN, 0 }, + /* 63 */ { Cache_UNKNOWN, 0 }, + /* 64 */ { Cache_UNKNOWN, 0 }, + /* 65 */ { Cache_UNKNOWN, 0 }, + /* 66 */ { Cache_L1d, 64 }, + /* 67 */ { Cache_L1d, 64 }, + /* 68 */ { Cache_L1d, 64 }, + /* 69 */ { Cache_UNKNOWN, 0 }, + /* 6a */ { Cache_UNKNOWN, 0 }, + /* 6b */ { Cache_UNKNOWN, 0 }, + /* 6c */ { Cache_UNKNOWN, 0 }, + /* 6d */ { Cache_UNKNOWN, 0 }, + /* 6e */ { Cache_UNKNOWN, 0 }, + /* 6f */ { Cache_UNKNOWN, 0 }, + /* 70 */ { Cache_Trace, 1 }, + /* 71 */ { Cache_Trace, 1 }, + /* 72 */ { Cache_Trace, 1 }, + /* 73 */ { Cache_UNKNOWN, 0 }, + /* 74 */ { Cache_UNKNOWN, 0 }, + /* 75 */ { Cache_UNKNOWN, 0 }, + /* 76 */ { Cache_UNKNOWN, 0 }, + /* 77 */ { Cache_UNKNOWN, 0 }, + /* 78 */ { Cache_UNKNOWN, 0 }, + /* 79 */ { Cache_L2, 64 }, + /* 7a */ { Cache_L2, 64 }, + /* 7b */ { Cache_L2, 64 }, + /* 7c */ { Cache_L2, 64 }, + /* 7d */ { Cache_UNKNOWN, 0 }, + /* 7e */ { Cache_UNKNOWN, 0 }, + /* 7f */ { Cache_UNKNOWN, 0 }, + /* 80 */ { Cache_UNKNOWN, 0 }, + /* 81 */ { Cache_UNKNOWN, 0 }, + /* 82 */ { Cache_L2, 32 }, + /* 83 */ { Cache_L2, 32 }, + /* 84 */ { Cache_L2, 32 }, + /* 85 */ { Cache_L2, 32 }, + /* 86 */ { Cache_L2, 64 }, + /* 87 */ { Cache_L2, 64 }, + /* 88 */ { Cache_UNKNOWN, 0 }, + /* 89 */ { Cache_UNKNOWN, 0 }, + /* 8a */ { Cache_UNKNOWN, 0 }, + /* 8b */ { Cache_UNKNOWN, 0 }, + /* 8c */ { Cache_UNKNOWN, 0 }, + /* 8d */ { Cache_UNKNOWN, 0 }, + /* 8e */ { Cache_UNKNOWN, 0 }, + /* 8f */ { Cache_UNKNOWN, 0 }, + /* 90 */ { Cache_UNKNOWN, 0 }, + /* 91 */ { Cache_UNKNOWN, 0 }, + /* 92 */ { Cache_UNKNOWN, 0 }, + /* 93 */ { Cache_UNKNOWN, 0 }, + /* 94 */ { Cache_UNKNOWN, 0 }, + /* 95 */ { Cache_UNKNOWN, 0 }, + /* 96 */ { Cache_UNKNOWN, 0 }, + /* 97 */ { Cache_UNKNOWN, 0 }, + /* 98 */ { Cache_UNKNOWN, 0 }, + /* 99 */ { Cache_UNKNOWN, 0 }, + /* 9a */ { Cache_UNKNOWN, 0 }, + /* 9b */ { Cache_UNKNOWN, 0 }, + /* 9c */ { Cache_UNKNOWN, 0 }, + /* 9d */ { Cache_UNKNOWN, 0 }, + /* 9e */ { Cache_UNKNOWN, 0 }, + /* 9f */ { Cache_UNKNOWN, 0 }, + /* a0 */ { Cache_UNKNOWN, 0 }, + /* a1 */ { Cache_UNKNOWN, 0 }, + /* a2 */ { Cache_UNKNOWN, 0 }, + /* a3 */ { Cache_UNKNOWN, 0 }, + /* a4 */ { Cache_UNKNOWN, 0 }, + /* a5 */ { Cache_UNKNOWN, 0 }, + /* a6 */ { Cache_UNKNOWN, 0 }, + /* a7 */ { Cache_UNKNOWN, 0 }, + /* a8 */ { Cache_UNKNOWN, 0 }, + /* a9 */ { Cache_UNKNOWN, 0 }, + /* aa */ { Cache_UNKNOWN, 0 }, + /* ab */ { Cache_UNKNOWN, 0 }, + /* ac */ { Cache_UNKNOWN, 0 }, + /* ad */ { Cache_UNKNOWN, 0 }, + /* ae */ { Cache_UNKNOWN, 0 }, + /* af */ { Cache_UNKNOWN, 0 }, + /* b0 */ { Cache_TLBi, 0 }, + /* b1 */ { Cache_UNKNOWN, 0 }, + /* b2 */ { Cache_UNKNOWN, 0 }, + /* b3 */ { Cache_TLBd, 0 }, + /* b4 */ { Cache_UNKNOWN, 0 }, + /* b5 */ { Cache_UNKNOWN, 0 }, + /* b6 */ { Cache_UNKNOWN, 0 }, + /* b7 */ { Cache_UNKNOWN, 0 }, + /* b8 */ { Cache_UNKNOWN, 0 }, + /* b9 */ { Cache_UNKNOWN, 0 }, + /* ba */ { Cache_UNKNOWN, 0 }, + /* bb */ { Cache_UNKNOWN, 0 }, + /* bc */ { Cache_UNKNOWN, 0 }, + /* bd */ { Cache_UNKNOWN, 0 }, + /* be */ { Cache_UNKNOWN, 0 }, + /* bf */ { Cache_UNKNOWN, 0 }, + /* c0 */ { Cache_UNKNOWN, 0 }, + /* c1 */ { Cache_UNKNOWN, 0 }, + /* c2 */ { Cache_UNKNOWN, 0 }, + /* c3 */ { Cache_UNKNOWN, 0 }, + /* c4 */ { Cache_UNKNOWN, 0 }, + /* c5 */ { Cache_UNKNOWN, 0 }, + /* c6 */ { Cache_UNKNOWN, 0 }, + /* c7 */ { Cache_UNKNOWN, 0 }, + /* c8 */ { Cache_UNKNOWN, 0 }, + /* c9 */ { Cache_UNKNOWN, 0 }, + /* ca */ { Cache_UNKNOWN, 0 }, + /* cb */ { Cache_UNKNOWN, 0 }, + /* cc */ { Cache_UNKNOWN, 0 }, + /* cd */ { Cache_UNKNOWN, 0 }, + /* ce */ { Cache_UNKNOWN, 0 }, + /* cf */ { Cache_UNKNOWN, 0 }, + /* d0 */ { Cache_UNKNOWN, 0 }, + /* d1 */ { Cache_UNKNOWN, 0 }, + /* d2 */ { Cache_UNKNOWN, 0 }, + /* d3 */ { Cache_UNKNOWN, 0 }, + /* d4 */ { Cache_UNKNOWN, 0 }, + /* d5 */ { Cache_UNKNOWN, 0 }, + /* d6 */ { Cache_UNKNOWN, 0 }, + /* d7 */ { Cache_UNKNOWN, 0 }, + /* d8 */ { Cache_UNKNOWN, 0 }, + /* d9 */ { Cache_UNKNOWN, 0 }, + /* da */ { Cache_UNKNOWN, 0 }, + /* db */ { Cache_UNKNOWN, 0 }, + /* dc */ { Cache_UNKNOWN, 0 }, + /* dd */ { Cache_UNKNOWN, 0 }, + /* de */ { Cache_UNKNOWN, 0 }, + /* df */ { Cache_UNKNOWN, 0 }, + /* e0 */ { Cache_UNKNOWN, 0 }, + /* e1 */ { Cache_UNKNOWN, 0 }, + /* e2 */ { Cache_UNKNOWN, 0 }, + /* e3 */ { Cache_UNKNOWN, 0 }, + /* e4 */ { Cache_UNKNOWN, 0 }, + /* e5 */ { Cache_UNKNOWN, 0 }, + /* e6 */ { Cache_UNKNOWN, 0 }, + /* e7 */ { Cache_UNKNOWN, 0 }, + /* e8 */ { Cache_UNKNOWN, 0 }, + /* e9 */ { Cache_UNKNOWN, 0 }, + /* ea */ { Cache_UNKNOWN, 0 }, + /* eb */ { Cache_UNKNOWN, 0 }, + /* ec */ { Cache_UNKNOWN, 0 }, + /* ed */ { Cache_UNKNOWN, 0 }, + /* ee */ { Cache_UNKNOWN, 0 }, + /* ef */ { Cache_UNKNOWN, 0 }, + /* f0 */ { Cache_UNKNOWN, 0 }, + /* f1 */ { Cache_UNKNOWN, 0 }, + /* f2 */ { Cache_UNKNOWN, 0 }, + /* f3 */ { Cache_UNKNOWN, 0 }, + /* f4 */ { Cache_UNKNOWN, 0 }, + /* f5 */ { Cache_UNKNOWN, 0 }, + /* f6 */ { Cache_UNKNOWN, 0 }, + /* f7 */ { Cache_UNKNOWN, 0 }, + /* f8 */ { Cache_UNKNOWN, 0 }, + /* f9 */ { Cache_UNKNOWN, 0 }, + /* fa */ { Cache_UNKNOWN, 0 }, + /* fb */ { Cache_UNKNOWN, 0 }, + /* fc */ { Cache_UNKNOWN, 0 }, + /* fd */ { Cache_UNKNOWN, 0 }, + /* fe */ { Cache_UNKNOWN, 0 }, + /* ff */ { Cache_UNKNOWN, 0 } }; - /* * use the above table to determine the CacheEntryLineSize. */ static void -getIntelCacheEntryLineSize(unsigned long val, int *level, - unsigned long *lineSize) +getIntelCacheEntryLineSize(unsigned long val, int *level, + unsigned long *lineSize) { CacheType type; @@ -485,28 +498,27 @@ getIntelCacheEntryLineSize(unsigned long val, int *level, * this data check has the side effect of rejecting that entry. If * that wasn't the case, we could have to reject it explicitly */ if (CacheMap[val].lineSize == 0) { - return; + return; } /* look at the caches, skip types we aren't interested in. * if we already have a value for a lower level cache, skip the * current entry */ - if ((type == Cache_L1)|| (type == Cache_L1d)) { - *level = 1; - *lineSize = CacheMap[val].lineSize; + if ((type == Cache_L1) || (type == Cache_L1d)) { + *level = 1; + *lineSize = CacheMap[val].lineSize; } else if ((*level >= 2) && ((type == Cache_L2) || (type == Cache_L2d))) { - *level = 2; - *lineSize = CacheMap[val].lineSize; + *level = 2; + *lineSize = CacheMap[val].lineSize; } else if ((*level >= 3) && ((type == Cache_L3) || (type == Cache_L3d))) { - *level = 3; - *lineSize = CacheMap[val].lineSize; + *level = 3; + *lineSize = CacheMap[val].lineSize; } return; } - static void -getIntelRegisterCacheLineSize(unsigned long val, - int *level, unsigned long *lineSize) +getIntelRegisterCacheLineSize(unsigned long val, + int *level, unsigned long *lineSize) { getIntelCacheEntryLineSize(val >> 24 & 0xff, level, lineSize); getIntelCacheEntryLineSize(val >> 16 & 0xff, level, lineSize); @@ -516,7 +528,7 @@ getIntelRegisterCacheLineSize(unsigned long val, /* * returns '0' if no recognized cache is found, or if the cache - * information is supported by this processor + * information is supported by this processor */ static unsigned long getIntelCacheLineSize(int cpuidLevel) @@ -527,13 +539,13 @@ getIntelCacheLineSize(int cpuidLevel) int repeat, count; if (cpuidLevel < 2) { - return 0; + return 0; } /* command '2' of the cpuid is intel's cache info call. Each byte of the - * 4 registers contain a potential descriptor for the cache. The CacheMap + * 4 registers contain a potential descriptor for the cache. The CacheMap * table maps the cache entry with the processor cache. Register 'al' - * contains a count value that cpuid '2' needs to be called in order to + * contains a count value that cpuid '2' needs to be called in order to * find all the cache descriptors. Only registers with the high bit set * to 'zero' have valid descriptors. This code loops through all the * required calls to cpuid '2' and passes any valid descriptors it finds @@ -543,28 +555,28 @@ getIntelCacheLineSize(int cpuidLevel) freebl_cpuid(2, &eax, &ebx, &ecx, &edx); repeat = eax & 0xf; for (count = 0; count < repeat; count++) { - if ((eax & 0x80000000) == 0) { - getIntelRegisterCacheLineSize(eax & 0xffffff00, &level, &lineSize); - } - if ((ebx & 0x80000000) == 0) { - getIntelRegisterCacheLineSize(ebx, &level, &lineSize); - } - if ((ecx & 0x80000000) == 0) { - getIntelRegisterCacheLineSize(ecx, &level, &lineSize); - } - if ((edx & 0x80000000) == 0) { - getIntelRegisterCacheLineSize(edx, &level, &lineSize); - } - if (count+1 != repeat) { - freebl_cpuid(2, &eax, &ebx, &ecx, &edx); - } + if ((eax & 0x80000000) == 0) { + getIntelRegisterCacheLineSize(eax & 0xffffff00, &level, &lineSize); + } + if ((ebx & 0x80000000) == 0) { + getIntelRegisterCacheLineSize(ebx, &level, &lineSize); + } + if ((ecx & 0x80000000) == 0) { + getIntelRegisterCacheLineSize(ecx, &level, &lineSize); + } + if ((edx & 0x80000000) == 0) { + getIntelRegisterCacheLineSize(edx, &level, &lineSize); + } + if (count + 1 != repeat) { + freebl_cpuid(2, &eax, &ebx, &ecx, &edx); + } } return lineSize; } /* * returns '0' if the cache info is not supported by this processor. - * This is based on the AMD extended cache commands for cpuid. + * This is based on the AMD extended cache commands for cpuid. * (see "AMD Processor Recognition Application Note" Publication 20734). * Some other processors use the identical scheme. * (see "Processor Recognition, Transmeta Corporation"). @@ -580,58 +592,57 @@ getOtherCacheLineSize(unsigned long cpuidLevel) cpuidLevel = eax; if (cpuidLevel >= 0x80000005) { - freebl_cpuid(0x80000005, &eax, &ebx, &ecx, &edx); - lineSize = ecx & 0xff; /* line Size, L1 Data Cache */ + freebl_cpuid(0x80000005, &eax, &ebx, &ecx, &edx); + lineSize = ecx & 0xff; /* line Size, L1 Data Cache */ } return lineSize; } -static const char * const manMap[] = { -#define INTEL 0 +static const char *const manMap[] = { +#define INTEL 0 "GenuineIntel", -#define AMD 1 +#define AMD 1 "AuthenticAMD", -#define CYRIX 2 +#define CYRIX 2 "CyrixInstead", -#define CENTAUR 2 +#define CENTAUR 2 "CentaurHauls", -#define NEXGEN 3 +#define NEXGEN 3 "NexGenDriven", #define TRANSMETA 4 "GenuineTMx86", -#define RISE 5 +#define RISE 5 "RiseRiseRise", -#define UMC 6 +#define UMC 6 "UMC UMC UMC ", -#define SIS 7 +#define SIS 7 "Sis Sis Sis ", -#define NATIONAL 8 +#define NATIONAL 8 "Geode by NSC", }; -static const int n_manufacturers = sizeof(manMap)/sizeof(manMap[0]); - +static const int n_manufacturers = sizeof(manMap) / sizeof(manMap[0]); #define MAN_UNKNOWN 9 #if !defined(AMD_64) -#define SSE2_FLAG (1<<26) +#define SSE2_FLAG (1 << 26) unsigned long s_mpi_is_sse2() { unsigned long eax, ebx, ecx, edx; if (is386() || is486()) { - return 0; + return 0; } freebl_cpuid(0, &eax, &ebx, &ecx, &edx); /* has no SSE2 extensions */ if (eax == 0) { - return 0; + return 0; } - freebl_cpuid(1,&eax,&ebx,&ecx,&edx); + freebl_cpuid(1, &eax, &ebx, &ecx, &edx); return (edx & SSE2_FLAG) == SSE2_FLAG; } #endif @@ -649,9 +660,10 @@ s_mpi_getProcessorLineSize() #if !defined(AMD_64) if (is386()) { - return 0; /* 386 had no cache */ - } if (is486()) { - return 32; /* really? need more info */ + return 0; /* 386 had no cache */ + } + if (is486()) { + return 32; /* really? need more info */ } #endif @@ -669,30 +681,30 @@ s_mpi_getProcessorLineSize() string[12] = 0; manufacturer = MAN_UNKNOWN; - for (i=0; i < n_manufacturers; i++) { - if ( strcmp(manMap[i],string) == 0) { - manufacturer = i; - } + for (i = 0; i < n_manufacturers; i++) { + if (strcmp(manMap[i], string) == 0) { + manufacturer = i; + } } if (manufacturer == INTEL) { - cacheLineSize = getIntelCacheLineSize(cpuidLevel); + cacheLineSize = getIntelCacheLineSize(cpuidLevel); } else { - cacheLineSize = getOtherCacheLineSize(cpuidLevel); + cacheLineSize = getOtherCacheLineSize(cpuidLevel); } /* doesn't support cache info based on cpuid. This means * an old pentium class processor, which have cache lines of * 32. If we learn differently, we can use a switch based on * the Manufacturer id */ if (cacheLineSize == 0) { - cacheLineSize = 32; + cacheLineSize = 32; } return cacheLineSize; } #define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1 #endif -#if defined(__ppc64__) +#if defined(__ppc64__) /* * Sigh, The PPC has some really nice features to help us determine cache * size, since it had lots of direct control functions to do so. The POWER @@ -700,48 +712,49 @@ s_mpi_getProcessorLineSize() * PowerPC. Unfortunately most of them are not available in user mode. * * The dcbz function would be a great way to determine cache line size except - * 1) it only works on write-back memory (it throws an exception otherwise), + * 1) it only works on write-back memory (it throws an exception otherwise), * and 2) because so many mac programs 'knew' the processor cache size was * 32 bytes, they used this instruction as a fast 'zero 32 bytes'. Now the new * G5 processor has 128 byte cache, but dcbz only clears 32 bytes to keep * these programs happy. dcbzl work if 64 bit instructions are supported. - * If you know 64 bit instructions are supported, and that stack is + * If you know 64 bit instructions are supported, and that stack is * write-back, you can use this code. */ #include "memory.h" /* clear the cache line that contains 'array' */ -static inline void dcbzl(char *array) +static inline void +dcbzl(char *array) { - register char *a asm("r2") = array; - __asm__ __volatile__( "dcbzl %0,r0" : "=r" (a): "0"(a) ); + register char *a asm("r2") = array; + __asm__ __volatile__("dcbzl %0,r0" + : "=r"(a) + : "0"(a)); } - -#define PPC_DO_ALIGN(x,y) ((char *)\ - ((((long long) (x))+((y)-1))&~((y)-1))) +#define PPC_DO_ALIGN(x, y) ((char *)((((long long)(x)) + ((y)-1)) & ~((y)-1))) #define PPC_MAX_LINE_SIZE 256 unsigned long s_mpi_getProcessorLineSize() { - char testArray[2*PPC_MAX_LINE_SIZE+1]; + char testArray[2 * PPC_MAX_LINE_SIZE + 1]; char *test; int i; /* align the array on a maximum line size boundary, so we * know we are starting to clear from the first address */ - test = PPC_DO_ALIGN(testArray, PPC_MAX_LINE_SIZE); + test = PPC_DO_ALIGN(testArray, PPC_MAX_LINE_SIZE); /* set all the values to 1's */ memset(test, 0xff, PPC_MAX_LINE_SIZE); /* clear one cache block starting at 'test' */ dcbzl(test); /* find the size of the cleared area, that's our block size */ - for (i=PPC_MAX_LINE_SIZE; i != 0; i = i/2) { - if (test[i-1] == 0) { - return i; - } + for (i = PPC_MAX_LINE_SIZE; i != 0; i = i / 2) { + if (test[i - 1] == 0) { + return i; + } } return 0; } @@ -749,42 +762,39 @@ s_mpi_getProcessorLineSize() #define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1 #endif - /* * put other processor and platform specific cache code here - * return the smallest cache line size in bytes on the processor + * return the smallest cache line size in bytes on the processor * (usually the L1 cache). If the OS has a call, this would be * a greate place to put it. * * If there is no cache, return 0; - * + * * define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED so the generic functions * below aren't compiled. * */ - -/* target.mk can define MPI_CACHE_LINE_SIZE if it's common for the family or +/* target.mk can define MPI_CACHE_LINE_SIZE if it's common for the family or * OS */ #if defined(MPI_CACHE_LINE_SIZE) && !defined(MPI_GET_PROCESSOR_LINE_SIZE_DEFINED) unsigned long s_mpi_getProcessorLineSize() { - return MPI_CACHE_LINE_SIZE; + return MPI_CACHE_LINE_SIZE; } #define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1 #endif - /* If no way to get the processor cache line size has been defined, assume * it's 32 bytes (most common value, does not significantly impact performance) - */ + */ #ifndef MPI_GET_PROCESSOR_LINE_SIZE_DEFINED unsigned long s_mpi_getProcessorLineSize() { - return 32; + return 32; } #endif @@ -794,5 +804,5 @@ s_mpi_getProcessorLineSize() main() { printf("line size = %d\n", s_mpi_getProcessorLineSize()); -} +} #endif diff --git a/nss/lib/freebl/mpi/mpcpucache_x86.s b/nss/lib/freebl/mpi/mpcpucache_x86.s index cc65ea3..af17ebc 100644 --- a/nss/lib/freebl/mpi/mpcpucache_x86.s +++ b/nss/lib/freebl/mpi/mpcpucache_x86.s @@ -569,6 +569,7 @@ freebl_cpuid: movl %edx, %ebp /APP pushl %ebx + xorl %ecx, %ecx cpuid mov %ebx,%esi popl %ebx diff --git a/nss/lib/freebl/mpi/mpi-config.h b/nss/lib/freebl/mpi/mpi-config.h index 1d35028..f365592 100644 --- a/nss/lib/freebl/mpi/mpi-config.h +++ b/nss/lib/freebl/mpi/mpi-config.h @@ -1,4 +1,4 @@ -/* Default configuration for MPI library +/* Default configuration for MPI library * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,7 +8,7 @@ #define MPI_CONFIG_H_ /* - For boolean options, + For boolean options, 0 = no 1 = yes @@ -17,31 +17,27 @@ */ #ifndef MP_IOFUNC -#define MP_IOFUNC 0 /* include mp_print() ? */ +#define MP_IOFUNC 0 /* include mp_print() ? */ #endif #ifndef MP_MODARITH -#define MP_MODARITH 1 /* include modular arithmetic ? */ +#define MP_MODARITH 1 /* include modular arithmetic ? */ #endif #ifndef MP_NUMTH -#define MP_NUMTH 1 /* include number theoretic functions? */ +#define MP_NUMTH 1 /* include number theoretic functions? */ #endif #ifndef MP_LOGTAB -#define MP_LOGTAB 1 /* use table of logs instead of log()? */ +#define MP_LOGTAB 1 /* use table of logs instead of log()? */ #endif #ifndef MP_MEMSET -#define MP_MEMSET 1 /* use memset() to zero buffers? */ +#define MP_MEMSET 1 /* use memset() to zero buffers? */ #endif #ifndef MP_MEMCPY -#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */ -#endif - -#ifndef MP_CRYPTO -#define MP_CRYPTO 1 /* erase memory on free? */ +#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */ #endif #ifndef MP_ARGCHK @@ -51,28 +47,22 @@ 2 = assertions; dump core on parameter errors */ #ifdef DEBUG -#define MP_ARGCHK 2 /* how to check input arguments */ +#define MP_ARGCHK 2 /* how to check input arguments */ #else -#define MP_ARGCHK 1 /* how to check input arguments */ +#define MP_ARGCHK 1 /* how to check input arguments */ #endif #endif #ifndef MP_DEBUG -#define MP_DEBUG 0 /* print diagnostic output? */ +#define MP_DEBUG 0 /* print diagnostic output? */ #endif #ifndef MP_DEFPREC -#define MP_DEFPREC 64 /* default precision, in digits */ -#endif - -#ifndef MP_MACRO -#define MP_MACRO 1 /* use macros for frequent calls? */ +#define MP_DEFPREC 64 /* default precision, in digits */ #endif #ifndef MP_SQUARE -#define MP_SQUARE 1 /* use separate squaring code? */ +#define MP_SQUARE 1 /* use separate squaring code? */ #endif #endif /* ifndef MPI_CONFIG_H_ */ - - diff --git a/nss/lib/freebl/mpi/mpi-priv.h b/nss/lib/freebl/mpi/mpi-priv.h index 7a0725f..b34452c 100644 --- a/nss/lib/freebl/mpi/mpi-priv.h +++ b/nss/lib/freebl/mpi/mpi-priv.h @@ -1,9 +1,9 @@ /* - * mpi-priv.h - Private header file for MPI + * mpi-priv.h - Private header file for MPI * Arbitrary precision integer arithmetic library * * NOTE WELL: the content of this header file is NOT part of the "public" - * API for the MPI library, and may change at any time. + * API for the MPI library, and may change at any time. * Application programs that use libmpi should NOT include this header file. * * This Source Code Form is subject to the terms of the Mozilla Public @@ -20,9 +20,14 @@ #if MP_DEBUG #include <stdio.h> -#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);} +#define DIAG(T, V) \ + { \ + fprintf(stderr, T); \ + mp_print(V, stderr); \ + fputc('\n', stderr); \ + } #else -#define DIAG(T,V) +#define DIAG(T, V) #endif /* If we aren't using a wired-in logarithm table, we need to include @@ -34,7 +39,7 @@ #if MP_LOGTAB /* A table of the logs of 2 for various bases (the 0 and 1 entries of - this table are meaningless and should not be referenced). + this table are meaningless and should not be referenced). This table is used to compute output lengths for the mp_toradix() function. Since a number n in radix r takes up about log_r(n) @@ -44,22 +49,22 @@ log_r(n) = log_2(n) * log_r(2) This table, therefore, is a table of log_r(2) for 2 <= r <= 36, - which are the output bases supported. + which are the output bases supported. */ extern const float s_logv_2[]; -#define LOG_V_2(R) s_logv_2[(R)] +#define LOG_V_2(R) s_logv_2[(R)] #else -/* +/* If MP_LOGTAB is not defined, use the math library to compute the logarithms on the fly. Otherwise, use the table. Pick which works best for your system. */ #include <math.h> -#define LOG_V_2(R) (log(2.0)/log(R)) +#define LOG_V_2(R) (log(2.0) / log(R)) #endif /* if MP_LOGTAB */ @@ -75,127 +80,81 @@ extern const float s_logv_2[]; ourselves with the low-order 2 mp_digits) */ -#define CARRYOUT(W) (mp_digit)((W)>>DIGIT_BIT) -#define ACCUM(W) (mp_digit)(W) +#define CARRYOUT(W) (mp_digit)((W) >> DIGIT_BIT) +#define ACCUM(W) (mp_digit)(W) -#define MP_MIN(a,b) (((a) < (b)) ? (a) : (b)) -#define MP_MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define MP_HOWMANY(a,b) (((a) + (b) - 1)/(b)) -#define MP_ROUNDUP(a,b) (MP_HOWMANY(a,b) * (b)) +#define MP_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MP_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MP_HOWMANY(a, b) (((a) + (b)-1) / (b)) +#define MP_ROUNDUP(a, b) (MP_HOWMANY(a, b) * (b)) /* }}} */ /* {{{ Comparison constants */ -#define MP_LT -1 -#define MP_EQ 0 -#define MP_GT 1 +#define MP_LT -1 +#define MP_EQ 0 +#define MP_GT 1 /* }}} */ /* {{{ private function declarations */ -/* - If MP_MACRO is false, these will be defined as actual functions; - otherwise, suitable macro definitions will be used. This works - around the fact that ANSI C89 doesn't support an 'inline' keyword - (although I hear C9x will ... about bloody time). At present, the - macro definitions are identical to the function bodies, but they'll - expand in place, instead of generating a function call. - - I chose these particular functions to be made into macros because - some profiling showed they are called a lot on a typical workload, - and yet they are primarily housekeeping. - */ -#if MP_MACRO == 0 - void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */ - void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count); /* copy */ - void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */ - void s_mp_free(void *ptr); /* general free function */ -extern unsigned long mp_allocs; -extern unsigned long mp_frees; -extern unsigned long mp_copies; -#else - - /* Even if these are defined as macros, we need to respect the settings - of the MP_MEMSET and MP_MEMCPY configuration options... - */ - #if MP_MEMSET == 0 - #define s_mp_setz(dp, count) \ - {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;} - #else - #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit)) - #endif /* MP_MEMSET */ - - #if MP_MEMCPY == 0 - #define s_mp_copy(sp, dp, count) \ - {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];} - #else - #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit)) - #endif /* MP_MEMCPY */ - - #define s_mp_alloc(nb, ni) calloc(nb, ni) - #define s_mp_free(ptr) {if(ptr) free(ptr);} -#endif /* MP_MACRO */ - -mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */ -mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */ - -#if MP_MACRO == 0 - void s_mp_clamp(mp_int *mp); /* clip leading zeroes */ -#else - #define s_mp_clamp(mp)\ - { mp_size used = MP_USED(mp); \ - while (used > 1 && DIGIT(mp, used - 1) == 0) --used; \ - MP_USED(mp) = used; \ - } -#endif /* MP_MACRO */ - -void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */ - -mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */ -void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */ -mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place */ -void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */ -void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */ -void s_mp_div_2(mp_int *mp); /* divide by 2 in place */ -mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */ -mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd); - /* normalize for division */ -mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */ -mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */ -mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */ -mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r); - /* unsigned digit divide */ -mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu); - /* Barrett reduction */ -mp_err s_mp_add(mp_int *a, const mp_int *b); /* magnitude addition */ -mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c); -mp_err s_mp_sub(mp_int *a, const mp_int *b); /* magnitude subtract */ -mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c); -mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset); - /* a += b * RADIX^offset */ -mp_err s_mp_mul(mp_int *a, const mp_int *b); /* magnitude multiply */ +void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */ +void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count); /* copy */ +void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */ +void s_mp_free(void *ptr); /* general free function */ + +mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */ +mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */ + +void s_mp_clamp(mp_int *mp); /* clip leading zeroes */ + +void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */ + +mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */ +void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */ +mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place */ +void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */ +void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */ +void s_mp_div_2(mp_int *mp); /* divide by 2 in place */ +mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */ +mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd); +/* normalize for division */ +mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */ +mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */ +mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */ +mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r); +/* unsigned digit divide */ +mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu); +/* Barrett reduction */ +mp_err s_mp_add(mp_int *a, const mp_int *b); /* magnitude addition */ +mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c); +mp_err s_mp_sub(mp_int *a, const mp_int *b); /* magnitude subtract */ +mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c); +mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset); +/* a += b * RADIX^offset */ +mp_err s_mp_mul(mp_int *a, const mp_int *b); /* magnitude multiply */ #if MP_SQUARE -mp_err s_mp_sqr(mp_int *a); /* magnitude square */ +mp_err s_mp_sqr(mp_int *a); /* magnitude square */ #else -#define s_mp_sqr(a) s_mp_mul(a, a) +#define s_mp_sqr(a) s_mp_mul(a, a) #endif -mp_err s_mp_div(mp_int *rem, mp_int *div, mp_int *quot); /* magnitude div */ -mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c); -mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */ -int s_mp_cmp(const mp_int *a, const mp_int *b); /* magnitude comparison */ -int s_mp_cmp_d(const mp_int *a, mp_digit d); /* magnitude digit compare */ -int s_mp_ispow2(const mp_int *v); /* is v a power of 2? */ -int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */ - -int s_mp_tovalue(char ch, int r); /* convert ch to value */ -char s_mp_todigit(mp_digit val, int r, int low); /* convert val to digit */ -int s_mp_outlen(int bits, int r); /* output length in bytes */ -mp_digit s_mp_invmod_radix(mp_digit P); /* returns (P ** -1) mod RADIX */ -mp_err s_mp_invmod_odd_m( const mp_int *a, const mp_int *m, mp_int *c); -mp_err s_mp_invmod_2d( const mp_int *a, mp_size k, mp_int *c); -mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c); +mp_err s_mp_div(mp_int *rem, mp_int *div, mp_int *quot); /* magnitude div */ +mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c); +mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */ +int s_mp_cmp(const mp_int *a, const mp_int *b); /* magnitude comparison */ +int s_mp_cmp_d(const mp_int *a, mp_digit d); /* magnitude digit compare */ +int s_mp_ispow2(const mp_int *v); /* is v a power of 2? */ +int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */ + +int s_mp_tovalue(char ch, int r); /* convert ch to value */ +char s_mp_todigit(mp_digit val, int r, int low); /* convert val to digit */ +int s_mp_outlen(int bits, int r); /* output length in bytes */ +mp_digit s_mp_invmod_radix(mp_digit P); /* returns (P ** -1) mod RADIX */ +mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c); +mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c); +mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c); #ifdef NSS_USE_COMBA @@ -214,7 +173,7 @@ void s_mp_sqr_comba_32(const mp_int *A, mp_int *B); #endif /* end NSS_USE_COMBA */ /* ------ mpv functions, operate on arrays of digits, not on mp_int's ------ */ -#if defined (__OS2__) && defined (__IBMC__) +#if defined(__OS2__) && defined(__IBMC__) #define MPI_ASM_DECL __cdecl #else #define MPI_ASM_DECL @@ -222,50 +181,49 @@ void s_mp_sqr_comba_32(const mp_int *A, mp_int *B); #ifdef MPI_AMD64 -mp_digit MPI_ASM_DECL s_mpv_mul_set_vec64(mp_digit*, mp_digit *, mp_size, mp_digit); -mp_digit MPI_ASM_DECL s_mpv_mul_add_vec64(mp_digit*, const mp_digit*, mp_size, mp_digit); +mp_digit MPI_ASM_DECL s_mpv_mul_set_vec64(mp_digit *, mp_digit *, mp_size, mp_digit); +mp_digit MPI_ASM_DECL s_mpv_mul_add_vec64(mp_digit *, const mp_digit *, mp_size, mp_digit); /* c = a * b */ #define s_mpv_mul_d(a, a_len, b, c) \ - ((mp_digit *)c)[a_len] = s_mpv_mul_set_vec64(c, a, a_len, b) + ((mp_digit *)c)[a_len] = s_mpv_mul_set_vec64(c, a, a_len, b) /* c += a * b */ #define s_mpv_mul_d_add(a, a_len, b, c) \ - ((mp_digit *)c)[a_len] = s_mpv_mul_add_vec64(c, a, a_len, b) - + ((mp_digit *)c)[a_len] = s_mpv_mul_add_vec64(c, a, a_len, b) #else -void MPI_ASM_DECL s_mpv_mul_d(const mp_digit *a, mp_size a_len, - mp_digit b, mp_digit *c); -void MPI_ASM_DECL s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, - mp_digit b, mp_digit *c); +void MPI_ASM_DECL s_mpv_mul_d(const mp_digit *a, mp_size a_len, + mp_digit b, mp_digit *c); +void MPI_ASM_DECL s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, + mp_digit b, mp_digit *c); #endif -void MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a, - mp_size a_len, mp_digit b, - mp_digit *c); -void MPI_ASM_DECL s_mpv_sqr_add_prop(const mp_digit *a, - mp_size a_len, - mp_digit *sqrs); +void MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a, + mp_size a_len, mp_digit b, + mp_digit *c); +void MPI_ASM_DECL s_mpv_sqr_add_prop(const mp_digit *a, + mp_size a_len, + mp_digit *sqrs); -mp_err MPI_ASM_DECL s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, - mp_digit divisor, mp_digit *quot, mp_digit *rem); +mp_err MPI_ASM_DECL s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, + mp_digit divisor, mp_digit *quot, mp_digit *rem); /* c += a * b * (MP_RADIX ** offset); */ /* Callers of this macro should be aware that the return type might vary; * it should be treated as a void function. */ #define s_mp_mul_d_add_offset(a, b, c, off) \ - s_mpv_mul_d_add_prop(MP_DIGITS(a), MP_USED(a), b, MP_DIGITS(c) + off) + s_mpv_mul_d_add_prop(MP_DIGITS(a), MP_USED(a), b, MP_DIGITS(c) + off) typedef struct { - mp_int N; /* modulus N */ - mp_digit n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */ + mp_int N; /* modulus N */ + mp_digit n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */ } mp_mont_modulus; -mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c, - mp_mont_modulus *mmm); +mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c, + mp_mont_modulus *mmm); mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm); /* @@ -283,4 +241,3 @@ unsigned long s_mpi_getProcessorLineSize(); /* }}} */ #endif - diff --git a/nss/lib/freebl/mpi/mpi-test.c b/nss/lib/freebl/mpi/mpi-test.c deleted file mode 100644 index 1276d35..0000000 --- a/nss/lib/freebl/mpi/mpi-test.c +++ /dev/null @@ -1,1952 +0,0 @@ -/* - * mpi-test.c - * - * This is a general test suite for the MPI library, which tests - * all the functions in the library with known values. The program - * exits with a zero (successful) status if the tests pass, or a - * nonzero status if the tests fail. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <limits.h> -#include <time.h> - -#include "mpi.h" -#include "mpprime.h" - -#include "test-info.c" - -/* ZS means Zero Suppressed (no leading zeros) */ -#if MP_USE_LONG_DIGIT -#define ZS_DIGIT_FMT "%lX" -#elif MP_USE_LONG_LONG_DIGIT -#define ZS_DIGIT_FMT "%llX" -#elif MP_USE_UINT_DIGIT -#define ZS_DIGIT_FMT "%X" -#else -#error "unknown type of digit" -#endif - -/* - Test vectors - - If you intend to change any of these values, you must also recompute - the corresponding solutions below. Basically, these are just hex - strings (for the big integers) or integer values (for the digits). - - The comparison tests think they know what relationships hold between - these values. If you change that, you may have to adjust the code - for the comparison tests accordingly. Most of the other tests - should be fine as long as you re-compute the solutions, though. - */ -const char *mp1 = "639A868CDA0C569861B"; -const char *mp2 = "AAFC0A3FE45E5E09DBE2C29"; -const char *mp3 = "B55AA8DF8A7E83241F38AC7A9E479CAEF2E4D7C5"; -const char *mp4 = "-63DBC2265B88268DC801C10EA68476B7BDE0090F"; -const char *mp5 = "F595CB42"; -const char *mp5a = "-4B597E"; -const char *mp6 = "0"; -const char *mp7 = "EBFA7121CD838CE6439CC59DDB4CBEF3"; -const char *mp8 = "5"; -const char *mp9 = "F74A2876A1432698923B0767DA19DCF3D71795EE"; -const char *mp10 = "9184E72A000"; -const char *mp11 = "54D79A3557E8"; -const char *mp12 = "10000000000000000"; -const char *mp13 = -"34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342BDAB6163963C" -"D5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45F2B050D226E6DA88"; -const char *mp14 = -"AC3FA0EABAAC45724814D798942A1E28E14C81E0DE8055CED630E7689DA648683645DB6E" -"458D9F5338CC3D4E33A5D1C9BF42780133599E60DEE0049AFA8F9489501AE5C9AA2B8C13" -"FD21285A538B2CA87A626BB56E0A654C8707535E637FF4E39174157402BDE3AA30C9F134" -"0C1307BAA864B075A9CC828B6A5E2B2BF1AE406D920CC5E7657D7C0E697DEE5375773AF9" -"E200A1B8FAD7CD141F9EE47ABB55511FEB9A4D99EBA22F3A3FF6792FA7EE9E5DC0EE94F7" -"7A631EDF3D7DD7C2DAAAFDF234D60302AB63D5234CEAE941B9AF0ADDD9E6E3A940A94EE5" -"5DB45A7C66E61EDD0477419BBEFA44C325129601C4F45671C6A0E64665DF341D17FBC71F" -"77418BD9F4375DDB3B9D56126526D8E5E0F35A121FD4F347013DA880020A752324F31DDD" -"9BCDB13A3B86E207A2DE086825E6EEB87B3A64232CFD8205B799BC018634AAE193F19531" -"D6EBC19A75F27CFFAA03EB5974898F53FD569AA5CE60F431B53B0CDE715A5F382405C9C4" -"761A8E24888328F09F7BCE4E8D80C957DF177629C8421ACCD0C268C63C0DD47C3C0D954F" -"D79F7D7297C6788DF4B3E51381759864D880ACA246DF09533739B8BB6085EAF7AE8DC2D9" -"F224E6874926C8D24D34B457FD2C9A586C6B99582DC24F787A39E3942786CF1D494B6EB4" -"A513498CDA0B217C4E80BCE7DA1C704C35E071AC21E0DA9F57C27C3533F46A8D20B04137" -"C1B1384BE4B2EB46"; -const char *mp15 = -"39849CF7FD65AF2E3C4D87FE5526221103D90BA26A6642FFE3C3ECC0887BBBC57E011BF1" -"05D822A841653509C68F79EBE51C0099B8CBB04DEF31F36F5954208A3209AC122F0E11D8" -"4AE67A494D78336A2066D394D42E27EF6B03DDAF6D69F5112C93E714D27C94F82FC7EF77" -"445768C68EAE1C4A1407BE1B303243391D325090449764AE469CC53EC8012C4C02A72F37" -"07ED7275D2CC8D0A14B5BCC6BF264941520EBA97E3E6BAE4EE8BC87EE0DDA1F5611A6ECB" -"65F8AEF4F184E10CADBDFA5A2FEF828901D18C20785E5CC63473D638762DA80625003711" -"9E984AC43E707915B133543AF9D5522C3E7180DC58E1E5381C1FB7DC6A5F4198F3E88FA6" -"CBB6DFA8B2D1C763226B253E18BCCB79A29EE82D2DE735078C8AE3C3C86D476AAA08434C" -"09C274BDD40A1D8FDE38D6536C22F44E807EB73DE4FB36C9F51E0BC835DDBE3A8EFCF2FE" -"672B525769DC39230EE624D5EEDBD837C82A52E153F37378C3AD68A81A7ADBDF3345DBCE" -"8FA18CA1DE618EF94DF72EAD928D4F45B9E51632ACF158CF8332C51891D1D12C2A7E6684" -"360C4BF177C952579A9F442CFFEC8DAE4821A8E7A31C4861D8464CA9116C60866C5E72F7" -"434ADBED36D54ACDFDFF70A4EFB46E285131FE725F1C637D1C62115EDAD01C4189716327" -"BFAA79618B1656CBFA22C2C965687D0381CC2FE0245913C4D8D96108213680BD8E93E821" -"822AD9DDBFE4BD04"; -const char *mp16 = "4A724340668DB150339A70"; -const char *mp17 = "8ADB90F58"; -const char *mp18 = "C64C230AB20E5"; -const char *mp19 = -"F1C9DACDA287F2E3C88DCE2393B8F53DAAAC1196DC36510962B6B59454CFE64B"; -const char *mp20 = -"D445662C8B6FE394107B867797750C326E0F4A967E135FC430F6CD7207913AC7"; -const char* mp21 = "2"; - -const mp_digit md1 = 0; -const mp_digit md2 = 0x1; -const mp_digit md3 = 0x80; -const mp_digit md4 = 0x9C97; -const mp_digit md5 = 0xF5BF; -const mp_digit md6 = 0x14A0; -const mp_digit md7 = 0x03E8; -const mp_digit md8 = 0x0101; -const mp_digit md9 = 0xA; - -/* - Solutions of the form x_mpABC, where: - - x = (p)roduct, (s)um, (d)ifference, (q)uotient, (r)emainder, (g)cd, - (i)nverse, (e)xponent, square roo(t), (g)cd, (l)cm. A - leading 'm' indicates a modular operation, e.g. ms_mp12 is the - modular sum of operands 1 and 2 - - ABC are the operand numbers involved in the computation. If a 'd' - precedes the number, it is a digit operand; if a 'c' precedes it, - it is a constant; otherwise, it is a full integer. - */ - -const char *p_mp12 = "4286AD72E095C9FE009938750743174ADDD7FD1E53"; -const char *p_mp34 = "-46BDBD66CA108C94A8CF46C325F7B6E2F2BA82D35" - "A1BFD6934C441EE369B60CA29BADC26845E918B"; -const char *p_mp57 = "E260C265A0A27C17AD5F4E59D6E0360217A2EBA6"; -const char *p_mp22 = "7233B5C1097FFC77CCF55928FDC3A5D31B712FDE7A1E91"; -const char *p_mp1d4 = "3CECEA2331F4220BEF68DED"; -const char *p_mp8d6 = "6720"; -const char *p_mp1113 = -"11590FC3831C8C3C51813142C88E566408DB04F9E27642F6471A1822E0100B12F7F1" -"5699A127C0FA9D26DCBFF458522661F30C6ADA4A07C8C90F9116893F6DBFBF24C3A2" -"4340"; -const char *p_mp1415 = -"26B36540DE8B3586699CCEAE218A2842C7D5A01590E70C4A26E789107FBCDB06AA2C" -"6DDC39E6FA18B16FCB2E934C9A5F844DAD60EE3B1EA82199EC5E9608F67F860FB965" -"736055DF0E8F2540EB28D07F47E309B5F5D7C94FF190AB9C83A6970160CA700B1081" -"F60518132AF28C6CEE6B7C473E461ABAC52C39CED50A08DD4E7EA8BA18DAD545126D" -"A388F6983C29B6BE3F9DCBC15766E8E6D626A92C5296A9C4653CAE5788350C0E2107" -"F57E5E8B6994C4847D727FF1A63A66A6CEF42B9C9E6BD04C92550B85D5527DE8A132" -"E6BE89341A9285C7CE7FB929D871BBCBD0ED2863B6B078B0DBB30FCA66D6C64284D6" -"57F394A0271E15B6EC7A9D530EBAC6CA262EF6F97E1A29FCE7749240E4AECA591ECF" -"272122BC587370F9371B67BB696B3CDC1BC8C5B64B6280994EBA00CDEB8EB0F5D06E" -"18F401D65FDCECF23DD7B9BB5B4C5458AEF2CCC09BA7F70EACB844750ACFD027521E" -"2E047DE8388B35F8512D3DA46FF1A12D4260213602BF7BFFDB6059439B1BD0676449" -"8D98C74F48FB3F548948D5BA0C8ECFCD054465132DC43466D6BBD59FBAF8D6D4E157" -"2D612B40A956C7D3E140F3B8562EF18568B24D335707D5BAC7495014DF2444172426" -"FD099DED560D30D1F945386604AFC85C64BD1E5F531F5C7840475FC0CF0F79810012" -"4572BAF5A9910CDBD02B27FFCC3C7E5E88EF59F3AE152476E33EDA696A4F751E0AE4" -"A3D2792DEA78E25B9110E12A19EFD09EA47FF9D6594DA445478BEB6901EAF8A35B2D" -"FD59BEE9BF7AA8535B7D326EFA5AA2121B5EBE04DD85827A3D43BD04F4AA6D7B62A2" -"B6D7A3077286A511A431E1EF75FCEBA3FAE9D5843A8ED17AA02BBB1B571F904699C5" -"A6073F87DDD012E2322AB3F41F2A61F428636FE86914148E19B8EF8314ED83332F2F" -"8C2ADE95071E792C0A68B903E060DD322A75FD0C2B992059FCCBB58AFA06B50D1634" -"BBD93F187FCE0566609FCC2BABB269C66CEB097598AA17957BB4FDA3E64A1B30402E" -"851CF9208E33D52E459A92C63FBB66435BB018E155E2C7F055E0B7AB82CD58FC4889" -"372ED9EEAC2A07E8E654AB445B9298D2830D6D4DFD117B9C8ABE3968927DC24B3633" -"BAD6E6466DB45DDAE87A0AB00336AC2CCCE176704F7214FCAB55743AB76C2B6CA231" -"7984610B27B5786DE55C184DDF556EDFEA79A3652831940DAD941E243F482DC17E50" -"284BC2FB1AD712A92542C573E55678878F02DFD9E3A863C7DF863227AEDE14B47AD3" -"957190124820ADC19F5353878EDB6BF7D0C77352A6E3BDB53EEB88F5AEF6226D6E68" -"756776A8FB49B77564147A641664C2A54F7E5B680CCC6A4D22D894E464DF20537094" -"548F1732452F9E7F810C0B4B430C073C0FBCE03F0D03F82630654BCE166AA772E1EE" -"DD0C08D3E3EBDF0AF54203B43AFDFC40D8FC79C97A4B0A4E1BEB14D8FCEFDDED8758" -"6ED65B18"; -const char *p_mp2121 = "4"; -const char *mp_mp345 = "B9B6D3A3"; -const char *mp_mp335 = "16609C2D"; - -const char *s_mp13 = "B55AA8DF8A7E83241F38B2B446B06A4FB84E5DE0"; -const char *s_mp34 = "517EE6B92EF65C965736EB6BF7C325F73504CEB6"; -const char *s_mp46 = "-63DBC2265B88268DC801C10EA68476B7BDE0090F"; -const char *s_mp5d4 = "F59667D9"; -const char *s_mp2d5 = "AAFC0A3FE45E5E09DBF21E8"; -const char *s_mp1415 = -"E5C43DE2B811F4A084625F96E9504039E5258D8348E698CEB9F4D4292622042DB446" -"F75F4B65C1FB7A317257FA354BB5A45E789AEC254EAECE11F80A53E3B513822491DB" -"D9399DEC4807A2A3A10360129AC93F4A42388D3BF20B310DD0E9E9F4BE07FC88D53A" -"78A26091E0AB506A70813712CCBFBDD440A69A906E650EE090FDD6A42A95AC1A414D" -"317F1A9F781E6A30E9EE142ECDA45A1E3454A1417A7B9A613DA90831CF88EA1F2E82" -"41AE88CC4053220903C2E05BCDD42F02B8CF8868F84C64C5858BAD356143C5494607" -"EE22E11650148BAF65A985F6FC4CA540A55697F2B5AA95D6B8CF96EF638416DE1DD6" -"3BA9E2C09E22D03E75B60BE456C642F86B82A709253E5E087B507DE3A45F8392423F" -"4DBC284E8DC88C43CA77BC8DCEFB6129A59025F80F90FF978116DEBB9209E306FBB9" -"1B6111F8B8CFACB7C7C9BC12691C22EE88303E1713F1DFCEB622B8EA102F6365678B" -"C580ED87225467AA78E875868BD53B17574BA59305BC1AC666E4B7E9ED72FCFC200E" -"189D98FC8C5C7533739C53F52DDECDDFA5A8668BFBD40DABC9640F8FCAE58F532940" -"8162261320A25589E9FB51B50F80056471F24B7E1AEC35D1356FC2747FFC13A04B34" -"24FCECE10880BD9D97CA8CDEB2F5969BF4F30256EB5ED2BCD1DC64BDC2EE65217848" -"48A37FB13F84ED4FB7ACA18C4639EE64309BDD3D552AEB4AAF44295943DC1229A497" -"A84A"; - -const char *ms_mp345 = "1E71E292"; - -const char *d_mp12 = "-AAFBA6A55DD183FD854A60E"; -const char *d_mp34 = "119366B05E606A9B1E73A6D8944CC1366B0C4E0D4"; -const char *d_mp5d4 = "F5952EAB"; -const char *d_mp6d2 = "-1"; -const char *md_mp345 = "26596B86"; - -const char *q_mp42 = "-95825A1FFA1A155D5"; -const char *r_mp42 = "-6312E99D7700A3DCB32ADF2"; -const char *q_mp45a = "15344CDA3D841F661D2B61B6EDF7828CE36"; -const char *r_mp45a = "-47C47B"; -const char *q_mp7c2 = "75FD3890E6C1C67321CE62CEEDA65F79"; -const char *q_mp3d6 = "8CAFD53C272BD6FE8B0847BDC3B539EFAB5C3"; -const char *r_mp3d6 = "1E5"; -const char *r_mp5d5 = "1257"; -const char *r_mp47 = "B3A9018D970281A90FB729A181D95CB8"; -const char *q_mp1404 = -"-1B994D869142D3EF6123A3CBBC3C0114FA071CFCEEF4B7D231D65591D32501AD80F" -"FF49AE4EC80514CC071EF6B42521C2508F4CB2FEAD69A2D2EF3934087DCAF88CC4C4" -"659F1CA8A7F4D36817D802F778F1392337FE36302D6865BF0D4645625DF8BB044E19" -"930635BE2609FAC8D99357D3A9F81F2578DE15A300964188292107DAC980E0A08CD7" -"E938A2135FAD45D50CB1D8C2D4C4E60C27AB98B9FBD7E4DBF752C57D2674520E4BB2" -"7E42324C0EFE84FB3E38CF6950E699E86FD45FE40D428400F2F94EDF7E94FAE10B45" -"89329E1BF61E5A378C7B31C9C6A234F8254D4C24823B84D0BF8D671D8BC9154DFAC9" -"49BD8ACABD6BD32DD4DC587F22C86153CB3954BDF7C2A890D623642492C482CF3E2C" -"776FC019C3BBC61688B485E6FD35D6376089C1E33F880E84C4E51E8ABEACE1B3FB70" -"3EAD0E28D2D44E7F1C0A859C840775E94F8C1369D985A3C5E8114B21D68B3CBB75D2" -"791C586153C85B90CAA483E57A40E2D97950AAB84920A4396C950C87C7FFFE748358" -"42A0BF65445B26D40F05BE164B822CA96321F41D85A289C5F5CD5F438A78704C9683" -"422299D21899A22F853B0C93081CC9925E350132A0717A611DD932A68A0ACC6E4C7F" -"7F685EF8C1F4910AEA5DC00BB5A36FCA07FFEAA490C547F6E14A08FE87041AB803E1" -"BD9E23E4D367A2C35762F209073DFF48F3"; -const char *r_mp1404 = "12FF98621ABF63144BFFC3207AC8FC10D8D1A09"; - -const char *q_mp13c = - "34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342" - "BDAB6163963CD5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45"; -const char *r_mp13c = "F2B050D226E6DA88"; -const char *q_mp9c16 = "F74A2876A1432698923B0767DA19DCF3D71795E"; -const char *r_mp9c16 = "E"; - -const char *e_mp5d9 = "A8FD7145E727A20E52E73D22990D35D158090307A" - "13A5215AAC4E9AB1E96BD34E531209E03310400"; -const char *e_mp78 = "AA5F72C737DFFD8CCD108008BFE7C79ADC01A819B" - "32B75FB82EC0FB8CA83311DA36D4063F1E57857A2" - "1AB226563D84A15BB63CE975FF1453BD6750C58D9" - "D113175764F5D0B3C89B262D4702F4D9640A3"; -const char *me_mp817 = "E504493ACB02F7F802B327AB13BF25"; -const char *me_mp5d47 = "1D45ED0D78F2778157992C951DD2734C"; -const char *me_mp1512 = "FB5B2A28D902B9D9"; -const char *me_mp161718 = "423C6AC6DBD74"; -const char *me_mp5114 = -"64F0F72807993578BBA3C7C36FFB184028F9EB9A810C92079E1498D8A80FC848E1F0" -"25F1DE43B7F6AC063F5CC29D8A7C2D7A66269D72BF5CDC327AF88AF8EF9E601DCB0A" -"3F35BFF3525FB1B61CE3A25182F17C0A0633B4089EA15BDC47664A43FEF639748AAC" -"19CF58E83D8FA32CD10661D2D4210CC84792937E6F36CB601851356622E63ADD4BD5" -"542412C2E0C4958E51FD2524AABDC7D60CFB5DB332EEC9DC84210F10FAE0BA2018F2" -"14C9D6867C9D6E49CF28C18D06CE009FD4D04BFC8837C3FAAA773F5CCF6DED1C22DE" -"181786AFE188540586F2D74BF312E595244E6936AE52E45742109BAA76C36F2692F5" -"CEF97AD462B138BE92721194B163254CBAAEE9B9864B21CCDD5375BCAD0D24132724" -"113D3374B4BCF9AA49BA5ACBC12288C0BCF46DCE6CB4A241A91BD559B130B6E9CD3D" -"D7A2C8B280C2A278BA9BF5D93244D563015C9484B86D9FEB602501DC16EEBC3EFF19" -"53D7999682BF1A1E3B2E7B21F4BDCA3C355039FEF55B9C0885F98DC355CA7A6D8ECF" -"5F7F1A6E11A764F2343C823B879B44616B56BF6AE3FA2ACF5483660E618882018E3F" -"C8459313BACFE1F93CECC37B2576A5C0B2714BD3EEDEEC22F0E7E3E77B11396B9B99" -"D683F2447A4004BBD4A57F6A616CDDFEC595C4FC19884CC2FC21CF5BF5B0B81E0F83" -"B9DDA0CF4DFF35BB8D31245912BF4497FD0BD95F0C604E26EA5A8EA4F5EAE870A5BD" -"FE8C"; - -const char *e_mpc2d3 = "100000000000000000000000000000000"; - -const char *t_mp9 = "FB9B6E32FF0452A34746"; -const char *i_mp27 = "B6AD8DCCDAF92B6FE57D062FFEE3A99"; -const char *i_mp2019 = -"BDF3D88DC373A63EED92903115B03FC8501910AF68297B4C41870AED3EA9F839"; -/* "15E3FE09E8AE5523AABA197BD2D16318D3CA148EDF4AE1C1C52FC96AFAF5680B"; */ - - -const char *t_mp15 = -"795853094E59B0008093BCA8DECF68587C64BDCA2F3F7F8963DABC12F1CFFFA9B8C4" -"365232FD4751870A0EF6CA619287C5D8B7F1747D95076AB19645EF309773E9EACEA0" -"975FA4AE16251A8DA5865349C3A903E3B8A2C0DEA3C0720B6020C7FED69AFF62BB72" -"10FAC443F9FFA2950776F949E819260C2AF8D94E8A1431A40F8C23C1973DE5D49AA2" -"0B3FF5DA5C1D5324E712A78FF33A9B1748F83FA529905924A31DF38643B3F693EF9B" -"58D846BB1AEAE4523ECC843FF551C1B300A130B65C1677402778F98C51C10813250E" -"2496882877B069E877B59740DC1226F18A5C0F66F64A5F59A9FAFC5E9FC45AEC0E7A" -"BEE244F7DD3AC268CF512A0E52E4F5BE5B94"; - -const char *g_mp71 = "1"; -const char *g_mp25 = "7"; -const char *l_mp1011 = "C589E3D7D64A6942A000"; - -/* mp9 in radices from 5 to 64 inclusive */ -#define LOW_RADIX 5 -#define HIGH_RADIX 64 -const char *v_mp9[] = { - "404041130042310320100141302000203430214122130002340212132414134210033", - "44515230120451152500101352430105520150025145320010504454125502", - "644641136612541136016610100564613624243140151310023515322", - "173512120732412062323044435407317550316717172705712756", - "265785018434285762514442046172754680368422060744852", - "1411774500397290569709059837552310354075408897518", - "184064268501499311A17746095910428222A241708032A", - "47706011B225950B02BB45602AA039893118A85950892", - "1A188C826B982353CB58422563AC602B783101671A86", - "105957B358B89B018958908A9114BC3DDC410B77982", - "CB7B3387E23452178846C55DD9D70C7CA9AEA78E8", - "F74A2876A1432698923B0767DA19DCF3D71795EE", - "17BF7C3673B76D7G7A5GA836277296F806E7453A", - "2EBG8HH3HFA6185D6H0596AH96G24C966DD3HG2", - "6G3HGBFEG8I3F25EAF61B904EIA40CFDH2124F", - "10AHC3D29EBHDF3HD97905CG0JA8061855C3FI", - "3BA5A55J5K699B2D09C38A4B237CH51IHA132", - "EDEA90DJ0B5CB3FGG1C8587FEB99D3C143CA", - "31M26JI1BBD56K3I028MML4EEDMAJK60LGLE", - "GGG5M3142FKKG82EJ28111D70EMHC241E4E", - "4446F4D5H10982023N297BF0DKBBHLLJB0I", - "12E9DEEOBMKAKEP0IM284MIP7FO1O521M46", - "85NN0HD48NN2FDDB1F5BMMKIB8CK20MDPK", - "2D882A7A0O0JPCJ4APDRIB77IABAKDGJP2", - "MFMCI0R7S27AAA3O3L2S8K44HKA7O02CN", - "7IGQS73FFSHC50NNH44B6PTTNLC3M6H78", - "2KLUB3U9850CSN6ANIDNIF1LB29MJ43LH", - "UT52GTL18CJ9H4HR0TJTK6ESUFBHF5FE", - "BTVL87QQBMUGF8PFWU4W3VU7U922QTMW", - "4OG10HW0MSWJBIDEE2PDH24GA7RIHIAA", - "1W8W9AX2DRUX48GXOLMK0PE42H0FEUWN", - "SVWI84VBH069WR15W1U2VTK06USY8Z2", - "CPTPNPDa5TYCPPNLALENT9IMX2GL0W2", - "5QU21UJMRaUYYYYYN6GHSMPOYOXEEUY", - "2O2Q7C6RPPB1SXJ9bR4035SPaQQ3H2W", - "18d994IbT4PHbD7cGIPCRP00bbQO0bc", - "NcDUEEWRO7XT76260WGeBHPVa72RdA", - "BbX2WCF9VfSB5LPdJAdeXKV1fd6LC2", - "60QDKW67P4JSQaTdQg7JE9ISafLaVU", - "33ba9XbDbRdNF4BeDB2XYMhAVDaBdA", - "1RIPZJA8gT5L5H7fTcaRhQ39geMMTc", - "d65j70fBATjcDiidPYXUGcaBVVLME", - "LKA9jhPabDG612TXWkhfT2gMXNIP2", - "BgNaYhjfT0G8PBcYRP8khJCR3C9QE", - "6Wk8RhJTAgDh10fYAiUVB1aM0HacG", - "3dOCjaf78kd5EQNViUZWj3AfFL90I", - "290VWkL3aiJoW4MBbHk0Z0bDo22Ni", - "1DbDZ1hpPZNUDBUp6UigcJllEdC26", - "dFSOLBUM7UZX8Vnc6qokGIOiFo1h", - "NcoUYJOg0HVmKI9fR2ag0S8R2hrK", - "EOpiJ5Te7oDe2pn8ZhAUKkhFHlZh", - "8nXK8rp8neV8LWta1WDgd1QnlWsU", - "5T3d6bcSBtHgrH9bCbu84tblaa7r", - "3PlUDIYUvMqOVCir7AtquK5dWanq", - "2A70gDPX2AtiicvIGGk9poiMtgvu", - "1MjiRxjk10J6SVAxFguv9kZiUnIc", - "rpre2vIDeb4h3sp50r1YBbtEx9L", - "ZHcoip0AglDAfibrsUcJ9M1C8fm", - "NHP18+eoe6uU54W49Kc6ZK7+bT2", - "FTAA7QXGoQOaZi7PzePtFFN5vNk" -}; - -const unsigned char b_mp4[] = { - 0x01, -#if MP_DIGIT_MAX > MP_32BIT_MAX - 0x00, 0x00, 0x00, 0x00, -#endif - 0x63, 0xDB, 0xC2, 0x26, - 0x5B, 0x88, 0x26, 0x8D, - 0xC8, 0x01, 0xC1, 0x0E, - 0xA6, 0x84, 0x76, 0xB7, - 0xBD, 0xE0, 0x09, 0x0F -}; - -/* Search for a test suite name in the names table */ -int find_name(char *name); -void reason(char *fmt, ...); - -/*------------------------------------------------------------------------*/ -/*------------------------------------------------------------------------*/ - -char g_intbuf[4096]; /* buffer for integer comparison */ -char a_intbuf[4096]; /* buffer for integer comparison */ -int g_verbose = 1; /* print out reasons for failure? */ -int res; - -#define IFOK(x) { if (MP_OKAY > (res = (x))) { \ - reason("test %s failed: error %d\n", #x, res); return 1; }} - -int main(int argc, char *argv[]) -{ - int which, res; - - srand((unsigned int)time(NULL)); - - if (argc < 2) { - fprintf(stderr, "Usage: %s <test-suite> | list\n" - "Type '%s help' for assistance\n", argv[0], argv[0]); - return 2; - } else if(argc > 2) { - if(strcmp(argv[2], "quiet") == 0) - g_verbose = 0; - } - - if(strcmp(argv[1], "help") == 0) { - fprintf(stderr, "Help for mpi-test\n\n" - "This program is a test driver for the MPI library, which\n" - "tests all the various functions in the library to make sure\n" - "they are working correctly. The syntax is:\n" - " %s <suite-name>\n" - "...where <suite-name> is the name of the test you wish to\n" - "run. To get a list of the tests, use '%s list'.\n\n" - "The program exits with a status of zero if the test passes,\n" - "or non-zero if it fails. Ordinarily, failure is accompanied\n" - "by a diagnostic message to standard error. To suppress this\n" - "add the keyword 'quiet' after the suite-name on the command\n" - "line.\n\n", argv[0], argv[0]); - return 0; - } - - if ((which = find_name(argv[1])) < 0) { - fprintf(stderr, "%s: test suite '%s' is not known\n", argv[0], argv[1]); - return 2; - } - - if((res = (g_tests[which])()) < 0) { - fprintf(stderr, "%s: test suite not implemented yet\n", argv[0]); - return 2; - } else { - return res; - } - -} - -/*------------------------------------------------------------------------*/ - -int find_name(char *name) -{ - int ix = 0; - - while(ix < g_count) { - if (strcmp(name, g_names[ix]) == 0) - return ix; - - ++ix; - } - - return -1; -} - -/*------------------------------------------------------------------------*/ - -int test_list(void) -{ - int ix; - - fprintf(stderr, "There are currently %d test suites available\n", - g_count); - - for(ix = 1; ix < g_count; ix++) - fprintf(stdout, "%-20s %s\n", g_names[ix], g_descs[ix]); - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_copy(void) -{ - mp_int a, b; - int ix; - - mp_init(&a); mp_init(&b); - - mp_read_radix(&a, mp3, 16); - mp_copy(&a, &b); - - if(SIGN(&a) != SIGN(&b) || USED(&a) != USED(&b)) { - if(SIGN(&a) != SIGN(&b)) { - reason("error: sign of original is %d, sign of copy is %d\n", - SIGN(&a), SIGN(&b)); - } else { - reason("error: original precision is %d, copy precision is %d\n", - USED(&a), USED(&b)); - } - mp_clear(&a); mp_clear(&b); - return 1; - } - - for(ix = 0; ix < USED(&b); ix++) { - if(DIGIT(&a, ix) != DIGIT(&b, ix)) { - reason("error: digit %d " DIGIT_FMT " != " DIGIT_FMT "\n", - ix, DIGIT(&a, ix), DIGIT(&b, ix)); - mp_clear(&a); mp_clear(&b); - return 1; - } - } - - mp_clear(&a); mp_clear(&b); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_exch(void) -{ - mp_int a, b; - - mp_init(&a); mp_init(&b); - mp_read_radix(&a, mp7, 16); mp_read_radix(&b, mp1, 16); - - mp_exch(&a, &b); - mp_toradix(&a, g_intbuf, 16); - - mp_clear(&a); - if(strcmp(g_intbuf, mp1) != 0) { - mp_clear(&b); - reason("error: exchange failed\n"); - return 1; - } - - mp_toradix(&b, g_intbuf, 16); - - mp_clear(&b); - if(strcmp(g_intbuf, mp7) != 0) { - reason("error: exchange failed\n"); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_zero(void) -{ - mp_int a; - - mp_init(&a); mp_read_radix(&a, mp7, 16); - mp_zero(&a); - - if(USED(&a) != 1 || DIGIT(&a, 1) != 0) { - mp_toradix(&a, g_intbuf, 16); - reason("error: result is %s\n", g_intbuf); - mp_clear(&a); - return 1; - } - - mp_clear(&a); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_set(void) -{ - mp_int a; - - /* Test single digit set */ - mp_init(&a); mp_set(&a, 5); - if(DIGIT(&a, 0) != 5) { - mp_toradix(&a, g_intbuf, 16); - reason("error: result is %s, expected 5\n", g_intbuf); - mp_clear(&a); - return 1; - } - - /* Test integer set */ - mp_set_int(&a, -4938110); - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); - if(strcmp(g_intbuf, mp5a) != 0) { - reason("error: result is %s, expected %s\n", g_intbuf, mp5a); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_abs(void) -{ - mp_int a; - - mp_init(&a); mp_read_radix(&a, mp4, 16); - mp_abs(&a, &a); - - if(SIGN(&a) != ZPOS) { - reason("error: sign of result is negative\n"); - mp_clear(&a); - return 1; - } - - mp_clear(&a); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_neg(void) -{ - mp_int a; - mp_sign s; - - mp_init(&a); mp_read_radix(&a, mp4, 16); - - s = SIGN(&a); - mp_neg(&a, &a); - if(SIGN(&a) == s) { - reason("error: sign of result is same as sign of nonzero input\n"); - mp_clear(&a); - return 1; - } - - mp_clear(&a); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_add_d(void) -{ - mp_int a; - - mp_init(&a); - - mp_read_radix(&a, mp5, 16); - mp_add_d(&a, md4, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, s_mp5d4) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, s_mp5d4); - mp_clear(&a); - return 1; - } - - mp_read_radix(&a, mp2, 16); - mp_add_d(&a, md5, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, s_mp2d5) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, s_mp2d5); - mp_clear(&a); - return 1; - } - - mp_clear(&a); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_add(void) -{ - mp_int a, b; - int res = 0; - - mp_init(&a); mp_init(&b); - - mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp3, 16); - mp_add(&a, &b, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, s_mp13) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, s_mp13); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp4, 16); - mp_add(&a, &b, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, s_mp34) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, s_mp34); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp4, 16); mp_read_radix(&b, mp6, 16); - mp_add(&a, &b, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, s_mp46) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, s_mp46); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp14, 16); mp_read_radix(&b, mp15, 16); - mp_add(&a, &b, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, s_mp1415) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, s_mp1415); - res = 1; - } - - CLEANUP: - mp_clear(&a); mp_clear(&b); - return res; -} - -/*------------------------------------------------------------------------*/ - -int test_sub_d(void) -{ - mp_int a; - - mp_init(&a); - mp_read_radix(&a, mp5, 16); - - mp_sub_d(&a, md4, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, d_mp5d4) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, d_mp5d4); - mp_clear(&a); - return 1; - } - - mp_read_radix(&a, mp6, 16); - - mp_sub_d(&a, md2, &a); - mp_toradix(&a, g_intbuf, 16); - - mp_clear(&a); - if(strcmp(g_intbuf, d_mp6d2) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, d_mp6d2); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_sub(void) -{ - mp_int a, b; - - mp_init(&a); mp_init(&b); - - mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp2, 16); - mp_sub(&a, &b, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, d_mp12) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, d_mp12); - mp_clear(&a); mp_clear(&b); - return 1; - } - - mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16); - mp_sub(&a, &b, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, d_mp34) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, d_mp34); - mp_clear(&a); mp_clear(&b); - return 1; - } - - mp_clear(&a); mp_clear(&b); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_mul_d(void) -{ - mp_int a; - - mp_init(&a); - mp_read_radix(&a, mp1, 16); - - IFOK( mp_mul_d(&a, md4, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, p_mp1d4) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, p_mp1d4); - mp_clear(&a); - return 1; - } - - mp_read_radix(&a, mp8, 16); - IFOK( mp_mul_d(&a, md6, &a) ); - mp_toradix(&a, g_intbuf, 16); - - mp_clear(&a); - if(strcmp(g_intbuf, p_mp8d6) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, p_mp8d6); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_mul(void) -{ - mp_int a, b; - int res = 0; - - mp_init(&a); mp_init(&b); - mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp2, 16); - - IFOK( mp_mul(&a, &b, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, p_mp12) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, p_mp12); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16); - IFOK( mp_mul(&a, &b, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, p_mp34) !=0) { - reason("error: computed %s, expected %s\n", g_intbuf, p_mp34); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp5, 16); mp_read_radix(&b, mp7, 16); - IFOK( mp_mul(&a, &b, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, p_mp57) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, p_mp57); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp11, 16); mp_read_radix(&b, mp13, 16); - IFOK( mp_mul(&a, &b, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, p_mp1113) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, p_mp1113); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp14, 16); mp_read_radix(&b, mp15, 16); - IFOK( mp_mul(&a, &b, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, p_mp1415) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, p_mp1415); - res = 1; - } - mp_read_radix(&a, mp21, 10); mp_read_radix(&b, mp21, 10); - - IFOK( mp_mul(&a, &b, &a) ); - mp_toradix(&a, g_intbuf, 10); - - if(strcmp(g_intbuf, p_mp2121) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, p_mp2121); - res = 1; goto CLEANUP; - } - - CLEANUP: - mp_clear(&a); mp_clear(&b); - return res; - -} - -/*------------------------------------------------------------------------*/ - -int test_sqr(void) -{ - mp_int a; - - mp_init(&a); mp_read_radix(&a, mp2, 16); - - mp_sqr(&a, &a); - mp_toradix(&a, g_intbuf, 16); - - mp_clear(&a); - if(strcmp(g_intbuf, p_mp22) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, p_mp22); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_div_d(void) -{ - mp_int a, q; - mp_digit r; - int err = 0; - - mp_init(&a); mp_init(&q); - mp_read_radix(&a, mp3, 16); - - IFOK( mp_div_d(&a, md6, &q, &r) ); - mp_toradix(&q, g_intbuf, 16); - - if(strcmp(g_intbuf, q_mp3d6) != 0) { - reason("error: computed q = %s, expected %s\n", g_intbuf, q_mp3d6); - ++err; - } - - sprintf(g_intbuf, ZS_DIGIT_FMT, r); - - if(strcmp(g_intbuf, r_mp3d6) != 0) { - reason("error: computed r = %s, expected %s\n", g_intbuf, r_mp3d6); - ++err; - } - - mp_read_radix(&a, mp9, 16); - IFOK( mp_div_d(&a, 16, &q, &r) ); - mp_toradix(&q, g_intbuf, 16); - - if(strcmp(g_intbuf, q_mp9c16) != 0) { - reason("error: computed q = %s, expected %s\n", g_intbuf, q_mp9c16); - ++err; - } - - sprintf(g_intbuf, ZS_DIGIT_FMT, r); - - if(strcmp(g_intbuf, r_mp9c16) != 0) { - reason("error: computed r = %s, expected %s\n", g_intbuf, r_mp9c16); - ++err; - } - - mp_clear(&a); mp_clear(&q); - return err; -} - -/*------------------------------------------------------------------------*/ - -int test_div_2(void) -{ - mp_int a; - - mp_init(&a); mp_read_radix(&a, mp7, 16); - IFOK( mp_div_2(&a, &a) ); - mp_toradix(&a, g_intbuf, 16); - - mp_clear(&a); - if(strcmp(g_intbuf, q_mp7c2) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, q_mp7c2); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_div_2d(void) -{ - mp_int a, q, r; - - mp_init(&q); mp_init(&r); - mp_init(&a); mp_read_radix(&a, mp13, 16); - - IFOK( mp_div_2d(&a, 64, &q, &r) ); - mp_clear(&a); - - mp_toradix(&q, g_intbuf, 16); - - if(strcmp(g_intbuf, q_mp13c) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, q_mp13c); - mp_clear(&q); mp_clear(&r); - return 1; - } - - mp_clear(&q); - - mp_toradix(&r, g_intbuf, 16); - if(strcmp(g_intbuf, r_mp13c) != 0) { - reason("error, computed %s, expected %s\n", g_intbuf, r_mp13c); - mp_clear(&r); - return 1; - } - - mp_clear(&r); - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_div(void) -{ - mp_int a, b, r; - int err = 0; - - mp_init(&a); mp_init(&b); mp_init(&r); - - mp_read_radix(&a, mp4, 16); mp_read_radix(&b, mp2, 16); - IFOK( mp_div(&a, &b, &a, &r) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, q_mp42) != 0) { - reason("error: test 1 computed quot %s, expected %s\n", g_intbuf, q_mp42); - ++err; - } - - mp_toradix(&r, g_intbuf, 16); - - if(strcmp(g_intbuf, r_mp42) != 0) { - reason("error: test 1 computed rem %s, expected %s\n", g_intbuf, r_mp42); - ++err; - } - - mp_read_radix(&a, mp4, 16); mp_read_radix(&b, mp5a, 16); - IFOK( mp_div(&a, &b, &a, &r) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, q_mp45a) != 0) { - reason("error: test 2 computed quot %s, expected %s\n", g_intbuf, q_mp45a); - ++err; - } - - mp_toradix(&r, g_intbuf, 16); - - if(strcmp(g_intbuf, r_mp45a) != 0) { - reason("error: test 2 computed rem %s, expected %s\n", g_intbuf, r_mp45a); - ++err; - } - - mp_read_radix(&a, mp14, 16); mp_read_radix(&b, mp4, 16); - IFOK( mp_div(&a, &b, &a, &r) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, q_mp1404) != 0) { - reason("error: test 3 computed quot %s, expected %s\n", g_intbuf, q_mp1404); - ++err; - } - - mp_toradix(&r, g_intbuf, 16); - - if(strcmp(g_intbuf, r_mp1404) != 0) { - reason("error: test 3 computed rem %s, expected %s\n", g_intbuf, r_mp1404); - ++err; - } - - mp_clear(&a); mp_clear(&b); mp_clear(&r); - - return err; -} - -/*------------------------------------------------------------------------*/ - -int test_expt_d(void) -{ - mp_int a; - - mp_init(&a); mp_read_radix(&a, mp5, 16); - mp_expt_d(&a, md9, &a); - mp_toradix(&a, g_intbuf, 16); - - mp_clear(&a); - if(strcmp(g_intbuf, e_mp5d9) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, e_mp5d9); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_expt(void) -{ - mp_int a, b; - - mp_init(&a); mp_init(&b); - mp_read_radix(&a, mp7, 16); mp_read_radix(&b, mp8, 16); - - mp_expt(&a, &b, &a); - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); mp_clear(&b); - - if(strcmp(g_intbuf, e_mp78) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, e_mp78); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_2expt(void) -{ - mp_int a; - - mp_init(&a); - mp_2expt(&a, md3); - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); - - if(strcmp(g_intbuf, e_mpc2d3) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, e_mpc2d3); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_sqrt(void) -{ - mp_int a; - int res = 0; - - mp_init(&a); mp_read_radix(&a, mp9, 16); - mp_sqrt(&a, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, t_mp9) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, t_mp9); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp15, 16); - mp_sqrt(&a, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, t_mp15) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, t_mp15); - res = 1; - } - - CLEANUP: - mp_clear(&a); - return res; -} - -/*------------------------------------------------------------------------*/ - -int test_mod_d(void) -{ - mp_int a; - mp_digit r; - - mp_init(&a); mp_read_radix(&a, mp5, 16); - IFOK( mp_mod_d(&a, md5, &r) ); - sprintf(g_intbuf, ZS_DIGIT_FMT, r); - mp_clear(&a); - - if(strcmp(g_intbuf, r_mp5d5) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, r_mp5d5); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_mod(void) -{ - mp_int a, m; - - mp_init(&a); mp_init(&m); - mp_read_radix(&a, mp4, 16); mp_read_radix(&m, mp7, 16); - IFOK( mp_mod(&a, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); mp_clear(&m); - - if(strcmp(g_intbuf, r_mp47) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, r_mp47); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_addmod(void) -{ - mp_int a, b, m; - - mp_init(&a); mp_init(&b); mp_init(&m); - mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16); - mp_read_radix(&m, mp5, 16); - - IFOK( mp_addmod(&a, &b, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); mp_clear(&b); mp_clear(&m); - - if(strcmp(g_intbuf, ms_mp345) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, ms_mp345); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_submod(void) -{ - mp_int a, b, m; - - mp_init(&a); mp_init(&b); mp_init(&m); - mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16); - mp_read_radix(&m, mp5, 16); - - IFOK( mp_submod(&a, &b, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); mp_clear(&b); mp_clear(&m); - - if(strcmp(g_intbuf, md_mp345) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, md_mp345); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_mulmod(void) -{ - mp_int a, b, m; - - mp_init(&a); mp_init(&b); mp_init(&m); - mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16); - mp_read_radix(&m, mp5, 16); - - IFOK( mp_mulmod(&a, &b, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); mp_clear(&b); mp_clear(&m); - - if(strcmp(g_intbuf, mp_mp345) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, mp_mp345); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_sqrmod(void) -{ - mp_int a, m; - - mp_init(&a); mp_init(&m); - mp_read_radix(&a, mp3, 16); mp_read_radix(&m, mp5, 16); - - IFOK( mp_sqrmod(&a, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); mp_clear(&m); - - if(strcmp(g_intbuf, mp_mp335) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, mp_mp335); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_exptmod(void) -{ - mp_int a, b, m; - int res = 0; - - mp_init(&a); mp_init(&b); mp_init(&m); - mp_read_radix(&a, mp8, 16); mp_read_radix(&b, mp1, 16); - mp_read_radix(&m, mp7, 16); - - IFOK( mp_exptmod(&a, &b, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, me_mp817) != 0) { - reason("case 1: error: computed %s, expected %s\n", g_intbuf, me_mp817); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp5, 16); - mp_read_radix(&m, mp12, 16); - - IFOK( mp_exptmod(&a, &b, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, me_mp1512) != 0) { - reason("case 2: error: computed %s, expected %s\n", g_intbuf, me_mp1512); - res = 1; goto CLEANUP; - } - - mp_read_radix(&a, mp5, 16); mp_read_radix(&b, mp1, 16); - mp_read_radix(&m, mp14, 16); - - IFOK( mp_exptmod(&a, &b, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, me_mp5114) != 0) { - reason("case 3: error: computed %s, expected %s\n", g_intbuf, me_mp5114); - res = 1; - } - - mp_read_radix(&a, mp16, 16); mp_read_radix(&b, mp17, 16); - mp_read_radix(&m, mp18, 16); - - IFOK( mp_exptmod(&a, &b, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, me_mp161718) != 0) { - reason("case 4: error: computed %s, expected %s\n", g_intbuf, me_mp161718); - res = 1; - } - - CLEANUP: - mp_clear(&a); mp_clear(&b); mp_clear(&m); - return res; -} - -/*------------------------------------------------------------------------*/ - -int test_exptmod_d(void) -{ - mp_int a, m; - - mp_init(&a); mp_init(&m); - mp_read_radix(&a, mp5, 16); mp_read_radix(&m, mp7, 16); - - IFOK( mp_exptmod_d(&a, md4, &m, &a) ); - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); mp_clear(&m); - - if(strcmp(g_intbuf, me_mp5d47) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, me_mp5d47); - return 1; - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_invmod(void) -{ - mp_int a, m, c; - mp_int p1, p2, p3, p4, p5; - mp_int t1, t2, t3, t4; - mp_err res; - - /* 5 128-bit primes. */ - static const char ivp1[] = { "AAD8A5A2A2BEF644BAEE7DB0CA643719" }; - static const char ivp2[] = { "CB371AD2B79A90BCC88D0430663E40B9" }; - static const char ivp3[] = { "C6C818D4DF2618406CA09280C0400099" }; - static const char ivp4[] = { "CE949C04512E68918006B1F0D7E93F27" }; - static const char ivp5[] = { "F8EE999B6416645040687440E0B89F51" }; - - mp_init(&a); mp_init(&m); - mp_read_radix(&a, mp2, 16); mp_read_radix(&m, mp7, 16); - - IFOK( mp_invmod(&a, &m, &a) ); - - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); mp_clear(&m); - - if(strcmp(g_intbuf, i_mp27) != 0) { - reason("error: invmod test 1 computed %s, expected %s\n", g_intbuf, i_mp27); - return 1; - } - - mp_init(&a); mp_init(&m); - mp_read_radix(&a, mp20, 16); mp_read_radix(&m, mp19, 16); - - IFOK( mp_invmod(&a, &m, &a) ); - - mp_toradix(&a, g_intbuf, 16); - mp_clear(&a); mp_clear(&m); - - if(strcmp(g_intbuf, i_mp2019) != 0) { - reason("error: invmod test 2 computed %s, expected %s\n", g_intbuf, i_mp2019); - return 1; - } - -/* Need the following test cases: - Odd modulus - - a is odd, relatively prime to m - - a is odd, not relatively prime to m - - a is even, relatively prime to m - - a is even, not relatively prime to m - Even modulus - - a is even (should fail) - - a is odd, not relatively prime to m - - a is odd, relatively prime to m, - m is not a power of 2 - - m has factor 2**k, k < 32 - - m has factor 2**k, k > 32 - m is a power of 2, 2**k - - k < 32 - - k > 32 -*/ - - mp_init(&a); mp_init(&m); mp_init(&c); - mp_init(&p1); mp_init(&p2); mp_init(&p3); mp_init(&p4); mp_init(&p5); - mp_init(&t1); mp_init(&t2); mp_init(&t3); mp_init(&t4); - - mp_read_radix(&p1, ivp1, 16); - mp_read_radix(&p2, ivp2, 16); - mp_read_radix(&p3, ivp3, 16); - mp_read_radix(&p4, ivp4, 16); - mp_read_radix(&p5, ivp5, 16); - - IFOK( mp_2expt(&t2, 68) ); /* t2 = 2**68 */ - IFOK( mp_2expt(&t3, 128) ); /* t3 = 2**128 */ - IFOK( mp_2expt(&t4, 31) ); /* t4 = 2**31 */ - -/* test 3: Odd modulus - a is odd, relatively prime to m */ - - IFOK( mp_mul(&p1, &p2, &a) ); - IFOK( mp_mul(&p3, &p4, &m) ); - IFOK( mp_invmod(&a, &m, &t1) ); - IFOK( mp_invmod_xgcd(&a, &m, &c) ); - - if (mp_cmp(&t1, &c) != 0) { - mp_toradix(&t1, g_intbuf, 16); - mp_toradix(&c, a_intbuf, 16); - reason("error: invmod test 3 computed %s, expected %s\n", - g_intbuf, a_intbuf); - return 1; - } - mp_clear(&a); mp_clear(&t1); mp_clear(&c); - mp_init(&a); mp_init(&t1); mp_init(&c); - -/* test 4: Odd modulus - a is odd, NOT relatively prime to m */ - - IFOK( mp_mul(&p1, &p3, &a) ); - /* reuse same m as before */ - - res = mp_invmod_xgcd(&a, &m, &c); - if (res != MP_UNDEF) - goto CLEANUP4; - - res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */ - if (res != MP_UNDEF) { -CLEANUP4: - reason("error: invmod test 4 succeeded, should have failed.\n"); - return 1; - } - mp_clear(&a); mp_clear(&t1); mp_clear(&c); - mp_init(&a); mp_init(&t1); mp_init(&c); - -/* test 5: Odd modulus - a is even, relatively prime to m */ - - IFOK( mp_mul(&p1, &t2, &a) ); - /* reuse m */ - IFOK( mp_invmod(&a, &m, &t1) ); - IFOK( mp_invmod_xgcd(&a, &m, &c) ); - - if (mp_cmp(&t1, &c) != 0) { - mp_toradix(&t1, g_intbuf, 16); - mp_toradix(&c, a_intbuf, 16); - reason("error: invmod test 5 computed %s, expected %s\n", - g_intbuf, a_intbuf); - return 1; - } - mp_clear(&a); mp_clear(&t1); mp_clear(&c); - mp_init(&a); mp_init(&t1); mp_init(&c); - -/* test 6: Odd modulus - a is odd, NOT relatively prime to m */ - - /* reuse t2 */ - IFOK( mp_mul(&t2, &p3, &a) ); - /* reuse same m as before */ - - res = mp_invmod_xgcd(&a, &m, &c); - if (res != MP_UNDEF) - goto CLEANUP6; - - res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */ - if (res != MP_UNDEF) { -CLEANUP6: - reason("error: invmod test 6 succeeded, should have failed.\n"); - return 1; - } - mp_clear(&a); mp_clear(&m); mp_clear(&c); mp_clear(&t1); - mp_init(&a); mp_init(&m); mp_init(&c); mp_init(&t1); - -/* test 7: Even modulus, even a, should fail */ - - IFOK( mp_mul(&p3, &t3, &m) ); /* even m */ - /* reuse t2 */ - IFOK( mp_mul(&p1, &t2, &a) ); /* even a */ - - res = mp_invmod_xgcd(&a, &m, &c); - if (res != MP_UNDEF) - goto CLEANUP7; - - res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */ - if (res != MP_UNDEF) { -CLEANUP7: - reason("error: invmod test 7 succeeded, should have failed.\n"); - return 1; - } - mp_clear(&a); mp_clear(&c); mp_clear(&t1); - mp_init(&a); mp_init(&c); mp_init(&t1); - -/* test 8: Even modulus - a is odd, not relatively prime to m */ - - /* reuse m */ - IFOK( mp_mul(&p3, &p1, &a) ); /* even a */ - - res = mp_invmod_xgcd(&a, &m, &c); - if (res != MP_UNDEF) - goto CLEANUP8; - - res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */ - if (res != MP_UNDEF) { -CLEANUP8: - reason("error: invmod test 8 succeeded, should have failed.\n"); - return 1; - } - mp_clear(&a); mp_clear(&m); mp_clear(&c); mp_clear(&t1); - mp_init(&a); mp_init(&m); mp_init(&c); mp_init(&t1); - -/* test 9: Even modulus - m has factor 2**k, k < 32 - * - a is odd, relatively prime to m, - */ - IFOK( mp_mul(&p3, &t4, &m) ); /* even m */ - IFOK( mp_mul(&p1, &p2, &a) ); - IFOK( mp_invmod(&a, &m, &t1) ); - IFOK( mp_invmod_xgcd(&a, &m, &c) ); - - if (mp_cmp(&t1, &c) != 0) { - mp_toradix(&t1, g_intbuf, 16); - mp_toradix(&c, a_intbuf, 16); - reason("error: invmod test 9 computed %s, expected %s\n", - g_intbuf, a_intbuf); - return 1; - } - mp_clear(&m); mp_clear(&t1); mp_clear(&c); - mp_init(&m); mp_init(&t1); mp_init(&c); - -/* test 10: Even modulus - m has factor 2**k, k > 32 - * - a is odd, relatively prime to m, - */ - IFOK( mp_mul(&p3, &t3, &m) ); /* even m */ - /* reuse a */ - IFOK( mp_invmod(&a, &m, &t1) ); - IFOK( mp_invmod_xgcd(&a, &m, &c) ); - - if (mp_cmp(&t1, &c) != 0) { - mp_toradix(&t1, g_intbuf, 16); - mp_toradix(&c, a_intbuf, 16); - reason("error: invmod test 10 computed %s, expected %s\n", - g_intbuf, a_intbuf); - return 1; - } - mp_clear(&t1); mp_clear(&c); - mp_init(&t1); mp_init(&c); - -/* test 11: Even modulus - m is a power of 2, 2**k | k < 32 - * - a is odd, relatively prime to m, - */ - IFOK( mp_invmod(&a, &t4, &t1) ); - IFOK( mp_invmod_xgcd(&a, &t4, &c) ); - - if (mp_cmp(&t1, &c) != 0) { - mp_toradix(&t1, g_intbuf, 16); - mp_toradix(&c, a_intbuf, 16); - reason("error: invmod test 11 computed %s, expected %s\n", - g_intbuf, a_intbuf); - return 1; - } - mp_clear(&t1); mp_clear(&c); - mp_init(&t1); mp_init(&c); - -/* test 12: Even modulus - m is a power of 2, 2**k | k > 32 - * - a is odd, relatively prime to m, - */ - IFOK( mp_invmod(&a, &t3, &t1) ); - IFOK( mp_invmod_xgcd(&a, &t3, &c) ); - - if (mp_cmp(&t1, &c) != 0) { - mp_toradix(&t1, g_intbuf, 16); - mp_toradix(&c, a_intbuf, 16); - reason("error: invmod test 12 computed %s, expected %s\n", - g_intbuf, a_intbuf); - return 1; - } - - mp_clear(&a); mp_clear(&m); mp_clear(&c); - mp_clear(&t1); mp_clear(&t2); mp_clear(&t3); mp_clear(&t4); - mp_clear(&p1); mp_clear(&p2); mp_clear(&p3); mp_clear(&p4); mp_clear(&p5); - - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_cmp_d(void) -{ - mp_int a; - - mp_init(&a); mp_read_radix(&a, mp8, 16); - - if(mp_cmp_d(&a, md8) >= 0) { - reason("error: %s >= " DIGIT_FMT "\n", mp8, md8); - mp_clear(&a); - return 1; - } - - mp_read_radix(&a, mp5, 16); - - if(mp_cmp_d(&a, md8) <= 0) { - reason("error: %s <= " DIGIT_FMT "\n", mp5, md8); - mp_clear(&a); - return 1; - } - - mp_read_radix(&a, mp6, 16); - - if(mp_cmp_d(&a, md1) != 0) { - reason("error: %s != " DIGIT_FMT "\n", mp6, md1); - mp_clear(&a); - return 1; - } - - mp_clear(&a); - return 0; - -} - -/*------------------------------------------------------------------------*/ - -int test_cmp_z(void) -{ - mp_int a; - - mp_init(&a); mp_read_radix(&a, mp6, 16); - - if(mp_cmp_z(&a) != 0) { - reason("error: someone thinks a zero value is non-zero\n"); - mp_clear(&a); - return 1; - } - - mp_read_radix(&a, mp1, 16); - - if(mp_cmp_z(&a) <= 0) { - reason("error: someone thinks a positive value is non-positive\n"); - mp_clear(&a); - return 1; - } - - mp_read_radix(&a, mp4, 16); - - if(mp_cmp_z(&a) >= 0) { - reason("error: someone thinks a negative value is non-negative\n"); - mp_clear(&a); - return 1; - } - - mp_clear(&a); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_cmp(void) -{ - mp_int a, b; - - mp_init(&a); mp_init(&b); - mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16); - - if(mp_cmp(&a, &b) <= 0) { - reason("error: %s <= %s\n", mp3, mp4); - mp_clear(&a); mp_clear(&b); - return 1; - } - - mp_read_radix(&b, mp3, 16); - if(mp_cmp(&a, &b) != 0) { - reason("error: %s != %s\n", mp3, mp3); - mp_clear(&a); mp_clear(&b); - return 1; - } - - mp_read_radix(&a, mp5, 16); - if(mp_cmp(&a, &b) >= 0) { - reason("error: %s >= %s\n", mp5, mp3); - mp_clear(&a); mp_clear(&b); - return 1; - } - - mp_read_radix(&a, mp5a, 16); - if(mp_cmp_int(&a, 1000000) >= 0 || - (mp_cmp_int(&a, -5000000) <= 0) || - (mp_cmp_int(&a, -4938110) != 0)) { - reason("error: long integer comparison failed (%s)", mp5a); - mp_clear(&a); mp_clear(&b); - return 1; - } - - mp_clear(&a); mp_clear(&b); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_cmp_mag(void) -{ - mp_int a, b; - - mp_init(&a); mp_init(&b); - mp_read_radix(&a, mp5, 16); mp_read_radix(&b, mp4, 16); - - if(mp_cmp_mag(&a, &b) >= 0) { - reason("error: %s >= %s\n", mp5, mp4); - mp_clear(&a); mp_clear(&b); - return 1; - } - - mp_read_radix(&b, mp5, 16); - if(mp_cmp_mag(&a, &b) != 0) { - reason("error: %s != %s\n", mp5, mp5); - mp_clear(&a); mp_clear(&b); - return 1; - } - - mp_read_radix(&a, mp1, 16); - if(mp_cmp_mag(&b, &a) >= 0) { - reason("error: %s >= %s\n", mp5, mp1); - mp_clear(&a); mp_clear(&b); - return 1; - } - - mp_clear(&a); mp_clear(&b); - return 0; - -} - -/*------------------------------------------------------------------------*/ - -int test_parity(void) -{ - mp_int a; - - mp_init(&a); mp_read_radix(&a, mp1, 16); - - if(!mp_isodd(&a)) { - reason("error: expected operand to be odd, but it isn't\n"); - mp_clear(&a); - return 1; - } - - mp_read_radix(&a, mp6, 16); - - if(!mp_iseven(&a)) { - reason("error: expected operand to be even, but it isn't\n"); - mp_clear(&a); - return 1; - } - - mp_clear(&a); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_gcd(void) -{ - mp_int a, b; - int out = 0; - - mp_init(&a); mp_init(&b); - mp_read_radix(&a, mp7, 16); mp_read_radix(&b, mp1, 16); - - mp_gcd(&a, &b, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, g_mp71) != 0) { - reason("error: computed %s, expected %s\n", g_intbuf, g_mp71); - out = 1; - } - - mp_clear(&a); mp_clear(&b); - return out; - -} - -/*------------------------------------------------------------------------*/ - -int test_lcm(void) -{ - mp_int a, b; - int out = 0; - - mp_init(&a); mp_init(&b); - mp_read_radix(&a, mp10, 16); mp_read_radix(&b, mp11, 16); - - mp_lcm(&a, &b, &a); - mp_toradix(&a, g_intbuf, 16); - - if(strcmp(g_intbuf, l_mp1011) != 0) { - reason("error: computed %s, expected%s\n", g_intbuf, l_mp1011); - out = 1; - } - - mp_clear(&a); mp_clear(&b); - - return out; - -} - -/*------------------------------------------------------------------------*/ - -int test_convert(void) -{ - int ix; - mp_int a; - - mp_init(&a); mp_read_radix(&a, mp9, 16); - - for(ix = LOW_RADIX; ix <= HIGH_RADIX; ix++) { - mp_toradix(&a, g_intbuf, ix); - - if(strcmp(g_intbuf, v_mp9[ix - LOW_RADIX]) != 0) { - reason("error: radix %d, computed %s, expected %s\n", - ix, g_intbuf, v_mp9[ix - LOW_RADIX]); - mp_clear(&a); - return 1; - } - } - - mp_clear(&a); - return 0; -} - -/*------------------------------------------------------------------------*/ - -int test_raw(void) -{ - int len, out = 0; - mp_int a; - char *buf; - - mp_init(&a); mp_read_radix(&a, mp4, 16); - - len = mp_raw_size(&a); - if(len != sizeof(b_mp4)) { - reason("error: test_raw: expected length %d, computed %d\n", sizeof(b_mp4), - len); - mp_clear(&a); - return 1; - } - - buf = calloc(len, sizeof(char)); - mp_toraw(&a, buf); - - if(memcmp(buf, b_mp4, sizeof(b_mp4)) != 0) { - reason("error: test_raw: binary output does not match test vector\n"); - out = 1; - } - - free(buf); - mp_clear(&a); - - return out; - -} - -/*------------------------------------------------------------------------*/ - -int test_pprime(void) -{ - mp_int p; - int err = 0; - mp_err res; - - mp_init(&p); - mp_read_radix(&p, mp7, 16); - - if(mpp_pprime(&p, 5) != MP_YES) { - reason("error: %s failed Rabin-Miller test, but is prime\n", mp7); - err = 1; - } - - IFOK( mp_set_int(&p, 9) ); - res = mpp_pprime(&p, 50); - if (res == MP_YES) { - reason("error: 9 is composite but passed Rabin-Miller test\n"); - err = 1; - } else if (res != MP_NO) { - reason("test mpp_pprime(9, 50) failed: error %d\n", res); - err = 1; - } - - IFOK( mp_set_int(&p, 15) ); - res = mpp_pprime(&p, 50); - if (res == MP_YES) { - reason("error: 15 is composite but passed Rabin-Miller test\n"); - err = 1; - } else if (res != MP_NO) { - reason("test mpp_pprime(15, 50) failed: error %d\n", res); - err = 1; - } - - mp_clear(&p); - - return err; - -} - -/*------------------------------------------------------------------------*/ - -int test_fermat(void) -{ - mp_int p; - mp_err res; - int err = 0; - - mp_init(&p); - mp_read_radix(&p, mp7, 16); - - if((res = mpp_fermat(&p, 2)) != MP_YES) { - reason("error: %s failed Fermat test on 2: %s\n", mp7, - mp_strerror(res)); - ++err; - } - - if((res = mpp_fermat(&p, 3)) != MP_YES) { - reason("error: %s failed Fermat test on 3: %s\n", mp7, - mp_strerror(res)); - ++err; - } - - mp_clear(&p); - - return err; - -} - -/*------------------------------------------------------------------------*/ -/* Like fprintf(), but only if we are behaving in a verbose manner */ - -void reason(char *fmt, ...) -{ - va_list ap; - - if(!g_verbose) - return; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -/*------------------------------------------------------------------------*/ -/* HERE THERE BE DRAGONS */ diff --git a/nss/lib/freebl/mpi/mpi.c b/nss/lib/freebl/mpi/mpi.c index 84f9b97..f6f7543 100644 --- a/nss/lib/freebl/mpi/mpi.c +++ b/nss/lib/freebl/mpi/mpi.c @@ -22,7 +22,7 @@ #if MP_LOGTAB /* A table of the logs of 2 for various bases (the 0 and 1 entries of - this table are meaningless and should not be referenced). + this table are meaningless and should not be referenced). This table is used to compute output lengths for the mp_toradix() function. Since a number n in radix r takes up about log_r(n) @@ -32,58 +32,80 @@ log_r(n) = log_2(n) * log_r(2) This table, therefore, is a table of log_r(2) for 2 <= r <= 36, - which are the output bases supported. + which are the output bases supported. */ #include "logtab.h" #endif +#ifdef CT_VERIF +#include <valgrind/memcheck.h> +#endif + /* {{{ Constant strings */ /* Constant strings returned by mp_strerror() */ static const char *mp_err_string[] = { - "unknown result code", /* say what? */ - "boolean true", /* MP_OKAY, MP_YES */ - "boolean false", /* MP_NO */ - "out of memory", /* MP_MEM */ - "argument out of range", /* MP_RANGE */ - "invalid input parameter", /* MP_BADARG */ - "result is undefined" /* MP_UNDEF */ + "unknown result code", /* say what? */ + "boolean true", /* MP_OKAY, MP_YES */ + "boolean false", /* MP_NO */ + "out of memory", /* MP_MEM */ + "argument out of range", /* MP_RANGE */ + "invalid input parameter", /* MP_BADARG */ + "result is undefined" /* MP_UNDEF */ }; /* Value to digit maps for radix conversion */ /* s_dmap_1 - standard digits and letters */ -static const char *s_dmap_1 = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +static const char *s_dmap_1 = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; /* }}} */ -unsigned long mp_allocs; -unsigned long mp_frees; -unsigned long mp_copies; - /* {{{ Default precision manipulation */ /* Default precision for newly created mp_int's */ static mp_size s_mp_defprec = MP_DEFPREC; -mp_size mp_get_prec(void) +mp_size +mp_get_prec(void) { - return s_mp_defprec; + return s_mp_defprec; } /* end mp_get_prec() */ -void mp_set_prec(mp_size prec) +void +mp_set_prec(mp_size prec) { - if(prec == 0) - s_mp_defprec = MP_DEFPREC; - else - s_mp_defprec = prec; + if (prec == 0) + s_mp_defprec = MP_DEFPREC; + else + s_mp_defprec = prec; } /* end mp_set_prec() */ /* }}} */ +#ifdef CT_VERIF +void +mp_taint(mp_int *mp) +{ + size_t i; + for (i = 0; i < mp->used; ++i) { + VALGRIND_MAKE_MEM_UNDEFINED(&(mp->dp[i]), sizeof(mp_digit)); + } +} + +void +mp_untaint(mp_int *mp) +{ + size_t i; + for (i = 0; i < mp->used; ++i) { + VALGRIND_MAKE_MEM_DEFINED(&(mp->dp[i]), sizeof(mp_digit)); + } +} +#endif + /*------------------------------------------------------------------------*/ /* {{{ mp_init(mp) */ @@ -94,9 +116,10 @@ void mp_set_prec(mp_size prec) MP_MEM if memory could not be allocated for the structure. */ -mp_err mp_init(mp_int *mp) +mp_err +mp_init(mp_int *mp) { - return mp_init_size(mp, s_mp_defprec); + return mp_init_size(mp, s_mp_defprec); } /* end mp_init() */ @@ -112,19 +135,20 @@ mp_err mp_init(mp_int *mp) not be allocated for the structure. */ -mp_err mp_init_size(mp_int *mp, mp_size prec) +mp_err +mp_init_size(mp_int *mp, mp_size prec) { - ARGCHK(mp != NULL && prec > 0, MP_BADARG); + ARGCHK(mp != NULL && prec > 0, MP_BADARG); - prec = MP_ROUNDUP(prec, s_mp_defprec); - if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL) - return MP_MEM; + prec = MP_ROUNDUP(prec, s_mp_defprec); + if ((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL) + return MP_MEM; - SIGN(mp) = ZPOS; - USED(mp) = 1; - ALLOC(mp) = prec; + SIGN(mp) = ZPOS; + USED(mp) = 1; + ALLOC(mp) = prec; - return MP_OKAY; + return MP_OKAY; } /* end mp_init_size() */ @@ -140,22 +164,23 @@ mp_err mp_init_size(mp_int *mp, mp_size prec) structure. */ -mp_err mp_init_copy(mp_int *mp, const mp_int *from) +mp_err +mp_init_copy(mp_int *mp, const mp_int *from) { - ARGCHK(mp != NULL && from != NULL, MP_BADARG); + ARGCHK(mp != NULL && from != NULL, MP_BADARG); - if(mp == from) - return MP_OKAY; + if (mp == from) + return MP_OKAY; - if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL) - return MP_MEM; + if ((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL) + return MP_MEM; - s_mp_copy(DIGITS(from), DIGITS(mp), USED(from)); - USED(mp) = USED(from); - ALLOC(mp) = ALLOC(from); - SIGN(mp) = SIGN(from); + s_mp_copy(DIGITS(from), DIGITS(mp), USED(from)); + USED(mp) = USED(from); + ALLOC(mp) = ALLOC(from); + SIGN(mp) = SIGN(from); - return MP_OKAY; + return MP_OKAY; } /* end mp_init_copy() */ @@ -171,50 +196,49 @@ mp_err mp_init_copy(mp_int *mp, const mp_int *from) instead). If 'from' and 'to' are identical, nothing happens. */ -mp_err mp_copy(const mp_int *from, mp_int *to) +mp_err +mp_copy(const mp_int *from, mp_int *to) { - ARGCHK(from != NULL && to != NULL, MP_BADARG); + ARGCHK(from != NULL && to != NULL, MP_BADARG); - if(from == to) - return MP_OKAY; + if (from == to) + return MP_OKAY; - { /* copy */ - mp_digit *tmp; + { /* copy */ + mp_digit *tmp; - /* - If the allocated buffer in 'to' already has enough space to hold - all the used digits of 'from', we'll re-use it to avoid hitting - the memory allocater more than necessary; otherwise, we'd have - to grow anyway, so we just allocate a hunk and make the copy as - usual - */ - if(ALLOC(to) >= USED(from)) { - s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from)); - s_mp_copy(DIGITS(from), DIGITS(to), USED(from)); - - } else { - if((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL) - return MP_MEM; + /* + If the allocated buffer in 'to' already has enough space to hold + all the used digits of 'from', we'll re-use it to avoid hitting + the memory allocater more than necessary; otherwise, we'd have + to grow anyway, so we just allocate a hunk and make the copy as + usual + */ + if (ALLOC(to) >= USED(from)) { + s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from)); + s_mp_copy(DIGITS(from), DIGITS(to), USED(from)); - s_mp_copy(DIGITS(from), tmp, USED(from)); + } else { + if ((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL) + return MP_MEM; - if(DIGITS(to) != NULL) { -#if MP_CRYPTO - s_mp_setz(DIGITS(to), ALLOC(to)); -#endif - s_mp_free(DIGITS(to)); - } + s_mp_copy(DIGITS(from), tmp, USED(from)); - DIGITS(to) = tmp; - ALLOC(to) = ALLOC(from); - } + if (DIGITS(to) != NULL) { + s_mp_setz(DIGITS(to), ALLOC(to)); + s_mp_free(DIGITS(to)); + } - /* Copy the precision and sign from the original */ - USED(to) = USED(from); - SIGN(to) = SIGN(from); - } /* end copy */ + DIGITS(to) = tmp; + ALLOC(to) = ALLOC(from); + } - return MP_OKAY; + /* Copy the precision and sign from the original */ + USED(to) = USED(from); + SIGN(to) = SIGN(from); + } /* end copy */ + + return MP_OKAY; } /* end mp_copy() */ @@ -230,16 +254,17 @@ mp_err mp_copy(const mp_int *from, mp_int *to) locals it creates...). This cannot fail. */ -void mp_exch(mp_int *mp1, mp_int *mp2) +void +mp_exch(mp_int *mp1, mp_int *mp2) { #if MP_ARGCHK == 2 - assert(mp1 != NULL && mp2 != NULL); + assert(mp1 != NULL && mp2 != NULL); #else - if(mp1 == NULL || mp2 == NULL) - return; + if (mp1 == NULL || mp2 == NULL) + return; #endif - s_mp_exch(mp1, mp2); + s_mp_exch(mp1, mp2); } /* end mp_exch() */ @@ -255,21 +280,20 @@ void mp_exch(mp_int *mp1, mp_int *mp2) get tollchocked. */ -void mp_clear(mp_int *mp) +void +mp_clear(mp_int *mp) { - if(mp == NULL) - return; + if (mp == NULL) + return; - if(DIGITS(mp) != NULL) { -#if MP_CRYPTO - s_mp_setz(DIGITS(mp), ALLOC(mp)); -#endif - s_mp_free(DIGITS(mp)); - DIGITS(mp) = NULL; - } + if (DIGITS(mp) != NULL) { + s_mp_setz(DIGITS(mp), ALLOC(mp)); + s_mp_free(DIGITS(mp)); + DIGITS(mp) = NULL; + } - USED(mp) = 0; - ALLOC(mp) = 0; + USED(mp) = 0; + ALLOC(mp) = 0; } /* end mp_clear() */ @@ -278,19 +302,20 @@ void mp_clear(mp_int *mp) /* {{{ mp_zero(mp) */ /* - mp_zero(mp) + mp_zero(mp) Set mp to zero. Does not change the allocated size of the structure, and therefore cannot fail (except on a bad argument, which we ignore) */ -void mp_zero(mp_int *mp) +void +mp_zero(mp_int *mp) { - if(mp == NULL) - return; + if (mp == NULL) + return; - s_mp_setz(DIGITS(mp), ALLOC(mp)); - USED(mp) = 1; - SIGN(mp) = ZPOS; + s_mp_setz(DIGITS(mp), ALLOC(mp)); + USED(mp) = 1; + SIGN(mp) = ZPOS; } /* end mp_zero() */ @@ -298,13 +323,14 @@ void mp_zero(mp_int *mp) /* {{{ mp_set(mp, d) */ -void mp_set(mp_int *mp, mp_digit d) +void +mp_set(mp_int *mp, mp_digit d) { - if(mp == NULL) - return; + if (mp == NULL) + return; - mp_zero(mp); - DIGIT(mp, 0) = d; + mp_zero(mp); + DIGIT(mp, 0) = d; } /* end mp_set() */ @@ -312,34 +338,35 @@ void mp_set(mp_int *mp, mp_digit d) /* {{{ mp_set_int(mp, z) */ -mp_err mp_set_int(mp_int *mp, long z) +mp_err +mp_set_int(mp_int *mp, long z) { - int ix; - unsigned long v = labs(z); - mp_err res; - - ARGCHK(mp != NULL, MP_BADARG); + int ix; + unsigned long v = labs(z); + mp_err res; - mp_zero(mp); - if(z == 0) - return MP_OKAY; /* shortcut for zero */ + ARGCHK(mp != NULL, MP_BADARG); - if (sizeof v <= sizeof(mp_digit)) { - DIGIT(mp,0) = v; - } else { - for (ix = sizeof(long) - 1; ix >= 0; ix--) { - if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY) - return res; + mp_zero(mp); + if (z == 0) + return MP_OKAY; /* shortcut for zero */ - res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX)); - if (res != MP_OKAY) - return res; + if (sizeof v <= sizeof(mp_digit)) { + DIGIT(mp, 0) = v; + } else { + for (ix = sizeof(long) - 1; ix >= 0; ix--) { + if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY) + return res; + + res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX)); + if (res != MP_OKAY) + return res; + } } - } - if(z < 0) - SIGN(mp) = NEG; + if (z < 0) + SIGN(mp) = NEG; - return MP_OKAY; + return MP_OKAY; } /* end mp_set_int() */ @@ -347,30 +374,31 @@ mp_err mp_set_int(mp_int *mp, long z) /* {{{ mp_set_ulong(mp, z) */ -mp_err mp_set_ulong(mp_int *mp, unsigned long z) +mp_err +mp_set_ulong(mp_int *mp, unsigned long z) { - int ix; - mp_err res; + int ix; + mp_err res; - ARGCHK(mp != NULL, MP_BADARG); + ARGCHK(mp != NULL, MP_BADARG); - mp_zero(mp); - if(z == 0) - return MP_OKAY; /* shortcut for zero */ + mp_zero(mp); + if (z == 0) + return MP_OKAY; /* shortcut for zero */ - if (sizeof z <= sizeof(mp_digit)) { - DIGIT(mp,0) = z; - } else { - for (ix = sizeof(long) - 1; ix >= 0; ix--) { - if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY) - return res; - - res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX)); - if (res != MP_OKAY) - return res; + if (sizeof z <= sizeof(mp_digit)) { + DIGIT(mp, 0) = z; + } else { + for (ix = sizeof(long) - 1; ix >= 0; ix--) { + if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY) + return res; + + res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX)); + if (res != MP_OKAY) + return res; + } } - } - return MP_OKAY; + return MP_OKAY; } /* end mp_set_ulong() */ /* }}} */ @@ -387,36 +415,37 @@ mp_err mp_set_ulong(mp_int *mp, unsigned long z) its primary addend (single digits are unsigned anyway). */ -mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b) +mp_err +mp_add_d(const mp_int *a, mp_digit d, mp_int *b) { - mp_int tmp; - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); + mp_int tmp; + mp_err res; - if((res = mp_init_copy(&tmp, a)) != MP_OKAY) - return res; + ARGCHK(a != NULL && b != NULL, MP_BADARG); - if(SIGN(&tmp) == ZPOS) { - if((res = s_mp_add_d(&tmp, d)) != MP_OKAY) - goto CLEANUP; - } else if(s_mp_cmp_d(&tmp, d) >= 0) { - if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY) - goto CLEANUP; - } else { - mp_neg(&tmp, &tmp); + if ((res = mp_init_copy(&tmp, a)) != MP_OKAY) + return res; + + if (SIGN(&tmp) == ZPOS) { + if ((res = s_mp_add_d(&tmp, d)) != MP_OKAY) + goto CLEANUP; + } else if (s_mp_cmp_d(&tmp, d) >= 0) { + if ((res = s_mp_sub_d(&tmp, d)) != MP_OKAY) + goto CLEANUP; + } else { + mp_neg(&tmp, &tmp); - DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0); - } + DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0); + } - if(s_mp_cmp_d(&tmp, 0) == 0) - SIGN(&tmp) = ZPOS; + if (s_mp_cmp_d(&tmp, 0) == 0) + SIGN(&tmp) = ZPOS; - s_mp_exch(&tmp, b); + s_mp_exch(&tmp, b); CLEANUP: - mp_clear(&tmp); - return res; + mp_clear(&tmp); + return res; } /* end mp_add_d() */ @@ -431,37 +460,38 @@ CLEANUP: sign of its subtrahend (single digits are unsigned anyway). */ -mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b) +mp_err +mp_sub_d(const mp_int *a, mp_digit d, mp_int *b) { - mp_int tmp; - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); + mp_int tmp; + mp_err res; - if((res = mp_init_copy(&tmp, a)) != MP_OKAY) - return res; + ARGCHK(a != NULL && b != NULL, MP_BADARG); - if(SIGN(&tmp) == NEG) { - if((res = s_mp_add_d(&tmp, d)) != MP_OKAY) - goto CLEANUP; - } else if(s_mp_cmp_d(&tmp, d) >= 0) { - if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY) - goto CLEANUP; - } else { - mp_neg(&tmp, &tmp); + if ((res = mp_init_copy(&tmp, a)) != MP_OKAY) + return res; + + if (SIGN(&tmp) == NEG) { + if ((res = s_mp_add_d(&tmp, d)) != MP_OKAY) + goto CLEANUP; + } else if (s_mp_cmp_d(&tmp, d) >= 0) { + if ((res = s_mp_sub_d(&tmp, d)) != MP_OKAY) + goto CLEANUP; + } else { + mp_neg(&tmp, &tmp); - DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0); - SIGN(&tmp) = NEG; - } + DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0); + SIGN(&tmp) = NEG; + } - if(s_mp_cmp_d(&tmp, 0) == 0) - SIGN(&tmp) = ZPOS; + if (s_mp_cmp_d(&tmp, 0) == 0) + SIGN(&tmp) = ZPOS; - s_mp_exch(&tmp, b); + s_mp_exch(&tmp, b); CLEANUP: - mp_clear(&tmp); - return res; + mp_clear(&tmp); + return res; } /* end mp_sub_d() */ @@ -476,23 +506,24 @@ CLEANUP: of its multiplicand (single digits are unsigned anyway) */ -mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b) +mp_err +mp_mul_d(const mp_int *a, mp_digit d, mp_int *b) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && b != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL, MP_BADARG); - if(d == 0) { - mp_zero(b); - return MP_OKAY; - } + if (d == 0) { + mp_zero(b); + return MP_OKAY; + } - if((res = mp_copy(a, b)) != MP_OKAY) - return res; + if ((res = mp_copy(a, b)) != MP_OKAY) + return res; - res = s_mp_mul_d(b, d); + res = s_mp_mul_d(b, d); - return res; + return res; } /* end mp_mul_d() */ @@ -500,16 +531,17 @@ mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b) /* {{{ mp_mul_2(a, c) */ -mp_err mp_mul_2(const mp_int *a, mp_int *c) +mp_err +mp_mul_2(const mp_int *a, mp_int *c) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && c != NULL, MP_BADARG); - if((res = mp_copy(a, c)) != MP_OKAY) - return res; + if ((res = mp_copy(a, c)) != MP_OKAY) + return res; - return s_mp_mul_2(c); + return s_mp_mul_2(c); } /* end mp_mul_2() */ @@ -525,52 +557,56 @@ mp_err mp_mul_2(const mp_int *a, mp_int *c) unsigned anyway). */ -mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r) +mp_err +mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r) { - mp_err res; - mp_int qp; - mp_digit rem; - int pow; + mp_err res; + mp_int qp; + mp_digit rem = 0; + int pow; - ARGCHK(a != NULL, MP_BADARG); + ARGCHK(a != NULL, MP_BADARG); - if(d == 0) - return MP_RANGE; + if (d == 0) + return MP_RANGE; - /* Shortcut for powers of two ... */ - if((pow = s_mp_ispow2d(d)) >= 0) { - mp_digit mask; + /* Shortcut for powers of two ... */ + if ((pow = s_mp_ispow2d(d)) >= 0) { + mp_digit mask; - mask = ((mp_digit)1 << pow) - 1; - rem = DIGIT(a, 0) & mask; + mask = ((mp_digit)1 << pow) - 1; + rem = DIGIT(a, 0) & mask; - if(q) { - mp_copy(a, q); - s_mp_div_2d(q, pow); - } + if (q) { + if ((res = mp_copy(a, q)) != MP_OKAY) { + return res; + } + s_mp_div_2d(q, pow); + } - if(r) - *r = rem; + if (r) + *r = rem; - return MP_OKAY; - } + return MP_OKAY; + } - if((res = mp_init_copy(&qp, a)) != MP_OKAY) - return res; + if ((res = mp_init_copy(&qp, a)) != MP_OKAY) + return res; - res = s_mp_div_d(&qp, d, &rem); + res = s_mp_div_d(&qp, d, &rem); - if(s_mp_cmp_d(&qp, 0) == 0) - SIGN(q) = ZPOS; + if (s_mp_cmp_d(&qp, 0) == 0) + SIGN(q) = ZPOS; - if(r) - *r = rem; + if (r) { + *r = rem; + } - if(q) - s_mp_exch(&qp, q); + if (q) + s_mp_exch(&qp, q); - mp_clear(&qp); - return res; + mp_clear(&qp); + return res; } /* end mp_div_d() */ @@ -584,18 +620,19 @@ mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r) Compute c = a / 2, disregarding the remainder. */ -mp_err mp_div_2(const mp_int *a, mp_int *c) +mp_err +mp_div_2(const mp_int *a, mp_int *c) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && c != NULL, MP_BADARG); - if((res = mp_copy(a, c)) != MP_OKAY) - return res; + if ((res = mp_copy(a, c)) != MP_OKAY) + return res; - s_mp_div_2(c); + s_mp_div_2(c); - return MP_OKAY; + return MP_OKAY; } /* end mp_div_2() */ @@ -603,40 +640,41 @@ mp_err mp_div_2(const mp_int *a, mp_int *c) /* {{{ mp_expt_d(a, d, b) */ -mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c) +mp_err +mp_expt_d(const mp_int *a, mp_digit d, mp_int *c) { - mp_int s, x; - mp_err res; + mp_int s, x; + mp_err res; - ARGCHK(a != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && c != NULL, MP_BADARG); - if((res = mp_init(&s)) != MP_OKAY) - return res; - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; + if ((res = mp_init(&s)) != MP_OKAY) + return res; + if ((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; - DIGIT(&s, 0) = 1; + DIGIT(&s, 0) = 1; - while(d != 0) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - } + while (d != 0) { + if (d & 1) { + if ((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + } - d /= 2; + d /= 2; - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - } + if ((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + } - s_mp_exch(&s, c); + s_mp_exch(&s, c); CLEANUP: - mp_clear(&x); + mp_clear(&x); X: - mp_clear(&s); + mp_clear(&s); - return res; + return res; } /* end mp_expt_d() */ @@ -655,18 +693,19 @@ X: Compute b = |a|. 'a' and 'b' may be identical. */ -mp_err mp_abs(const mp_int *a, mp_int *b) +mp_err +mp_abs(const mp_int *a, mp_int *b) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && b != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL, MP_BADARG); - if((res = mp_copy(a, b)) != MP_OKAY) - return res; + if ((res = mp_copy(a, b)) != MP_OKAY) + return res; - SIGN(b) = ZPOS; + SIGN(b) = ZPOS; - return MP_OKAY; + return MP_OKAY; } /* end mp_abs() */ @@ -680,21 +719,22 @@ mp_err mp_abs(const mp_int *a, mp_int *b) Compute b = -a. 'a' and 'b' may be identical. */ -mp_err mp_neg(const mp_int *a, mp_int *b) +mp_err +mp_neg(const mp_int *a, mp_int *b) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && b != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL, MP_BADARG); - if((res = mp_copy(a, b)) != MP_OKAY) - return res; + if ((res = mp_copy(a, b)) != MP_OKAY) + return res; - if(s_mp_cmp_d(b, 0) == MP_EQ) - SIGN(b) = ZPOS; - else - SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG; + if (s_mp_cmp_d(b, 0) == MP_EQ) + SIGN(b) = ZPOS; + else + SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG; - return MP_OKAY; + return MP_OKAY; } /* end mp_neg() */ @@ -708,25 +748,26 @@ mp_err mp_neg(const mp_int *a, mp_int *b) Compute c = a + b. All parameters may be identical. */ -mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c) +mp_err +mp_add(const mp_int *a, const mp_int *b, mp_int *c) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */ - MP_CHECKOK( s_mp_add_3arg(a, b, c) ); - } else if(s_mp_cmp(a, b) >= 0) { /* different sign: |a| >= |b| */ - MP_CHECKOK( s_mp_sub_3arg(a, b, c) ); - } else { /* different sign: |a| < |b| */ - MP_CHECKOK( s_mp_sub_3arg(b, a, c) ); - } + if (SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */ + MP_CHECKOK(s_mp_add_3arg(a, b, c)); + } else if (s_mp_cmp(a, b) >= 0) { /* different sign: |a| >= |b| */ + MP_CHECKOK(s_mp_sub_3arg(a, b, c)); + } else { /* different sign: |a| < |b| */ + MP_CHECKOK(s_mp_sub_3arg(b, a, c)); + } - if (s_mp_cmp_d(c, 0) == MP_EQ) - SIGN(c) = ZPOS; + if (s_mp_cmp_d(c, 0) == MP_EQ) + SIGN(c) = ZPOS; CLEANUP: - return res; + return res; } /* end mp_add() */ @@ -740,35 +781,36 @@ CLEANUP: Compute c = a - b. All parameters may be identical. */ -mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) +mp_err +mp_sub(const mp_int *a, const mp_int *b, mp_int *c) { - mp_err res; - int magDiff; + mp_err res; + int magDiff; - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - if (a == b) { - mp_zero(c); - return MP_OKAY; - } + if (a == b) { + mp_zero(c); + return MP_OKAY; + } - if (MP_SIGN(a) != MP_SIGN(b)) { - MP_CHECKOK( s_mp_add_3arg(a, b, c) ); - } else if (!(magDiff = s_mp_cmp(a, b))) { - mp_zero(c); - res = MP_OKAY; - } else if (magDiff > 0) { - MP_CHECKOK( s_mp_sub_3arg(a, b, c) ); - } else { - MP_CHECKOK( s_mp_sub_3arg(b, a, c) ); - MP_SIGN(c) = !MP_SIGN(a); - } + if (MP_SIGN(a) != MP_SIGN(b)) { + MP_CHECKOK(s_mp_add_3arg(a, b, c)); + } else if (!(magDiff = s_mp_cmp(a, b))) { + mp_zero(c); + res = MP_OKAY; + } else if (magDiff > 0) { + MP_CHECKOK(s_mp_sub_3arg(a, b, c)); + } else { + MP_CHECKOK(s_mp_sub_3arg(b, a, c)); + MP_SIGN(c) = !MP_SIGN(a); + } - if (s_mp_cmp_d(c, 0) == MP_EQ) - MP_SIGN(c) = MP_ZPOS; + if (s_mp_cmp_d(c, 0) == MP_EQ) + MP_SIGN(c) = MP_ZPOS; CLEANUP: - return res; + return res; } /* end mp_sub() */ @@ -781,87 +823,89 @@ CLEANUP: Compute c = a * b. All parameters may be identical. */ -mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int * c) +mp_err +mp_mul(const mp_int *a, const mp_int *b, mp_int *c) { - mp_digit *pb; - mp_int tmp; - mp_err res; - mp_size ib; - mp_size useda, usedb; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if (a == c) { - if ((res = mp_init_copy(&tmp, a)) != MP_OKAY) - return res; - if (a == b) - b = &tmp; - a = &tmp; - } else if (b == c) { - if ((res = mp_init_copy(&tmp, b)) != MP_OKAY) - return res; - b = &tmp; - } else { - MP_DIGITS(&tmp) = 0; - } + mp_digit *pb; + mp_int tmp; + mp_err res; + mp_size ib; + mp_size useda, usedb; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if (a == c) { + if ((res = mp_init_copy(&tmp, a)) != MP_OKAY) + return res; + if (a == b) + b = &tmp; + a = &tmp; + } else if (b == c) { + if ((res = mp_init_copy(&tmp, b)) != MP_OKAY) + return res; + b = &tmp; + } else { + MP_DIGITS(&tmp) = 0; + } - if (MP_USED(a) < MP_USED(b)) { - const mp_int *xch = b; /* switch a and b, to do fewer outer loops */ - b = a; - a = xch; - } + if (MP_USED(a) < MP_USED(b)) { + const mp_int *xch = b; /* switch a and b, to do fewer outer loops */ + b = a; + a = xch; + } - MP_USED(c) = 1; MP_DIGIT(c, 0) = 0; - if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY) - goto CLEANUP; + MP_USED(c) = 1; + MP_DIGIT(c, 0) = 0; + if ((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY) + goto CLEANUP; #ifdef NSS_USE_COMBA - if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) { - if (MP_USED(a) == 4) { - s_mp_mul_comba_4(a, b, c); - goto CLEANUP; - } - if (MP_USED(a) == 8) { - s_mp_mul_comba_8(a, b, c); - goto CLEANUP; - } - if (MP_USED(a) == 16) { - s_mp_mul_comba_16(a, b, c); - goto CLEANUP; - } - if (MP_USED(a) == 32) { - s_mp_mul_comba_32(a, b, c); - goto CLEANUP; - } - } + if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) { + if (MP_USED(a) == 4) { + s_mp_mul_comba_4(a, b, c); + goto CLEANUP; + } + if (MP_USED(a) == 8) { + s_mp_mul_comba_8(a, b, c); + goto CLEANUP; + } + if (MP_USED(a) == 16) { + s_mp_mul_comba_16(a, b, c); + goto CLEANUP; + } + if (MP_USED(a) == 32) { + s_mp_mul_comba_32(a, b, c); + goto CLEANUP; + } + } #endif - pb = MP_DIGITS(b); - s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c)); + pb = MP_DIGITS(b); + s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c)); - /* Outer loop: Digits of b */ - useda = MP_USED(a); - usedb = MP_USED(b); - for (ib = 1; ib < usedb; ib++) { - mp_digit b_i = *pb++; + /* Outer loop: Digits of b */ + useda = MP_USED(a); + usedb = MP_USED(b); + for (ib = 1; ib < usedb; ib++) { + mp_digit b_i = *pb++; - /* Inner product: Digits of a */ - if (b_i) - s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib); - else - MP_DIGIT(c, ib + useda) = b_i; - } + /* Inner product: Digits of a */ + if (b_i) + s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib); + else + MP_DIGIT(c, ib + useda) = b_i; + } - s_mp_clamp(c); + s_mp_clamp(c); - if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ) - SIGN(c) = ZPOS; - else - SIGN(c) = NEG; + if (SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ) + SIGN(c) = ZPOS; + else + SIGN(c) = NEG; CLEANUP: - mp_clear(&tmp); - return res; + mp_clear(&tmp); + return res; } /* end mp_mul() */ /* }}} */ @@ -878,81 +922,82 @@ CLEANUP: */ /* sqr = a^2; Caller provides both a and tmp; */ -mp_err mp_sqr(const mp_int *a, mp_int *sqr) +mp_err +mp_sqr(const mp_int *a, mp_int *sqr) { - mp_digit *pa; - mp_digit d; - mp_err res; - mp_size ix; - mp_int tmp; - int count; - - ARGCHK(a != NULL && sqr != NULL, MP_BADARG); - - if (a == sqr) { - if((res = mp_init_copy(&tmp, a)) != MP_OKAY) - return res; - a = &tmp; - } else { - DIGITS(&tmp) = 0; - res = MP_OKAY; - } + mp_digit *pa; + mp_digit d; + mp_err res; + mp_size ix; + mp_int tmp; + int count; + + ARGCHK(a != NULL && sqr != NULL, MP_BADARG); + + if (a == sqr) { + if ((res = mp_init_copy(&tmp, a)) != MP_OKAY) + return res; + a = &tmp; + } else { + DIGITS(&tmp) = 0; + res = MP_OKAY; + } - ix = 2 * MP_USED(a); - if (ix > MP_ALLOC(sqr)) { - MP_USED(sqr) = 1; - MP_CHECKOK( s_mp_grow(sqr, ix) ); - } - MP_USED(sqr) = ix; - MP_DIGIT(sqr, 0) = 0; + ix = 2 * MP_USED(a); + if (ix > MP_ALLOC(sqr)) { + MP_USED(sqr) = 1; + MP_CHECKOK(s_mp_grow(sqr, ix)); + } + MP_USED(sqr) = ix; + MP_DIGIT(sqr, 0) = 0; #ifdef NSS_USE_COMBA - if (IS_POWER_OF_2(MP_USED(a))) { - if (MP_USED(a) == 4) { - s_mp_sqr_comba_4(a, sqr); - goto CLEANUP; - } - if (MP_USED(a) == 8) { - s_mp_sqr_comba_8(a, sqr); - goto CLEANUP; - } - if (MP_USED(a) == 16) { - s_mp_sqr_comba_16(a, sqr); - goto CLEANUP; - } - if (MP_USED(a) == 32) { - s_mp_sqr_comba_32(a, sqr); - goto CLEANUP; - } - } + if (IS_POWER_OF_2(MP_USED(a))) { + if (MP_USED(a) == 4) { + s_mp_sqr_comba_4(a, sqr); + goto CLEANUP; + } + if (MP_USED(a) == 8) { + s_mp_sqr_comba_8(a, sqr); + goto CLEANUP; + } + if (MP_USED(a) == 16) { + s_mp_sqr_comba_16(a, sqr); + goto CLEANUP; + } + if (MP_USED(a) == 32) { + s_mp_sqr_comba_32(a, sqr); + goto CLEANUP; + } + } #endif - pa = MP_DIGITS(a); - count = MP_USED(a) - 1; - if (count > 0) { - d = *pa++; - s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1); - for (ix = 3; --count > 0; ix += 2) { - d = *pa++; - s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix); - } /* for(ix ...) */ - MP_DIGIT(sqr, MP_USED(sqr)-1) = 0; /* above loop stopped short of this. */ - - /* now sqr *= 2 */ - s_mp_mul_2(sqr); - } else { - MP_DIGIT(sqr, 1) = 0; - } - - /* now add the squares of the digits of a to sqr. */ - s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr)); - - SIGN(sqr) = ZPOS; - s_mp_clamp(sqr); + pa = MP_DIGITS(a); + count = MP_USED(a) - 1; + if (count > 0) { + d = *pa++; + s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1); + for (ix = 3; --count > 0; ix += 2) { + d = *pa++; + s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix); + } /* for(ix ...) */ + MP_DIGIT(sqr, MP_USED(sqr) - 1) = 0; /* above loop stopped short of this. */ + + /* now sqr *= 2 */ + s_mp_mul_2(sqr); + } else { + MP_DIGIT(sqr, 1) = 0; + } + + /* now add the squares of the digits of a to sqr. */ + s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr)); + + SIGN(sqr) = ZPOS; + s_mp_clamp(sqr); CLEANUP: - mp_clear(&tmp); - return res; + mp_clear(&tmp); + return res; } /* end mp_sqr() */ #endif @@ -968,85 +1013,86 @@ CLEANUP: as output parameters. If q or r is NULL, that portion of the computation will be discarded (although it will still be computed) */ -mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r) +mp_err +mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r) { - mp_err res; - mp_int *pQ, *pR; - mp_int qtmp, rtmp, btmp; - int cmp; - mp_sign signA; - mp_sign signB; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - signA = MP_SIGN(a); - signB = MP_SIGN(b); - - if(mp_cmp_z(b) == MP_EQ) - return MP_RANGE; - - DIGITS(&qtmp) = 0; - DIGITS(&rtmp) = 0; - DIGITS(&btmp) = 0; - - /* Set up some temporaries... */ - if (!r || r == a || r == b) { - MP_CHECKOK( mp_init_copy(&rtmp, a) ); - pR = &rtmp; - } else { - MP_CHECKOK( mp_copy(a, r) ); - pR = r; - } - - if (!q || q == a || q == b) { - MP_CHECKOK( mp_init_size(&qtmp, MP_USED(a)) ); - pQ = &qtmp; - } else { - MP_CHECKOK( s_mp_pad(q, MP_USED(a)) ); - pQ = q; - mp_zero(pQ); - } - - /* - If |a| <= |b|, we can compute the solution without division; - otherwise, we actually do the work required. - */ - if ((cmp = s_mp_cmp(a, b)) <= 0) { - if (cmp) { - /* r was set to a above. */ - mp_zero(pQ); + mp_err res; + mp_int *pQ, *pR; + mp_int qtmp, rtmp, btmp; + int cmp; + mp_sign signA; + mp_sign signB; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + signA = MP_SIGN(a); + signB = MP_SIGN(b); + + if (mp_cmp_z(b) == MP_EQ) + return MP_RANGE; + + DIGITS(&qtmp) = 0; + DIGITS(&rtmp) = 0; + DIGITS(&btmp) = 0; + + /* Set up some temporaries... */ + if (!r || r == a || r == b) { + MP_CHECKOK(mp_init_copy(&rtmp, a)); + pR = &rtmp; + } else { + MP_CHECKOK(mp_copy(a, r)); + pR = r; + } + + if (!q || q == a || q == b) { + MP_CHECKOK(mp_init_size(&qtmp, MP_USED(a))); + pQ = &qtmp; } else { - mp_set(pQ, 1); - mp_zero(pR); + MP_CHECKOK(s_mp_pad(q, MP_USED(a))); + pQ = q; + mp_zero(pQ); } - } else { - MP_CHECKOK( mp_init_copy(&btmp, b) ); - MP_CHECKOK( s_mp_div(pR, &btmp, pQ) ); - } - /* Compute the signs for the output */ - MP_SIGN(pR) = signA; /* Sr = Sa */ - /* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */ - MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG; + /* + If |a| <= |b|, we can compute the solution without division; + otherwise, we actually do the work required. + */ + if ((cmp = s_mp_cmp(a, b)) <= 0) { + if (cmp) { + /* r was set to a above. */ + mp_zero(pQ); + } else { + mp_set(pQ, 1); + mp_zero(pR); + } + } else { + MP_CHECKOK(mp_init_copy(&btmp, b)); + MP_CHECKOK(s_mp_div(pR, &btmp, pQ)); + } + + /* Compute the signs for the output */ + MP_SIGN(pR) = signA; /* Sr = Sa */ + /* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */ + MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG; - if(s_mp_cmp_d(pQ, 0) == MP_EQ) - SIGN(pQ) = ZPOS; - if(s_mp_cmp_d(pR, 0) == MP_EQ) - SIGN(pR) = ZPOS; + if (s_mp_cmp_d(pQ, 0) == MP_EQ) + SIGN(pQ) = ZPOS; + if (s_mp_cmp_d(pR, 0) == MP_EQ) + SIGN(pR) = ZPOS; - /* Copy output, if it is needed */ - if(q && q != pQ) - s_mp_exch(pQ, q); + /* Copy output, if it is needed */ + if (q && q != pQ) + s_mp_exch(pQ, q); - if(r && r != pR) - s_mp_exch(pR, r); + if (r && r != pR) + s_mp_exch(pR, r); CLEANUP: - mp_clear(&btmp); - mp_clear(&rtmp); - mp_clear(&qtmp); + mp_clear(&btmp); + mp_clear(&rtmp); + mp_clear(&qtmp); - return res; + return res; } /* end mp_div() */ @@ -1054,28 +1100,29 @@ CLEANUP: /* {{{ mp_div_2d(a, d, q, r) */ -mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r) +mp_err +mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r) { - mp_err res; - - ARGCHK(a != NULL, MP_BADARG); - - if(q) { - if((res = mp_copy(a, q)) != MP_OKAY) - return res; - } - if(r) { - if((res = mp_copy(a, r)) != MP_OKAY) - return res; - } - if(q) { - s_mp_div_2d(q, d); - } - if(r) { - s_mp_mod_2d(r, d); - } - - return MP_OKAY; + mp_err res; + + ARGCHK(a != NULL, MP_BADARG); + + if (q) { + if ((res = mp_copy(a, q)) != MP_OKAY) + return res; + } + if (r) { + if ((res = mp_copy(a, r)) != MP_OKAY) + return res; + } + if (q) { + s_mp_div_2d(q, d); + } + if (r) { + s_mp_mod_2d(r, d); + } + + return MP_OKAY; } /* end mp_div_2d() */ @@ -1090,70 +1137,71 @@ mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r) standard iterative square-and-multiply technique. */ -mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c) +mp_err +mp_expt(mp_int *a, mp_int *b, mp_int *c) { - mp_int s, x; - mp_err res; - mp_digit d; - unsigned int dig, bit; + mp_int s, x; + mp_err res; + mp_digit d; + unsigned int dig, bit; - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - if(mp_cmp_z(b) < 0) - return MP_RANGE; + if (mp_cmp_z(b) < 0) + return MP_RANGE; - if((res = mp_init(&s)) != MP_OKAY) - return res; + if ((res = mp_init(&s)) != MP_OKAY) + return res; + + mp_set(&s, 1); - mp_set(&s, 1); + if ((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; + /* Loop over low-order digits in ascending order */ + for (dig = 0; dig < (USED(b) - 1); dig++) { + d = DIGIT(b, dig); - /* Loop over low-order digits in ascending order */ - for(dig = 0; dig < (USED(b) - 1); dig++) { - d = DIGIT(b, dig); + /* Loop over bits of each non-maximal digit */ + for (bit = 0; bit < DIGIT_BIT; bit++) { + if (d & 1) { + if ((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + } - /* Loop over bits of each non-maximal digit */ - for(bit = 0; bit < DIGIT_BIT; bit++) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - } + d >>= 1; - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; + if ((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + } } - } - /* Consider now the last digit... */ - d = DIGIT(b, dig); + /* Consider now the last digit... */ + d = DIGIT(b, dig); - while(d) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - } + while (d) { + if (d & 1) { + if ((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + } - d >>= 1; + d >>= 1; - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - } - - if(mp_iseven(b)) - SIGN(&s) = SIGN(a); + if ((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + } - res = mp_copy(&s, c); + if (mp_iseven(b)) + SIGN(&s) = SIGN(a); + + res = mp_copy(&s, c); CLEANUP: - mp_clear(&x); + mp_clear(&x); X: - mp_clear(&s); + mp_clear(&s); - return res; + return res; } /* end mp_expt() */ @@ -1163,11 +1211,12 @@ X: /* Compute a = 2^k */ -mp_err mp_2expt(mp_int *a, mp_digit k) +mp_err +mp_2expt(mp_int *a, mp_digit k) { - ARGCHK(a != NULL, MP_BADARG); + ARGCHK(a != NULL, MP_BADARG); - return s_mp_2expt(a, k); + return s_mp_2expt(a, k); } /* end mp_2expt() */ @@ -1181,19 +1230,20 @@ mp_err mp_2expt(mp_int *a, mp_digit k) Compute c = a (mod m). Result will always be 0 <= c < m. */ -mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c) +mp_err +mp_mod(const mp_int *a, const mp_int *m, mp_int *c) { - mp_err res; - int mag; + mp_err res; + int mag; - ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); - if(SIGN(m) == NEG) - return MP_RANGE; + if (SIGN(m) == NEG) + return MP_RANGE; - /* + /* If |a| > m, we need to divide to get the remainder and take the - absolute value. + absolute value. If |a| < m, we don't need to do any division, just copy and adjust the sign (if a is negative). @@ -1203,32 +1253,30 @@ mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c) This order is intended to minimize the average path length of the comparison chain on common workloads -- the most frequent cases are that |a| != m, so we do those first. - */ - if((mag = s_mp_cmp(a, m)) > 0) { - if((res = mp_div(a, m, NULL, c)) != MP_OKAY) - return res; - - if(SIGN(c) == NEG) { - if((res = mp_add(c, m, c)) != MP_OKAY) - return res; - } + */ + if ((mag = s_mp_cmp(a, m)) > 0) { + if ((res = mp_div(a, m, NULL, c)) != MP_OKAY) + return res; - } else if(mag < 0) { - if((res = mp_copy(a, c)) != MP_OKAY) - return res; + if (SIGN(c) == NEG) { + if ((res = mp_add(c, m, c)) != MP_OKAY) + return res; + } - if(mp_cmp_z(a) < 0) { - if((res = mp_add(c, m, c)) != MP_OKAY) - return res; + } else if (mag < 0) { + if ((res = mp_copy(a, c)) != MP_OKAY) + return res; - } - - } else { - mp_zero(c); + if (mp_cmp_z(a) < 0) { + if ((res = mp_add(c, m, c)) != MP_OKAY) + return res; + } - } + } else { + mp_zero(c); + } - return MP_OKAY; + return MP_OKAY; } /* end mp_mod() */ @@ -1241,115 +1289,34 @@ mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c) Compute c = a (mod d). Result will always be 0 <= c < d */ -mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c) +mp_err +mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c) { - mp_err res; - mp_digit rem; + mp_err res; + mp_digit rem; - ARGCHK(a != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && c != NULL, MP_BADARG); - if(s_mp_cmp_d(a, d) > 0) { - if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY) - return res; + if (s_mp_cmp_d(a, d) > 0) { + if ((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY) + return res; - } else { - if(SIGN(a) == NEG) - rem = d - DIGIT(a, 0); - else - rem = DIGIT(a, 0); - } + } else { + if (SIGN(a) == NEG) + rem = d - DIGIT(a, 0); + else + rem = DIGIT(a, 0); + } - if(c) - *c = rem; + if (c) + *c = rem; - return MP_OKAY; + return MP_OKAY; } /* end mp_mod_d() */ /* }}} */ -/* {{{ mp_sqrt(a, b) */ - -/* - mp_sqrt(a, b) - - Compute the integer square root of a, and store the result in b. - Uses an integer-arithmetic version of Newton's iterative linear - approximation technique to determine this value; the result has the - following two properties: - - b^2 <= a - (b+1)^2 >= a - - It is a range error to pass a negative value. - */ -mp_err mp_sqrt(const mp_int *a, mp_int *b) -{ - mp_int x, t; - mp_err res; - mp_size used; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - /* Cannot take square root of a negative value */ - if(SIGN(a) == NEG) - return MP_RANGE; - - /* Special cases for zero and one, trivial */ - if(mp_cmp_d(a, 1) <= 0) - return mp_copy(a, b); - - /* Initialize the temporaries we'll use below */ - if((res = mp_init_size(&t, USED(a))) != MP_OKAY) - return res; - - /* Compute an initial guess for the iteration as a itself */ - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - - used = MP_USED(&x); - if (used > 1) { - s_mp_rshd(&x, used / 2); - } - - for(;;) { - /* t = (x * x) - a */ - mp_copy(&x, &t); /* can't fail, t is big enough for original x */ - if((res = mp_sqr(&t, &t)) != MP_OKAY || - (res = mp_sub(&t, a, &t)) != MP_OKAY) - goto CLEANUP; - - /* t = t / 2x */ - s_mp_mul_2(&x); - if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY) - goto CLEANUP; - s_mp_div_2(&x); - - /* Terminate the loop, if the quotient is zero */ - if(mp_cmp_z(&t) == MP_EQ) - break; - - /* x = x - t */ - if((res = mp_sub(&x, &t, &x)) != MP_OKAY) - goto CLEANUP; - - } - - /* Copy result to output parameter */ - mp_sub_d(&x, 1, &x); - s_mp_exch(&x, b); - - CLEANUP: - mp_clear(&x); - X: - mp_clear(&t); - - return res; - -} /* end mp_sqrt() */ - -/* }}} */ - /* }}} */ /*------------------------------------------------------------------------*/ @@ -1364,19 +1331,19 @@ mp_err mp_sqrt(const mp_int *a, mp_int *b) Compute c = (a + b) mod m */ -mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) +mp_err +mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); - if((res = mp_add(a, b, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; + if ((res = mp_add(a, b, c)) != MP_OKAY) + return res; + if ((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + return MP_OKAY; } /* }}} */ @@ -1389,19 +1356,19 @@ mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) Compute c = (a - b) mod m */ -mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) +mp_err +mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); - if((res = mp_sub(a, b, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; + if ((res = mp_sub(a, b, c)) != MP_OKAY) + return res; + if ((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + return MP_OKAY; } /* }}} */ @@ -1414,19 +1381,19 @@ mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) Compute c = (a * b) mod m */ -mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) +mp_err +mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) { - mp_err res; - - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); + mp_err res; - if((res = mp_mul(a, b, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); - return MP_OKAY; + if ((res = mp_mul(a, b, c)) != MP_OKAY) + return res; + if ((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + return MP_OKAY; } /* }}} */ @@ -1434,18 +1401,19 @@ mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) /* {{{ mp_sqrmod(a, m, c) */ #if MP_SQUARE -mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c) +mp_err +mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); - if((res = mp_sqr(a, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; + if ((res = mp_sqr(a, c)) != MP_OKAY) + return res; + if ((res = mp_mod(c, m, c)) != MP_OKAY) + return res; - return MP_OKAY; + return MP_OKAY; } /* end mp_sqrmod() */ #endif @@ -1460,90 +1428,93 @@ mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c) Compute c = (a ** b) mod m. Uses a standard square-and-multiply method with modular reductions at each step. (This is basically the same code as mp_expt(), except for the addition of the reductions) - + The modular reductions are done using Barrett's algorithm (see s_mp_reduce() below for details) */ -mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) +mp_err +s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) { - mp_int s, x, mu; - mp_err res; - mp_digit d; - unsigned int dig, bit; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0) - return MP_RANGE; + mp_int s, x, mu; + mp_err res; + mp_digit d; + unsigned int dig, bit; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if (mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0) + return MP_RANGE; + + if ((res = mp_init(&s)) != MP_OKAY) + return res; + if ((res = mp_init_copy(&x, a)) != MP_OKAY || + (res = mp_mod(&x, m, &x)) != MP_OKAY) + goto X; + if ((res = mp_init(&mu)) != MP_OKAY) + goto MU; + + mp_set(&s, 1); + + /* mu = b^2k / m */ + if ((res = s_mp_add_d(&mu, 1)) != MP_OKAY) + goto CLEANUP; + if ((res = s_mp_lshd(&mu, 2 * USED(m))) != MP_OKAY) + goto CLEANUP; + if ((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY) + goto CLEANUP; + + /* Loop over digits of b in ascending order, except highest order */ + for (dig = 0; dig < (USED(b) - 1); dig++) { + d = DIGIT(b, dig); + + /* Loop over the bits of the lower-order digits */ + for (bit = 0; bit < DIGIT_BIT; bit++) { + if (d & 1) { + if ((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + if ((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if ((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + if ((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + } - if((res = mp_init(&s)) != MP_OKAY) - return res; - if((res = mp_init_copy(&x, a)) != MP_OKAY || - (res = mp_mod(&x, m, &x)) != MP_OKAY) - goto X; - if((res = mp_init(&mu)) != MP_OKAY) - goto MU; - - mp_set(&s, 1); - - /* mu = b^2k / m */ - s_mp_add_d(&mu, 1); - s_mp_lshd(&mu, 2 * USED(m)); - if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY) - goto CLEANUP; - - /* Loop over digits of b in ascending order, except highest order */ - for(dig = 0; dig < (USED(b) - 1); dig++) { + /* Now do the last digit... */ d = DIGIT(b, dig); - /* Loop over the bits of the lower-order digits */ - for(bit = 0; bit < DIGIT_BIT; bit++) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) - goto CLEANUP; - } + while (d) { + if (d & 1) { + if ((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + if ((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) + goto CLEANUP; + } - d >>= 1; + d >>= 1; - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) - goto CLEANUP; + if ((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + if ((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) + goto CLEANUP; } - } - - /* Now do the last digit... */ - d = DIGIT(b, dig); - - while(d) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) - goto CLEANUP; - } + s_mp_exch(&s, c); - s_mp_exch(&s, c); - - CLEANUP: - mp_clear(&mu); - MU: - mp_clear(&x); - X: - mp_clear(&s); +CLEANUP: + mp_clear(&mu); +MU: + mp_clear(&x); +X: + mp_clear(&s); - return res; + return res; } /* end s_mp_exptmod() */ @@ -1551,42 +1522,43 @@ mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c /* {{{ mp_exptmod_d(a, d, m, c) */ -mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c) +mp_err +mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c) { - mp_int s, x; - mp_err res; + mp_int s, x; + mp_err res; - ARGCHK(a != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && c != NULL, MP_BADARG); - if((res = mp_init(&s)) != MP_OKAY) - return res; - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; + if ((res = mp_init(&s)) != MP_OKAY) + return res; + if ((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; - mp_set(&s, 1); + mp_set(&s, 1); - while(d != 0) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY || - (res = mp_mod(&s, m, &s)) != MP_OKAY) - goto CLEANUP; - } + while (d != 0) { + if (d & 1) { + if ((res = s_mp_mul(&s, &x)) != MP_OKAY || + (res = mp_mod(&s, m, &s)) != MP_OKAY) + goto CLEANUP; + } - d /= 2; + d /= 2; - if((res = s_mp_sqr(&x)) != MP_OKAY || - (res = mp_mod(&x, m, &x)) != MP_OKAY) - goto CLEANUP; - } + if ((res = s_mp_sqr(&x)) != MP_OKAY || + (res = mp_mod(&x, m, &x)) != MP_OKAY) + goto CLEANUP; + } - s_mp_exch(&s, c); + s_mp_exch(&s, c); CLEANUP: - mp_clear(&x); + mp_clear(&x); X: - mp_clear(&s); + mp_clear(&s); - return res; + return res; } /* end mp_exptmod_d() */ @@ -1606,14 +1578,15 @@ X: Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0. */ -int mp_cmp_z(const mp_int *a) +int +mp_cmp_z(const mp_int *a) { - if(SIGN(a) == NEG) - return MP_LT; - else if(USED(a) == 1 && DIGIT(a, 0) == 0) - return MP_EQ; - else - return MP_GT; + if (SIGN(a) == NEG) + return MP_LT; + else if (USED(a) == 1 && DIGIT(a, 0) == 0) + return MP_EQ; + else + return MP_GT; } /* end mp_cmp_z() */ @@ -1627,14 +1600,15 @@ int mp_cmp_z(const mp_int *a) Compare a <=> d. Returns <0 if a<d, 0 if a=d, >0 if a>d */ -int mp_cmp_d(const mp_int *a, mp_digit d) +int +mp_cmp_d(const mp_int *a, mp_digit d) { - ARGCHK(a != NULL, MP_EQ); + ARGCHK(a != NULL, MP_EQ); - if(SIGN(a) == NEG) - return MP_LT; + if (SIGN(a) == NEG) + return MP_LT; - return s_mp_cmp_d(a, d); + return s_mp_cmp_d(a, d); } /* end mp_cmp_d() */ @@ -1642,26 +1616,27 @@ int mp_cmp_d(const mp_int *a, mp_digit d) /* {{{ mp_cmp(a, b) */ -int mp_cmp(const mp_int *a, const mp_int *b) +int +mp_cmp(const mp_int *a, const mp_int *b) { - ARGCHK(a != NULL && b != NULL, MP_EQ); + ARGCHK(a != NULL && b != NULL, MP_EQ); - if(SIGN(a) == SIGN(b)) { - int mag; + if (SIGN(a) == SIGN(b)) { + int mag; - if((mag = s_mp_cmp(a, b)) == MP_EQ) - return MP_EQ; + if ((mag = s_mp_cmp(a, b)) == MP_EQ) + return MP_EQ; - if(SIGN(a) == ZPOS) - return mag; - else - return -mag; + if (SIGN(a) == ZPOS) + return mag; + else + return -mag; - } else if(SIGN(a) == ZPOS) { - return MP_GT; - } else { - return MP_LT; - } + } else if (SIGN(a) == ZPOS) { + return MP_GT; + } else { + return MP_LT; + } } /* end mp_cmp() */ @@ -1675,41 +1650,17 @@ int mp_cmp(const mp_int *a, const mp_int *b) Compares |a| <=> |b|, and returns an appropriate comparison result */ -int mp_cmp_mag(mp_int *a, mp_int *b) +int +mp_cmp_mag(const mp_int *a, const mp_int *b) { - ARGCHK(a != NULL && b != NULL, MP_EQ); + ARGCHK(a != NULL && b != NULL, MP_EQ); - return s_mp_cmp(a, b); + return s_mp_cmp(a, b); } /* end mp_cmp_mag() */ /* }}} */ -/* {{{ mp_cmp_int(a, z) */ - -/* - This just converts z to an mp_int, and uses the existing comparison - routines. This is sort of inefficient, but it's not clear to me how - frequently this wil get used anyway. For small positive constants, - you can always use mp_cmp_d(), and for zero, there is mp_cmp_z(). - */ -int mp_cmp_int(const mp_int *a, long z) -{ - mp_int tmp; - int out; - - ARGCHK(a != NULL, MP_EQ); - - mp_init(&tmp); mp_set_int(&tmp, z); - out = mp_cmp(a, &tmp); - mp_clear(&tmp); - - return out; - -} /* end mp_cmp_int() */ - -/* }}} */ - /* {{{ mp_isodd(a) */ /* @@ -1717,11 +1668,12 @@ int mp_cmp_int(const mp_int *a, long z) Returns a true (non-zero) value if a is odd, false (zero) otherwise. */ -int mp_isodd(const mp_int *a) +int +mp_isodd(const mp_int *a) { - ARGCHK(a != NULL, 0); + ARGCHK(a != NULL, 0); - return (int)(DIGIT(a, 0) & 1); + return (int)(DIGIT(a, 0) & 1); } /* end mp_isodd() */ @@ -1729,9 +1681,10 @@ int mp_isodd(const mp_int *a) /* {{{ mp_iseven(a) */ -int mp_iseven(const mp_int *a) +int +mp_iseven(const mp_int *a) { - return !mp_isodd(a); + return !mp_isodd(a); } /* end mp_iseven() */ @@ -1749,94 +1702,94 @@ int mp_iseven(const mp_int *a) Like the old mp_gcd() function, except computes the GCD using the binary algorithm due to Josef Stein in 1961 (via Knuth). */ -mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c) +mp_err +mp_gcd(mp_int *a, mp_int *b, mp_int *c) { - mp_err res; - mp_int u, v, t; - mp_size k = 0; + mp_err res; + mp_int u, v, t; + mp_size k = 0; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if (mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ) + return MP_RANGE; + if (mp_cmp_z(a) == MP_EQ) { + return mp_copy(b, c); + } else if (mp_cmp_z(b) == MP_EQ) { + return mp_copy(a, c); + } - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + if ((res = mp_init(&t)) != MP_OKAY) + return res; + if ((res = mp_init_copy(&u, a)) != MP_OKAY) + goto U; + if ((res = mp_init_copy(&v, b)) != MP_OKAY) + goto V; + + SIGN(&u) = ZPOS; + SIGN(&v) = ZPOS; + + /* Divide out common factors of 2 until at least 1 of a, b is even */ + while (mp_iseven(&u) && mp_iseven(&v)) { + s_mp_div_2(&u); + s_mp_div_2(&v); + ++k; + } - if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ) - return MP_RANGE; - if(mp_cmp_z(a) == MP_EQ) { - return mp_copy(b, c); - } else if(mp_cmp_z(b) == MP_EQ) { - return mp_copy(a, c); - } + /* Initialize t */ + if (mp_isodd(&u)) { + if ((res = mp_copy(&v, &t)) != MP_OKAY) + goto CLEANUP; - if((res = mp_init(&t)) != MP_OKAY) - return res; - if((res = mp_init_copy(&u, a)) != MP_OKAY) - goto U; - if((res = mp_init_copy(&v, b)) != MP_OKAY) - goto V; - - SIGN(&u) = ZPOS; - SIGN(&v) = ZPOS; - - /* Divide out common factors of 2 until at least 1 of a, b is even */ - while(mp_iseven(&u) && mp_iseven(&v)) { - s_mp_div_2(&u); - s_mp_div_2(&v); - ++k; - } - - /* Initialize t */ - if(mp_isodd(&u)) { - if((res = mp_copy(&v, &t)) != MP_OKAY) - goto CLEANUP; - - /* t = -v */ - if(SIGN(&v) == ZPOS) - SIGN(&t) = NEG; - else - SIGN(&t) = ZPOS; - - } else { - if((res = mp_copy(&u, &t)) != MP_OKAY) - goto CLEANUP; + /* t = -v */ + if (SIGN(&v) == ZPOS) + SIGN(&t) = NEG; + else + SIGN(&t) = ZPOS; - } - - for(;;) { - while(mp_iseven(&t)) { - s_mp_div_2(&t); + } else { + if ((res = mp_copy(&u, &t)) != MP_OKAY) + goto CLEANUP; } - if(mp_cmp_z(&t) == MP_GT) { - if((res = mp_copy(&t, &u)) != MP_OKAY) - goto CLEANUP; + for (;;) { + while (mp_iseven(&t)) { + s_mp_div_2(&t); + } - } else { - if((res = mp_copy(&t, &v)) != MP_OKAY) - goto CLEANUP; + if (mp_cmp_z(&t) == MP_GT) { + if ((res = mp_copy(&t, &u)) != MP_OKAY) + goto CLEANUP; - /* v = -t */ - if(SIGN(&t) == ZPOS) - SIGN(&v) = NEG; - else - SIGN(&v) = ZPOS; - } + } else { + if ((res = mp_copy(&t, &v)) != MP_OKAY) + goto CLEANUP; - if((res = mp_sub(&u, &v, &t)) != MP_OKAY) - goto CLEANUP; + /* v = -t */ + if (SIGN(&t) == ZPOS) + SIGN(&v) = NEG; + else + SIGN(&v) = ZPOS; + } - if(s_mp_cmp_d(&t, 0) == MP_EQ) - break; - } + if ((res = mp_sub(&u, &v, &t)) != MP_OKAY) + goto CLEANUP; - s_mp_2expt(&v, k); /* v = 2^k */ - res = mp_mul(&u, &v, c); /* c = u * v */ + if (s_mp_cmp_d(&t, 0) == MP_EQ) + break; + } - CLEANUP: - mp_clear(&v); - V: - mp_clear(&u); - U: - mp_clear(&t); + s_mp_2expt(&v, k); /* v = 2^k */ + res = mp_mul(&u, &v, c); /* c = u * v */ - return res; +CLEANUP: + mp_clear(&v); +V: + mp_clear(&u); +U: + mp_clear(&t); + + return res; } /* end mp_gcd() */ @@ -1851,32 +1804,33 @@ mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c) ... by computing the product, and dividing out the gcd. */ -mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c) +mp_err +mp_lcm(mp_int *a, mp_int *b, mp_int *c) { - mp_int gcd, prod; - mp_err res; + mp_int gcd, prod; + mp_err res; - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - /* Set up temporaries */ - if((res = mp_init(&gcd)) != MP_OKAY) - return res; - if((res = mp_init(&prod)) != MP_OKAY) - goto GCD; + /* Set up temporaries */ + if ((res = mp_init(&gcd)) != MP_OKAY) + return res; + if ((res = mp_init(&prod)) != MP_OKAY) + goto GCD; - if((res = mp_mul(a, b, &prod)) != MP_OKAY) - goto CLEANUP; - if((res = mp_gcd(a, b, &gcd)) != MP_OKAY) - goto CLEANUP; + if ((res = mp_mul(a, b, &prod)) != MP_OKAY) + goto CLEANUP; + if ((res = mp_gcd(a, b, &gcd)) != MP_OKAY) + goto CLEANUP; - res = mp_div(&prod, &gcd, c, NULL); + res = mp_div(&prod, &gcd, c, NULL); - CLEANUP: - mp_clear(&prod); - GCD: - mp_clear(&gcd); +CLEANUP: + mp_clear(&prod); +GCD: + mp_clear(&gcd); - return res; + return res; } /* end mp_lcm() */ @@ -1893,156 +1847,161 @@ mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c) See algorithm 14.61 in Handbook of Applied Cryptogrpahy. */ -mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y) +mp_err +mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y) { - mp_int gx, xc, yc, u, v, A, B, C, D; - mp_int *clean[9]; - mp_err res; - int last = -1; - - if(mp_cmp_z(b) == 0) - return MP_RANGE; - - /* Initialize all these variables we need */ - MP_CHECKOK( mp_init(&u) ); - clean[++last] = &u; - MP_CHECKOK( mp_init(&v) ); - clean[++last] = &v; - MP_CHECKOK( mp_init(&gx) ); - clean[++last] = &gx; - MP_CHECKOK( mp_init(&A) ); - clean[++last] = &A; - MP_CHECKOK( mp_init(&B) ); - clean[++last] = &B; - MP_CHECKOK( mp_init(&C) ); - clean[++last] = &C; - MP_CHECKOK( mp_init(&D) ); - clean[++last] = &D; - MP_CHECKOK( mp_init_copy(&xc, a) ); - clean[++last] = &xc; - mp_abs(&xc, &xc); - MP_CHECKOK( mp_init_copy(&yc, b) ); - clean[++last] = &yc; - mp_abs(&yc, &yc); - - mp_set(&gx, 1); - - /* Divide by two until at least one of them is odd */ - while(mp_iseven(&xc) && mp_iseven(&yc)) { - mp_size nx = mp_trailing_zeros(&xc); - mp_size ny = mp_trailing_zeros(&yc); - mp_size n = MP_MIN(nx, ny); - s_mp_div_2d(&xc,n); - s_mp_div_2d(&yc,n); - MP_CHECKOK( s_mp_mul_2d(&gx,n) ); - } - - mp_copy(&xc, &u); - mp_copy(&yc, &v); - mp_set(&A, 1); mp_set(&D, 1); - - /* Loop through binary GCD algorithm */ - do { - while(mp_iseven(&u)) { - s_mp_div_2(&u); - - if(mp_iseven(&A) && mp_iseven(&B)) { - s_mp_div_2(&A); s_mp_div_2(&B); - } else { - MP_CHECKOK( mp_add(&A, &yc, &A) ); - s_mp_div_2(&A); - MP_CHECKOK( mp_sub(&B, &xc, &B) ); - s_mp_div_2(&B); - } - } - - while(mp_iseven(&v)) { - s_mp_div_2(&v); - - if(mp_iseven(&C) && mp_iseven(&D)) { - s_mp_div_2(&C); s_mp_div_2(&D); - } else { - MP_CHECKOK( mp_add(&C, &yc, &C) ); - s_mp_div_2(&C); - MP_CHECKOK( mp_sub(&D, &xc, &D) ); - s_mp_div_2(&D); - } - } - - if(mp_cmp(&u, &v) >= 0) { - MP_CHECKOK( mp_sub(&u, &v, &u) ); - MP_CHECKOK( mp_sub(&A, &C, &A) ); - MP_CHECKOK( mp_sub(&B, &D, &B) ); - } else { - MP_CHECKOK( mp_sub(&v, &u, &v) ); - MP_CHECKOK( mp_sub(&C, &A, &C) ); - MP_CHECKOK( mp_sub(&D, &B, &D) ); + mp_int gx, xc, yc, u, v, A, B, C, D; + mp_int *clean[9]; + mp_err res; + int last = -1; + + if (mp_cmp_z(b) == 0) + return MP_RANGE; + + /* Initialize all these variables we need */ + MP_CHECKOK(mp_init(&u)); + clean[++last] = &u; + MP_CHECKOK(mp_init(&v)); + clean[++last] = &v; + MP_CHECKOK(mp_init(&gx)); + clean[++last] = &gx; + MP_CHECKOK(mp_init(&A)); + clean[++last] = &A; + MP_CHECKOK(mp_init(&B)); + clean[++last] = &B; + MP_CHECKOK(mp_init(&C)); + clean[++last] = &C; + MP_CHECKOK(mp_init(&D)); + clean[++last] = &D; + MP_CHECKOK(mp_init_copy(&xc, a)); + clean[++last] = &xc; + mp_abs(&xc, &xc); + MP_CHECKOK(mp_init_copy(&yc, b)); + clean[++last] = &yc; + mp_abs(&yc, &yc); + + mp_set(&gx, 1); + + /* Divide by two until at least one of them is odd */ + while (mp_iseven(&xc) && mp_iseven(&yc)) { + mp_size nx = mp_trailing_zeros(&xc); + mp_size ny = mp_trailing_zeros(&yc); + mp_size n = MP_MIN(nx, ny); + s_mp_div_2d(&xc, n); + s_mp_div_2d(&yc, n); + MP_CHECKOK(s_mp_mul_2d(&gx, n)); } - } while (mp_cmp_z(&u) != 0); - - /* copy results to output */ - if(x) - MP_CHECKOK( mp_copy(&C, x) ); - if(y) - MP_CHECKOK( mp_copy(&D, y) ); - - if(g) - MP_CHECKOK( mp_mul(&gx, &v, g) ); + MP_CHECKOK(mp_copy(&xc, &u)); + MP_CHECKOK(mp_copy(&yc, &v)); + mp_set(&A, 1); + mp_set(&D, 1); + + /* Loop through binary GCD algorithm */ + do { + while (mp_iseven(&u)) { + s_mp_div_2(&u); + + if (mp_iseven(&A) && mp_iseven(&B)) { + s_mp_div_2(&A); + s_mp_div_2(&B); + } else { + MP_CHECKOK(mp_add(&A, &yc, &A)); + s_mp_div_2(&A); + MP_CHECKOK(mp_sub(&B, &xc, &B)); + s_mp_div_2(&B); + } + } + + while (mp_iseven(&v)) { + s_mp_div_2(&v); + + if (mp_iseven(&C) && mp_iseven(&D)) { + s_mp_div_2(&C); + s_mp_div_2(&D); + } else { + MP_CHECKOK(mp_add(&C, &yc, &C)); + s_mp_div_2(&C); + MP_CHECKOK(mp_sub(&D, &xc, &D)); + s_mp_div_2(&D); + } + } + + if (mp_cmp(&u, &v) >= 0) { + MP_CHECKOK(mp_sub(&u, &v, &u)); + MP_CHECKOK(mp_sub(&A, &C, &A)); + MP_CHECKOK(mp_sub(&B, &D, &B)); + } else { + MP_CHECKOK(mp_sub(&v, &u, &v)); + MP_CHECKOK(mp_sub(&C, &A, &C)); + MP_CHECKOK(mp_sub(&D, &B, &D)); + } + } while (mp_cmp_z(&u) != 0); + + /* copy results to output */ + if (x) + MP_CHECKOK(mp_copy(&C, x)); + + if (y) + MP_CHECKOK(mp_copy(&D, y)); + + if (g) + MP_CHECKOK(mp_mul(&gx, &v, g)); - CLEANUP: - while(last >= 0) - mp_clear(clean[last--]); +CLEANUP: + while (last >= 0) + mp_clear(clean[last--]); - return res; + return res; } /* end mp_xgcd() */ /* }}} */ -mp_size mp_trailing_zeros(const mp_int *mp) +mp_size +mp_trailing_zeros(const mp_int *mp) { - mp_digit d; - mp_size n = 0; - unsigned int ix; + mp_digit d; + mp_size n = 0; + unsigned int ix; - if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp)) - return n; + if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp)) + return n; - for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix) - n += MP_DIGIT_BIT; - if (!d) - return 0; /* shouldn't happen, but ... */ + for (ix = 0; !(d = MP_DIGIT(mp, ix)) && (ix < MP_USED(mp)); ++ix) + n += MP_DIGIT_BIT; + if (!d) + return 0; /* shouldn't happen, but ... */ #if !defined(MP_USE_UINT_DIGIT) - if (!(d & 0xffffffffU)) { - d >>= 32; - n += 32; - } + if (!(d & 0xffffffffU)) { + d >>= 32; + n += 32; + } #endif - if (!(d & 0xffffU)) { - d >>= 16; - n += 16; - } - if (!(d & 0xffU)) { - d >>= 8; - n += 8; - } - if (!(d & 0xfU)) { - d >>= 4; - n += 4; - } - if (!(d & 0x3U)) { - d >>= 2; - n += 2; - } - if (!(d & 0x1U)) { - d >>= 1; - n += 1; - } + if (!(d & 0xffffU)) { + d >>= 16; + n += 16; + } + if (!(d & 0xffU)) { + d >>= 8; + n += 8; + } + if (!(d & 0xfU)) { + d >>= 4; + n += 4; + } + if (!(d & 0x3U)) { + d >>= 2; + n += 2; + } + if (!(d & 0x1U)) { + d >>= 1; + n += 1; + } #if MP_ARGCHK == 2 - assert(0 != (d & 1)); + assert(0 != (d & 1)); #endif - return n; + return n; } /* Given a and prime p, computes c and k such that a*c == 2**k (mod p). @@ -2050,337 +2009,343 @@ mp_size mp_trailing_zeros(const mp_int *mp) ** This technique from the paper "Fast Modular Reciprocals" (unpublished) ** by Richard Schroeppel (a.k.a. Captain Nemo). */ -mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c) +mp_err +s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c) { - mp_err res; - mp_err k = 0; - mp_int d, f, g; - - ARGCHK(a && p && c, MP_BADARG); - - MP_DIGITS(&d) = 0; - MP_DIGITS(&f) = 0; - MP_DIGITS(&g) = 0; - MP_CHECKOK( mp_init(&d) ); - MP_CHECKOK( mp_init_copy(&f, a) ); /* f = a */ - MP_CHECKOK( mp_init_copy(&g, p) ); /* g = p */ - - mp_set(c, 1); - mp_zero(&d); - - if (mp_cmp_z(&f) == 0) { - res = MP_UNDEF; - } else - for (;;) { - int diff_sign; - while (mp_iseven(&f)) { - mp_size n = mp_trailing_zeros(&f); - if (!n) { - res = MP_UNDEF; - goto CLEANUP; - } - s_mp_div_2d(&f, n); - MP_CHECKOK( s_mp_mul_2d(&d, n) ); - k += n; - } - if (mp_cmp_d(&f, 1) == MP_EQ) { /* f == 1 */ - res = k; - break; - } - diff_sign = mp_cmp(&f, &g); - if (diff_sign < 0) { /* f < g */ - s_mp_exch(&f, &g); - s_mp_exch(c, &d); - } else if (diff_sign == 0) { /* f == g */ - res = MP_UNDEF; /* a and p are not relatively prime */ - break; - } - if ((MP_DIGIT(&f,0) % 4) == (MP_DIGIT(&g,0) % 4)) { - MP_CHECKOK( mp_sub(&f, &g, &f) ); /* f = f - g */ - MP_CHECKOK( mp_sub(c, &d, c) ); /* c = c - d */ - } else { - MP_CHECKOK( mp_add(&f, &g, &f) ); /* f = f + g */ - MP_CHECKOK( mp_add(c, &d, c) ); /* c = c + d */ - } - } - if (res >= 0) { - while (MP_SIGN(c) != MP_ZPOS) { - MP_CHECKOK( mp_add(c, p, c) ); + mp_err res; + mp_err k = 0; + mp_int d, f, g; + + ARGCHK(a && p && c, MP_BADARG); + + MP_DIGITS(&d) = 0; + MP_DIGITS(&f) = 0; + MP_DIGITS(&g) = 0; + MP_CHECKOK(mp_init(&d)); + MP_CHECKOK(mp_init_copy(&f, a)); /* f = a */ + MP_CHECKOK(mp_init_copy(&g, p)); /* g = p */ + + mp_set(c, 1); + mp_zero(&d); + + if (mp_cmp_z(&f) == 0) { + res = MP_UNDEF; + } else + for (;;) { + int diff_sign; + while (mp_iseven(&f)) { + mp_size n = mp_trailing_zeros(&f); + if (!n) { + res = MP_UNDEF; + goto CLEANUP; + } + s_mp_div_2d(&f, n); + MP_CHECKOK(s_mp_mul_2d(&d, n)); + k += n; + } + if (mp_cmp_d(&f, 1) == MP_EQ) { /* f == 1 */ + res = k; + break; + } + diff_sign = mp_cmp(&f, &g); + if (diff_sign < 0) { /* f < g */ + s_mp_exch(&f, &g); + s_mp_exch(c, &d); + } else if (diff_sign == 0) { /* f == g */ + res = MP_UNDEF; /* a and p are not relatively prime */ + break; + } + if ((MP_DIGIT(&f, 0) % 4) == (MP_DIGIT(&g, 0) % 4)) { + MP_CHECKOK(mp_sub(&f, &g, &f)); /* f = f - g */ + MP_CHECKOK(mp_sub(c, &d, c)); /* c = c - d */ + } else { + MP_CHECKOK(mp_add(&f, &g, &f)); /* f = f + g */ + MP_CHECKOK(mp_add(c, &d, c)); /* c = c + d */ + } + } + if (res >= 0) { + while (MP_SIGN(c) != MP_ZPOS) { + MP_CHECKOK(mp_add(c, p, c)); + } + res = k; } - res = k; - } CLEANUP: - mp_clear(&d); - mp_clear(&f); - mp_clear(&g); - return res; + mp_clear(&d); + mp_clear(&f); + mp_clear(&g); + return res; } /* Compute T = (P ** -1) mod MP_RADIX. Also works for 16-bit mp_digits. ** This technique from the paper "Fast Modular Reciprocals" (unpublished) ** by Richard Schroeppel (a.k.a. Captain Nemo). */ -mp_digit s_mp_invmod_radix(mp_digit P) +mp_digit +s_mp_invmod_radix(mp_digit P) { - mp_digit T = P; - T *= 2 - (P * T); - T *= 2 - (P * T); - T *= 2 - (P * T); - T *= 2 - (P * T); + mp_digit T = P; + T *= 2 - (P * T); + T *= 2 - (P * T); + T *= 2 - (P * T); + T *= 2 - (P * T); #if !defined(MP_USE_UINT_DIGIT) - T *= 2 - (P * T); - T *= 2 - (P * T); + T *= 2 - (P * T); + T *= 2 - (P * T); #endif - return T; + return T; } -/* Given c, k, and prime p, where a*c == 2**k (mod p), +/* Given c, k, and prime p, where a*c == 2**k (mod p), ** Compute x = (a ** -1) mod p. This is similar to Montgomery reduction. ** This technique from the paper "Fast Modular Reciprocals" (unpublished) ** by Richard Schroeppel (a.k.a. Captain Nemo). */ -mp_err s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int *x) +mp_err +s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int *x) { - int k_orig = k; - mp_digit r; - mp_size ix; - mp_err res; - - if (mp_cmp_z(c) < 0) { /* c < 0 */ - MP_CHECKOK( mp_add(c, p, x) ); /* x = c + p */ - } else { - MP_CHECKOK( mp_copy(c, x) ); /* x = c */ - } - - /* make sure x is large enough */ - ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1; - ix = MP_MAX(ix, MP_USED(x)); - MP_CHECKOK( s_mp_pad(x, ix) ); - - r = 0 - s_mp_invmod_radix(MP_DIGIT(p,0)); - - for (ix = 0; k > 0; ix++) { - int j = MP_MIN(k, MP_DIGIT_BIT); - mp_digit v = r * MP_DIGIT(x, ix); - if (j < MP_DIGIT_BIT) { - v &= ((mp_digit)1 << j) - 1; /* v = v mod (2 ** j) */ - } - s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */ - k -= j; - } - s_mp_clamp(x); - s_mp_div_2d(x, k_orig); - res = MP_OKAY; + int k_orig = k; + mp_digit r; + mp_size ix; + mp_err res; + + if (mp_cmp_z(c) < 0) { /* c < 0 */ + MP_CHECKOK(mp_add(c, p, x)); /* x = c + p */ + } else { + MP_CHECKOK(mp_copy(c, x)); /* x = c */ + } + + /* make sure x is large enough */ + ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1; + ix = MP_MAX(ix, MP_USED(x)); + MP_CHECKOK(s_mp_pad(x, ix)); + + r = 0 - s_mp_invmod_radix(MP_DIGIT(p, 0)); + + for (ix = 0; k > 0; ix++) { + int j = MP_MIN(k, MP_DIGIT_BIT); + mp_digit v = r * MP_DIGIT(x, ix); + if (j < MP_DIGIT_BIT) { + v &= ((mp_digit)1 << j) - 1; /* v = v mod (2 ** j) */ + } + s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */ + k -= j; + } + s_mp_clamp(x); + s_mp_div_2d(x, k_orig); + res = MP_OKAY; CLEANUP: - return res; + return res; } /* compute mod inverse using Schroeppel's method, only if m is odd */ -mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c) +mp_err +s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c) { - int k; - mp_err res; - mp_int x; - - ARGCHK(a && m && c, MP_BADARG); + int k; + mp_err res; + mp_int x; - if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) - return MP_RANGE; - if (mp_iseven(m)) - return MP_UNDEF; + ARGCHK(a && m && c, MP_BADARG); - MP_DIGITS(&x) = 0; + if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) + return MP_RANGE; + if (mp_iseven(m)) + return MP_UNDEF; - if (a == c) { - if ((res = mp_init_copy(&x, a)) != MP_OKAY) - return res; - if (a == m) - m = &x; - a = &x; - } else if (m == c) { - if ((res = mp_init_copy(&x, m)) != MP_OKAY) - return res; - m = &x; - } else { MP_DIGITS(&x) = 0; - } - MP_CHECKOK( s_mp_almost_inverse(a, m, c) ); - k = res; - MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) ); + if (a == c) { + if ((res = mp_init_copy(&x, a)) != MP_OKAY) + return res; + if (a == m) + m = &x; + a = &x; + } else if (m == c) { + if ((res = mp_init_copy(&x, m)) != MP_OKAY) + return res; + m = &x; + } else { + MP_DIGITS(&x) = 0; + } + + MP_CHECKOK(s_mp_almost_inverse(a, m, c)); + k = res; + MP_CHECKOK(s_mp_fixup_reciprocal(c, m, k, c)); CLEANUP: - mp_clear(&x); - return res; + mp_clear(&x); + return res; } /* Known good algorithm for computing modular inverse. But slow. */ -mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c) +mp_err +mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c) { - mp_int g, x; - mp_err res; + mp_int g, x; + mp_err res; - ARGCHK(a && m && c, MP_BADARG); + ARGCHK(a && m && c, MP_BADARG); - if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) - return MP_RANGE; + if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) + return MP_RANGE; - MP_DIGITS(&g) = 0; - MP_DIGITS(&x) = 0; - MP_CHECKOK( mp_init(&x) ); - MP_CHECKOK( mp_init(&g) ); + MP_DIGITS(&g) = 0; + MP_DIGITS(&x) = 0; + MP_CHECKOK(mp_init(&x)); + MP_CHECKOK(mp_init(&g)); - MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) ); + MP_CHECKOK(mp_xgcd(a, m, &g, &x, NULL)); - if (mp_cmp_d(&g, 1) != MP_EQ) { - res = MP_UNDEF; - goto CLEANUP; - } + if (mp_cmp_d(&g, 1) != MP_EQ) { + res = MP_UNDEF; + goto CLEANUP; + } - res = mp_mod(&x, m, c); - SIGN(c) = SIGN(a); + res = mp_mod(&x, m, c); + SIGN(c) = SIGN(a); CLEANUP: - mp_clear(&x); - mp_clear(&g); + mp_clear(&x); + mp_clear(&g); - return res; + return res; } /* modular inverse where modulus is 2**k. */ /* c = a**-1 mod 2**k */ -mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c) +mp_err +s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c) { - mp_err res; - mp_size ix = k + 4; - mp_int t0, t1, val, tmp, two2k; - - static const mp_digit d2 = 2; - static const mp_int two = { MP_ZPOS, 1, 1, (mp_digit *)&d2 }; - - if (mp_iseven(a)) - return MP_UNDEF; - if (k <= MP_DIGIT_BIT) { - mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0)); - if (k < MP_DIGIT_BIT) - i &= ((mp_digit)1 << k) - (mp_digit)1; - mp_set(c, i); - return MP_OKAY; - } - MP_DIGITS(&t0) = 0; - MP_DIGITS(&t1) = 0; - MP_DIGITS(&val) = 0; - MP_DIGITS(&tmp) = 0; - MP_DIGITS(&two2k) = 0; - MP_CHECKOK( mp_init_copy(&val, a) ); - s_mp_mod_2d(&val, k); - MP_CHECKOK( mp_init_copy(&t0, &val) ); - MP_CHECKOK( mp_init_copy(&t1, &t0) ); - MP_CHECKOK( mp_init(&tmp) ); - MP_CHECKOK( mp_init(&two2k) ); - MP_CHECKOK( s_mp_2expt(&two2k, k) ); - do { - MP_CHECKOK( mp_mul(&val, &t1, &tmp) ); - MP_CHECKOK( mp_sub(&two, &tmp, &tmp) ); - MP_CHECKOK( mp_mul(&t1, &tmp, &t1) ); - s_mp_mod_2d(&t1, k); - while (MP_SIGN(&t1) != MP_ZPOS) { - MP_CHECKOK( mp_add(&t1, &two2k, &t1) ); - } - if (mp_cmp(&t1, &t0) == MP_EQ) - break; - MP_CHECKOK( mp_copy(&t1, &t0) ); - } while (--ix > 0); - if (!ix) { - res = MP_UNDEF; - } else { - mp_exch(c, &t1); - } + mp_err res; + mp_size ix = k + 4; + mp_int t0, t1, val, tmp, two2k; + + static const mp_digit d2 = 2; + static const mp_int two = { MP_ZPOS, 1, 1, (mp_digit *)&d2 }; + + if (mp_iseven(a)) + return MP_UNDEF; + if (k <= MP_DIGIT_BIT) { + mp_digit i = s_mp_invmod_radix(MP_DIGIT(a, 0)); + if (k < MP_DIGIT_BIT) + i &= ((mp_digit)1 << k) - (mp_digit)1; + mp_set(c, i); + return MP_OKAY; + } + MP_DIGITS(&t0) = 0; + MP_DIGITS(&t1) = 0; + MP_DIGITS(&val) = 0; + MP_DIGITS(&tmp) = 0; + MP_DIGITS(&two2k) = 0; + MP_CHECKOK(mp_init_copy(&val, a)); + s_mp_mod_2d(&val, k); + MP_CHECKOK(mp_init_copy(&t0, &val)); + MP_CHECKOK(mp_init_copy(&t1, &t0)); + MP_CHECKOK(mp_init(&tmp)); + MP_CHECKOK(mp_init(&two2k)); + MP_CHECKOK(s_mp_2expt(&two2k, k)); + do { + MP_CHECKOK(mp_mul(&val, &t1, &tmp)); + MP_CHECKOK(mp_sub(&two, &tmp, &tmp)); + MP_CHECKOK(mp_mul(&t1, &tmp, &t1)); + s_mp_mod_2d(&t1, k); + while (MP_SIGN(&t1) != MP_ZPOS) { + MP_CHECKOK(mp_add(&t1, &two2k, &t1)); + } + if (mp_cmp(&t1, &t0) == MP_EQ) + break; + MP_CHECKOK(mp_copy(&t1, &t0)); + } while (--ix > 0); + if (!ix) { + res = MP_UNDEF; + } else { + mp_exch(c, &t1); + } CLEANUP: - mp_clear(&t0); - mp_clear(&t1); - mp_clear(&val); - mp_clear(&tmp); - mp_clear(&two2k); - return res; + mp_clear(&t0); + mp_clear(&t1); + mp_clear(&val); + mp_clear(&tmp); + mp_clear(&two2k); + return res; } -mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c) +mp_err +s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c) { - mp_err res; - mp_size k; - mp_int oddFactor, evenFactor; /* factors of the modulus */ - mp_int oddPart, evenPart; /* parts to combine via CRT. */ - mp_int C2, tmp1, tmp2; - - /*static const mp_digit d1 = 1; */ - /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */ - - if ((res = s_mp_ispow2(m)) >= 0) { - k = res; - return s_mp_invmod_2d(a, k, c); - } - MP_DIGITS(&oddFactor) = 0; - MP_DIGITS(&evenFactor) = 0; - MP_DIGITS(&oddPart) = 0; - MP_DIGITS(&evenPart) = 0; - MP_DIGITS(&C2) = 0; - MP_DIGITS(&tmp1) = 0; - MP_DIGITS(&tmp2) = 0; - - MP_CHECKOK( mp_init_copy(&oddFactor, m) ); /* oddFactor = m */ - MP_CHECKOK( mp_init(&evenFactor) ); - MP_CHECKOK( mp_init(&oddPart) ); - MP_CHECKOK( mp_init(&evenPart) ); - MP_CHECKOK( mp_init(&C2) ); - MP_CHECKOK( mp_init(&tmp1) ); - MP_CHECKOK( mp_init(&tmp2) ); - - k = mp_trailing_zeros(m); - s_mp_div_2d(&oddFactor, k); - MP_CHECKOK( s_mp_2expt(&evenFactor, k) ); - - /* compute a**-1 mod oddFactor. */ - MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) ); - /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */ - MP_CHECKOK( s_mp_invmod_2d( a, k, &evenPart) ); - - /* Use Chinese Remainer theorem to compute a**-1 mod m. */ - /* let m1 = oddFactor, v1 = oddPart, - * let m2 = evenFactor, v2 = evenPart. - */ + mp_err res; + mp_size k; + mp_int oddFactor, evenFactor; /* factors of the modulus */ + mp_int oddPart, evenPart; /* parts to combine via CRT. */ + mp_int C2, tmp1, tmp2; + + /*static const mp_digit d1 = 1; */ + /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */ + + if ((res = s_mp_ispow2(m)) >= 0) { + k = res; + return s_mp_invmod_2d(a, k, c); + } + MP_DIGITS(&oddFactor) = 0; + MP_DIGITS(&evenFactor) = 0; + MP_DIGITS(&oddPart) = 0; + MP_DIGITS(&evenPart) = 0; + MP_DIGITS(&C2) = 0; + MP_DIGITS(&tmp1) = 0; + MP_DIGITS(&tmp2) = 0; + + MP_CHECKOK(mp_init_copy(&oddFactor, m)); /* oddFactor = m */ + MP_CHECKOK(mp_init(&evenFactor)); + MP_CHECKOK(mp_init(&oddPart)); + MP_CHECKOK(mp_init(&evenPart)); + MP_CHECKOK(mp_init(&C2)); + MP_CHECKOK(mp_init(&tmp1)); + MP_CHECKOK(mp_init(&tmp2)); + + k = mp_trailing_zeros(m); + s_mp_div_2d(&oddFactor, k); + MP_CHECKOK(s_mp_2expt(&evenFactor, k)); + + /* compute a**-1 mod oddFactor. */ + MP_CHECKOK(s_mp_invmod_odd_m(a, &oddFactor, &oddPart)); + /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */ + MP_CHECKOK(s_mp_invmod_2d(a, k, &evenPart)); + + /* Use Chinese Remainer theorem to compute a**-1 mod m. */ + /* let m1 = oddFactor, v1 = oddPart, + * let m2 = evenFactor, v2 = evenPart. + */ - /* Compute C2 = m1**-1 mod m2. */ - MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k, &C2) ); + /* Compute C2 = m1**-1 mod m2. */ + MP_CHECKOK(s_mp_invmod_2d(&oddFactor, k, &C2)); - /* compute u = (v2 - v1)*C2 mod m2 */ - MP_CHECKOK( mp_sub(&evenPart, &oddPart, &tmp1) ); - MP_CHECKOK( mp_mul(&tmp1, &C2, &tmp2) ); - s_mp_mod_2d(&tmp2, k); - while (MP_SIGN(&tmp2) != MP_ZPOS) { - MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) ); - } + /* compute u = (v2 - v1)*C2 mod m2 */ + MP_CHECKOK(mp_sub(&evenPart, &oddPart, &tmp1)); + MP_CHECKOK(mp_mul(&tmp1, &C2, &tmp2)); + s_mp_mod_2d(&tmp2, k); + while (MP_SIGN(&tmp2) != MP_ZPOS) { + MP_CHECKOK(mp_add(&tmp2, &evenFactor, &tmp2)); + } - /* compute answer = v1 + u*m1 */ - MP_CHECKOK( mp_mul(&tmp2, &oddFactor, c) ); - MP_CHECKOK( mp_add(&oddPart, c, c) ); - /* not sure this is necessary, but it's low cost if not. */ - MP_CHECKOK( mp_mod(c, m, c) ); + /* compute answer = v1 + u*m1 */ + MP_CHECKOK(mp_mul(&tmp2, &oddFactor, c)); + MP_CHECKOK(mp_add(&oddPart, c, c)); + /* not sure this is necessary, but it's low cost if not. */ + MP_CHECKOK(mp_mod(c, m, c)); CLEANUP: - mp_clear(&oddFactor); - mp_clear(&evenFactor); - mp_clear(&oddPart); - mp_clear(&evenPart); - mp_clear(&C2); - mp_clear(&tmp1); - mp_clear(&tmp2); - return res; + mp_clear(&oddFactor); + mp_clear(&evenFactor); + mp_clear(&oddPart); + mp_clear(&evenPart); + mp_clear(&C2); + mp_clear(&tmp1); + mp_clear(&tmp2); + return res; } - /* {{{ mp_invmod(a, m, c) */ /* @@ -2391,21 +2356,22 @@ CLEANUP: MP_UNDEF is returned, and there is no inverse. */ -mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c) +mp_err +mp_invmod(const mp_int *a, const mp_int *m, mp_int *c) { - ARGCHK(a && m && c, MP_BADARG); + ARGCHK(a && m && c, MP_BADARG); - if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) - return MP_RANGE; + if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) + return MP_RANGE; - if (mp_isodd(m)) { - return s_mp_invmod_odd_m(a, m, c); - } - if (mp_iseven(a)) - return MP_UNDEF; /* not invertable */ + if (mp_isodd(m)) { + return s_mp_invmod_odd_m(a, m, c); + } + if (mp_iseven(a)) + return MP_UNDEF; /* not invertable */ - return s_mp_invmod_even_m(a, m, c); + return s_mp_invmod_even_m(a, m, c); } /* end mp_invmod() */ @@ -2425,18 +2391,19 @@ mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c) stream 'ofp'. Output is generated using the internal radix. */ -void mp_print(mp_int *mp, FILE *ofp) +void +mp_print(mp_int *mp, FILE *ofp) { - int ix; + int ix; - if(mp == NULL || ofp == NULL) - return; + if (mp == NULL || ofp == NULL) + return; - fputc((SIGN(mp) == NEG) ? '-' : '+', ofp); + fputc((SIGN(mp) == NEG) ? '-' : '+', ofp); - for(ix = USED(mp) - 1; ix >= 0; ix--) { - fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix)); - } + for (ix = USED(mp) - 1; ix >= 0; ix--) { + fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix)); + } } /* end mp_print() */ @@ -2449,37 +2416,38 @@ void mp_print(mp_int *mp, FILE *ofp) /* {{{ mp_read_raw(mp, str, len) */ -/* +/* mp_read_raw(mp, str, len) Read in a raw value (base 256) into the given mp_int */ -mp_err mp_read_raw(mp_int *mp, char *str, int len) +mp_err +mp_read_raw(mp_int *mp, char *str, int len) { - int ix; - mp_err res; - unsigned char *ustr = (unsigned char *)str; - - ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); + int ix; + mp_err res; + unsigned char *ustr = (unsigned char *)str; - mp_zero(mp); + ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); - /* Get sign from first byte */ - if(ustr[0]) - SIGN(mp) = NEG; - else - SIGN(mp) = ZPOS; + mp_zero(mp); - /* Read the rest of the digits */ - for(ix = 1; ix < len; ix++) { - if((res = mp_mul_d(mp, 256, mp)) != MP_OKAY) - return res; - if((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY) - return res; - } + /* Get sign from first byte */ + if (ustr[0]) + SIGN(mp) = NEG; + else + SIGN(mp) = ZPOS; + + /* Read the rest of the digits */ + for (ix = 1; ix < len; ix++) { + if ((res = mp_mul_d(mp, 256, mp)) != MP_OKAY) + return res; + if ((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY) + return res; + } - return MP_OKAY; + return MP_OKAY; } /* end mp_read_raw() */ @@ -2487,11 +2455,12 @@ mp_err mp_read_raw(mp_int *mp, char *str, int len) /* {{{ mp_raw_size(mp) */ -int mp_raw_size(mp_int *mp) +int +mp_raw_size(mp_int *mp) { - ARGCHK(mp != NULL, 0); + ARGCHK(mp != NULL, 0); - return (USED(mp) * sizeof(mp_digit)) + 1; + return (USED(mp) * sizeof(mp_digit)) + 1; } /* end mp_raw_size() */ @@ -2499,25 +2468,26 @@ int mp_raw_size(mp_int *mp) /* {{{ mp_toraw(mp, str) */ -mp_err mp_toraw(mp_int *mp, char *str) +mp_err +mp_toraw(mp_int *mp, char *str) { - int ix, jx, pos = 1; + int ix, jx, pos = 1; - ARGCHK(mp != NULL && str != NULL, MP_BADARG); + ARGCHK(mp != NULL && str != NULL, MP_BADARG); - str[0] = (char)SIGN(mp); + str[0] = (char)SIGN(mp); - /* Iterate over each digit... */ - for(ix = USED(mp) - 1; ix >= 0; ix--) { - mp_digit d = DIGIT(mp, ix); + /* Iterate over each digit... */ + for (ix = USED(mp) - 1; ix >= 0; ix--) { + mp_digit d = DIGIT(mp, ix); - /* Unpack digit bytes, high order first */ - for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { - str[pos++] = (char)(d >> (jx * CHAR_BIT)); + /* Unpack digit bytes, high order first */ + for (jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { + str[pos++] = (char)(d >> (jx * CHAR_BIT)); + } } - } - return MP_OKAY; + return MP_OKAY; } /* end mp_toraw() */ @@ -2534,103 +2504,106 @@ mp_err mp_toraw(mp_int *mp, char *str) character or the end of the string. */ -mp_err mp_read_radix(mp_int *mp, const char *str, int radix) +mp_err +mp_read_radix(mp_int *mp, const char *str, int radix) { - int ix = 0, val = 0; - mp_err res; - mp_sign sig = ZPOS; - - ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX, - MP_BADARG); - - mp_zero(mp); - - /* Skip leading non-digit characters until a digit or '-' or '+' */ - while(str[ix] && - (s_mp_tovalue(str[ix], radix) < 0) && - str[ix] != '-' && - str[ix] != '+') { - ++ix; - } - - if(str[ix] == '-') { - sig = NEG; - ++ix; - } else if(str[ix] == '+') { - sig = ZPOS; /* this is the default anyway... */ - ++ix; - } - - while((val = s_mp_tovalue(str[ix], radix)) >= 0) { - if((res = s_mp_mul_d(mp, radix)) != MP_OKAY) - return res; - if((res = s_mp_add_d(mp, val)) != MP_OKAY) - return res; - ++ix; - } - - if(s_mp_cmp_d(mp, 0) == MP_EQ) - SIGN(mp) = ZPOS; - else - SIGN(mp) = sig; + int ix = 0, val = 0; + mp_err res; + mp_sign sig = ZPOS; + + ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX, + MP_BADARG); - return MP_OKAY; + mp_zero(mp); + + /* Skip leading non-digit characters until a digit or '-' or '+' */ + while (str[ix] && + (s_mp_tovalue(str[ix], radix) < 0) && + str[ix] != '-' && + str[ix] != '+') { + ++ix; + } + + if (str[ix] == '-') { + sig = NEG; + ++ix; + } else if (str[ix] == '+') { + sig = ZPOS; /* this is the default anyway... */ + ++ix; + } + + while ((val = s_mp_tovalue(str[ix], radix)) >= 0) { + if ((res = s_mp_mul_d(mp, radix)) != MP_OKAY) + return res; + if ((res = s_mp_add_d(mp, val)) != MP_OKAY) + return res; + ++ix; + } + + if (s_mp_cmp_d(mp, 0) == MP_EQ) + SIGN(mp) = ZPOS; + else + SIGN(mp) = sig; + + return MP_OKAY; } /* end mp_read_radix() */ -mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix) +mp_err +mp_read_variable_radix(mp_int *a, const char *str, int default_radix) { - int radix = default_radix; - int cx; - mp_sign sig = ZPOS; - mp_err res; - - /* Skip leading non-digit characters until a digit or '-' or '+' */ - while ((cx = *str) != 0 && - (s_mp_tovalue(cx, radix) < 0) && - cx != '-' && - cx != '+') { - ++str; - } - - if (cx == '-') { - sig = NEG; - ++str; - } else if (cx == '+') { - sig = ZPOS; /* this is the default anyway... */ - ++str; - } - - if (str[0] == '0') { - if ((str[1] | 0x20) == 'x') { - radix = 16; - str += 2; - } else { - radix = 8; - str++; - } - } - res = mp_read_radix(a, str, radix); - if (res == MP_OKAY) { - MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig; - } - return res; + int radix = default_radix; + int cx; + mp_sign sig = ZPOS; + mp_err res; + + /* Skip leading non-digit characters until a digit or '-' or '+' */ + while ((cx = *str) != 0 && + (s_mp_tovalue(cx, radix) < 0) && + cx != '-' && + cx != '+') { + ++str; + } + + if (cx == '-') { + sig = NEG; + ++str; + } else if (cx == '+') { + sig = ZPOS; /* this is the default anyway... */ + ++str; + } + + if (str[0] == '0') { + if ((str[1] | 0x20) == 'x') { + radix = 16; + str += 2; + } else { + radix = 8; + str++; + } + } + res = mp_read_radix(a, str, radix); + if (res == MP_OKAY) { + MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig; + } + return res; } /* }}} */ /* {{{ mp_radix_size(mp, radix) */ -int mp_radix_size(mp_int *mp, int radix) +int +mp_radix_size(mp_int *mp, int radix) { - int bits; + int bits; + + if (!mp || radix < 2 || radix > MAX_RADIX) + return 0; - if(!mp || radix < 2 || radix > MAX_RADIX) - return 0; + bits = USED(mp) * DIGIT_BIT - 1; - bits = USED(mp) * DIGIT_BIT - 1; - - return s_mp_outlen(bits, radix); + return s_mp_outlen(bits, radix); } /* end mp_radix_size() */ @@ -2638,64 +2611,66 @@ int mp_radix_size(mp_int *mp, int radix) /* {{{ mp_toradix(mp, str, radix) */ -mp_err mp_toradix(mp_int *mp, char *str, int radix) +mp_err +mp_toradix(mp_int *mp, char *str, int radix) { - int ix, pos = 0; - - ARGCHK(mp != NULL && str != NULL, MP_BADARG); - ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE); - - if(mp_cmp_z(mp) == MP_EQ) { - str[0] = '0'; - str[1] = '\0'; - } else { - mp_err res; - mp_int tmp; - mp_sign sgn; - mp_digit rem, rdx = (mp_digit)radix; - char ch; + int ix, pos = 0; - if((res = mp_init_copy(&tmp, mp)) != MP_OKAY) - return res; + ARGCHK(mp != NULL && str != NULL, MP_BADARG); + ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE); - /* Save sign for later, and take absolute value */ - sgn = SIGN(&tmp); SIGN(&tmp) = ZPOS; - - /* Generate output digits in reverse order */ - while(mp_cmp_z(&tmp) != 0) { - if((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - /* Generate digits, use capital letters */ - ch = s_mp_todigit(rem, radix, 0); - - str[pos++] = ch; - } - - /* Add - sign if original value was negative */ - if(sgn == NEG) - str[pos++] = '-'; - - /* Add trailing NUL to end the string */ - str[pos--] = '\0'; - - /* Reverse the digits and sign indicator */ - ix = 0; - while(ix < pos) { - char tmp = str[ix]; - - str[ix] = str[pos]; - str[pos] = tmp; - ++ix; - --pos; + if (mp_cmp_z(mp) == MP_EQ) { + str[0] = '0'; + str[1] = '\0'; + } else { + mp_err res; + mp_int tmp; + mp_sign sgn; + mp_digit rem, rdx = (mp_digit)radix; + char ch; + + if ((res = mp_init_copy(&tmp, mp)) != MP_OKAY) + return res; + + /* Save sign for later, and take absolute value */ + sgn = SIGN(&tmp); + SIGN(&tmp) = ZPOS; + + /* Generate output digits in reverse order */ + while (mp_cmp_z(&tmp) != 0) { + if ((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + /* Generate digits, use capital letters */ + ch = s_mp_todigit(rem, radix, 0); + + str[pos++] = ch; + } + + /* Add - sign if original value was negative */ + if (sgn == NEG) + str[pos++] = '-'; + + /* Add trailing NUL to end the string */ + str[pos--] = '\0'; + + /* Reverse the digits and sign indicator */ + ix = 0; + while (ix < pos) { + char tmp = str[ix]; + + str[ix] = str[pos]; + str[pos] = tmp; + ++ix; + --pos; + } + + mp_clear(&tmp); } - - mp_clear(&tmp); - } - return MP_OKAY; + return MP_OKAY; } /* end mp_toradix() */ @@ -2703,9 +2678,10 @@ mp_err mp_toradix(mp_int *mp, char *str, int radix) /* {{{ mp_tovalue(ch, r) */ -int mp_tovalue(char ch, int r) +int +mp_tovalue(char ch, int r) { - return s_mp_tovalue(ch, r); + return s_mp_tovalue(ch, r); } /* end mp_tovalue() */ @@ -2723,17 +2699,18 @@ int mp_tovalue(char ch, int r) not attempt to modify or free the memory associated with this string. */ -const char *mp_strerror(mp_err ec) +const char * +mp_strerror(mp_err ec) { - int aec = (ec < 0) ? -ec : ec; + int aec = (ec < 0) ? -ec : ec; - /* Code values are negative, so the senses of these comparisons + /* Code values are negative, so the senses of these comparisons are accurate */ - if(ec < MP_LAST_CODE || ec > MP_OKAY) { - return mp_err_string[0]; /* unknown error code */ - } else { - return mp_err_string[aec + 1]; - } + if (ec < MP_LAST_CODE || ec > MP_OKAY) { + return mp_err_string[0]; /* unknown error code */ + } else { + return mp_err_string[aec + 1]; + } } /* end mp_strerror() */ @@ -2748,28 +2725,27 @@ const char *mp_strerror(mp_err ec) /* {{{ s_mp_grow(mp, min) */ /* Make sure there are at least 'min' digits allocated to mp */ -mp_err s_mp_grow(mp_int *mp, mp_size min) +mp_err +s_mp_grow(mp_int *mp, mp_size min) { - if(min > ALLOC(mp)) { - mp_digit *tmp; + if (min > ALLOC(mp)) { + mp_digit *tmp; - /* Set min to next nearest default precision block size */ - min = MP_ROUNDUP(min, s_mp_defprec); + /* Set min to next nearest default precision block size */ + min = MP_ROUNDUP(min, s_mp_defprec); - if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL) - return MP_MEM; + if ((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL) + return MP_MEM; - s_mp_copy(DIGITS(mp), tmp, USED(mp)); + s_mp_copy(DIGITS(mp), tmp, USED(mp)); -#if MP_CRYPTO - s_mp_setz(DIGITS(mp), ALLOC(mp)); -#endif - s_mp_free(DIGITS(mp)); - DIGITS(mp) = tmp; - ALLOC(mp) = min; - } + s_mp_setz(DIGITS(mp), ALLOC(mp)); + s_mp_free(DIGITS(mp)); + DIGITS(mp) = tmp; + ALLOC(mp) = min; + } - return MP_OKAY; + return MP_OKAY; } /* end s_mp_grow() */ @@ -2778,24 +2754,25 @@ mp_err s_mp_grow(mp_int *mp, mp_size min) /* {{{ s_mp_pad(mp, min) */ /* Make sure the used size of mp is at least 'min', growing if needed */ -mp_err s_mp_pad(mp_int *mp, mp_size min) +mp_err +s_mp_pad(mp_int *mp, mp_size min) { - if(min > USED(mp)) { - mp_err res; - - /* Make sure there is room to increase precision */ - if (min > ALLOC(mp)) { - if ((res = s_mp_grow(mp, min)) != MP_OKAY) - return res; - } else { - s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp)); + if (min > USED(mp)) { + mp_err res; + + /* Make sure there is room to increase precision */ + if (min > ALLOC(mp)) { + if ((res = s_mp_grow(mp, min)) != MP_OKAY) + return res; + } else { + s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp)); + } + + /* Increase precision; should already be 0-filled */ + USED(mp) = min; } - /* Increase precision; should already be 0-filled */ - USED(mp) = min; - } - - return MP_OKAY; + return MP_OKAY; } /* end s_mp_pad() */ @@ -2803,99 +2780,91 @@ mp_err s_mp_pad(mp_int *mp, mp_size min) /* {{{ s_mp_setz(dp, count) */ -#if MP_MACRO == 0 /* Set 'count' digits pointed to by dp to be zeroes */ -void s_mp_setz(mp_digit *dp, mp_size count) +void +s_mp_setz(mp_digit *dp, mp_size count) { #if MP_MEMSET == 0 - int ix; + int ix; - for(ix = 0; ix < count; ix++) - dp[ix] = 0; + for (ix = 0; ix < count; ix++) + dp[ix] = 0; #else - memset(dp, 0, count * sizeof(mp_digit)); + memset(dp, 0, count * sizeof(mp_digit)); #endif } /* end s_mp_setz() */ -#endif /* }}} */ /* {{{ s_mp_copy(sp, dp, count) */ -#if MP_MACRO == 0 /* Copy 'count' digits from sp to dp */ -void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count) +void +s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count) { #if MP_MEMCPY == 0 - int ix; + int ix; - for(ix = 0; ix < count; ix++) - dp[ix] = sp[ix]; + for (ix = 0; ix < count; ix++) + dp[ix] = sp[ix]; #else - memcpy(dp, sp, count * sizeof(mp_digit)); + memcpy(dp, sp, count * sizeof(mp_digit)); #endif - ++mp_copies; - } /* end s_mp_copy() */ -#endif /* }}} */ /* {{{ s_mp_alloc(nb, ni) */ -#if MP_MACRO == 0 /* Allocate ni records of nb bytes each, and return a pointer to that */ -void *s_mp_alloc(size_t nb, size_t ni) +void * +s_mp_alloc(size_t nb, size_t ni) { - ++mp_allocs; - return calloc(nb, ni); + return calloc(nb, ni); } /* end s_mp_alloc() */ -#endif /* }}} */ /* {{{ s_mp_free(ptr) */ -#if MP_MACRO == 0 /* Free the memory pointed to by ptr */ -void s_mp_free(void *ptr) +void +s_mp_free(void *ptr) { - if(ptr) { - ++mp_frees; - free(ptr); - } + if (ptr) { + free(ptr); + } } /* end s_mp_free() */ -#endif /* }}} */ /* {{{ s_mp_clamp(mp) */ -#if MP_MACRO == 0 /* Remove leading zeroes from the given value */ -void s_mp_clamp(mp_int *mp) +void +s_mp_clamp(mp_int *mp) { - mp_size used = MP_USED(mp); - while (used > 1 && DIGIT(mp, used - 1) == 0) - --used; - MP_USED(mp) = used; + mp_size used = MP_USED(mp); + while (used > 1 && DIGIT(mp, used - 1) == 0) + --used; + MP_USED(mp) = used; } /* end s_mp_clamp() */ -#endif /* }}} */ /* {{{ s_mp_exch(a, b) */ /* Exchange the data for a and b; (b, a) = (a, b) */ -void s_mp_exch(mp_int *a, mp_int *b) +void +s_mp_exch(mp_int *a, mp_int *b) { - mp_int tmp; + mp_int tmp; - tmp = *a; - *a = *b; - *b = tmp; + tmp = *a; + *a = *b; + *b = tmp; } /* end s_mp_exch() */ @@ -2907,36 +2876,37 @@ void s_mp_exch(mp_int *a, mp_int *b) /* {{{ s_mp_lshd(mp, p) */ -/* +/* Shift mp leftward by p digits, growing if needed, and zero-filling the in-shifted digits at the right end. This is a convenient alternative to multiplication by powers of the radix - */ + */ -mp_err s_mp_lshd(mp_int *mp, mp_size p) +mp_err +s_mp_lshd(mp_int *mp, mp_size p) { - mp_err res; - unsigned int ix; + mp_err res; + unsigned int ix; - if(p == 0) - return MP_OKAY; + if (p == 0) + return MP_OKAY; - if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0) - return MP_OKAY; + if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0) + return MP_OKAY; - if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY) - return res; + if ((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY) + return res; - /* Shift all the significant figures over as needed */ - for (ix = USED(mp) - p; ix-- > 0;) { - DIGIT(mp, ix + p) = DIGIT(mp, ix); - } + /* Shift all the significant figures over as needed */ + for (ix = USED(mp) - p; ix-- > 0;) { + DIGIT(mp, ix + p) = DIGIT(mp, ix); + } - /* Fill the bottom digits with zeroes */ - for(ix = 0; (mp_size)ix < p; ix++) - DIGIT(mp, ix) = 0; + /* Fill the bottom digits with zeroes */ + for (ix = 0; (mp_size)ix < p; ix++) + DIGIT(mp, ix) = 0; - return MP_OKAY; + return MP_OKAY; } /* end s_mp_lshd() */ @@ -2948,81 +2918,82 @@ mp_err s_mp_lshd(mp_int *mp, mp_size p) Multiply the integer by 2^d, where d is a number of bits. This amounts to a bitwise shift of the value. */ -mp_err s_mp_mul_2d(mp_int *mp, mp_digit d) +mp_err +s_mp_mul_2d(mp_int *mp, mp_digit d) { - mp_err res; - mp_digit dshift, bshift; - mp_digit mask; - - ARGCHK(mp != NULL, MP_BADARG); - - dshift = d / MP_DIGIT_BIT; - bshift = d % MP_DIGIT_BIT; - /* bits to be shifted out of the top word */ - mask = ((mp_digit)~0 << (MP_DIGIT_BIT - bshift)); - mask &= MP_DIGIT(mp, MP_USED(mp) - 1); + mp_err res; + mp_digit dshift, bshift; + mp_digit mask; + + ARGCHK(mp != NULL, MP_BADARG); + + dshift = d / MP_DIGIT_BIT; + bshift = d % MP_DIGIT_BIT; + /* bits to be shifted out of the top word */ + if (bshift) { + mask = (mp_digit)~0 << (MP_DIGIT_BIT - bshift); + mask &= MP_DIGIT(mp, MP_USED(mp) - 1); + } else { + mask = 0; + } - if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) ))) - return res; + if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0)))) + return res; - if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift))) - return res; + if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift))) + return res; - if (bshift) { - mp_digit *pa = MP_DIGITS(mp); - mp_digit *alim = pa + MP_USED(mp); - mp_digit prev = 0; + if (bshift) { + mp_digit *pa = MP_DIGITS(mp); + mp_digit *alim = pa + MP_USED(mp); + mp_digit prev = 0; - for (pa += dshift; pa < alim; ) { - mp_digit x = *pa; - *pa++ = (x << bshift) | prev; - prev = x >> (DIGIT_BIT - bshift); + for (pa += dshift; pa < alim;) { + mp_digit x = *pa; + *pa++ = (x << bshift) | prev; + prev = x >> (DIGIT_BIT - bshift); + } } - } - s_mp_clamp(mp); - return MP_OKAY; + s_mp_clamp(mp); + return MP_OKAY; } /* end s_mp_mul_2d() */ /* {{{ s_mp_rshd(mp, p) */ -/* +/* Shift mp rightward by p digits. Maintains the invariant that digits above the precision are all zero. Digits shifted off the end are lost. Cannot fail. */ -void s_mp_rshd(mp_int *mp, mp_size p) +void +s_mp_rshd(mp_int *mp, mp_size p) { - mp_size ix; - mp_digit *src, *dst; + mp_size ix; + mp_digit *src, *dst; + + if (p == 0) + return; + + /* Shortcut when all digits are to be shifted off */ + if (p >= USED(mp)) { + s_mp_setz(DIGITS(mp), ALLOC(mp)); + USED(mp) = 1; + SIGN(mp) = ZPOS; + return; + } - if(p == 0) - return; + /* Shift all the significant figures over as needed */ + dst = MP_DIGITS(mp); + src = dst + p; + for (ix = USED(mp) - p; ix > 0; ix--) + *dst++ = *src++; - /* Shortcut when all digits are to be shifted off */ - if(p >= USED(mp)) { - s_mp_setz(DIGITS(mp), ALLOC(mp)); - USED(mp) = 1; - SIGN(mp) = ZPOS; - return; - } - - /* Shift all the significant figures over as needed */ - dst = MP_DIGITS(mp); - src = dst + p; - for (ix = USED(mp) - p; ix > 0; ix--) - *dst++ = *src++; - - MP_USED(mp) -= p; - /* Fill the top digits with zeroes */ - while (p-- > 0) - *dst++ = 0; - -#if 0 - /* Strip off any leading zeroes */ - s_mp_clamp(mp); -#endif + MP_USED(mp) -= p; + /* Fill the top digits with zeroes */ + while (p-- > 0) + *dst++ = 0; } /* end s_mp_rshd() */ @@ -3031,9 +3002,10 @@ void s_mp_rshd(mp_int *mp, mp_size p) /* {{{ s_mp_div_2(mp) */ /* Divide by two -- take advantage of radix properties to do it fast */ -void s_mp_div_2(mp_int *mp) +void +s_mp_div_2(mp_int *mp) { - s_mp_div_2d(mp, 1); + s_mp_div_2d(mp, 1); } /* end s_mp_div_2() */ @@ -3041,34 +3013,35 @@ void s_mp_div_2(mp_int *mp) /* {{{ s_mp_mul_2(mp) */ -mp_err s_mp_mul_2(mp_int *mp) +mp_err +s_mp_mul_2(mp_int *mp) { - mp_digit *pd; - unsigned int ix, used; - mp_digit kin = 0; + mp_digit *pd; + unsigned int ix, used; + mp_digit kin = 0; - /* Shift digits leftward by 1 bit */ - used = MP_USED(mp); - pd = MP_DIGITS(mp); - for (ix = 0; ix < used; ix++) { - mp_digit d = *pd; - *pd++ = (d << 1) | kin; - kin = (d >> (DIGIT_BIT - 1)); - } - - /* Deal with rollover from last digit */ - if (kin) { - if (ix >= ALLOC(mp)) { - mp_err res; - if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY) - return res; + /* Shift digits leftward by 1 bit */ + used = MP_USED(mp); + pd = MP_DIGITS(mp); + for (ix = 0; ix < used; ix++) { + mp_digit d = *pd; + *pd++ = (d << 1) | kin; + kin = (d >> (DIGIT_BIT - 1)); } - DIGIT(mp, ix) = kin; - USED(mp) += 1; - } + /* Deal with rollover from last digit */ + if (kin) { + if (ix >= ALLOC(mp)) { + mp_err res; + if ((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY) + return res; + } - return MP_OKAY; + DIGIT(mp, ix) = kin; + USED(mp) += 1; + } + + return MP_OKAY; } /* end s_mp_mul_2() */ @@ -3081,24 +3054,25 @@ mp_err s_mp_mul_2(mp_int *mp) amounts to a bitwise AND of the value, and does not require the full division code */ -void s_mp_mod_2d(mp_int *mp, mp_digit d) +void +s_mp_mod_2d(mp_int *mp, mp_digit d) { - mp_size ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT); - mp_size ix; - mp_digit dmask; + mp_size ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT); + mp_size ix; + mp_digit dmask; - if(ndig >= USED(mp)) - return; + if (ndig >= USED(mp)) + return; - /* Flush all the bits above 2^d in its digit */ - dmask = ((mp_digit)1 << nbit) - 1; - DIGIT(mp, ndig) &= dmask; + /* Flush all the bits above 2^d in its digit */ + dmask = ((mp_digit)1 << nbit) - 1; + DIGIT(mp, ndig) &= dmask; - /* Flush all digits above the one with 2^d in it */ - for(ix = ndig + 1; ix < USED(mp); ix++) - DIGIT(mp, ix) = 0; + /* Flush all digits above the one with 2^d in it */ + for (ix = ndig + 1; ix < USED(mp); ix++) + DIGIT(mp, ix) = 0; - s_mp_clamp(mp); + s_mp_clamp(mp); } /* end s_mp_mod_2d() */ @@ -3111,23 +3085,24 @@ void s_mp_mod_2d(mp_int *mp, mp_digit d) amounts to a bitwise shift of the value, and does not require the full division code (used in Barrett reduction, see below) */ -void s_mp_div_2d(mp_int *mp, mp_digit d) +void +s_mp_div_2d(mp_int *mp, mp_digit d) { - int ix; - mp_digit save, next, mask; - - s_mp_rshd(mp, d / DIGIT_BIT); - d %= DIGIT_BIT; - if (d) { - mask = ((mp_digit)1 << d) - 1; - save = 0; - for(ix = USED(mp) - 1; ix >= 0; ix--) { - next = DIGIT(mp, ix) & mask; - DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d)); - save = next; - } - } - s_mp_clamp(mp); + int ix; + mp_digit save, next, mask; + + s_mp_rshd(mp, d / DIGIT_BIT); + d %= DIGIT_BIT; + if (d) { + mask = ((mp_digit)1 << d) - 1; + save = 0; + for (ix = USED(mp) - 1; ix >= 0; ix--) { + next = DIGIT(mp, ix) & mask; + DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d)); + save = next; + } + } + s_mp_clamp(mp); } /* end s_mp_div_2d() */ @@ -3141,34 +3116,35 @@ void s_mp_div_2d(mp_int *mp, mp_digit d) Normalize a and b for division, where b is the divisor. In order that we might make good guesses for quotient digits, we want the leading digit of b to be at least half the radix, which we - accomplish by multiplying a and b by a power of 2. The exponent - (shift count) is placed in *pd, so that the remainder can be shifted + accomplish by multiplying a and b by a power of 2. The exponent + (shift count) is placed in *pd, so that the remainder can be shifted back at the end of the division process. */ -mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd) +mp_err +s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd) { - mp_digit d; - mp_digit mask; - mp_digit b_msd; - mp_err res = MP_OKAY; - - d = 0; - mask = DIGIT_MAX & ~(DIGIT_MAX >> 1); /* mask is msb of digit */ - b_msd = DIGIT(b, USED(b) - 1); - while (!(b_msd & mask)) { - b_msd <<= 1; - ++d; - } - - if (d) { - MP_CHECKOK( s_mp_mul_2d(a, d) ); - MP_CHECKOK( s_mp_mul_2d(b, d) ); - } - - *pd = d; + mp_digit d; + mp_digit mask; + mp_digit b_msd; + mp_err res = MP_OKAY; + + d = 0; + mask = DIGIT_MAX & ~(DIGIT_MAX >> 1); /* mask is msb of digit */ + b_msd = DIGIT(b, USED(b) - 1); + while (!(b_msd & mask)) { + b_msd <<= 1; + ++d; + } + + if (d) { + MP_CHECKOK(s_mp_mul_2d(a, d)); + MP_CHECKOK(s_mp_mul_2d(b, d)); + } + + *pd = d; CLEANUP: - return res; + return res; } /* end s_mp_norm() */ @@ -3181,55 +3157,55 @@ CLEANUP: /* {{{ s_mp_add_d(mp, d) */ /* Add d to |mp| in place */ -mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */ +mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */ { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - mp_word w, k = 0; - mp_size ix = 1; - - w = (mp_word)DIGIT(mp, 0) + d; - DIGIT(mp, 0) = ACCUM(w); - k = CARRYOUT(w); + mp_word w, k = 0; + mp_size ix = 1; - while(ix < USED(mp) && k) { - w = (mp_word)DIGIT(mp, ix) + k; - DIGIT(mp, ix) = ACCUM(w); + w = (mp_word)DIGIT(mp, 0) + d; + DIGIT(mp, 0) = ACCUM(w); k = CARRYOUT(w); - ++ix; - } - if(k != 0) { - mp_err res; + while (ix < USED(mp) && k) { + w = (mp_word)DIGIT(mp, ix) + k; + DIGIT(mp, ix) = ACCUM(w); + k = CARRYOUT(w); + ++ix; + } - if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY) - return res; + if (k != 0) { + mp_err res; - DIGIT(mp, ix) = (mp_digit)k; - } + if ((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY) + return res; - return MP_OKAY; + DIGIT(mp, ix) = (mp_digit)k; + } + + return MP_OKAY; #else - mp_digit * pmp = MP_DIGITS(mp); - mp_digit sum, mp_i, carry = 0; - mp_err res = MP_OKAY; - int used = (int)MP_USED(mp); - - mp_i = *pmp; - *pmp++ = sum = d + mp_i; - carry = (sum < d); - while (carry && --used > 0) { + mp_digit *pmp = MP_DIGITS(mp); + mp_digit sum, mp_i, carry = 0; + mp_err res = MP_OKAY; + int used = (int)MP_USED(mp); + mp_i = *pmp; - *pmp++ = sum = carry + mp_i; - carry = !sum; - } - if (carry && !used) { - /* mp is growing */ - used = MP_USED(mp); - MP_CHECKOK( s_mp_pad(mp, used + 1) ); - MP_DIGIT(mp, used) = carry; - } + *pmp++ = sum = d + mp_i; + carry = (sum < d); + while (carry && --used > 0) { + mp_i = *pmp; + *pmp++ = sum = carry + mp_i; + carry = !sum; + } + if (carry && !used) { + /* mp is growing */ + used = MP_USED(mp); + MP_CHECKOK(s_mp_pad(mp, used + 1)); + MP_DIGIT(mp, used) = carry; + } CLEANUP: - return res; + return res; #endif } /* end s_mp_add_d() */ @@ -3238,48 +3214,48 @@ CLEANUP: /* {{{ s_mp_sub_d(mp, d) */ /* Subtract d from |mp| in place, assumes |mp| > d */ -mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */ +mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */ { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD) - mp_word w, b = 0; - mp_size ix = 1; - - /* Compute initial subtraction */ - w = (RADIX + (mp_word)DIGIT(mp, 0)) - d; - b = CARRYOUT(w) ? 0 : 1; - DIGIT(mp, 0) = ACCUM(w); + mp_word w, b = 0; + mp_size ix = 1; - /* Propagate borrows leftward */ - while(b && ix < USED(mp)) { - w = (RADIX + (mp_word)DIGIT(mp, ix)) - b; + /* Compute initial subtraction */ + w = (RADIX + (mp_word)DIGIT(mp, 0)) - d; b = CARRYOUT(w) ? 0 : 1; - DIGIT(mp, ix) = ACCUM(w); - ++ix; - } + DIGIT(mp, 0) = ACCUM(w); + + /* Propagate borrows leftward */ + while (b && ix < USED(mp)) { + w = (RADIX + (mp_word)DIGIT(mp, ix)) - b; + b = CARRYOUT(w) ? 0 : 1; + DIGIT(mp, ix) = ACCUM(w); + ++ix; + } - /* Remove leading zeroes */ - s_mp_clamp(mp); + /* Remove leading zeroes */ + s_mp_clamp(mp); - /* If we have a borrow out, it's a violation of the input invariant */ - if(b) - return MP_RANGE; - else - return MP_OKAY; + /* If we have a borrow out, it's a violation of the input invariant */ + if (b) + return MP_RANGE; + else + return MP_OKAY; #else - mp_digit *pmp = MP_DIGITS(mp); - mp_digit mp_i, diff, borrow; - mp_size used = MP_USED(mp); - - mp_i = *pmp; - *pmp++ = diff = mp_i - d; - borrow = (diff > mp_i); - while (borrow && --used) { + mp_digit *pmp = MP_DIGITS(mp); + mp_digit mp_i, diff, borrow; + mp_size used = MP_USED(mp); + mp_i = *pmp; - *pmp++ = diff = mp_i - borrow; + *pmp++ = diff = mp_i - d; borrow = (diff > mp_i); - } - s_mp_clamp(mp); - return (borrow && !used) ? MP_RANGE : MP_OKAY; + while (borrow && --used) { + mp_i = *pmp; + *pmp++ = diff = mp_i - borrow; + borrow = (diff > mp_i); + } + s_mp_clamp(mp); + return (borrow && !used) ? MP_RANGE : MP_OKAY; #endif } /* end s_mp_sub_d() */ @@ -3288,32 +3264,33 @@ mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */ /* {{{ s_mp_mul_d(a, d) */ /* Compute a = a * d, single digit multiplication */ -mp_err s_mp_mul_d(mp_int *a, mp_digit d) +mp_err +s_mp_mul_d(mp_int *a, mp_digit d) { - mp_err res; - mp_size used; - int pow; + mp_err res; + mp_size used; + int pow; - if (!d) { - mp_zero(a); - return MP_OKAY; - } - if (d == 1) - return MP_OKAY; - if (0 <= (pow = s_mp_ispow2d(d))) { - return s_mp_mul_2d(a, (mp_digit)pow); - } + if (!d) { + mp_zero(a); + return MP_OKAY; + } + if (d == 1) + return MP_OKAY; + if (0 <= (pow = s_mp_ispow2d(d))) { + return s_mp_mul_2d(a, (mp_digit)pow); + } - used = MP_USED(a); - MP_CHECKOK( s_mp_pad(a, used + 1) ); + used = MP_USED(a); + MP_CHECKOK(s_mp_pad(a, used + 1)); - s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a)); + s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a)); - s_mp_clamp(a); + s_mp_clamp(a); CLEANUP: - return res; - + return res; + } /* end s_mp_mul_d() */ /* }}} */ @@ -3327,114 +3304,115 @@ CLEANUP: single digit d. If r is null, the remainder will be discarded. */ -mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r) +mp_err +s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) - mp_word w = 0, q; + mp_word w = 0, q; #else - mp_digit w, q; + mp_digit w = 0, q; #endif - int ix; - mp_err res; - mp_int quot; - mp_int rem; - - if(d == 0) - return MP_RANGE; - if (d == 1) { - if (r) - *r = 0; - return MP_OKAY; - } - /* could check for power of 2 here, but mp_div_d does that. */ - if (MP_USED(mp) == 1) { - mp_digit n = MP_DIGIT(mp,0); - mp_digit rem; - - q = n / d; - rem = n % d; - MP_DIGIT(mp,0) = q; - if (r) - *r = rem; - return MP_OKAY; - } + int ix; + mp_err res; + mp_int quot; + mp_int rem; + + if (d == 0) + return MP_RANGE; + if (d == 1) { + if (r) + *r = 0; + return MP_OKAY; + } + /* could check for power of 2 here, but mp_div_d does that. */ + if (MP_USED(mp) == 1) { + mp_digit n = MP_DIGIT(mp, 0); + mp_digit rem; + + q = n / d; + rem = n % d; + MP_DIGIT(mp, 0) = q; + if (r) + *r = rem; + return MP_OKAY; + } - MP_DIGITS(&rem) = 0; - MP_DIGITS(") = 0; - /* Make room for the quotient */ - MP_CHECKOK( mp_init_size(", USED(mp)) ); + MP_DIGITS(&rem) = 0; + MP_DIGITS(") = 0; + /* Make room for the quotient */ + MP_CHECKOK(mp_init_size(", USED(mp))); #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) - for(ix = USED(mp) - 1; ix >= 0; ix--) { - w = (w << DIGIT_BIT) | DIGIT(mp, ix); - - if(w >= d) { - q = w / d; - w = w % d; - } else { - q = 0; + for (ix = USED(mp) - 1; ix >= 0; ix--) { + w = (w << DIGIT_BIT) | DIGIT(mp, ix); + + if (w >= d) { + q = w / d; + w = w % d; + } else { + q = 0; + } + + s_mp_lshd(", 1); + DIGIT(", 0) = (mp_digit)q; } - - s_mp_lshd(", 1); - DIGIT(", 0) = (mp_digit)q; - } #else - { - mp_digit p; + { + mp_digit p; #if !defined(MP_ASSEMBLY_DIV_2DX1D) - mp_digit norm; + mp_digit norm; #endif - MP_CHECKOK( mp_init_copy(&rem, mp) ); + MP_CHECKOK(mp_init_copy(&rem, mp)); #if !defined(MP_ASSEMBLY_DIV_2DX1D) - MP_DIGIT(", 0) = d; - MP_CHECKOK( s_mp_norm(&rem, ", &norm) ); - if (norm) - d <<= norm; - MP_DIGIT(", 0) = 0; + MP_DIGIT(", 0) = d; + MP_CHECKOK(s_mp_norm(&rem, ", &norm)); + if (norm) + d <<= norm; + MP_DIGIT(", 0) = 0; #endif - p = 0; - for (ix = USED(&rem) - 1; ix >= 0; ix--) { - w = DIGIT(&rem, ix); - - if (p) { - MP_CHECKOK( s_mpv_div_2dx1d(p, w, d, &q, &w) ); - } else if (w >= d) { - q = w / d; - w = w % d; - } else { - q = 0; - } - - MP_CHECKOK( s_mp_lshd(", 1) ); - DIGIT(", 0) = q; - p = w; - } + p = 0; + for (ix = USED(&rem) - 1; ix >= 0; ix--) { + w = DIGIT(&rem, ix); + + if (p) { + MP_CHECKOK(s_mpv_div_2dx1d(p, w, d, &q, &w)); + } else if (w >= d) { + q = w / d; + w = w % d; + } else { + q = 0; + } + + MP_CHECKOK(s_mp_lshd(", 1)); + DIGIT(", 0) = q; + p = w; + } #if !defined(MP_ASSEMBLY_DIV_2DX1D) - if (norm) - w >>= norm; + if (norm) + w >>= norm; #endif - } + } #endif - /* Deliver the remainder, if desired */ - if(r) - *r = (mp_digit)w; + /* Deliver the remainder, if desired */ + if (r) { + *r = (mp_digit)w; + } - s_mp_clamp("); - mp_exch(", mp); + s_mp_clamp("); + mp_exch(", mp); CLEANUP: - mp_clear("); - mp_clear(&rem); + mp_clear("); + mp_clear(&rem); - return res; + return res; } /* end s_mp_div_d() */ /* }}} */ - /* }}} */ /* {{{ Primitive full arithmetic */ @@ -3442,259 +3420,261 @@ CLEANUP: /* {{{ s_mp_add(a, b) */ /* Compute a = |a| + |b| */ -mp_err s_mp_add(mp_int *a, const mp_int *b) /* magnitude addition */ +mp_err s_mp_add(mp_int *a, const mp_int *b) /* magnitude addition */ { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - mp_word w = 0; + mp_word w = 0; #else - mp_digit d, sum, carry = 0; + mp_digit d, sum, carry = 0; #endif - mp_digit *pa, *pb; - mp_size ix; - mp_size used; - mp_err res; + mp_digit *pa, *pb; + mp_size ix; + mp_size used; + mp_err res; - /* Make sure a has enough precision for the output value */ - if((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY) - return res; + /* Make sure a has enough precision for the output value */ + if ((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY) + return res; - /* - Add up all digits up to the precision of b. If b had initially - the same precision as a, or greater, we took care of it by the - padding step above, so there is no problem. If b had initially - less precision, we'll have to make sure the carry out is duly - propagated upward among the higher-order digits of the sum. - */ - pa = MP_DIGITS(a); - pb = MP_DIGITS(b); - used = MP_USED(b); - for(ix = 0; ix < used; ix++) { + /* + Add up all digits up to the precision of b. If b had initially + the same precision as a, or greater, we took care of it by the + padding step above, so there is no problem. If b had initially + less precision, we'll have to make sure the carry out is duly + propagated upward among the higher-order digits of the sum. + */ + pa = MP_DIGITS(a); + pb = MP_DIGITS(b); + used = MP_USED(b); + for (ix = 0; ix < used; ix++) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - w = w + *pa + *pb++; - *pa++ = ACCUM(w); - w = CARRYOUT(w); + w = w + *pa + *pb++; + *pa++ = ACCUM(w); + w = CARRYOUT(w); #else - d = *pa; - sum = d + *pb++; - d = (sum < d); /* detect overflow */ - *pa++ = sum += carry; - carry = d + (sum < carry); /* detect overflow */ + d = *pa; + sum = d + *pb++; + d = (sum < d); /* detect overflow */ + *pa++ = sum += carry; + carry = d + (sum < carry); /* detect overflow */ #endif - } + } - /* If we run out of 'b' digits before we're actually done, make - sure the carries get propagated upward... - */ - used = MP_USED(a); + /* If we run out of 'b' digits before we're actually done, make + sure the carries get propagated upward... + */ + used = MP_USED(a); #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - while (w && ix < used) { - w = w + *pa; - *pa++ = ACCUM(w); - w = CARRYOUT(w); - ++ix; - } + while (w && ix < used) { + w = w + *pa; + *pa++ = ACCUM(w); + w = CARRYOUT(w); + ++ix; + } #else - while (carry && ix < used) { - sum = carry + *pa; - *pa++ = sum; - carry = !sum; - ++ix; - } + while (carry && ix < used) { + sum = carry + *pa; + *pa++ = sum; + carry = !sum; + ++ix; + } #endif - /* If there's an overall carry out, increase precision and include +/* If there's an overall carry out, increase precision and include it. We could have done this initially, but why touch the memory allocator unless we're sure we have to? */ #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - if (w) { - if((res = s_mp_pad(a, used + 1)) != MP_OKAY) - return res; + if (w) { + if ((res = s_mp_pad(a, used + 1)) != MP_OKAY) + return res; - DIGIT(a, ix) = (mp_digit)w; - } + DIGIT(a, ix) = (mp_digit)w; + } #else - if (carry) { - if((res = s_mp_pad(a, used + 1)) != MP_OKAY) - return res; + if (carry) { + if ((res = s_mp_pad(a, used + 1)) != MP_OKAY) + return res; - DIGIT(a, used) = carry; - } + DIGIT(a, used) = carry; + } #endif - return MP_OKAY; + return MP_OKAY; } /* end s_mp_add() */ /* }}} */ /* Compute c = |a| + |b| */ /* magnitude addition */ -mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c) +mp_err +s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c) { - mp_digit *pa, *pb, *pc; + mp_digit *pa, *pb, *pc; #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - mp_word w = 0; + mp_word w = 0; #else - mp_digit sum, carry = 0, d; + mp_digit sum, carry = 0, d; #endif - mp_size ix; - mp_size used; - mp_err res; - - MP_SIGN(c) = MP_SIGN(a); - if (MP_USED(a) < MP_USED(b)) { - const mp_int *xch = a; - a = b; - b = xch; - } - - /* Make sure a has enough precision for the output value */ - if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a)))) - return res; + mp_size ix; + mp_size used; + mp_err res; + + MP_SIGN(c) = MP_SIGN(a); + if (MP_USED(a) < MP_USED(b)) { + const mp_int *xch = a; + a = b; + b = xch; + } - /* - Add up all digits up to the precision of b. If b had initially - the same precision as a, or greater, we took care of it by the - exchange step above, so there is no problem. If b had initially - less precision, we'll have to make sure the carry out is duly - propagated upward among the higher-order digits of the sum. - */ - pa = MP_DIGITS(a); - pb = MP_DIGITS(b); - pc = MP_DIGITS(c); - used = MP_USED(b); - for (ix = 0; ix < used; ix++) { + /* Make sure a has enough precision for the output value */ + if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a)))) + return res; + + /* + Add up all digits up to the precision of b. If b had initially + the same precision as a, or greater, we took care of it by the + exchange step above, so there is no problem. If b had initially + less precision, we'll have to make sure the carry out is duly + propagated upward among the higher-order digits of the sum. + */ + pa = MP_DIGITS(a); + pb = MP_DIGITS(b); + pc = MP_DIGITS(c); + used = MP_USED(b); + for (ix = 0; ix < used; ix++) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - w = w + *pa++ + *pb++; - *pc++ = ACCUM(w); - w = CARRYOUT(w); + w = w + *pa++ + *pb++; + *pc++ = ACCUM(w); + w = CARRYOUT(w); #else - d = *pa++; - sum = d + *pb++; - d = (sum < d); /* detect overflow */ - *pc++ = sum += carry; - carry = d + (sum < carry); /* detect overflow */ + d = *pa++; + sum = d + *pb++; + d = (sum < d); /* detect overflow */ + *pc++ = sum += carry; + carry = d + (sum < carry); /* detect overflow */ #endif - } + } - /* If we run out of 'b' digits before we're actually done, make - sure the carries get propagated upward... + /* If we run out of 'b' digits before we're actually done, make + sure the carries get propagated upward... */ - for (used = MP_USED(a); ix < used; ++ix) { + for (used = MP_USED(a); ix < used; ++ix) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - w = w + *pa++; - *pc++ = ACCUM(w); - w = CARRYOUT(w); + w = w + *pa++; + *pc++ = ACCUM(w); + w = CARRYOUT(w); #else - *pc++ = sum = carry + *pa++; - carry = (sum < carry); + *pc++ = sum = carry + *pa++; + carry = (sum < carry); #endif - } + } - /* If there's an overall carry out, increase precision and include +/* If there's an overall carry out, increase precision and include it. We could have done this initially, but why touch the memory allocator unless we're sure we have to? */ #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - if (w) { - if((res = s_mp_pad(c, used + 1)) != MP_OKAY) - return res; + if (w) { + if ((res = s_mp_pad(c, used + 1)) != MP_OKAY) + return res; - DIGIT(c, used) = (mp_digit)w; - ++used; - } + DIGIT(c, used) = (mp_digit)w; + ++used; + } #else - if (carry) { - if((res = s_mp_pad(c, used + 1)) != MP_OKAY) - return res; + if (carry) { + if ((res = s_mp_pad(c, used + 1)) != MP_OKAY) + return res; - DIGIT(c, used) = carry; - ++used; - } + DIGIT(c, used) = carry; + ++used; + } #endif - MP_USED(c) = used; - return MP_OKAY; + MP_USED(c) = used; + return MP_OKAY; } /* {{{ s_mp_add_offset(a, b, offset) */ /* Compute a = |a| + ( |b| * (RADIX ** offset) ) */ -mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset) +mp_err +s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - mp_word w, k = 0; + mp_word w, k = 0; #else - mp_digit d, sum, carry = 0; + mp_digit d, sum, carry = 0; #endif - mp_size ib; - mp_size ia; - mp_size lim; - mp_err res; - - /* Make sure a has enough precision for the output value */ - lim = MP_USED(b) + offset; - if((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY) - return res; + mp_size ib; + mp_size ia; + mp_size lim; + mp_err res; + + /* Make sure a has enough precision for the output value */ + lim = MP_USED(b) + offset; + if ((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY) + return res; - /* + /* Add up all digits up to the precision of b. If b had initially the same precision as a, or greater, we took care of it by the padding step above, so there is no problem. If b had initially less precision, we'll have to make sure the carry out is duly propagated upward among the higher-order digits of the sum. */ - lim = USED(b); - for(ib = 0, ia = offset; ib < lim; ib++, ia++) { + lim = USED(b); + for (ib = 0, ia = offset; ib < lim; ib++, ia++) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k; - DIGIT(a, ia) = ACCUM(w); - k = CARRYOUT(w); + w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k; + DIGIT(a, ia) = ACCUM(w); + k = CARRYOUT(w); #else - d = MP_DIGIT(a, ia); - sum = d + MP_DIGIT(b, ib); - d = (sum < d); - MP_DIGIT(a,ia) = sum += carry; - carry = d + (sum < carry); + d = MP_DIGIT(a, ia); + sum = d + MP_DIGIT(b, ib); + d = (sum < d); + MP_DIGIT(a, ia) = sum += carry; + carry = d + (sum < carry); #endif - } + } - /* If we run out of 'b' digits before we're actually done, make - sure the carries get propagated upward... +/* If we run out of 'b' digits before we're actually done, make + sure the carries get propagated upward... */ #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - for (lim = MP_USED(a); k && (ia < lim); ++ia) { - w = (mp_word)DIGIT(a, ia) + k; - DIGIT(a, ia) = ACCUM(w); - k = CARRYOUT(w); - } + for (lim = MP_USED(a); k && (ia < lim); ++ia) { + w = (mp_word)DIGIT(a, ia) + k; + DIGIT(a, ia) = ACCUM(w); + k = CARRYOUT(w); + } #else - for (lim = MP_USED(a); carry && (ia < lim); ++ia) { - d = MP_DIGIT(a, ia); - MP_DIGIT(a,ia) = sum = d + carry; - carry = (sum < d); - } + for (lim = MP_USED(a); carry && (ia < lim); ++ia) { + d = MP_DIGIT(a, ia); + MP_DIGIT(a, ia) = sum = d + carry; + carry = (sum < d); + } #endif - /* If there's an overall carry out, increase precision and include +/* If there's an overall carry out, increase precision and include it. We could have done this initially, but why touch the memory allocator unless we're sure we have to? */ #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) - if(k) { - if((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY) - return res; + if (k) { + if ((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY) + return res; - DIGIT(a, ia) = (mp_digit)k; - } + DIGIT(a, ia) = (mp_digit)k; + } #else - if (carry) { - if((res = s_mp_pad(a, lim + 1)) != MP_OKAY) - return res; + if (carry) { + if ((res = s_mp_pad(a, lim + 1)) != MP_OKAY) + return res; - DIGIT(a, lim) = carry; - } + DIGIT(a, lim) = carry; + } #endif - s_mp_clamp(a); + s_mp_clamp(a); - return MP_OKAY; + return MP_OKAY; } /* end s_mp_add_offset() */ @@ -3703,399 +3683,419 @@ mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset) /* {{{ s_mp_sub(a, b) */ /* Compute a = |a| - |b|, assumes |a| >= |b| */ -mp_err s_mp_sub(mp_int *a, const mp_int *b) /* magnitude subtract */ +mp_err s_mp_sub(mp_int *a, const mp_int *b) /* magnitude subtract */ { - mp_digit *pa, *pb, *limit; + mp_digit *pa, *pb, *limit; #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD) - mp_sword w = 0; + mp_sword w = 0; #else - mp_digit d, diff, borrow = 0; + mp_digit d, diff, borrow = 0; #endif - /* + /* Subtract and propagate borrow. Up to the precision of b, this accounts for the digits of b; after that, we just make sure the carries get to the right place. This saves having to pad b out to the precision of a just to make the loops work right... */ - pa = MP_DIGITS(a); - pb = MP_DIGITS(b); - limit = pb + MP_USED(b); - while (pb < limit) { + pa = MP_DIGITS(a); + pb = MP_DIGITS(b); + limit = pb + MP_USED(b); + while (pb < limit) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD) - w = w + *pa - *pb++; - *pa++ = ACCUM(w); - w >>= MP_DIGIT_BIT; + w = w + *pa - *pb++; + *pa++ = ACCUM(w); + w >>= MP_DIGIT_BIT; #else - d = *pa; - diff = d - *pb++; - d = (diff > d); /* detect borrow */ - if (borrow && --diff == MP_DIGIT_MAX) - ++d; - *pa++ = diff; - borrow = d; + d = *pa; + diff = d - *pb++; + d = (diff > d); /* detect borrow */ + if (borrow && --diff == MP_DIGIT_MAX) + ++d; + *pa++ = diff; + borrow = d; #endif - } - limit = MP_DIGITS(a) + MP_USED(a); + } + limit = MP_DIGITS(a) + MP_USED(a); #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD) - while (w && pa < limit) { - w = w + *pa; - *pa++ = ACCUM(w); - w >>= MP_DIGIT_BIT; - } + while (w && pa < limit) { + w = w + *pa; + *pa++ = ACCUM(w); + w >>= MP_DIGIT_BIT; + } #else - while (borrow && pa < limit) { - d = *pa; - *pa++ = diff = d - borrow; - borrow = (diff > d); - } + while (borrow && pa < limit) { + d = *pa; + *pa++ = diff = d - borrow; + borrow = (diff > d); + } #endif - /* Clobber any leading zeroes we created */ - s_mp_clamp(a); + /* Clobber any leading zeroes we created */ + s_mp_clamp(a); - /* +/* If there was a borrow out, then |b| > |a| in violation of our input invariant. We've already done the work, but we'll at least complain about it... */ #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD) - return w ? MP_RANGE : MP_OKAY; + return w ? MP_RANGE : MP_OKAY; #else - return borrow ? MP_RANGE : MP_OKAY; + return borrow ? MP_RANGE : MP_OKAY; #endif } /* end s_mp_sub() */ /* }}} */ /* Compute c = |a| - |b|, assumes |a| >= |b| */ /* magnitude subtract */ -mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c) +mp_err +s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c) { - mp_digit *pa, *pb, *pc; + mp_digit *pa, *pb, *pc; #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD) - mp_sword w = 0; + mp_sword w = 0; #else - mp_digit d, diff, borrow = 0; + mp_digit d, diff, borrow = 0; #endif - int ix, limit; - mp_err res; + int ix, limit; + mp_err res; - MP_SIGN(c) = MP_SIGN(a); + MP_SIGN(c) = MP_SIGN(a); - /* Make sure a has enough precision for the output value */ - if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a)))) - return res; + /* Make sure a has enough precision for the output value */ + if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a)))) + return res; - /* + /* Subtract and propagate borrow. Up to the precision of b, this accounts for the digits of b; after that, we just make sure the carries get to the right place. This saves having to pad b out to the precision of a just to make the loops work right... */ - pa = MP_DIGITS(a); - pb = MP_DIGITS(b); - pc = MP_DIGITS(c); - limit = MP_USED(b); - for (ix = 0; ix < limit; ++ix) { + pa = MP_DIGITS(a); + pb = MP_DIGITS(b); + pc = MP_DIGITS(c); + limit = MP_USED(b); + for (ix = 0; ix < limit; ++ix) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD) - w = w + *pa++ - *pb++; - *pc++ = ACCUM(w); - w >>= MP_DIGIT_BIT; + w = w + *pa++ - *pb++; + *pc++ = ACCUM(w); + w >>= MP_DIGIT_BIT; #else - d = *pa++; - diff = d - *pb++; - d = (diff > d); - if (borrow && --diff == MP_DIGIT_MAX) - ++d; - *pc++ = diff; - borrow = d; + d = *pa++; + diff = d - *pb++; + d = (diff > d); + if (borrow && --diff == MP_DIGIT_MAX) + ++d; + *pc++ = diff; + borrow = d; #endif - } - for (limit = MP_USED(a); ix < limit; ++ix) { + } + for (limit = MP_USED(a); ix < limit; ++ix) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD) - w = w + *pa++; - *pc++ = ACCUM(w); - w >>= MP_DIGIT_BIT; + w = w + *pa++; + *pc++ = ACCUM(w); + w >>= MP_DIGIT_BIT; #else - d = *pa++; - *pc++ = diff = d - borrow; - borrow = (diff > d); + d = *pa++; + *pc++ = diff = d - borrow; + borrow = (diff > d); #endif - } + } - /* Clobber any leading zeroes we created */ - MP_USED(c) = ix; - s_mp_clamp(c); + /* Clobber any leading zeroes we created */ + MP_USED(c) = ix; + s_mp_clamp(c); - /* +/* If there was a borrow out, then |b| > |a| in violation of our input invariant. We've already done the work, but we'll at least complain about it... */ #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD) - return w ? MP_RANGE : MP_OKAY; + return w ? MP_RANGE : MP_OKAY; #else - return borrow ? MP_RANGE : MP_OKAY; + return borrow ? MP_RANGE : MP_OKAY; #endif } /* {{{ s_mp_mul(a, b) */ /* Compute a = |a| * |b| */ -mp_err s_mp_mul(mp_int *a, const mp_int *b) +mp_err +s_mp_mul(mp_int *a, const mp_int *b) { - return mp_mul(a, b, a); + return mp_mul(a, b, a); } /* end s_mp_mul() */ /* }}} */ #if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY) /* This trick works on Sparc V8 CPUs with the Workshop compilers. */ -#define MP_MUL_DxD(a, b, Phi, Plo) \ - { unsigned long long product = (unsigned long long)a * b; \ - Plo = (mp_digit)product; \ - Phi = (mp_digit)(product >> MP_DIGIT_BIT); } +#define MP_MUL_DxD(a, b, Phi, Plo) \ + { \ + unsigned long long product = (unsigned long long)a * b; \ + Plo = (mp_digit)product; \ + Phi = (mp_digit)(product >> MP_DIGIT_BIT); \ + } #elif defined(OSF1) -#define MP_MUL_DxD(a, b, Phi, Plo) \ - { Plo = asm ("mulq %a0, %a1, %v0", a, b);\ - Phi = asm ("umulh %a0, %a1, %v0", a, b); } +#define MP_MUL_DxD(a, b, Phi, Plo) \ + { \ + Plo = asm("mulq %a0, %a1, %v0", a, b); \ + Phi = asm("umulh %a0, %a1, %v0", a, b); \ + } #else -#define MP_MUL_DxD(a, b, Phi, Plo) \ - { mp_digit a0b1, a1b0; \ - Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \ - Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \ - a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \ - a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \ - a1b0 += a0b1; \ - Phi += a1b0 >> MP_HALF_DIGIT_BIT; \ - if (a1b0 < a0b1) \ - Phi += MP_HALF_RADIX; \ - a1b0 <<= MP_HALF_DIGIT_BIT; \ - Plo += a1b0; \ - if (Plo < a1b0) \ - ++Phi; \ - } +#define MP_MUL_DxD(a, b, Phi, Plo) \ + { \ + mp_digit a0b1, a1b0; \ + Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \ + Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \ + a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \ + a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \ + a1b0 += a0b1; \ + Phi += a1b0 >> MP_HALF_DIGIT_BIT; \ + if (a1b0 < a0b1) \ + Phi += MP_HALF_RADIX; \ + a1b0 <<= MP_HALF_DIGIT_BIT; \ + Plo += a1b0; \ + if (Plo < a1b0) \ + ++Phi; \ + } #endif #if !defined(MP_ASSEMBLY_MULTIPLY) /* c = a * b */ -void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +void +s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD) - mp_digit d = 0; - - /* Inner product: Digits of a */ - while (a_len--) { - mp_word w = ((mp_word)b * *a++) + d; - *c++ = ACCUM(w); - d = CARRYOUT(w); - } - *c = d; + mp_digit d = 0; + + /* Inner product: Digits of a */ + while (a_len--) { + mp_word w = ((mp_word)b * *a++) + d; + *c++ = ACCUM(w); + d = CARRYOUT(w); + } + *c = d; #else - mp_digit carry = 0; - while (a_len--) { - mp_digit a_i = *a++; - mp_digit a0b0, a1b1; - - MP_MUL_DxD(a_i, b, a1b1, a0b0); - - a0b0 += carry; - if (a0b0 < carry) - ++a1b1; - *c++ = a0b0; - carry = a1b1; - } - *c = carry; + mp_digit carry = 0; + while (a_len--) { + mp_digit a_i = *a++; + mp_digit a0b0, a1b1; + + MP_MUL_DxD(a_i, b, a1b1, a0b0); + + a0b0 += carry; + if (a0b0 < carry) + ++a1b1; + *c++ = a0b0; + carry = a1b1; + } + *c = carry; #endif } /* c += a * b */ -void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, - mp_digit *c) +void +s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, + mp_digit *c) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD) - mp_digit d = 0; - - /* Inner product: Digits of a */ - while (a_len--) { - mp_word w = ((mp_word)b * *a++) + *c + d; - *c++ = ACCUM(w); - d = CARRYOUT(w); - } - *c = d; + mp_digit d = 0; + + /* Inner product: Digits of a */ + while (a_len--) { + mp_word w = ((mp_word)b * *a++) + *c + d; + *c++ = ACCUM(w); + d = CARRYOUT(w); + } + *c = d; #else - mp_digit carry = 0; - while (a_len--) { - mp_digit a_i = *a++; - mp_digit a0b0, a1b1; - - MP_MUL_DxD(a_i, b, a1b1, a0b0); - - a0b0 += carry; - if (a0b0 < carry) - ++a1b1; - a0b0 += a_i = *c; - if (a0b0 < a_i) - ++a1b1; - *c++ = a0b0; - carry = a1b1; - } - *c = carry; + mp_digit carry = 0; + while (a_len--) { + mp_digit a_i = *a++; + mp_digit a0b0, a1b1; + + MP_MUL_DxD(a_i, b, a1b1, a0b0); + + a0b0 += carry; + if (a0b0 < carry) + ++a1b1; + a0b0 += a_i = *c; + if (a0b0 < a_i) + ++a1b1; + *c++ = a0b0; + carry = a1b1; + } + *c = carry; #endif } /* Presently, this is only used by the Montgomery arithmetic code. */ /* c += a * b */ -void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +void +s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD) - mp_digit d = 0; - - /* Inner product: Digits of a */ - while (a_len--) { - mp_word w = ((mp_word)b * *a++) + *c + d; - *c++ = ACCUM(w); - d = CARRYOUT(w); - } - - while (d) { - mp_word w = (mp_word)*c + d; - *c++ = ACCUM(w); - d = CARRYOUT(w); - } + mp_digit d = 0; + + /* Inner product: Digits of a */ + while (a_len--) { + mp_word w = ((mp_word)b * *a++) + *c + d; + *c++ = ACCUM(w); + d = CARRYOUT(w); + } + + while (d) { + mp_word w = (mp_word)*c + d; + *c++ = ACCUM(w); + d = CARRYOUT(w); + } #else - mp_digit carry = 0; - while (a_len--) { - mp_digit a_i = *a++; - mp_digit a0b0, a1b1; - - MP_MUL_DxD(a_i, b, a1b1, a0b0); - - a0b0 += carry; - if (a0b0 < carry) - ++a1b1; - - a0b0 += a_i = *c; - if (a0b0 < a_i) - ++a1b1; - - *c++ = a0b0; - carry = a1b1; - } - while (carry) { - mp_digit c_i = *c; - carry += c_i; - *c++ = carry; - carry = carry < c_i; - } + mp_digit carry = 0; + while (a_len--) { + mp_digit a_i = *a++; + mp_digit a0b0, a1b1; + + MP_MUL_DxD(a_i, b, a1b1, a0b0); + + a0b0 += carry; + if (a0b0 < carry) + ++a1b1; + + a0b0 += a_i = *c; + if (a0b0 < a_i) + ++a1b1; + + *c++ = a0b0; + carry = a1b1; + } + while (carry) { + mp_digit c_i = *c; + carry += c_i; + *c++ = carry; + carry = carry < c_i; + } #endif } #endif #if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY) /* This trick works on Sparc V8 CPUs with the Workshop compilers. */ -#define MP_SQR_D(a, Phi, Plo) \ - { unsigned long long square = (unsigned long long)a * a; \ - Plo = (mp_digit)square; \ - Phi = (mp_digit)(square >> MP_DIGIT_BIT); } +#define MP_SQR_D(a, Phi, Plo) \ + { \ + unsigned long long square = (unsigned long long)a * a; \ + Plo = (mp_digit)square; \ + Phi = (mp_digit)(square >> MP_DIGIT_BIT); \ + } #elif defined(OSF1) -#define MP_SQR_D(a, Phi, Plo) \ - { Plo = asm ("mulq %a0, %a0, %v0", a);\ - Phi = asm ("umulh %a0, %a0, %v0", a); } +#define MP_SQR_D(a, Phi, Plo) \ + { \ + Plo = asm("mulq %a0, %a0, %v0", a); \ + Phi = asm("umulh %a0, %a0, %v0", a); \ + } #else -#define MP_SQR_D(a, Phi, Plo) \ - { mp_digit Pmid; \ - Plo = (a & MP_HALF_DIGIT_MAX) * (a & MP_HALF_DIGIT_MAX); \ - Phi = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \ - Pmid = (a & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \ - Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1); \ - Pmid <<= (MP_HALF_DIGIT_BIT + 1); \ - Plo += Pmid; \ - if (Plo < Pmid) \ - ++Phi; \ - } +#define MP_SQR_D(a, Phi, Plo) \ + { \ + mp_digit Pmid; \ + Plo = (a & MP_HALF_DIGIT_MAX) * (a & MP_HALF_DIGIT_MAX); \ + Phi = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \ + Pmid = (a & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \ + Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1); \ + Pmid <<= (MP_HALF_DIGIT_BIT + 1); \ + Plo += Pmid; \ + if (Plo < Pmid) \ + ++Phi; \ + } #endif #if !defined(MP_ASSEMBLY_SQUARE) /* Add the squares of the digits of a to the digits of b. */ -void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps) +void +s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps) { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD) - mp_word w; - mp_digit d; - mp_size ix; - - w = 0; -#define ADD_SQUARE(n) \ - d = pa[n]; \ - w += (d * (mp_word)d) + ps[2*n]; \ - ps[2*n] = ACCUM(w); \ - w = (w >> DIGIT_BIT) + ps[2*n+1]; \ - ps[2*n+1] = ACCUM(w); \ + mp_word w; + mp_digit d; + mp_size ix; + + w = 0; +#define ADD_SQUARE(n) \ + d = pa[n]; \ + w += (d * (mp_word)d) + ps[2 * n]; \ + ps[2 * n] = ACCUM(w); \ + w = (w >> DIGIT_BIT) + ps[2 * n + 1]; \ + ps[2 * n + 1] = ACCUM(w); \ w = (w >> DIGIT_BIT) - for (ix = a_len; ix >= 4; ix -= 4) { - ADD_SQUARE(0); - ADD_SQUARE(1); - ADD_SQUARE(2); - ADD_SQUARE(3); - pa += 4; - ps += 8; - } - if (ix) { - ps += 2*ix; - pa += ix; - switch (ix) { - case 3: ADD_SQUARE(-3); /* FALLTHRU */ - case 2: ADD_SQUARE(-2); /* FALLTHRU */ - case 1: ADD_SQUARE(-1); /* FALLTHRU */ - case 0: break; - } - } - while (w) { - w += *ps; - *ps++ = ACCUM(w); - w = (w >> DIGIT_BIT); - } + for (ix = a_len; ix >= 4; ix -= 4) { + ADD_SQUARE(0); + ADD_SQUARE(1); + ADD_SQUARE(2); + ADD_SQUARE(3); + pa += 4; + ps += 8; + } + if (ix) { + ps += 2 * ix; + pa += ix; + switch (ix) { + case 3: + ADD_SQUARE(-3); /* FALLTHRU */ + case 2: + ADD_SQUARE(-2); /* FALLTHRU */ + case 1: + ADD_SQUARE(-1); /* FALLTHRU */ + case 0: + break; + } + } + while (w) { + w += *ps; + *ps++ = ACCUM(w); + w = (w >> DIGIT_BIT); + } #else - mp_digit carry = 0; - while (a_len--) { - mp_digit a_i = *pa++; - mp_digit a0a0, a1a1; - - MP_SQR_D(a_i, a1a1, a0a0); - - /* here a1a1 and a0a0 constitute a_i ** 2 */ - a0a0 += carry; - if (a0a0 < carry) - ++a1a1; - - /* now add to ps */ - a0a0 += a_i = *ps; - if (a0a0 < a_i) - ++a1a1; - *ps++ = a0a0; - a1a1 += a_i = *ps; - carry = (a1a1 < a_i); - *ps++ = a1a1; - } - while (carry) { - mp_digit s_i = *ps; - carry += s_i; - *ps++ = carry; - carry = carry < s_i; - } + mp_digit carry = 0; + while (a_len--) { + mp_digit a_i = *pa++; + mp_digit a0a0, a1a1; + + MP_SQR_D(a_i, a1a1, a0a0); + + /* here a1a1 and a0a0 constitute a_i ** 2 */ + a0a0 += carry; + if (a0a0 < carry) + ++a1a1; + + /* now add to ps */ + a0a0 += a_i = *ps; + if (a0a0 < a_i) + ++a1a1; + *ps++ = a0a0; + a1a1 += a_i = *ps; + carry = (a1a1 < a_i); + *ps++ = a1a1; + } + while (carry) { + mp_digit s_i = *ps; + carry += s_i; + *ps++ = carry; + carry = carry < s_i; + } #endif } #endif -#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) \ -&& !defined(MP_ASSEMBLY_DIV_2DX1D) +#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) && !defined(MP_ASSEMBLY_DIV_2DX1D) /* -** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized +** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized ** so its high bit is 1. This code is from NSPR. */ -mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, - mp_digit *qp, mp_digit *rp) +mp_err +s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, + mp_digit *qp, mp_digit *rp) { mp_digit d1, d0, q1, q0; mp_digit r1, r0, m; @@ -4109,8 +4109,8 @@ mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, if (r1 < m) { q1--, r1 += divisor; if (r1 >= divisor && r1 < m) { - q1--, r1 += divisor; - } + q1--, r1 += divisor; + } } r1 -= m; r0 = r1 % d1; @@ -4120,13 +4120,13 @@ mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, if (r0 < m) { q0--, r0 += divisor; if (r0 >= divisor && r0 < m) { - q0--, r0 += divisor; - } + q0--, r0 += divisor; + } } if (qp) - *qp = (q1 << MP_HALF_DIGIT_BIT) | q0; + *qp = (q1 << MP_HALF_DIGIT_BIT) | q0; if (rp) - *rp = r0 - m; + *rp = r0 - m; return MP_OKAY; } #endif @@ -4134,19 +4134,20 @@ mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, #if MP_SQUARE /* {{{ s_mp_sqr(a) */ -mp_err s_mp_sqr(mp_int *a) +mp_err +s_mp_sqr(mp_int *a) { - mp_err res; - mp_int tmp; - - if((res = mp_init_size(&tmp, 2 * USED(a))) != MP_OKAY) + mp_err res; + mp_int tmp; + + if ((res = mp_init_size(&tmp, 2 * USED(a))) != MP_OKAY) + return res; + res = mp_sqr(a, &tmp); + if (res == MP_OKAY) { + s_mp_exch(&tmp, a); + } + mp_clear(&tmp); return res; - res = mp_sqr(a, &tmp); - if (res == MP_OKAY) { - s_mp_exch(&tmp, a); - } - mp_clear(&tmp); - return res; } /* }}} */ @@ -4160,170 +4161,170 @@ mp_err s_mp_sqr(mp_int *a) Compute a = a / b and b = a mod b. Assumes b > a. */ -mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ - mp_int *div, /* i: divisor */ - mp_int *quot) /* i: 0; o: quotient */ +mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ + mp_int *div, /* i: divisor */ + mp_int *quot) /* i: 0; o: quotient */ { - mp_int part, t; + mp_int part, t; #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) - mp_word q_msd; + mp_word q_msd; #else - mp_digit q_msd; + mp_digit q_msd; #endif - mp_err res; - mp_digit d; - mp_digit div_msd; - int ix; - - if(mp_cmp_z(div) == 0) - return MP_RANGE; - - DIGITS(&t) = 0; - /* Shortcut if divisor is power of two */ - if((ix = s_mp_ispow2(div)) >= 0) { - MP_CHECKOK( mp_copy(rem, quot) ); - s_mp_div_2d(quot, (mp_digit)ix); - s_mp_mod_2d(rem, (mp_digit)ix); - - return MP_OKAY; - } + mp_err res; + mp_digit d; + mp_digit div_msd; + int ix; + + if (mp_cmp_z(div) == 0) + return MP_RANGE; + + DIGITS(&t) = 0; + /* Shortcut if divisor is power of two */ + if ((ix = s_mp_ispow2(div)) >= 0) { + MP_CHECKOK(mp_copy(rem, quot)); + s_mp_div_2d(quot, (mp_digit)ix); + s_mp_mod_2d(rem, (mp_digit)ix); + + return MP_OKAY; + } - MP_SIGN(rem) = ZPOS; - MP_SIGN(div) = ZPOS; - MP_SIGN(&part) = ZPOS; + MP_SIGN(rem) = ZPOS; + MP_SIGN(div) = ZPOS; + MP_SIGN(&part) = ZPOS; - /* A working temporary for division */ - MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem))); + /* A working temporary for division */ + MP_CHECKOK(mp_init_size(&t, MP_ALLOC(rem))); - /* Normalize to optimize guessing */ - MP_CHECKOK( s_mp_norm(rem, div, &d) ); + /* Normalize to optimize guessing */ + MP_CHECKOK(s_mp_norm(rem, div, &d)); - /* Perform the division itself...woo! */ - MP_USED(quot) = MP_ALLOC(quot); + /* Perform the division itself...woo! */ + MP_USED(quot) = MP_ALLOC(quot); - /* Find a partial substring of rem which is at least div */ - /* If we didn't find one, we're finished dividing */ - while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) { - int i; - int unusedRem; - int partExtended = 0; /* set to true if we need to extend part */ + /* Find a partial substring of rem which is at least div */ + /* If we didn't find one, we're finished dividing */ + while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) { + int i; + int unusedRem; + int partExtended = 0; /* set to true if we need to extend part */ - unusedRem = MP_USED(rem) - MP_USED(div); - MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem; - MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem; - MP_USED(&part) = MP_USED(div); + unusedRem = MP_USED(rem) - MP_USED(div); + MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem; + MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem; + MP_USED(&part) = MP_USED(div); - /* We have now truncated the part of the remainder to the same length as + /* We have now truncated the part of the remainder to the same length as * the divisor. If part is smaller than div, extend part by one digit. */ - if (s_mp_cmp(&part, div) < 0) { - -- unusedRem; + if (s_mp_cmp(&part, div) < 0) { + --unusedRem; #if MP_ARGCHK == 2 - assert(unusedRem >= 0); + assert(unusedRem >= 0); #endif - -- MP_DIGITS(&part); - ++ MP_USED(&part); - ++ MP_ALLOC(&part); - partExtended = 1; - } - - /* Compute a guess for the next quotient digit */ - q_msd = MP_DIGIT(&part, MP_USED(&part) - 1); - div_msd = MP_DIGIT(div, MP_USED(div) - 1); - if (!partExtended) { - /* In this case, q_msd /= div_msd is always 1. First, since div_msd is + --MP_DIGITS(&part); + ++MP_USED(&part); + ++MP_ALLOC(&part); + partExtended = 1; + } + + /* Compute a guess for the next quotient digit */ + q_msd = MP_DIGIT(&part, MP_USED(&part) - 1); + div_msd = MP_DIGIT(div, MP_USED(div) - 1); + if (!partExtended) { + /* In this case, q_msd /= div_msd is always 1. First, since div_msd is * normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since * we didn't extend part, q_msd >= div_msd. Therefore we know that * div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we * get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */ - q_msd = 1; - } else { + q_msd = 1; + } else { #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) - q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2); - q_msd /= div_msd; - if (q_msd == RADIX) - --q_msd; + q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2); + q_msd /= div_msd; + if (q_msd == RADIX) + --q_msd; #else - if (q_msd == div_msd) { - q_msd = MP_DIGIT_MAX; - } else { - mp_digit r; - MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), - div_msd, &q_msd, &r) ); - } + if (q_msd == div_msd) { + q_msd = MP_DIGIT_MAX; + } else { + mp_digit r; + MP_CHECKOK(s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), + div_msd, &q_msd, &r)); + } #endif - } + } #if MP_ARGCHK == 2 - assert(q_msd > 0); /* This case should never occur any more. */ + assert(q_msd > 0); /* This case should never occur any more. */ #endif - if (q_msd <= 0) - break; + if (q_msd <= 0) + break; - /* See what that multiplies out to */ - mp_copy(div, &t); - MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) ); + /* See what that multiplies out to */ + mp_copy(div, &t); + MP_CHECKOK(s_mp_mul_d(&t, (mp_digit)q_msd)); - /* + /* If it's too big, back it off. We should not have to do this more than once, or, in rare cases, twice. Knuth describes a method by which this could be reduced to a maximum of once, but I didn't implement that here. * When using s_mpv_div_2dx1d, we may have to do this 3 times. */ - for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) { - --q_msd; - s_mp_sub(&t, div); /* t -= div */ - } - if (i < 0) { - res = MP_RANGE; - goto CLEANUP; - } - - /* At this point, q_msd should be the right next digit */ - MP_CHECKOK( s_mp_sub(&part, &t) ); /* part -= t */ - s_mp_clamp(rem); - - /* + for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) { + --q_msd; + MP_CHECKOK(s_mp_sub(&t, div)); /* t -= div */ + } + if (i < 0) { + res = MP_RANGE; + goto CLEANUP; + } + + /* At this point, q_msd should be the right next digit */ + MP_CHECKOK(s_mp_sub(&part, &t)); /* part -= t */ + s_mp_clamp(rem); + + /* Include the digit in the quotient. We allocated enough memory for any quotient we could ever possibly get, so we should not have to check for failures here */ - MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd; - } + MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd; + } - /* Denormalize remainder */ - if (d) { - s_mp_div_2d(rem, d); - } + /* Denormalize remainder */ + if (d) { + s_mp_div_2d(rem, d); + } - s_mp_clamp(quot); + s_mp_clamp(quot); CLEANUP: - mp_clear(&t); + mp_clear(&t); - return res; + return res; } /* end s_mp_div() */ - /* }}} */ /* {{{ s_mp_2expt(a, k) */ -mp_err s_mp_2expt(mp_int *a, mp_digit k) +mp_err +s_mp_2expt(mp_int *a, mp_digit k) { - mp_err res; - mp_size dig, bit; + mp_err res; + mp_size dig, bit; - dig = k / DIGIT_BIT; - bit = k % DIGIT_BIT; + dig = k / DIGIT_BIT; + bit = k % DIGIT_BIT; - mp_zero(a); - if((res = s_mp_pad(a, dig + 1)) != MP_OKAY) - return res; - - DIGIT(a, dig) |= ((mp_digit)1 << bit); + mp_zero(a); + if ((res = s_mp_pad(a, dig + 1)) != MP_OKAY) + return res; - return MP_OKAY; + DIGIT(a, dig) |= ((mp_digit)1 << bit); + + return MP_OKAY; } /* end s_mp_2expt() */ @@ -4341,51 +4342,52 @@ mp_err s_mp_2expt(mp_int *a, mp_digit k) This algorithm was derived from the _Handbook of Applied Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14, - pp. 603-604. + pp. 603-604. */ -mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) +mp_err +s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) { - mp_int q; - mp_err res; - - if((res = mp_init_copy(&q, x)) != MP_OKAY) - return res; - - s_mp_rshd(&q, USED(m) - 1); /* q1 = x / b^(k-1) */ - s_mp_mul(&q, mu); /* q2 = q1 * mu */ - s_mp_rshd(&q, USED(m) + 1); /* q3 = q2 / b^(k+1) */ - - /* x = x mod b^(k+1), quick (no division) */ - s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1)); - - /* q = q * m mod b^(k+1), quick (no division) */ - s_mp_mul(&q, m); - s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1)); - - /* x = x - q */ - if((res = mp_sub(x, &q, x)) != MP_OKAY) - goto CLEANUP; - - /* If x < 0, add b^(k+1) to it */ - if(mp_cmp_z(x) < 0) { - mp_set(&q, 1); - if((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY) - goto CLEANUP; - if((res = mp_add(x, &q, x)) != MP_OKAY) - goto CLEANUP; - } + mp_int q; + mp_err res; + + if ((res = mp_init_copy(&q, x)) != MP_OKAY) + return res; + + s_mp_rshd(&q, USED(m) - 1); /* q1 = x / b^(k-1) */ + s_mp_mul(&q, mu); /* q2 = q1 * mu */ + s_mp_rshd(&q, USED(m) + 1); /* q3 = q2 / b^(k+1) */ + + /* x = x mod b^(k+1), quick (no division) */ + s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1)); + + /* q = q * m mod b^(k+1), quick (no division) */ + s_mp_mul(&q, m); + s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1)); + + /* x = x - q */ + if ((res = mp_sub(x, &q, x)) != MP_OKAY) + goto CLEANUP; + + /* If x < 0, add b^(k+1) to it */ + if (mp_cmp_z(x) < 0) { + mp_set(&q, 1); + if ((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY) + goto CLEANUP; + if ((res = mp_add(x, &q, x)) != MP_OKAY) + goto CLEANUP; + } - /* Back off if it's too big */ - while(mp_cmp(x, m) >= 0) { - if((res = s_mp_sub(x, m)) != MP_OKAY) - break; - } + /* Back off if it's too big */ + while (mp_cmp(x, m) >= 0) { + if ((res = s_mp_sub(x, m)) != MP_OKAY) + break; + } - CLEANUP: - mp_clear(&q); +CLEANUP: + mp_clear(&q); - return res; + return res; } /* end s_mp_reduce() */ @@ -4398,47 +4400,50 @@ mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) /* {{{ s_mp_cmp(a, b) */ /* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b */ -int s_mp_cmp(const mp_int *a, const mp_int *b) +int +s_mp_cmp(const mp_int *a, const mp_int *b) { - mp_size used_a = MP_USED(a); - { - mp_size used_b = MP_USED(b); - - if (used_a > used_b) - goto IS_GT; - if (used_a < used_b) - goto IS_LT; - } - { - mp_digit *pa, *pb; - mp_digit da = 0, db = 0; - -#define CMP_AB(n) if ((da = pa[n]) != (db = pb[n])) goto done - - pa = MP_DIGITS(a) + used_a; - pb = MP_DIGITS(b) + used_a; - while (used_a >= 4) { - pa -= 4; - pb -= 4; - used_a -= 4; - CMP_AB(3); - CMP_AB(2); - CMP_AB(1); - CMP_AB(0); - } - while (used_a-- > 0 && ((da = *--pa) == (db = *--pb))) - /* do nothing */; -done: - if (da > db) - goto IS_GT; - if (da < db) - goto IS_LT; - } - return MP_EQ; + mp_size used_a = MP_USED(a); + { + mp_size used_b = MP_USED(b); + + if (used_a > used_b) + goto IS_GT; + if (used_a < used_b) + goto IS_LT; + } + { + mp_digit *pa, *pb; + mp_digit da = 0, db = 0; + +#define CMP_AB(n) \ + if ((da = pa[n]) != (db = pb[n])) \ + goto done + + pa = MP_DIGITS(a) + used_a; + pb = MP_DIGITS(b) + used_a; + while (used_a >= 4) { + pa -= 4; + pb -= 4; + used_a -= 4; + CMP_AB(3); + CMP_AB(2); + CMP_AB(1); + CMP_AB(0); + } + while (used_a-- > 0 && ((da = *--pa) == (db = *--pb))) + /* do nothing */; + done: + if (da > db) + goto IS_GT; + if (da < db) + goto IS_LT; + } + return MP_EQ; IS_LT: - return MP_LT; + return MP_LT; IS_GT: - return MP_GT; + return MP_GT; } /* end s_mp_cmp() */ /* }}} */ @@ -4446,17 +4451,18 @@ IS_GT: /* {{{ s_mp_cmp_d(a, d) */ /* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d */ -int s_mp_cmp_d(const mp_int *a, mp_digit d) +int +s_mp_cmp_d(const mp_int *a, mp_digit d) { - if(USED(a) > 1) - return MP_GT; + if (USED(a) > 1) + return MP_GT; - if(DIGIT(a, 0) < d) - return MP_LT; - else if(DIGIT(a, 0) > d) - return MP_GT; - else - return MP_EQ; + if (DIGIT(a, 0) < d) + return MP_LT; + else if (DIGIT(a, 0) > d) + return MP_GT; + else + return MP_EQ; } /* end s_mp_cmp_d() */ @@ -4468,25 +4474,26 @@ int s_mp_cmp_d(const mp_int *a, mp_digit d) Returns -1 if the value is not a power of two; otherwise, it returns k such that v = 2^k, i.e. lg(v). */ -int s_mp_ispow2(const mp_int *v) +int +s_mp_ispow2(const mp_int *v) { - mp_digit d; - int extra = 0, ix; + mp_digit d; + int extra = 0, ix; - ix = MP_USED(v) - 1; - d = MP_DIGIT(v, ix); /* most significant digit of v */ + ix = MP_USED(v) - 1; + d = MP_DIGIT(v, ix); /* most significant digit of v */ - extra = s_mp_ispow2d(d); - if (extra < 0 || ix == 0) - return extra; + extra = s_mp_ispow2d(d); + if (extra < 0 || ix == 0) + return extra; - while (--ix >= 0) { - if (DIGIT(v, ix) != 0) - return -1; /* not a power of two */ - extra += MP_DIGIT_BIT; - } + while (--ix >= 0) { + if (DIGIT(v, ix) != 0) + return -1; /* not a power of two */ + extra += MP_DIGIT_BIT; + } - return extra; + return extra; } /* end s_mp_ispow2() */ @@ -4494,53 +4501,54 @@ int s_mp_ispow2(const mp_int *v) /* {{{ s_mp_ispow2d(d) */ -int s_mp_ispow2d(mp_digit d) +int +s_mp_ispow2d(mp_digit d) { - if ((d != 0) && ((d & (d-1)) == 0)) { /* d is a power of 2 */ - int pow = 0; -#if defined (MP_USE_UINT_DIGIT) - if (d & 0xffff0000U) - pow += 16; - if (d & 0xff00ff00U) - pow += 8; - if (d & 0xf0f0f0f0U) - pow += 4; - if (d & 0xccccccccU) - pow += 2; - if (d & 0xaaaaaaaaU) - pow += 1; + if ((d != 0) && ((d & (d - 1)) == 0)) { /* d is a power of 2 */ + int pow = 0; +#if defined(MP_USE_UINT_DIGIT) + if (d & 0xffff0000U) + pow += 16; + if (d & 0xff00ff00U) + pow += 8; + if (d & 0xf0f0f0f0U) + pow += 4; + if (d & 0xccccccccU) + pow += 2; + if (d & 0xaaaaaaaaU) + pow += 1; #elif defined(MP_USE_LONG_LONG_DIGIT) - if (d & 0xffffffff00000000ULL) - pow += 32; - if (d & 0xffff0000ffff0000ULL) - pow += 16; - if (d & 0xff00ff00ff00ff00ULL) - pow += 8; - if (d & 0xf0f0f0f0f0f0f0f0ULL) - pow += 4; - if (d & 0xccccccccccccccccULL) - pow += 2; - if (d & 0xaaaaaaaaaaaaaaaaULL) - pow += 1; + if (d & 0xffffffff00000000ULL) + pow += 32; + if (d & 0xffff0000ffff0000ULL) + pow += 16; + if (d & 0xff00ff00ff00ff00ULL) + pow += 8; + if (d & 0xf0f0f0f0f0f0f0f0ULL) + pow += 4; + if (d & 0xccccccccccccccccULL) + pow += 2; + if (d & 0xaaaaaaaaaaaaaaaaULL) + pow += 1; #elif defined(MP_USE_LONG_DIGIT) - if (d & 0xffffffff00000000UL) - pow += 32; - if (d & 0xffff0000ffff0000UL) - pow += 16; - if (d & 0xff00ff00ff00ff00UL) - pow += 8; - if (d & 0xf0f0f0f0f0f0f0f0UL) - pow += 4; - if (d & 0xccccccccccccccccUL) - pow += 2; - if (d & 0xaaaaaaaaaaaaaaaaUL) - pow += 1; + if (d & 0xffffffff00000000UL) + pow += 32; + if (d & 0xffff0000ffff0000UL) + pow += 16; + if (d & 0xff00ff00ff00ff00UL) + pow += 8; + if (d & 0xf0f0f0f0f0f0f0f0UL) + pow += 4; + if (d & 0xccccccccccccccccUL) + pow += 2; + if (d & 0xaaaaaaaaaaaaaaaaUL) + pow += 1; #else #error "unknown type for mp_digit" #endif - return pow; - } - return -1; + return pow; + } + return -1; } /* end s_mp_ispow2d() */ @@ -4560,32 +4568,33 @@ int s_mp_ispow2d(mp_digit d) The results will be odd if you use a radix < 2 or > 62, you are expected to know what you're up to. */ -int s_mp_tovalue(char ch, int r) +int +s_mp_tovalue(char ch, int r) { - int val, xch; - - if(r > 36) - xch = ch; - else - xch = toupper(ch); - - if(isdigit(xch)) - val = xch - '0'; - else if(isupper(xch)) - val = xch - 'A' + 10; - else if(islower(xch)) - val = xch - 'a' + 36; - else if(xch == '+') - val = 62; - else if(xch == '/') - val = 63; - else - return -1; + int val, xch; - if(val < 0 || val >= r) - return -1; + if (r > 36) + xch = ch; + else + xch = toupper(ch); + + if (isdigit(xch)) + val = xch - '0'; + else if (isupper(xch)) + val = xch - 'A' + 10; + else if (islower(xch)) + val = xch - 'a' + 36; + else if (xch == '+') + val = 62; + else if (xch == '/') + val = 63; + else + return -1; - return val; + if (val < 0 || val >= r) + return -1; + + return val; } /* end s_mp_tovalue() */ @@ -4601,20 +4610,21 @@ int s_mp_tovalue(char ch, int r) The results may be odd if you use a radix < 2 or > 64, you are expected to know what you're doing. */ - -char s_mp_todigit(mp_digit val, int r, int low) + +char +s_mp_todigit(mp_digit val, int r, int low) { - char ch; + char ch; - if(val >= r) - return 0; + if (val >= r) + return 0; - ch = s_dmap_1[val]; + ch = s_dmap_1[val]; - if(r <= 36 && low) - ch = tolower(ch); + if (r <= 36 && low) + ch = tolower(ch); - return ch; + return ch; } /* end s_mp_todigit() */ @@ -4622,14 +4632,15 @@ char s_mp_todigit(mp_digit val, int r, int low) /* {{{ s_mp_outlen(bits, radix) */ -/* +/* Return an estimate for how long a string is needed to hold a radix r representation of a number with 'bits' significant bits, plus an extra for a zero terminator (assuming C style strings here) */ -int s_mp_outlen(int bits, int r) +int +s_mp_outlen(int bits, int r) { - return (int)((double)bits * LOG_V_2(r) + 1.5) + 1; + return (int)((double)bits * LOG_V_2(r) + 1.5) + 1; } /* end s_mp_outlen() */ @@ -4643,40 +4654,40 @@ int s_mp_outlen(int bits, int r) No sign bit, number is positive. Leading zeros ignored. */ -mp_err +mp_err mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len) { - int count; - mp_err res; - mp_digit d; + int count; + mp_err res; + mp_digit d; - ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); + ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); - mp_zero(mp); + mp_zero(mp); - count = len % sizeof(mp_digit); - if (count) { - for (d = 0; count-- > 0; --len) { - d = (d << 8) | *str++; + count = len % sizeof(mp_digit); + if (count) { + for (d = 0; count-- > 0; --len) { + d = (d << 8) | *str++; + } + MP_DIGIT(mp, 0) = d; } - MP_DIGIT(mp, 0) = d; - } - /* Read the rest of the digits */ - for(; len > 0; len -= sizeof(mp_digit)) { - for (d = 0, count = sizeof(mp_digit); count > 0; --count) { - d = (d << 8) | *str++; - } - if (MP_EQ == mp_cmp_z(mp)) { - if (!d) - continue; - } else { - if((res = s_mp_lshd(mp, 1)) != MP_OKAY) - return res; + /* Read the rest of the digits */ + for (; len > 0; len -= sizeof(mp_digit)) { + for (d = 0, count = sizeof(mp_digit); count > 0; --count) { + d = (d << 8) | *str++; + } + if (MP_EQ == mp_cmp_z(mp)) { + if (!d) + continue; + } else { + if ((res = s_mp_lshd(mp, 1)) != MP_OKAY) + return res; + } + MP_DIGIT(mp, 0) = d; } - MP_DIGIT(mp, 0) = d; - } - return MP_OKAY; + return MP_OKAY; } /* end mp_read_unsigned_octets() */ /* }}} */ @@ -4684,146 +4695,145 @@ mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len) unsigned int mp_unsigned_octet_size(const mp_int *mp) { - unsigned int bytes; - int ix; - mp_digit d = 0; - - ARGCHK(mp != NULL, MP_BADARG); - ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG); - - bytes = (USED(mp) * sizeof(mp_digit)); - - /* subtract leading zeros. */ - /* Iterate over each digit... */ - for(ix = USED(mp) - 1; ix >= 0; ix--) { - d = DIGIT(mp, ix); - if (d) - break; - bytes -= sizeof(d); - } - if (!bytes) - return 1; - - /* Have MSD, check digit bytes, high order first */ - for(ix = sizeof(mp_digit) - 1; ix >= 0; ix--) { - unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT)); - if (x) - break; - --bytes; - } - return bytes; + unsigned int bytes; + int ix; + mp_digit d = 0; + + ARGCHK(mp != NULL, MP_BADARG); + ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG); + + bytes = (USED(mp) * sizeof(mp_digit)); + + /* subtract leading zeros. */ + /* Iterate over each digit... */ + for (ix = USED(mp) - 1; ix >= 0; ix--) { + d = DIGIT(mp, ix); + if (d) + break; + bytes -= sizeof(d); + } + if (!bytes) + return 1; + + /* Have MSD, check digit bytes, high order first */ + for (ix = sizeof(mp_digit) - 1; ix >= 0; ix--) { + unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT)); + if (x) + break; + --bytes; + } + return bytes; } /* end mp_unsigned_octet_size() */ /* }}} */ /* {{{ mp_to_unsigned_octets(mp, str) */ /* output a buffer of big endian octets no longer than specified. */ -mp_err +mp_err mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) { - int ix, pos = 0; - unsigned int bytes; - - ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); - - bytes = mp_unsigned_octet_size(mp); - ARGCHK(bytes <= maxlen, MP_BADARG); - - /* Iterate over each digit... */ - for(ix = USED(mp) - 1; ix >= 0; ix--) { - mp_digit d = DIGIT(mp, ix); - int jx; - - /* Unpack digit bytes, high order first */ - for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { - unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); - if (!pos && !x) /* suppress leading zeros */ - continue; - str[pos++] = x; - } - } - if (!pos) - str[pos++] = 0; - return pos; + int ix, pos = 0; + unsigned int bytes; + + ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); + + bytes = mp_unsigned_octet_size(mp); + ARGCHK(bytes <= maxlen, MP_BADARG); + + /* Iterate over each digit... */ + for (ix = USED(mp) - 1; ix >= 0; ix--) { + mp_digit d = DIGIT(mp, ix); + int jx; + + /* Unpack digit bytes, high order first */ + for (jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { + unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); + if (!pos && !x) /* suppress leading zeros */ + continue; + str[pos++] = x; + } + } + if (!pos) + str[pos++] = 0; + return pos; } /* end mp_to_unsigned_octets() */ /* }}} */ /* {{{ mp_to_signed_octets(mp, str) */ /* output a buffer of big endian octets no longer than specified. */ -mp_err +mp_err mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) { - int ix, pos = 0; - unsigned int bytes; - - ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); - - bytes = mp_unsigned_octet_size(mp); - ARGCHK(bytes <= maxlen, MP_BADARG); - - /* Iterate over each digit... */ - for(ix = USED(mp) - 1; ix >= 0; ix--) { - mp_digit d = DIGIT(mp, ix); - int jx; - - /* Unpack digit bytes, high order first */ - for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { - unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); - if (!pos) { - if (!x) /* suppress leading zeros */ - continue; - if (x & 0x80) { /* add one leading zero to make output positive. */ - ARGCHK(bytes + 1 <= maxlen, MP_BADARG); - if (bytes + 1 > maxlen) - return MP_BADARG; - str[pos++] = 0; - } - } - str[pos++] = x; - } - } - if (!pos) - str[pos++] = 0; - return pos; + int ix, pos = 0; + unsigned int bytes; + + ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); + + bytes = mp_unsigned_octet_size(mp); + ARGCHK(bytes <= maxlen, MP_BADARG); + + /* Iterate over each digit... */ + for (ix = USED(mp) - 1; ix >= 0; ix--) { + mp_digit d = DIGIT(mp, ix); + int jx; + + /* Unpack digit bytes, high order first */ + for (jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { + unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); + if (!pos) { + if (!x) /* suppress leading zeros */ + continue; + if (x & 0x80) { /* add one leading zero to make output positive. */ + ARGCHK(bytes + 1 <= maxlen, MP_BADARG); + if (bytes + 1 > maxlen) + return MP_BADARG; + str[pos++] = 0; + } + } + str[pos++] = x; + } + } + if (!pos) + str[pos++] = 0; + return pos; } /* end mp_to_signed_octets() */ /* }}} */ /* {{{ mp_to_fixlen_octets(mp, str) */ /* output a buffer of big endian octets exactly as long as requested. */ -mp_err +mp_err mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length) { - int ix, pos = 0; - unsigned int bytes; - - ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); - - bytes = mp_unsigned_octet_size(mp); - ARGCHK(bytes <= length, MP_BADARG); - - /* place any needed leading zeros */ - for (;length > bytes; --length) { - *str++ = 0; - } - - /* Iterate over each digit... */ - for(ix = USED(mp) - 1; ix >= 0; ix--) { - mp_digit d = DIGIT(mp, ix); - int jx; - - /* Unpack digit bytes, high order first */ - for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { - unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); - if (!pos && !x) /* suppress leading zeros */ - continue; - str[pos++] = x; - } - } - if (!pos) - str[pos++] = 0; - return MP_OKAY; + int ix, pos = 0; + unsigned int bytes; + + ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); + + bytes = mp_unsigned_octet_size(mp); + ARGCHK(bytes <= length, MP_BADARG); + + /* place any needed leading zeros */ + for (; length > bytes; --length) { + *str++ = 0; + } + + /* Iterate over each digit... */ + for (ix = USED(mp) - 1; ix >= 0; ix--) { + mp_digit d = DIGIT(mp, ix); + int jx; + + /* Unpack digit bytes, high order first */ + for (jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { + unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); + if (!pos && !x) /* suppress leading zeros */ + continue; + str[pos++] = x; + } + } + if (!pos) + str[pos++] = 0; + return MP_OKAY; } /* end mp_to_fixlen_octets() */ /* }}} */ - /*------------------------------------------------------------------------*/ /* HERE THERE BE DRAGONS */ diff --git a/nss/lib/freebl/mpi/mpi.h b/nss/lib/freebl/mpi/mpi.h index b1b45d2..64ffe75 100644 --- a/nss/lib/freebl/mpi/mpi.h +++ b/nss/lib/freebl/mpi/mpi.h @@ -12,6 +12,9 @@ #include "mpi-config.h" +#include "seccomon.h" +SEC_BEGIN_PROTOS + #if MP_DEBUG #undef MP_IOFUNC #define MP_IOFUNC 1 @@ -30,25 +33,25 @@ #include <sys/types.h> -#define MP_NEG 1 -#define MP_ZPOS 0 +#define MP_NEG 1 +#define MP_ZPOS 0 -#define MP_OKAY 0 /* no error, all is well */ -#define MP_YES 0 /* yes (boolean result) */ -#define MP_NO -1 /* no (boolean result) */ -#define MP_MEM -2 /* out of memory */ -#define MP_RANGE -3 /* argument out of range */ -#define MP_BADARG -4 /* invalid parameter */ -#define MP_UNDEF -5 /* answer is undefined */ -#define MP_LAST_CODE MP_UNDEF +#define MP_OKAY 0 /* no error, all is well */ +#define MP_YES 0 /* yes (boolean result) */ +#define MP_NO -1 /* no (boolean result) */ +#define MP_MEM -2 /* out of memory */ +#define MP_RANGE -3 /* argument out of range */ +#define MP_BADARG -4 /* invalid parameter */ +#define MP_UNDEF -5 /* answer is undefined */ +#define MP_LAST_CODE MP_UNDEF -typedef unsigned int mp_sign; -typedef unsigned int mp_size; -typedef int mp_err; +typedef unsigned int mp_sign; +typedef unsigned int mp_size; +typedef int mp_err; #define MP_32BIT_MAX 4294967295U -#if !defined(ULONG_MAX) +#if !defined(ULONG_MAX) #error "ULONG_MAX not defined" #elif !defined(UINT_MAX) #error "UINT_MAX not defined" @@ -56,119 +59,118 @@ typedef int mp_err; #error "USHRT_MAX not defined" #endif -#if defined(ULLONG_MAX) /* C99, Solaris */ +#if defined(ULLONG_MAX) /* C99, Solaris */ #define MP_ULONG_LONG_MAX ULLONG_MAX /* MP_ULONG_LONG_MAX was defined to be ULLONG_MAX */ -#elif defined(ULONG_LONG_MAX) /* HPUX */ +#elif defined(ULONG_LONG_MAX) /* HPUX */ #define MP_ULONG_LONG_MAX ULONG_LONG_MAX -#elif defined(ULONGLONG_MAX) /* IRIX, AIX */ +#elif defined(ULONGLONG_MAX) /* IRIX, AIX */ #define MP_ULONG_LONG_MAX ULONGLONG_MAX #endif /* We only use unsigned long for mp_digit iff long is more than 32 bits. */ #if !defined(MP_USE_UINT_DIGIT) && ULONG_MAX > MP_32BIT_MAX -typedef unsigned long mp_digit; -#define MP_DIGIT_MAX ULONG_MAX -#define MP_DIGIT_FMT "%016lX" /* printf() format for 1 digit */ +typedef unsigned long mp_digit; +#define MP_DIGIT_MAX ULONG_MAX +#define MP_DIGIT_FMT "%016lX" /* printf() format for 1 digit */ #define MP_HALF_DIGIT_MAX UINT_MAX -#undef MP_NO_MP_WORD +#undef MP_NO_MP_WORD #define MP_NO_MP_WORD 1 -#undef MP_USE_LONG_DIGIT +#undef MP_USE_LONG_DIGIT #define MP_USE_LONG_DIGIT 1 -#undef MP_USE_LONG_LONG_DIGIT +#undef MP_USE_LONG_LONG_DIGIT -#elif !defined(MP_USE_UINT_DIGIT) && defined(MP_ULONG_LONG_MAX) +#elif !defined(MP_USE_UINT_DIGIT) && defined(MP_ULONG_LONG_MAX) typedef unsigned long long mp_digit; -#define MP_DIGIT_MAX MP_ULONG_LONG_MAX -#define MP_DIGIT_FMT "%016llX" /* printf() format for 1 digit */ -#define MP_HALF_DIGIT_MAX UINT_MAX -#undef MP_NO_MP_WORD +#define MP_DIGIT_MAX MP_ULONG_LONG_MAX +#define MP_DIGIT_FMT "%016llX" /* printf() format for 1 digit */ +#define MP_HALF_DIGIT_MAX UINT_MAX +#undef MP_NO_MP_WORD #define MP_NO_MP_WORD 1 -#undef MP_USE_LONG_LONG_DIGIT +#undef MP_USE_LONG_LONG_DIGIT #define MP_USE_LONG_LONG_DIGIT 1 -#undef MP_USE_LONG_DIGIT +#undef MP_USE_LONG_DIGIT #else -typedef unsigned int mp_digit; -#define MP_DIGIT_MAX UINT_MAX -#define MP_DIGIT_FMT "%08X" /* printf() format for 1 digit */ +typedef unsigned int mp_digit; +#define MP_DIGIT_MAX UINT_MAX +#define MP_DIGIT_FMT "%08X" /* printf() format for 1 digit */ #define MP_HALF_DIGIT_MAX USHRT_MAX -#undef MP_USE_UINT_DIGIT +#undef MP_USE_UINT_DIGIT #define MP_USE_UINT_DIGIT 1 -#undef MP_USE_LONG_LONG_DIGIT -#undef MP_USE_LONG_DIGIT +#undef MP_USE_LONG_LONG_DIGIT +#undef MP_USE_LONG_DIGIT #endif -#if !defined(MP_NO_MP_WORD) -#if defined(MP_USE_UINT_DIGIT) && \ +#if !defined(MP_NO_MP_WORD) +#if defined(MP_USE_UINT_DIGIT) && \ (defined(MP_ULONG_LONG_MAX) || (ULONG_MAX > UINT_MAX)) #if (ULONG_MAX > UINT_MAX) -typedef unsigned long mp_word; -typedef long mp_sword; -#define MP_WORD_MAX ULONG_MAX +typedef unsigned long mp_word; +typedef long mp_sword; +#define MP_WORD_MAX ULONG_MAX #else typedef unsigned long long mp_word; -typedef long long mp_sword; -#define MP_WORD_MAX MP_ULONG_LONG_MAX +typedef long long mp_sword; +#define MP_WORD_MAX MP_ULONG_LONG_MAX #endif -#else +#else #define MP_NO_MP_WORD 1 #endif #endif /* !defined(MP_NO_MP_WORD) */ #if !defined(MP_WORD_MAX) && defined(MP_DEFINE_SMALL_WORD) -typedef unsigned int mp_word; -typedef int mp_sword; -#define MP_WORD_MAX UINT_MAX +typedef unsigned int mp_word; +typedef int mp_sword; +#define MP_WORD_MAX UINT_MAX #endif -#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit)) -#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word)) -#define MP_RADIX (1+(mp_word)MP_DIGIT_MAX) +#define MP_DIGIT_BIT (CHAR_BIT * sizeof(mp_digit)) +#define MP_WORD_BIT (CHAR_BIT * sizeof(mp_word)) +#define MP_RADIX (1 + (mp_word)MP_DIGIT_MAX) -#define MP_HALF_DIGIT_BIT (MP_DIGIT_BIT/2) -#define MP_HALF_RADIX (1+(mp_digit)MP_HALF_DIGIT_MAX) -/* MP_HALF_RADIX really ought to be called MP_SQRT_RADIX, but it's named -** MP_HALF_RADIX because it's the radix for MP_HALF_DIGITs, and it's +#define MP_HALF_DIGIT_BIT (MP_DIGIT_BIT / 2) +#define MP_HALF_RADIX (1 + (mp_digit)MP_HALF_DIGIT_MAX) +/* MP_HALF_RADIX really ought to be called MP_SQRT_RADIX, but it's named +** MP_HALF_RADIX because it's the radix for MP_HALF_DIGITs, and it's ** consistent with the other _HALF_ names. */ - /* Macros for accessing the mp_int internals */ -#define MP_SIGN(MP) ((MP)->sign) -#define MP_USED(MP) ((MP)->used) -#define MP_ALLOC(MP) ((MP)->alloc) -#define MP_DIGITS(MP) ((MP)->dp) -#define MP_DIGIT(MP,N) (MP)->dp[(N)] +#define MP_SIGN(MP) ((MP)->sign) +#define MP_USED(MP) ((MP)->used) +#define MP_ALLOC(MP) ((MP)->alloc) +#define MP_DIGITS(MP) ((MP)->dp) +#define MP_DIGIT(MP, N) (MP)->dp[(N)] /* This defines the maximum I/O base (minimum is 2) */ -#define MP_MAX_RADIX 64 +#define MP_MAX_RADIX 64 typedef struct { - mp_sign sign; /* sign of this quantity */ - mp_size alloc; /* how many digits allocated */ - mp_size used; /* how many digits used */ - mp_digit *dp; /* the digits themselves */ + mp_sign sign; /* sign of this quantity */ + mp_size alloc; /* how many digits allocated */ + mp_size used; /* how many digits used */ + mp_digit *dp; /* the digits themselves */ } mp_int; /* Default precision */ mp_size mp_get_prec(void); -void mp_set_prec(mp_size prec); +void mp_set_prec(mp_size prec); /* Memory management */ mp_err mp_init(mp_int *mp); mp_err mp_init_size(mp_int *mp, mp_size prec); mp_err mp_init_copy(mp_int *mp, const mp_int *from); mp_err mp_copy(const mp_int *from, mp_int *to); -void mp_exch(mp_int *mp1, mp_int *mp2); -void mp_clear(mp_int *mp); -void mp_zero(mp_int *mp); -void mp_set(mp_int *mp, mp_digit d); +void mp_exch(mp_int *mp1, mp_int *mp2); +void mp_clear(mp_int *mp); +void mp_zero(mp_int *mp); +void mp_set(mp_int *mp, mp_digit d); mp_err mp_set_int(mp_int *mp, long z); -#define mp_set_long(mp,z) mp_set_int(mp,z) +#define mp_set_long(mp, z) mp_set_int(mp, z) mp_err mp_set_ulong(mp_int *mp, unsigned long z); /* Single digit arithmetic */ @@ -197,7 +199,6 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r); mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r); mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c); mp_err mp_2expt(mp_int *a, mp_digit k); -mp_err mp_sqrt(const mp_int *a, mp_int *b); /* Modular arithmetic */ #if MP_MODARITH @@ -216,13 +217,12 @@ mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c); #endif /* MP_MODARITH */ /* Comparisons */ -int mp_cmp_z(const mp_int *a); -int mp_cmp_d(const mp_int *a, mp_digit d); -int mp_cmp(const mp_int *a, const mp_int *b); -int mp_cmp_mag(mp_int *a, mp_int *b); -int mp_cmp_int(const mp_int *a, long z); -int mp_isodd(const mp_int *a); -int mp_iseven(const mp_int *a); +int mp_cmp_z(const mp_int *a); +int mp_cmp_d(const mp_int *a, mp_digit d); +int mp_cmp(const mp_int *a, const mp_int *b); +int mp_cmp_mag(const mp_int *a, const mp_int *b); +int mp_isodd(const mp_int *a); +int mp_iseven(const mp_int *a); /* Number theoretic */ #if MP_NUMTH @@ -235,26 +235,26 @@ mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c); /* Input and output */ #if MP_IOFUNC -void mp_print(mp_int *mp, FILE *ofp); +void mp_print(mp_int *mp, FILE *ofp); #endif /* end MP_IOFUNC */ /* Base conversion */ mp_err mp_read_raw(mp_int *mp, char *str, int len); -int mp_raw_size(mp_int *mp); +int mp_raw_size(mp_int *mp); mp_err mp_toraw(mp_int *mp, char *str); mp_err mp_read_radix(mp_int *mp, const char *str, int radix); -mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix); -int mp_radix_size(mp_int *mp, int radix); +mp_err mp_read_variable_radix(mp_int *a, const char *str, int default_radix); +int mp_radix_size(mp_int *mp, int radix); mp_err mp_toradix(mp_int *mp, char *str, int radix); -int mp_tovalue(char ch, int r); +int mp_tovalue(char ch, int r); -#define mp_tobinary(M, S) mp_toradix((M), (S), 2) -#define mp_tooctal(M, S) mp_toradix((M), (S), 8) +#define mp_tobinary(M, S) mp_toradix((M), (S), 2) +#define mp_tooctal(M, S) mp_toradix((M), (S), 8) #define mp_todecimal(M, S) mp_toradix((M), (S), 10) -#define mp_tohex(M, S) mp_toradix((M), (S), 16) +#define mp_tohex(M, S) mp_toradix((M), (S), 16) /* Error strings */ -const char *mp_strerror(mp_err ec); +const char *mp_strerror(mp_err ec); /* Octet string conversion functions */ mp_err mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len); @@ -266,35 +266,48 @@ mp_err mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size len); /* Miscellaneous */ mp_size mp_trailing_zeros(const mp_int *mp); void freebl_cpuid(unsigned long op, unsigned long *eax, - unsigned long *ebx, unsigned long *ecx, - unsigned long *edx); - - -#define MP_CHECKOK(x) if (MP_OKAY > (res = (x))) goto CLEANUP -#define MP_CHECKERR(x) if (MP_OKAY > (res = (x))) goto CLEANUP - -#if defined(MP_API_COMPATIBLE) -#define NEG MP_NEG -#define ZPOS MP_ZPOS -#define DIGIT_MAX MP_DIGIT_MAX -#define DIGIT_BIT MP_DIGIT_BIT -#define DIGIT_FMT MP_DIGIT_FMT -#define RADIX MP_RADIX -#define MAX_RADIX MP_MAX_RADIX -#define SIGN(MP) MP_SIGN(MP) -#define USED(MP) MP_USED(MP) -#define ALLOC(MP) MP_ALLOC(MP) -#define DIGITS(MP) MP_DIGITS(MP) -#define DIGIT(MP,N) MP_DIGIT(MP,N) + unsigned long *ebx, unsigned long *ecx, + unsigned long *edx); + +#define MP_CHECKOK(x) \ + if (MP_OKAY > (res = (x))) \ + goto CLEANUP +#define MP_CHECKERR(x) \ + if (MP_OKAY > (res = (x))) \ + goto CLEANUP + +#define NEG MP_NEG +#define ZPOS MP_ZPOS +#define DIGIT_MAX MP_DIGIT_MAX +#define DIGIT_BIT MP_DIGIT_BIT +#define DIGIT_FMT MP_DIGIT_FMT +#define RADIX MP_RADIX +#define MAX_RADIX MP_MAX_RADIX +#define SIGN(MP) MP_SIGN(MP) +#define USED(MP) MP_USED(MP) +#define ALLOC(MP) MP_ALLOC(MP) +#define DIGITS(MP) MP_DIGITS(MP) +#define DIGIT(MP, N) MP_DIGIT(MP, N) #if MP_ARGCHK == 1 -#define ARGCHK(X,Y) {if(!(X)){return (Y);}} +#define ARGCHK(X, Y) \ + { \ + if (!(X)) { \ + return (Y); \ + } \ + } #elif MP_ARGCHK == 2 #include <assert.h> -#define ARGCHK(X,Y) assert(X) +#define ARGCHK(X, Y) assert(X) #else -#define ARGCHK(X,Y) /* */ +#define ARGCHK(X, Y) /* */ #endif -#endif /* defined MP_API_COMPATIBLE */ + +#ifdef CT_VERIF +void mp_taint(mp_int *mp); +void mp_untaint(mp_int *mp); +#endif + +SEC_END_PROTOS #endif /* end _H_MPI_ */ diff --git a/nss/lib/freebl/mpi/mpi_amd64.c b/nss/lib/freebl/mpi/mpi_amd64.c index 9c9b1f9..9e538bb 100644 --- a/nss/lib/freebl/mpi/mpi_amd64.c +++ b/nss/lib/freebl/mpi/mpi_amd64.c @@ -15,18 +15,18 @@ /* Presently, this is only used by the Montgomery arithmetic code. */ /* c += a * b */ -void MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, - mp_digit b, mp_digit *c) +void MPI_ASM_DECL +s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, + mp_digit b, mp_digit *c) { - mp_digit w; - mp_digit d; + mp_digit w; + mp_digit d; - d = s_mpv_mul_add_vec64(c, a, a_len, b); - c += a_len; - while (d) { - w = c[0] + d; - d = (w < c[0] || w < d); - *c++ = w; - } + d = s_mpv_mul_add_vec64(c, a, a_len, b); + c += a_len; + while (d) { + w = c[0] + d; + d = (w < c[0] || w < d); + *c++ = w; + } } - diff --git a/nss/lib/freebl/mpi/mpi_arm.c b/nss/lib/freebl/mpi/mpi_arm.c index 9199aab..b5139f2 100644 --- a/nss/lib/freebl/mpi/mpi_arm.c +++ b/nss/lib/freebl/mpi/mpi_arm.c @@ -14,158 +14,162 @@ #include "mpi-priv.h" #ifdef MP_ASSEMBLY_MULTIPLY -void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +void +s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { - __asm__ __volatile__( - "mov r5, #0\n" + __asm__ __volatile__( + "mov r5, #0\n" #ifdef __thumb2__ - "cbz %1, 2f\n" + "cbz %1, 2f\n" #else - "cmp %1, r5\n" /* r5 is 0 now */ - "beq 2f\n" + "cmp %1, r5\n" /* r5 is 0 now */ + "beq 2f\n" #endif - "1:\n" - "mov r4, #0\n" - "ldr r6, [%0], #4\n" - "umlal r5, r4, r6, %2\n" - "str r5, [%3], #4\n" - "mov r5, r4\n" - - "subs %1, #1\n" - "bne 1b\n" - - "2:\n" - "str r5, [%3]\n" - : - : "r"(a), "r"(a_len), "r"(b), "r"(c) - : "memory", "cc", "%r4", "%r5", "%r6"); + "1:\n" + "mov r4, #0\n" + "ldr r6, [%0], #4\n" + "umlal r5, r4, r6, %2\n" + "str r5, [%3], #4\n" + "mov r5, r4\n" + + "subs %1, #1\n" + "bne 1b\n" + + "2:\n" + "str r5, [%3]\n" + : + : "r"(a), "r"(a_len), "r"(b), "r"(c) + : "memory", "cc", "%r4", "%r5", "%r6"); } -void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +void +s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { - __asm__ __volatile__( - "mov r5, #0\n" + __asm__ __volatile__( + "mov r5, #0\n" #ifdef __thumb2__ - "cbz %1, 2f\n" + "cbz %1, 2f\n" #else - "cmp %1, r5\n" /* r5 is 0 now */ - "beq 2f\n" + "cmp %1, r5\n" /* r5 is 0 now */ + "beq 2f\n" #endif - "1:\n" - "mov r4, #0\n" - "ldr r6, [%3]\n" - "adds r5, r6\n" - "adc r4, r4, #0\n" - - "ldr r6, [%0], #4\n" - "umlal r5, r4, r6, %2\n" - "str r5, [%3], #4\n" - "mov r5, r4\n" - - "subs %1, #1\n" - "bne 1b\n" - - "2:\n" - "str r5, [%3]\n" - : - : "r"(a), "r"(a_len), "r"(b), "r"(c) - : "memory", "cc", "%r4", "%r5", "%r6"); + "1:\n" + "mov r4, #0\n" + "ldr r6, [%3]\n" + "adds r5, r6\n" + "adc r4, r4, #0\n" + + "ldr r6, [%0], #4\n" + "umlal r5, r4, r6, %2\n" + "str r5, [%3], #4\n" + "mov r5, r4\n" + + "subs %1, #1\n" + "bne 1b\n" + + "2:\n" + "str r5, [%3]\n" + : + : "r"(a), "r"(a_len), "r"(b), "r"(c) + : "memory", "cc", "%r4", "%r5", "%r6"); } -void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +void +s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { - if (!a_len) - return; + if (!a_len) + return; - __asm__ __volatile__( - "mov r5, #0\n" + __asm__ __volatile__( + "mov r5, #0\n" - "1:\n" - "mov r4, #0\n" - "ldr r6, [%3]\n" - "adds r5, r6\n" - "adc r4, r4, #0\n" - "ldr r6, [%0], #4\n" - "umlal r5, r4, r6, %2\n" - "str r5, [%3], #4\n" - "mov r5, r4\n" + "1:\n" + "mov r4, #0\n" + "ldr r6, [%3]\n" + "adds r5, r6\n" + "adc r4, r4, #0\n" + "ldr r6, [%0], #4\n" + "umlal r5, r4, r6, %2\n" + "str r5, [%3], #4\n" + "mov r5, r4\n" - "subs %1, #1\n" - "bne 1b\n" + "subs %1, #1\n" + "bne 1b\n" #ifdef __thumb2__ - "cbz r4, 3f\n" + "cbz r4, 3f\n" #else - "cmp r4, #0\n" - "beq 3f\n" + "cmp r4, #0\n" + "beq 3f\n" #endif - "2:\n" - "mov r4, #0\n" - "ldr r6, [%3]\n" - "adds r5, r6\n" - "adc r4, r4, #0\n" - "str r5, [%3], #4\n" - "movs r5, r4\n" - "bne 2b\n" - - "3:\n" - : - : "r"(a), "r"(a_len), "r"(b), "r"(c) - : "memory", "cc", "%r4", "%r5", "%r6"); + "2:\n" + "mov r4, #0\n" + "ldr r6, [%3]\n" + "adds r5, r6\n" + "adc r4, r4, #0\n" + "str r5, [%3], #4\n" + "movs r5, r4\n" + "bne 2b\n" + + "3:\n" + : + : "r"(a), "r"(a_len), "r"(b), "r"(c) + : "memory", "cc", "%r4", "%r5", "%r6"); } #endif #ifdef MP_ASSEMBLY_SQUARE -void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps) +void +s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps) { - if (!a_len) - return; - - __asm__ __volatile__( - "mov r3, #0\n" - - "1:\n" - "mov r4, #0\n" - "ldr r6, [%0], #4\n" - "ldr r5, [%2]\n" - "adds r3, r5\n" - "adc r4, r4, #0\n" - "umlal r3, r4, r6, r6\n" /* w = r3:r4 */ - "str r3, [%2], #4\n" - - "ldr r5, [%2]\n" - "adds r3, r4, r5\n" - "mov r4, #0\n" - "adc r4, r4, #0\n" - "str r3, [%2], #4\n" - "mov r3, r4\n" - - "subs %1, #1\n" - "bne 1b\n" + if (!a_len) + return; + + __asm__ __volatile__( + "mov r3, #0\n" + + "1:\n" + "mov r4, #0\n" + "ldr r6, [%0], #4\n" + "ldr r5, [%2]\n" + "adds r3, r5\n" + "adc r4, r4, #0\n" + "umlal r3, r4, r6, r6\n" /* w = r3:r4 */ + "str r3, [%2], #4\n" + + "ldr r5, [%2]\n" + "adds r3, r4, r5\n" + "mov r4, #0\n" + "adc r4, r4, #0\n" + "str r3, [%2], #4\n" + "mov r3, r4\n" + + "subs %1, #1\n" + "bne 1b\n" #ifdef __thumb2__ - "cbz r3, 3f\n" + "cbz r3, 3f\n" #else - "cmp r3, #0\n" - "beq 3f\n" + "cmp r3, #0\n" + "beq 3f\n" #endif - "2:\n" - "mov r4, #0\n" - "ldr r5, [%2]\n" - "adds r3, r5\n" - "adc r4, r4, #0\n" - "str r3, [%2], #4\n" - "movs r3, r4\n" - "bne 2b\n" - - "3:" - : - : "r"(pa), "r"(a_len), "r"(ps) - : "memory", "cc", "%r3", "%r4", "%r5", "%r6"); + "2:\n" + "mov r4, #0\n" + "ldr r5, [%2]\n" + "adds r3, r5\n" + "adc r4, r4, #0\n" + "str r3, [%2], #4\n" + "movs r3, r4\n" + "bne 2b\n" + + "3:" + : + : "r"(pa), "r"(a_len), "r"(ps) + : "memory", "cc", "%r3", "%r4", "%r5", "%r6"); } #endif #endif diff --git a/nss/lib/freebl/mpi/mpi_hp.c b/nss/lib/freebl/mpi/mpi_hp.c index e86d3d6..0cea768 100644 --- a/nss/lib/freebl/mpi/mpi_hp.c +++ b/nss/lib/freebl/mpi/mpi_hp.c @@ -11,72 +11,71 @@ /* #include <sys/systeminfo.h> */ #include <strings.h> -extern void multacc512( - int length, /* doublewords in multiplicand vector. */ - const mp_digit *scalaraddr, /* Address of scalar. */ - const mp_digit *multiplicand, /* The multiplicand vector. */ - mp_digit * result); /* Where to accumulate the result. */ +extern void multacc512( + int length, /* doublewords in multiplicand vector. */ + const mp_digit *scalaraddr, /* Address of scalar. */ + const mp_digit *multiplicand, /* The multiplicand vector. */ + mp_digit *result); /* Where to accumulate the result. */ extern void maxpy_little( - int length, /* doublewords in multiplicand vector. */ - const mp_digit *scalaraddr, /* Address of scalar. */ - const mp_digit *multiplicand, /* The multiplicand vector. */ - mp_digit * result); /* Where to accumulate the result. */ + int length, /* doublewords in multiplicand vector. */ + const mp_digit *scalaraddr, /* Address of scalar. */ + const mp_digit *multiplicand, /* The multiplicand vector. */ + mp_digit *result); /* Where to accumulate the result. */ extern void add_diag_little( - int length, /* doublewords in input vector. */ - const mp_digit *root, /* The vector to square. */ - mp_digit * result); /* Where to accumulate the result. */ + int length, /* doublewords in input vector. */ + const mp_digit *root, /* The vector to square. */ + mp_digit *result); /* Where to accumulate the result. */ -void +void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps) { add_diag_little(a_len, pa, ps); } #define MAX_STACK_DIGITS 258 -#define MULTACC512_LEN (512 / MP_DIGIT_BIT) -#define HP_MPY_ADD_FN (a_len == MULTACC512_LEN ? multacc512 : maxpy_little) +#define MULTACC512_LEN (512 / MP_DIGIT_BIT) +#define HP_MPY_ADD_FN (a_len == MULTACC512_LEN ? multacc512 : maxpy_little) /* c = a * b */ -void +void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit x[MAX_STACK_DIGITS]; mp_digit *px = x; - size_t xSize = 0; + size_t xSize = 0; if (a == c) { - if (a_len > MAX_STACK_DIGITS) { - xSize = sizeof(mp_digit) * (a_len + 2); - px = malloc(xSize); - if (!px) - return; - } - memcpy(px, a, a_len * sizeof(*a)); - a = px; + if (a_len > MAX_STACK_DIGITS) { + xSize = sizeof(mp_digit) * (a_len + 2); + px = malloc(xSize); + if (!px) + return; + } + memcpy(px, a, a_len * sizeof(*a)); + a = px; } s_mp_setz(c, a_len + 1); HP_MPY_ADD_FN(a_len, &b, a, c); if (px != x && px) { - memset(px, 0, xSize); - free(px); + memset(px, 0, xSize); + free(px); } } /* c += a * b, where a is a_len words long. */ -void +void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { - c[a_len] = 0; /* so carry propagation stops here. */ + c[a_len] = 0; /* so carry propagation stops here. */ HP_MPY_ADD_FN(a_len, &b, a, c); } /* c += a * b, where a is y words long. */ -void -s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, - mp_digit *c) +void +s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, + mp_digit *c) { HP_MPY_ADD_FN(a_len, &b, a, c); } - diff --git a/nss/lib/freebl/mpi/mpi_sparc.c b/nss/lib/freebl/mpi/mpi_sparc.c index 628843e..1e88357 100644 --- a/nss/lib/freebl/mpi/mpi_sparc.c +++ b/nss/lib/freebl/mpi/mpi_sparc.c @@ -18,207 +18,209 @@ extern mp_digit mul_add_inp(mp_digit *x, const mp_digit *y, int n, mp_digit a); /* vector z = vector x + vector y * scaler a; where y is of length n words. */ -extern mp_digit mul_add(mp_digit *z, const mp_digit *x, const mp_digit *y, - int n, mp_digit a); +extern mp_digit mul_add(mp_digit *z, const mp_digit *x, const mp_digit *y, + int n, mp_digit a); /* v8 versions of these functions run on any Sparc v8 CPU. */ /* This trick works on Sparc V8 CPUs with the Workshop compilers. */ -#define MP_MUL_DxD(a, b, Phi, Plo) \ - { unsigned long long product = (unsigned long long)a * b; \ - Plo = (mp_digit)product; \ - Phi = (mp_digit)(product >> MP_DIGIT_BIT); } +#define MP_MUL_DxD(a, b, Phi, Plo) \ + { \ + unsigned long long product = (unsigned long long)a * b; \ + Plo = (mp_digit)product; \ + Phi = (mp_digit)(product >> MP_DIGIT_BIT); \ + } /* c = a * b */ -static void +static void v8_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { #if !defined(MP_NO_MP_WORD) - mp_digit d = 0; - - /* Inner product: Digits of a */ - while (a_len--) { - mp_word w = ((mp_word)b * *a++) + d; - *c++ = ACCUM(w); - d = CARRYOUT(w); - } - *c = d; + mp_digit d = 0; + + /* Inner product: Digits of a */ + while (a_len--) { + mp_word w = ((mp_word)b * *a++) + d; + *c++ = ACCUM(w); + d = CARRYOUT(w); + } + *c = d; #else - mp_digit carry = 0; - while (a_len--) { - mp_digit a_i = *a++; - mp_digit a0b0, a1b1; - - MP_MUL_DxD(a_i, b, a1b1, a0b0); - - a0b0 += carry; - if (a0b0 < carry) - ++a1b1; - *c++ = a0b0; - carry = a1b1; - } - *c = carry; + mp_digit carry = 0; + while (a_len--) { + mp_digit a_i = *a++; + mp_digit a0b0, a1b1; + + MP_MUL_DxD(a_i, b, a1b1, a0b0); + + a0b0 += carry; + if (a0b0 < carry) + ++a1b1; + *c++ = a0b0; + carry = a1b1; + } + *c = carry; #endif } /* c += a * b */ -static void +static void v8_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { #if !defined(MP_NO_MP_WORD) - mp_digit d = 0; - - /* Inner product: Digits of a */ - while (a_len--) { - mp_word w = ((mp_word)b * *a++) + *c + d; - *c++ = ACCUM(w); - d = CARRYOUT(w); - } - *c = d; + mp_digit d = 0; + + /* Inner product: Digits of a */ + while (a_len--) { + mp_word w = ((mp_word)b * *a++) + *c + d; + *c++ = ACCUM(w); + d = CARRYOUT(w); + } + *c = d; #else - mp_digit carry = 0; - while (a_len--) { - mp_digit a_i = *a++; - mp_digit a0b0, a1b1; - - MP_MUL_DxD(a_i, b, a1b1, a0b0); - - a0b0 += carry; - if (a0b0 < carry) - ++a1b1; - a0b0 += a_i = *c; - if (a0b0 < a_i) - ++a1b1; - *c++ = a0b0; - carry = a1b1; - } - *c = carry; + mp_digit carry = 0; + while (a_len--) { + mp_digit a_i = *a++; + mp_digit a0b0, a1b1; + + MP_MUL_DxD(a_i, b, a1b1, a0b0); + + a0b0 += carry; + if (a0b0 < carry) + ++a1b1; + a0b0 += a_i = *c; + if (a0b0 < a_i) + ++a1b1; + *c++ = a0b0; + carry = a1b1; + } + *c = carry; #endif } /* Presently, this is only used by the Montgomery arithmetic code. */ /* c += a * b */ -static void +static void v8_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { #if !defined(MP_NO_MP_WORD) - mp_digit d = 0; - - /* Inner product: Digits of a */ - while (a_len--) { - mp_word w = ((mp_word)b * *a++) + *c + d; - *c++ = ACCUM(w); - d = CARRYOUT(w); - } - - while (d) { - mp_word w = (mp_word)*c + d; - *c++ = ACCUM(w); - d = CARRYOUT(w); - } + mp_digit d = 0; + + /* Inner product: Digits of a */ + while (a_len--) { + mp_word w = ((mp_word)b * *a++) + *c + d; + *c++ = ACCUM(w); + d = CARRYOUT(w); + } + + while (d) { + mp_word w = (mp_word)*c + d; + *c++ = ACCUM(w); + d = CARRYOUT(w); + } #else - mp_digit carry = 0; - while (a_len--) { - mp_digit a_i = *a++; - mp_digit a0b0, a1b1; - - MP_MUL_DxD(a_i, b, a1b1, a0b0); - - a0b0 += carry; - if (a0b0 < carry) - ++a1b1; - - a0b0 += a_i = *c; - if (a0b0 < a_i) - ++a1b1; - - *c++ = a0b0; - carry = a1b1; - } - while (carry) { - mp_digit c_i = *c; - carry += c_i; - *c++ = carry; - carry = carry < c_i; - } + mp_digit carry = 0; + while (a_len--) { + mp_digit a_i = *a++; + mp_digit a0b0, a1b1; + + MP_MUL_DxD(a_i, b, a1b1, a0b0); + + a0b0 += carry; + if (a0b0 < carry) + ++a1b1; + + a0b0 += a_i = *c; + if (a0b0 < a_i) + ++a1b1; + + *c++ = a0b0; + carry = a1b1; + } + while (carry) { + mp_digit c_i = *c; + carry += c_i; + *c++ = carry; + carry = carry < c_i; + } #endif } /* These functions run only on v8plus+vis or v9+vis CPUs. */ /* c = a * b */ -void +void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit d; mp_digit x[258]; if (a_len <= 256) { - if (a == c || ((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) { - mp_digit * px; - px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x; - memcpy(px, a, a_len * sizeof(*a)); - a = px; - if (a_len & 1) { - px[a_len] = 0; - } - } - s_mp_setz(c, a_len + 1); - d = mul_add_inp(c, a, a_len, b); - c[a_len] = d; + if (a == c || ((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) { + mp_digit *px; + px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x; + memcpy(px, a, a_len * sizeof(*a)); + a = px; + if (a_len & 1) { + px[a_len] = 0; + } + } + s_mp_setz(c, a_len + 1); + d = mul_add_inp(c, a, a_len, b); + c[a_len] = d; } else { - v8_mpv_mul_d(a, a_len, b, c); + v8_mpv_mul_d(a, a_len, b, c); } } /* c += a * b, where a is a_len words long. */ -void +void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit d; mp_digit x[258]; if (a_len <= 256) { - if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) { - mp_digit * px; - px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x; - memcpy(px, a, a_len * sizeof(*a)); - a = px; - if (a_len & 1) { - px[a_len] = 0; - } - } - d = mul_add_inp(c, a, a_len, b); - c[a_len] = d; + if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) { + mp_digit *px; + px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x; + memcpy(px, a, a_len * sizeof(*a)); + a = px; + if (a_len & 1) { + px[a_len] = 0; + } + } + d = mul_add_inp(c, a, a_len, b); + c[a_len] = d; } else { - v8_mpv_mul_d_add(a, a_len, b, c); + v8_mpv_mul_d_add(a, a_len, b, c); } } /* c += a * b, where a is y words long. */ -void +void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit d; mp_digit x[258]; if (a_len <= 256) { - if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) { - mp_digit * px; - px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x; - memcpy(px, a, a_len * sizeof(*a)); - a = px; - if (a_len & 1) { - px[a_len] = 0; - } - } - d = mul_add_inp(c, a, a_len, b); - if (d) { - c += a_len; - do { - mp_digit sum = d + *c; - *c++ = sum; - d = sum < d; - } while (d); - } + if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) { + mp_digit *px; + px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x; + memcpy(px, a, a_len * sizeof(*a)); + a = px; + if (a_len & 1) { + px[a_len] = 0; + } + } + d = mul_add_inp(c, a, a_len, b); + if (d) { + c += a_len; + do { + mp_digit sum = d + *c; + *c++ = sum; + d = sum < d; + } while (d); + } } else { - v8_mpv_mul_d_add_prop(a, a_len, b, c); + v8_mpv_mul_d_add_prop(a, a_len, b, c); } } diff --git a/nss/lib/freebl/mpi/mpi_x86_asm.c b/nss/lib/freebl/mpi/mpi_x86_asm.c index e25166e..4faeef3 100644 --- a/nss/lib/freebl/mpi/mpi_x86_asm.c +++ b/nss/lib/freebl/mpi/mpi_x86_asm.c @@ -1,6 +1,6 @@ /* * mpi_x86_asm.c - MSVC inline assembly implementation of s_mpv_ functions. - * + * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -11,33 +11,32 @@ static int is_sse = -1; extern unsigned long s_mpi_is_sse2(); /* - * ebp - 36: caller's esi - * ebp - 32: caller's edi - * ebp - 28: - * ebp - 24: - * ebp - 20: - * ebp - 16: - * ebp - 12: - * ebp - 8: - * ebp - 4: - * ebp + 0: caller's ebp - * ebp + 4: return address - * ebp + 8: a argument - * ebp + 12: a_len argument - * ebp + 16: b argument - * ebp + 20: c argument + * ebp - 36: caller's esi + * ebp - 32: caller's edi + * ebp - 28: + * ebp - 24: + * ebp - 20: + * ebp - 16: + * ebp - 12: + * ebp - 8: + * ebp - 4: + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: a argument + * ebp + 12: a_len argument + * ebp + 16: b argument + * ebp + 20: c argument * registers: - * eax: - * ebx: carry - * ecx: a_len - * edx: - * esi: a ptr - * edi: c ptr + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr */ -__declspec(naked) void -s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +__declspec(naked) void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { - __asm { + __asm { mov eax, is_sse cmp eax, 0 je s_mpv_mul_d_x86 @@ -53,95 +52,94 @@ s_mpv_mul_d_x86: push edi push esi push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; ecx = a_len + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; ecx = a_len mov edi,[ebp+20] cmp ecx,0 - je L_2 ; jmp if a_len == 0 - mov esi,[ebp+8] ; esi = a + je L_2 ; jmp if a_len == 0 + mov esi,[ebp+8] ; esi = a cld L_1: - lodsd ; eax = [ds:esi]; esi += 4 - mov edx,[ebp+16] ; edx = b - mul edx ; edx:eax = Phi:Plo = a_i * b + lodsd ; eax = [ds:esi]; esi += 4 + mov edx,[ebp+16] ; edx = b + mul edx ; edx:eax = Phi:Plo = a_i * b - add eax,ebx ; add carry (ebx) to edx:eax + add eax,ebx ; add carry (ebx) to edx:eax adc edx,0 - mov ebx,edx ; high half of product becomes next carry + mov ebx,edx ; high half of product becomes next carry - stosd ; [es:edi] = ax; edi += 4; - dec ecx ; --a_len - jnz L_1 ; jmp if a_len != 0 + stosd ; [es:edi] = ax; edi += 4; + dec ecx ; --a_len + jnz L_1 ; jmp if a_len != 0 L_2: - mov [edi],ebx ; *c = carry + mov [edi],ebx ; *c = carry pop ebx pop esi pop edi - leave - ret + leave + ret nop s_mpv_mul_d_sse2: push ebp mov ebp, esp push edi push esi - psubq mm2, mm2 ; carry = 0 - mov ecx, [ebp+12] ; ecx = a_len - movd mm1, [ebp+16] ; mm1 = b + psubq mm2, mm2 ; carry = 0 + mov ecx, [ebp+12] ; ecx = a_len + movd mm1, [ebp+16] ; mm1 = b mov edi, [ebp+20] cmp ecx, 0 - je L_6 ; jmp if a_len == 0 - mov esi, [ebp+8] ; esi = a + je L_6 ; jmp if a_len == 0 + mov esi, [ebp+8] ; esi = a cld L_5: - movd mm0, [esi] ; mm0 = *a++ + movd mm0, [esi] ; mm0 = *a++ add esi, 4 - pmuludq mm0, mm1 ; mm0 = b * *a++ - paddq mm2, mm0 ; add the carry - movd [edi], mm2 ; store the 32bit result + pmuludq mm0, mm1 ; mm0 = b * *a++ + paddq mm2, mm0 ; add the carry + movd [edi], mm2 ; store the 32bit result add edi, 4 - psrlq mm2, 32 ; save the carry - dec ecx ; --a_len - jnz L_5 ; jmp if a_len != 0 + psrlq mm2, 32 ; save the carry + dec ecx ; --a_len + jnz L_5 ; jmp if a_len != 0 L_6: - movd [edi], mm2 ; *c = carry + movd [edi], mm2 ; *c = carry emms pop esi pop edi - leave - ret + leave + ret nop - } + } } /* - * ebp - 36: caller's esi - * ebp - 32: caller's edi - * ebp - 28: - * ebp - 24: - * ebp - 20: - * ebp - 16: - * ebp - 12: - * ebp - 8: - * ebp - 4: - * ebp + 0: caller's ebp - * ebp + 4: return address - * ebp + 8: a argument - * ebp + 12: a_len argument - * ebp + 16: b argument - * ebp + 20: c argument + * ebp - 36: caller's esi + * ebp - 32: caller's edi + * ebp - 28: + * ebp - 24: + * ebp - 20: + * ebp - 16: + * ebp - 12: + * ebp - 8: + * ebp - 4: + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: a argument + * ebp + 12: a_len argument + * ebp + 16: b argument + * ebp + 20: c argument * registers: - * eax: - * ebx: carry - * ecx: a_len - * edx: - * esi: a ptr - * edi: c ptr + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr */ -__declspec(naked) void -s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +__declspec(naked) void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { - __asm { + __asm { mov eax, is_sse cmp eax, 0 je s_mpv_mul_d_add_x86 @@ -157,100 +155,99 @@ s_mpv_mul_d_add_x86: push edi push esi push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; ecx = a_len + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; ecx = a_len mov edi,[ebp+20] cmp ecx,0 - je L_11 ; jmp if a_len == 0 - mov esi,[ebp+8] ; esi = a + je L_11 ; jmp if a_len == 0 + mov esi,[ebp+8] ; esi = a cld L_10: - lodsd ; eax = [ds:esi]; esi += 4 - mov edx,[ebp+16] ; edx = b - mul edx ; edx:eax = Phi:Plo = a_i * b + lodsd ; eax = [ds:esi]; esi += 4 + mov edx,[ebp+16] ; edx = b + mul edx ; edx:eax = Phi:Plo = a_i * b - add eax,ebx ; add carry (ebx) to edx:eax + add eax,ebx ; add carry (ebx) to edx:eax adc edx,0 - mov ebx,[edi] ; add in current word from *c - add eax,ebx + mov ebx,[edi] ; add in current word from *c + add eax,ebx adc edx,0 - mov ebx,edx ; high half of product becomes next carry + mov ebx,edx ; high half of product becomes next carry - stosd ; [es:edi] = ax; edi += 4; - dec ecx ; --a_len - jnz L_10 ; jmp if a_len != 0 + stosd ; [es:edi] = ax; edi += 4; + dec ecx ; --a_len + jnz L_10 ; jmp if a_len != 0 L_11: - mov [edi],ebx ; *c = carry + mov [edi],ebx ; *c = carry pop ebx pop esi pop edi - leave - ret + leave + ret nop s_mpv_mul_d_add_sse2: push ebp mov ebp, esp push edi push esi - psubq mm2, mm2 ; carry = 0 - mov ecx, [ebp+12] ; ecx = a_len - movd mm1, [ebp+16] ; mm1 = b + psubq mm2, mm2 ; carry = 0 + mov ecx, [ebp+12] ; ecx = a_len + movd mm1, [ebp+16] ; mm1 = b mov edi, [ebp+20] cmp ecx, 0 - je L_16 ; jmp if a_len == 0 - mov esi, [ebp+8] ; esi = a + je L_16 ; jmp if a_len == 0 + mov esi, [ebp+8] ; esi = a cld L_15: - movd mm0, [esi] ; mm0 = *a++ + movd mm0, [esi] ; mm0 = *a++ add esi, 4 - pmuludq mm0, mm1 ; mm0 = b * *a++ - paddq mm2, mm0 ; add the carry + pmuludq mm0, mm1 ; mm0 = b * *a++ + paddq mm2, mm0 ; add the carry movd mm0, [edi] - paddq mm2, mm0 ; add the carry - movd [edi], mm2 ; store the 32bit result + paddq mm2, mm0 ; add the carry + movd [edi], mm2 ; store the 32bit result add edi, 4 - psrlq mm2, 32 ; save the carry - dec ecx ; --a_len - jnz L_15 ; jmp if a_len != 0 + psrlq mm2, 32 ; save the carry + dec ecx ; --a_len + jnz L_15 ; jmp if a_len != 0 L_16: - movd [edi], mm2 ; *c = carry + movd [edi], mm2 ; *c = carry emms pop esi pop edi - leave - ret + leave + ret nop - } + } } /* - * ebp - 36: caller's esi - * ebp - 32: caller's edi - * ebp - 28: - * ebp - 24: - * ebp - 20: - * ebp - 16: - * ebp - 12: - * ebp - 8: - * ebp - 4: - * ebp + 0: caller's ebp - * ebp + 4: return address - * ebp + 8: a argument - * ebp + 12: a_len argument - * ebp + 16: b argument - * ebp + 20: c argument + * ebp - 36: caller's esi + * ebp - 32: caller's edi + * ebp - 28: + * ebp - 24: + * ebp - 20: + * ebp - 16: + * ebp - 12: + * ebp - 8: + * ebp - 4: + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: a argument + * ebp + 12: a_len argument + * ebp + 16: b argument + * ebp + 20: c argument * registers: - * eax: - * ebx: carry - * ecx: a_len - * edx: - * esi: a ptr - * edi: c ptr + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr */ -__declspec(naked) void -s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +__declspec(naked) void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { - __asm { + __asm { mov eax, is_sse cmp eax, 0 je s_mpv_mul_d_add_prop_x86 @@ -266,46 +263,46 @@ s_mpv_mul_d_add_prop_x86: push edi push esi push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; ecx = a_len + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; ecx = a_len mov edi,[ebp+20] cmp ecx,0 - je L_21 ; jmp if a_len == 0 + je L_21 ; jmp if a_len == 0 cld - mov esi,[ebp+8] ; esi = a + mov esi,[ebp+8] ; esi = a L_20: - lodsd ; eax = [ds:esi]; esi += 4 - mov edx,[ebp+16] ; edx = b - mul edx ; edx:eax = Phi:Plo = a_i * b + lodsd ; eax = [ds:esi]; esi += 4 + mov edx,[ebp+16] ; edx = b + mul edx ; edx:eax = Phi:Plo = a_i * b - add eax,ebx ; add carry (ebx) to edx:eax + add eax,ebx ; add carry (ebx) to edx:eax adc edx,0 - mov ebx,[edi] ; add in current word from *c - add eax,ebx + mov ebx,[edi] ; add in current word from *c + add eax,ebx adc edx,0 - mov ebx,edx ; high half of product becomes next carry + mov ebx,edx ; high half of product becomes next carry - stosd ; [es:edi] = ax; edi += 4; - dec ecx ; --a_len - jnz L_20 ; jmp if a_len != 0 + stosd ; [es:edi] = ax; edi += 4; + dec ecx ; --a_len + jnz L_20 ; jmp if a_len != 0 L_21: - cmp ebx,0 ; is carry zero? + cmp ebx,0 ; is carry zero? jz L_23 - mov eax,[edi] ; add in current word from *c + mov eax,[edi] ; add in current word from *c add eax,ebx - stosd ; [es:edi] = ax; edi += 4; + stosd ; [es:edi] = ax; edi += 4; jnc L_23 L_22: - mov eax,[edi] ; add in current word from *c + mov eax,[edi] ; add in current word from *c adc eax,0 - stosd ; [es:edi] = ax; edi += 4; + stosd ; [es:edi] = ax; edi += 4; jc L_22 L_23: pop ebx pop esi pop edi - leave - ret + leave + ret nop s_mpv_mul_d_add_prop_sse2: push ebp @@ -313,74 +310,73 @@ s_mpv_mul_d_add_prop_sse2: push edi push esi push ebx - psubq mm2, mm2 ; carry = 0 - mov ecx, [ebp+12] ; ecx = a_len - movd mm1, [ebp+16] ; mm1 = b + psubq mm2, mm2 ; carry = 0 + mov ecx, [ebp+12] ; ecx = a_len + movd mm1, [ebp+16] ; mm1 = b mov edi, [ebp+20] cmp ecx, 0 - je L_26 ; jmp if a_len == 0 - mov esi, [ebp+8] ; esi = a + je L_26 ; jmp if a_len == 0 + mov esi, [ebp+8] ; esi = a cld L_25: - movd mm0, [esi] ; mm0 = *a++ - movd mm3, [edi] ; fetch the sum + movd mm0, [esi] ; mm0 = *a++ + movd mm3, [edi] ; fetch the sum add esi, 4 - pmuludq mm0, mm1 ; mm0 = b * *a++ - paddq mm2, mm0 ; add the carry - paddq mm2, mm3 ; add *c++ - movd [edi], mm2 ; store the 32bit result + pmuludq mm0, mm1 ; mm0 = b * *a++ + paddq mm2, mm0 ; add the carry + paddq mm2, mm3 ; add *c++ + movd [edi], mm2 ; store the 32bit result add edi, 4 - psrlq mm2, 32 ; save the carry - dec ecx ; --a_len - jnz L_25 ; jmp if a_len != 0 + psrlq mm2, 32 ; save the carry + dec ecx ; --a_len + jnz L_25 ; jmp if a_len != 0 L_26: movd ebx, mm2 - cmp ebx, 0 ; is carry zero? + cmp ebx, 0 ; is carry zero? jz L_28 mov eax, [edi] add eax, ebx stosd jnc L_28 L_27: - mov eax, [edi] ; add in current word from *c - adc eax, 0 - stosd ; [es:edi] = ax; edi += 4; + mov eax, [edi] ; add in current word from *c + adc eax, 0 + stosd ; [es:edi] = ax; edi += 4; jc L_27 L_28: emms pop ebx pop esi pop edi - leave - ret + leave + ret nop - } + } } /* - * ebp - 20: caller's esi - * ebp - 16: caller's edi - * ebp - 12: - * ebp - 8: carry - * ebp - 4: a_len local - * ebp + 0: caller's ebp - * ebp + 4: return address - * ebp + 8: pa argument - * ebp + 12: a_len argument - * ebp + 16: ps argument - * ebp + 20: + * ebp - 20: caller's esi + * ebp - 16: caller's edi + * ebp - 12: + * ebp - 8: carry + * ebp - 4: a_len local + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: pa argument + * ebp + 12: a_len argument + * ebp + 16: ps argument + * ebp + 20: * registers: - * eax: - * ebx: carry - * ecx: a_len - * edx: - * esi: a ptr - * edi: c ptr + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr */ -__declspec(naked) void -s_mpv_sqr_add_prop(const mp_digit *a, mp_size a_len, mp_digit *sqrs) +__declspec(naked) void s_mpv_sqr_add_prop(const mp_digit *a, mp_size a_len, mp_digit *sqrs) { - __asm { + __asm { mov eax, is_sse cmp eax, 0 je s_mpv_sqr_add_prop_x86 @@ -396,48 +392,48 @@ s_mpv_sqr_add_prop_x86: push edi push esi push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; a_len - mov edi,[ebp+16] ; edi = ps + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; a_len + mov edi,[ebp+16] ; edi = ps cmp ecx,0 - je L_31 ; jump if a_len == 0 + je L_31 ; jump if a_len == 0 cld - mov esi,[ebp+8] ; esi = pa + mov esi,[ebp+8] ; esi = pa L_30: - lodsd ; eax = [ds:si]; si += 4; + lodsd ; eax = [ds:si]; si += 4; mul eax - add eax,ebx ; add "carry" + add eax,ebx ; add "carry" adc edx,0 mov ebx,[edi] - add eax,ebx ; add low word from result + add eax,ebx ; add low word from result mov ebx,[edi+4] - stosd ; [es:di] = eax; di += 4; - adc edx,ebx ; add high word from result + stosd ; [es:di] = eax; di += 4; + adc edx,ebx ; add high word from result mov ebx,0 mov eax,edx adc ebx,0 - stosd ; [es:di] = eax; di += 4; - dec ecx ; --a_len - jnz L_30 ; jmp if a_len != 0 + stosd ; [es:di] = eax; di += 4; + dec ecx ; --a_len + jnz L_30 ; jmp if a_len != 0 L_31: - cmp ebx,0 ; is carry zero? + cmp ebx,0 ; is carry zero? jz L_34 - mov eax,[edi] ; add in current word from *c + mov eax,[edi] ; add in current word from *c add eax,ebx - stosd ; [es:edi] = ax; edi += 4; + stosd ; [es:edi] = ax; edi += 4; jnc L_34 L_32: - mov eax,[edi] ; add in current word from *c + mov eax,[edi] ; add in current word from *c adc eax,0 - stosd ; [es:edi] = ax; edi += 4; + stosd ; [es:edi] = ax; edi += 4; jc L_32 L_34: pop ebx pop esi pop edi - leave - ret + leave + ret nop s_mpv_sqr_add_prop_sse2: push ebp @@ -445,79 +441,79 @@ s_mpv_sqr_add_prop_sse2: push edi push esi push ebx - psubq mm2, mm2 ; carry = 0 - mov ecx, [ebp+12] ; ecx = a_len + psubq mm2, mm2 ; carry = 0 + mov ecx, [ebp+12] ; ecx = a_len mov edi, [ebp+16] cmp ecx, 0 - je L_36 ; jmp if a_len == 0 - mov esi, [ebp+8] ; esi = a + je L_36 ; jmp if a_len == 0 + mov esi, [ebp+8] ; esi = a cld L_35: - movd mm0, [esi] ; mm0 = *a - movd mm3, [edi] ; fetch the sum - add esi, 4 - pmuludq mm0, mm0 ; mm0 = sqr(a) - paddq mm2, mm0 ; add the carry - paddq mm2, mm3 ; add the low word + movd mm0, [esi] ; mm0 = *a + movd mm3, [edi] ; fetch the sum + add esi, 4 + pmuludq mm0, mm0 ; mm0 = sqr(a) + paddq mm2, mm0 ; add the carry + paddq mm2, mm3 ; add the low word movd mm3, [edi+4] - movd [edi], mm2 ; store the 32bit result - psrlq mm2, 32 - paddq mm2, mm3 ; add the high word - movd [edi+4], mm2 ; store the 32bit result - psrlq mm2, 32 ; save the carry. + movd [edi], mm2 ; store the 32bit result + psrlq mm2, 32 + paddq mm2, mm3 ; add the high word + movd [edi+4], mm2 ; store the 32bit result + psrlq mm2, 32 ; save the carry. add edi, 8 - dec ecx ; --a_len - jnz L_35 ; jmp if a_len != 0 + dec ecx ; --a_len + jnz L_35 ; jmp if a_len != 0 L_36: movd ebx, mm2 - cmp ebx, 0 ; is carry zero? + cmp ebx, 0 ; is carry zero? jz L_38 mov eax, [edi] add eax, ebx stosd jnc L_38 L_37: - mov eax, [edi] ; add in current word from *c - adc eax, 0 - stosd ; [es:edi] = ax; edi += 4; + mov eax, [edi] ; add in current word from *c + adc eax, 0 + stosd ; [es:edi] = ax; edi += 4; jc L_37 L_38: emms pop ebx pop esi pop edi - leave - ret + leave + ret nop - } + } } -/* +/* * Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized * so its high bit is 1. This code is from NSPR. * * Dump of assembler code for function s_mpv_div_2dx1d: - * + * * esp + 0: Caller's ebx - * esp + 4: return address - * esp + 8: Nhi argument - * esp + 12: Nlo argument - * esp + 16: divisor argument - * esp + 20: qp argument - * esp + 24: rp argument + * esp + 4: return address + * esp + 8: Nhi argument + * esp + 12: Nlo argument + * esp + 16: divisor argument + * esp + 20: qp argument + * esp + 24: rp argument * registers: - * eax: - * ebx: carry - * ecx: a_len - * edx: - * esi: a ptr - * edi: c ptr - */ + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ __declspec(naked) mp_err -s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, - mp_digit *qp, mp_digit *rp) + s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, + mp_digit *qp, mp_digit *rp) { - __asm { + __asm { push ebx mov edx,[esp+8] mov eax,[esp+12] @@ -527,9 +523,9 @@ s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, mov [ebx],eax mov ebx,[esp+24] mov [ebx],edx - xor eax,eax ; return zero + xor eax,eax ; return zero pop ebx - ret + ret nop - } + } } diff --git a/nss/lib/freebl/mpi/mplogic.c b/nss/lib/freebl/mpi/mplogic.c index df0aad0..89fd03a 100644 --- a/nss/lib/freebl/mpi/mplogic.c +++ b/nss/lib/freebl/mpi/mplogic.c @@ -13,22 +13,22 @@ /* {{{ Lookup table for population count */ static unsigned char bitc[] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; /* }}} */ @@ -43,23 +43,24 @@ static unsigned char bitc[] = { /* {{{ mpl_not(a, b) */ -mp_err mpl_not(mp_int *a, mp_int *b) +mp_err +mpl_not(mp_int *a, mp_int *b) { - mp_err res; - unsigned int ix; + mp_err res; + unsigned int ix; - ARGCHK(a != NULL && b != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL, MP_BADARG); - if((res = mp_copy(a, b)) != MP_OKAY) - return res; + if ((res = mp_copy(a, b)) != MP_OKAY) + return res; - /* This relies on the fact that the digit type is unsigned */ - for(ix = 0; ix < USED(b); ix++) - DIGIT(b, ix) = ~DIGIT(b, ix); + /* This relies on the fact that the digit type is unsigned */ + for (ix = 0; ix < USED(b); ix++) + DIGIT(b, ix) = ~DIGIT(b, ix); - s_mp_clamp(b); + s_mp_clamp(b); - return MP_OKAY; + return MP_OKAY; } /* end mpl_not() */ @@ -67,31 +68,32 @@ mp_err mpl_not(mp_int *a, mp_int *b) /* {{{ mpl_and(a, b, c) */ -mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c) +mp_err +mpl_and(mp_int *a, mp_int *b, mp_int *c) { - mp_int *which, *other; - mp_err res; - unsigned int ix; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(USED(a) <= USED(b)) { - which = a; - other = b; - } else { - which = b; - other = a; - } + mp_int *which, *other; + mp_err res; + unsigned int ix; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if (USED(a) <= USED(b)) { + which = a; + other = b; + } else { + which = b; + other = a; + } - if((res = mp_copy(which, c)) != MP_OKAY) - return res; + if ((res = mp_copy(which, c)) != MP_OKAY) + return res; - for(ix = 0; ix < USED(which); ix++) - DIGIT(c, ix) &= DIGIT(other, ix); + for (ix = 0; ix < USED(which); ix++) + DIGIT(c, ix) &= DIGIT(other, ix); - s_mp_clamp(c); + s_mp_clamp(c); - return MP_OKAY; + return MP_OKAY; } /* end mpl_and() */ @@ -99,29 +101,30 @@ mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c) /* {{{ mpl_or(a, b, c) */ -mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c) +mp_err +mpl_or(mp_int *a, mp_int *b, mp_int *c) { - mp_int *which, *other; - mp_err res; - unsigned int ix; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(USED(a) >= USED(b)) { - which = a; - other = b; - } else { - which = b; - other = a; - } + mp_int *which, *other; + mp_err res; + unsigned int ix; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if (USED(a) >= USED(b)) { + which = a; + other = b; + } else { + which = b; + other = a; + } - if((res = mp_copy(which, c)) != MP_OKAY) - return res; + if ((res = mp_copy(which, c)) != MP_OKAY) + return res; - for(ix = 0; ix < USED(which); ix++) - DIGIT(c, ix) |= DIGIT(other, ix); + for (ix = 0; ix < USED(which); ix++) + DIGIT(c, ix) |= DIGIT(other, ix); - return MP_OKAY; + return MP_OKAY; } /* end mpl_or() */ @@ -129,31 +132,32 @@ mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c) /* {{{ mpl_xor(a, b, c) */ -mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c) +mp_err +mpl_xor(mp_int *a, mp_int *b, mp_int *c) { - mp_int *which, *other; - mp_err res; - unsigned int ix; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(USED(a) >= USED(b)) { - which = a; - other = b; - } else { - which = b; - other = a; - } + mp_int *which, *other; + mp_err res; + unsigned int ix; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if (USED(a) >= USED(b)) { + which = a; + other = b; + } else { + which = b; + other = a; + } - if((res = mp_copy(which, c)) != MP_OKAY) - return res; + if ((res = mp_copy(which, c)) != MP_OKAY) + return res; - for(ix = 0; ix < USED(which); ix++) - DIGIT(c, ix) ^= DIGIT(other, ix); + for (ix = 0; ix < USED(which); ix++) + DIGIT(c, ix) ^= DIGIT(other, ix); - s_mp_clamp(c); + s_mp_clamp(c); - return MP_OKAY; + return MP_OKAY; } /* end mpl_xor() */ @@ -167,18 +171,19 @@ mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c) /* {{{ mpl_rsh(a, b, d) */ -mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d) +mp_err +mpl_rsh(const mp_int *a, mp_int *b, mp_digit d) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && b != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL, MP_BADARG); - if((res = mp_copy(a, b)) != MP_OKAY) - return res; + if ((res = mp_copy(a, b)) != MP_OKAY) + return res; - s_mp_div_2d(b, d); + s_mp_div_2d(b, d); - return MP_OKAY; + return MP_OKAY; } /* end mpl_rsh() */ @@ -186,16 +191,17 @@ mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d) /* {{{ mpl_lsh(a, b, d) */ -mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d) +mp_err +mpl_lsh(const mp_int *a, mp_int *b, mp_digit d) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && b != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL, MP_BADARG); - if((res = mp_copy(a, b)) != MP_OKAY) - return res; + if ((res = mp_copy(a, b)) != MP_OKAY) + return res; - return s_mp_mul_2d(b, d); + return s_mp_mul_2d(b, d); } /* end mpl_lsh() */ @@ -215,29 +221,30 @@ mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d) /* {{{ mpl_num_set(a, num) */ -mp_err mpl_num_set(mp_int *a, int *num) +mp_err +mpl_num_set(mp_int *a, int *num) { - unsigned int ix; - int db, nset = 0; - mp_digit cur; - unsigned char reg; + unsigned int ix; + int db, nset = 0; + mp_digit cur; + unsigned char reg; + + ARGCHK(a != NULL, MP_BADARG); - ARGCHK(a != NULL, MP_BADARG); + for (ix = 0; ix < USED(a); ix++) { + cur = DIGIT(a, ix); - for(ix = 0; ix < USED(a); ix++) { - cur = DIGIT(a, ix); - - for(db = 0; db < sizeof(mp_digit); db++) { - reg = (unsigned char)(cur >> (CHAR_BIT * db)); + for (db = 0; db < sizeof(mp_digit); db++) { + reg = (unsigned char)(cur >> (CHAR_BIT * db)); - nset += bitc[reg]; + nset += bitc[reg]; + } } - } - if(num) - *num = nset; + if (num) + *num = nset; - return MP_OKAY; + return MP_OKAY; } /* end mpl_num_set() */ @@ -245,30 +252,30 @@ mp_err mpl_num_set(mp_int *a, int *num) /* {{{ mpl_num_clear(a, num) */ -mp_err mpl_num_clear(mp_int *a, int *num) +mp_err +mpl_num_clear(mp_int *a, int *num) { - unsigned int ix; - int db, nset = 0; - mp_digit cur; - unsigned char reg; + unsigned int ix; + int db, nset = 0; + mp_digit cur; + unsigned char reg; - ARGCHK(a != NULL, MP_BADARG); + ARGCHK(a != NULL, MP_BADARG); - for(ix = 0; ix < USED(a); ix++) { - cur = DIGIT(a, ix); - - for(db = 0; db < sizeof(mp_digit); db++) { - reg = (unsigned char)(cur >> (CHAR_BIT * db)); + for (ix = 0; ix < USED(a); ix++) { + cur = DIGIT(a, ix); - nset += bitc[UCHAR_MAX - reg]; - } - } + for (db = 0; db < sizeof(mp_digit); db++) { + reg = (unsigned char)(cur >> (CHAR_BIT * db)); - if(num) - *num = nset; + nset += bitc[UCHAR_MAX - reg]; + } + } - return MP_OKAY; + if (num) + *num = nset; + return MP_OKAY; } /* end mpl_num_clear() */ @@ -285,34 +292,35 @@ mp_err mpl_num_clear(mp_int *a, int *num) /* {{{ mpl_parity(a) */ -mp_err mpl_parity(mp_int *a) +mp_err +mpl_parity(mp_int *a) { - unsigned int ix; - int par = 0; - mp_digit cur; + unsigned int ix; + int par = 0; + mp_digit cur; - ARGCHK(a != NULL, MP_BADARG); + ARGCHK(a != NULL, MP_BADARG); - for(ix = 0; ix < USED(a); ix++) { - int shft = (sizeof(mp_digit) * CHAR_BIT) / 2; + for (ix = 0; ix < USED(a); ix++) { + int shft = (sizeof(mp_digit) * CHAR_BIT) / 2; - cur = DIGIT(a, ix); + cur = DIGIT(a, ix); - /* Compute parity for current digit */ - while(shft != 0) { - cur ^= (cur >> shft); - shft >>= 1; - } - cur &= 1; + /* Compute parity for current digit */ + while (shft != 0) { + cur ^= (cur >> shft); + shft >>= 1; + } + cur &= 1; - /* XOR with running parity so far */ - par ^= cur; - } + /* XOR with running parity so far */ + par ^= cur; + } - if(par) - return MP_ODD; - else - return MP_EVEN; + if (par) + return MP_ODD; + else + return MP_EVEN; } /* end mpl_parity() */ @@ -324,29 +332,30 @@ mp_err mpl_parity(mp_int *a) Returns MP_OKAY or some error code. Grows a if needed to set a bit to 1. */ -mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value) +mp_err +mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value) { - mp_size ix; - mp_err rv; - mp_digit mask; - - ARGCHK(a != NULL, MP_BADARG); - - ix = bitNum / MP_DIGIT_BIT; - if (ix + 1 > MP_USED(a)) { - rv = s_mp_pad(a, ix + 1); - if (rv != MP_OKAY) - return rv; - } - - bitNum = bitNum % MP_DIGIT_BIT; - mask = (mp_digit)1 << bitNum; - if (value) - MP_DIGIT(a,ix) |= mask; - else - MP_DIGIT(a,ix) &= ~mask; - s_mp_clamp(a); - return MP_OKAY; + mp_size ix; + mp_err rv; + mp_digit mask; + + ARGCHK(a != NULL, MP_BADARG); + + ix = bitNum / MP_DIGIT_BIT; + if (ix + 1 > MP_USED(a)) { + rv = s_mp_pad(a, ix + 1); + if (rv != MP_OKAY) + return rv; + } + + bitNum = bitNum % MP_DIGIT_BIT; + mask = (mp_digit)1 << bitNum; + if (value) + MP_DIGIT(a, ix) |= mask; + else + MP_DIGIT(a, ix) &= ~mask; + s_mp_clamp(a); + return MP_OKAY; } /* @@ -354,48 +363,50 @@ mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value) returns 0 or 1 or some (negative) error code. */ -mp_err mpl_get_bit(const mp_int *a, mp_size bitNum) +mp_err +mpl_get_bit(const mp_int *a, mp_size bitNum) { - mp_size bit, ix; - mp_err rv; + mp_size bit, ix; + mp_err rv; - ARGCHK(a != NULL, MP_BADARG); + ARGCHK(a != NULL, MP_BADARG); - ix = bitNum / MP_DIGIT_BIT; - ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE); + ix = bitNum / MP_DIGIT_BIT; + ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE); - bit = bitNum % MP_DIGIT_BIT; - rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1; - return rv; + bit = bitNum % MP_DIGIT_BIT; + rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1; + return rv; } /* mpl_get_bits - Extracts numBits bits from a, where the least significant extracted bit is bit lsbNum. Returns a negative value if error occurs. - - Because sign bit is used to indicate error, maximum number of bits to + - Because sign bit is used to indicate error, maximum number of bits to be returned is the lesser of (a) the number of bits in an mp_digit, or (b) one less than the number of bits in an mp_err. - lsbNum + numbits can be greater than the number of significant bits in integer a, as long as bit lsbNum is in the high order digit of a. */ -mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits) +mp_err +mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits) { - mp_size rshift = (lsbNum % MP_DIGIT_BIT); - mp_size lsWndx = (lsbNum / MP_DIGIT_BIT); - mp_digit * digit = MP_DIGITS(a) + lsWndx; - mp_digit mask = ((1 << numBits) - 1); - - ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG); - ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE); - - if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) || - (lsWndx + 1 >= MP_USED(a))) { - mask &= (digit[0] >> rshift); - } else { - mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift))); - } - return (mp_err)mask; + mp_size rshift = (lsbNum % MP_DIGIT_BIT); + mp_size lsWndx = (lsbNum / MP_DIGIT_BIT); + mp_digit *digit = MP_DIGITS(a) + lsWndx; + mp_digit mask = ((1 << numBits) - 1); + + ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG); + ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE); + + if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) || + (lsWndx + 1 >= MP_USED(a))) { + mask &= (digit[0] >> rshift); + } else { + mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift))); + } + return (mp_err)mask; } /* @@ -403,29 +414,29 @@ mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits) returns number of significnant bits in abs(a). returns 1 if value is zero. */ -mp_size mpl_significant_bits(const mp_int *a) +mp_size +mpl_significant_bits(const mp_int *a) { - mp_size bits = 0; - int ix; - - ARGCHK(a != NULL, MP_BADARG); - - ix = MP_USED(a); - for (ix = MP_USED(a); ix > 0; ) { - mp_digit d; - d = MP_DIGIT(a, --ix); - if (d) { - while (d) { - ++bits; - d >>= 1; - } - break; + mp_size bits = 0; + int ix; + + ARGCHK(a != NULL, MP_BADARG); + + for (ix = MP_USED(a); ix > 0;) { + mp_digit d; + d = MP_DIGIT(a, --ix); + if (d) { + while (d) { + ++bits; + d >>= 1; + } + break; + } } - } - bits += ix * MP_DIGIT_BIT; - if (!bits) - bits = 1; - return bits; + bits += ix * MP_DIGIT_BIT; + if (!bits) + bits = 1; + return bits; } /*------------------------------------------------------------------------*/ diff --git a/nss/lib/freebl/mpi/mplogic.h b/nss/lib/freebl/mpi/mplogic.h index e05374a..a4a6b77 100644 --- a/nss/lib/freebl/mpi/mplogic.h +++ b/nss/lib/freebl/mpi/mplogic.h @@ -21,8 +21,8 @@ /* Parity results */ -#define MP_EVEN MP_YES -#define MP_ODD MP_NO +#define MP_EVEN MP_YES +#define MP_ODD MP_NO /* Bitwise functions */ @@ -33,14 +33,14 @@ mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c); /* bitwise XOR */ /* Shift functions */ -mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d); /* right shift */ -mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d); /* left shift */ +mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d); /* right shift */ +mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d); /* left shift */ /* Bit count and parity */ -mp_err mpl_num_set(mp_int *a, int *num); /* count set bits */ -mp_err mpl_num_clear(mp_int *a, int *num); /* count clear bits */ -mp_err mpl_parity(mp_int *a); /* determine parity */ +mp_err mpl_num_set(mp_int *a, int *num); /* count set bits */ +mp_err mpl_num_clear(mp_int *a, int *num); /* count clear bits */ +mp_err mpl_parity(mp_int *a); /* determine parity */ /* Get & Set the value of a bit */ diff --git a/nss/lib/freebl/mpi/mpmontg.c b/nss/lib/freebl/mpi/mpmontg.c index 9667755..06fd41b 100644 --- a/nss/lib/freebl/mpi/mpmontg.c +++ b/nss/lib/freebl/mpi/mpmontg.c @@ -11,7 +11,7 @@ * published by Springer Verlag. */ -#define MP_USING_CACHE_SAFE_MOD_EXP 1 +#define MP_USING_CACHE_SAFE_MOD_EXP 1 #include <string.h> #include "mpi-priv.h" #include "mplogic.h" @@ -20,53 +20,46 @@ #include "montmulf.h" #endif #include <stddef.h> /* ptrdiff_t */ - -/* if MP_CHAR_STORE_SLOW is defined, we */ -/* need to know endianness of this platform. */ -#ifdef MP_CHAR_STORE_SLOW -#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN) -#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \ - " if you define MP_CHAR_STORE_SLOW." -#endif -#endif +#include <assert.h> #define STATIC -#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */ +#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */ -/*! computes T = REDC(T), 2^b == R +/*! computes T = REDC(T), 2^b == R \param T < RN */ -mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm) +mp_err +s_mp_redc(mp_int *T, mp_mont_modulus *mmm) { - mp_err res; - mp_size i; - - i = (MP_USED(&mmm->N) << 1) + 1; - MP_CHECKOK( s_mp_pad(T, i) ); - for (i = 0; i < MP_USED(&mmm->N); ++i ) { - mp_digit m_i = MP_DIGIT(T, i) * mmm->n0prime; - /* T += N * m_i * (MP_RADIX ** i); */ - s_mp_mul_d_add_offset(&mmm->N, m_i, T, i); - } - s_mp_clamp(T); - - /* T /= R */ - s_mp_rshd( T, MP_USED(&mmm->N) ); - - if ((res = s_mp_cmp(T, &mmm->N)) >= 0) { - /* T = T - N */ - MP_CHECKOK( s_mp_sub(T, &mmm->N) ); -#ifdef DEBUG - if ((res = mp_cmp(T, &mmm->N)) >= 0) { - res = MP_UNDEF; - goto CLEANUP; + mp_err res; + mp_size i; + + i = (MP_USED(&mmm->N) << 1) + 1; + MP_CHECKOK(s_mp_pad(T, i)); + for (i = 0; i < MP_USED(&mmm->N); ++i) { + mp_digit m_i = MP_DIGIT(T, i) * mmm->n0prime; + /* T += N * m_i * (MP_RADIX ** i); */ + s_mp_mul_d_add_offset(&mmm->N, m_i, T, i); } + s_mp_clamp(T); + + /* T /= R */ + s_mp_rshd(T, MP_USED(&mmm->N)); + + if ((res = s_mp_cmp(T, &mmm->N)) >= 0) { + /* T = T - N */ + MP_CHECKOK(s_mp_sub(T, &mmm->N)); +#ifdef DEBUG + if ((res = mp_cmp(T, &mmm->N)) >= 0) { + res = MP_UNDEF; + goto CLEANUP; + } #endif - } - res = MP_OKAY; + } + res = MP_OKAY; CLEANUP: - return res; + return res; } #if !defined(MP_MONT_USE_MP_MUL) @@ -76,75 +69,78 @@ CLEANUP: \param b < N i.e. "reduced" \param mmm modulus N and n0' of N */ -mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c, - mp_mont_modulus *mmm) +mp_err +s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c, + mp_mont_modulus *mmm) { - mp_digit *pb; - mp_digit m_i; - mp_err res; - mp_size ib; /* "index b": index of current digit of B */ - mp_size useda, usedb; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if (MP_USED(a) < MP_USED(b)) { - const mp_int *xch = b; /* switch a and b, to do fewer outer loops */ - b = a; - a = xch; - } - - MP_USED(c) = 1; MP_DIGIT(c, 0) = 0; - ib = (MP_USED(&mmm->N) << 1) + 1; - if((res = s_mp_pad(c, ib)) != MP_OKAY) - goto CLEANUP; - - useda = MP_USED(a); - pb = MP_DIGITS(b); - s_mpv_mul_d(MP_DIGITS(a), useda, *pb++, MP_DIGITS(c)); - s_mp_setz(MP_DIGITS(c) + useda + 1, ib - (useda + 1)); - m_i = MP_DIGIT(c, 0) * mmm->n0prime; - s_mp_mul_d_add_offset(&mmm->N, m_i, c, 0); - - /* Outer loop: Digits of b */ - usedb = MP_USED(b); - for (ib = 1; ib < usedb; ib++) { - mp_digit b_i = *pb++; - - /* Inner product: Digits of a */ - if (b_i) - s_mpv_mul_d_add_prop(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib); - m_i = MP_DIGIT(c, ib) * mmm->n0prime; - s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib); - } - if (usedb < MP_USED(&mmm->N)) { - for (usedb = MP_USED(&mmm->N); ib < usedb; ++ib ) { - m_i = MP_DIGIT(c, ib) * mmm->n0prime; - s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib); + mp_digit *pb; + mp_digit m_i; + mp_err res; + mp_size ib; /* "index b": index of current digit of B */ + mp_size useda, usedb; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if (MP_USED(a) < MP_USED(b)) { + const mp_int *xch = b; /* switch a and b, to do fewer outer loops */ + b = a; + a = xch; } - } - s_mp_clamp(c); - s_mp_rshd( c, MP_USED(&mmm->N) ); /* c /= R */ - if (s_mp_cmp(c, &mmm->N) >= 0) { - MP_CHECKOK( s_mp_sub(c, &mmm->N) ); - } - res = MP_OKAY; + + MP_USED(c) = 1; + MP_DIGIT(c, 0) = 0; + ib = (MP_USED(&mmm->N) << 1) + 1; + if ((res = s_mp_pad(c, ib)) != MP_OKAY) + goto CLEANUP; + + useda = MP_USED(a); + pb = MP_DIGITS(b); + s_mpv_mul_d(MP_DIGITS(a), useda, *pb++, MP_DIGITS(c)); + s_mp_setz(MP_DIGITS(c) + useda + 1, ib - (useda + 1)); + m_i = MP_DIGIT(c, 0) * mmm->n0prime; + s_mp_mul_d_add_offset(&mmm->N, m_i, c, 0); + + /* Outer loop: Digits of b */ + usedb = MP_USED(b); + for (ib = 1; ib < usedb; ib++) { + mp_digit b_i = *pb++; + + /* Inner product: Digits of a */ + if (b_i) + s_mpv_mul_d_add_prop(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib); + m_i = MP_DIGIT(c, ib) * mmm->n0prime; + s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib); + } + if (usedb < MP_USED(&mmm->N)) { + for (usedb = MP_USED(&mmm->N); ib < usedb; ++ib) { + m_i = MP_DIGIT(c, ib) * mmm->n0prime; + s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib); + } + } + s_mp_clamp(c); + s_mp_rshd(c, MP_USED(&mmm->N)); /* c /= R */ + if (s_mp_cmp(c, &mmm->N) >= 0) { + MP_CHECKOK(s_mp_sub(c, &mmm->N)); + } + res = MP_OKAY; CLEANUP: - return res; + return res; } #endif STATIC -mp_err s_mp_to_mont(const mp_int *x, mp_mont_modulus *mmm, mp_int *xMont) +mp_err +s_mp_to_mont(const mp_int *x, mp_mont_modulus *mmm, mp_int *xMont) { - mp_err res; + mp_err res; - /* xMont = x * R mod N where N is modulus */ - MP_CHECKOK( mp_copy( x, xMont ) ); - MP_CHECKOK( s_mp_lshd( xMont, MP_USED(&mmm->N) ) ); /* xMont = x << b */ - MP_CHECKOK( mp_div(xMont, &mmm->N, 0, xMont) ); /* mod N */ + /* xMont = x * R mod N where N is modulus */ + MP_CHECKOK(mp_copy(x, xMont)); + MP_CHECKOK(s_mp_lshd(xMont, MP_USED(&mmm->N))); /* xMont = x << b */ + MP_CHECKOK(mp_div(xMont, &mmm->N, 0, xMont)); /* mod N */ CLEANUP: - return res; + return res; } #ifdef MP_USING_MONT_MULF @@ -159,329 +155,508 @@ CLEANUP: unsigned int mp_using_mont_mulf = 1; /* computes montgomery square of the integer in mResult */ -#define SQR \ - conv_i32_to_d32_and_d16(dm1, d16Tmp, mResult, nLen); \ - mont_mulf_noconv(mResult, dm1, d16Tmp, \ - dTmp, dn, MP_DIGITS(modulus), nLen, dn0) +#define SQR \ + conv_i32_to_d32_and_d16(dm1, d16Tmp, mResult, nLen); \ + mont_mulf_noconv(mResult, dm1, d16Tmp, \ + dTmp, dn, MP_DIGITS(modulus), nLen, dn0) /* computes montgomery product of x and the integer in mResult */ -#define MUL(x) \ - conv_i32_to_d32(dm1, mResult, nLen); \ - mont_mulf_noconv(mResult, dm1, oddPowers[x], \ - dTmp, dn, MP_DIGITS(modulus), nLen, dn0) +#define MUL(x) \ + conv_i32_to_d32(dm1, mResult, nLen); \ + mont_mulf_noconv(mResult, dm1, oddPowers[x], \ + dTmp, dn, MP_DIGITS(modulus), nLen, dn0) /* Do modular exponentiation using floating point multiply code. */ -mp_err mp_exptmod_f(const mp_int * montBase, - const mp_int * exponent, - const mp_int * modulus, - mp_int * result, - mp_mont_modulus *mmm, - int nLen, - mp_size bits_in_exponent, - mp_size window_bits, - mp_size odd_ints) +mp_err +mp_exptmod_f(const mp_int *montBase, + const mp_int *exponent, + const mp_int *modulus, + mp_int *result, + mp_mont_modulus *mmm, + int nLen, + mp_size bits_in_exponent, + mp_size window_bits, + mp_size odd_ints) { - mp_digit *mResult; - double *dBuf = 0, *dm1, *dn, *dSqr, *d16Tmp, *dTmp; - double dn0; - mp_size i; - mp_err res; - int expOff; - int dSize = 0, oddPowSize, dTmpSize; - mp_int accum1; - double *oddPowers[MAX_ODD_INTS]; - - /* function for computing n0prime only works if n0 is odd */ - - MP_DIGITS(&accum1) = 0; - - for (i = 0; i < MAX_ODD_INTS; ++i) - oddPowers[i] = 0; - - MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) ); - - mp_set(&accum1, 1); - MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) ); - MP_CHECKOK( s_mp_pad(&accum1, nLen) ); - - oddPowSize = 2 * nLen + 1; - dTmpSize = 2 * oddPowSize; - dSize = sizeof(double) * (nLen * 4 + 1 + - ((odd_ints + 1) * oddPowSize) + dTmpSize); - dBuf = (double *)malloc(dSize); - dm1 = dBuf; /* array of d32 */ - dn = dBuf + nLen; /* array of d32 */ - dSqr = dn + nLen; /* array of d32 */ - d16Tmp = dSqr + nLen; /* array of d16 */ - dTmp = d16Tmp + oddPowSize; - - for (i = 0; i < odd_ints; ++i) { - oddPowers[i] = dTmp; - dTmp += oddPowSize; - } - mResult = (mp_digit *)(dTmp + dTmpSize); /* size is nLen + 1 */ - - /* Make dn and dn0 */ - conv_i32_to_d32(dn, MP_DIGITS(modulus), nLen); - dn0 = (double)(mmm->n0prime & 0xffff); - - /* Make dSqr */ - conv_i32_to_d32_and_d16(dm1, oddPowers[0], MP_DIGITS(montBase), nLen); - mont_mulf_noconv(mResult, dm1, oddPowers[0], - dTmp, dn, MP_DIGITS(modulus), nLen, dn0); - conv_i32_to_d32(dSqr, mResult, nLen); - - for (i = 1; i < odd_ints; ++i) { - mont_mulf_noconv(mResult, dSqr, oddPowers[i - 1], - dTmp, dn, MP_DIGITS(modulus), nLen, dn0); - conv_i32_to_d16(oddPowers[i], mResult, nLen); - } - - s_mp_copy(MP_DIGITS(&accum1), mResult, nLen); /* from, to, len */ - - for (expOff = bits_in_exponent - window_bits; expOff >= 0; expOff -= window_bits) { - mp_size smallExp; - MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) ); - smallExp = (mp_size)res; - - if (window_bits == 1) { - if (!smallExp) { - SQR; - } else if (smallExp & 1) { - SQR; MUL(0); - } else { - abort(); - } - } else if (window_bits == 4) { - if (!smallExp) { - SQR; SQR; SQR; SQR; - } else if (smallExp & 1) { - SQR; SQR; SQR; SQR; MUL(smallExp/2); - } else if (smallExp & 2) { - SQR; SQR; SQR; MUL(smallExp/4); SQR; - } else if (smallExp & 4) { - SQR; SQR; MUL(smallExp/8); SQR; SQR; - } else if (smallExp & 8) { - SQR; MUL(smallExp/16); SQR; SQR; SQR; - } else { - abort(); - } - } else if (window_bits == 5) { - if (!smallExp) { - SQR; SQR; SQR; SQR; SQR; - } else if (smallExp & 1) { - SQR; SQR; SQR; SQR; SQR; MUL(smallExp/2); - } else if (smallExp & 2) { - SQR; SQR; SQR; SQR; MUL(smallExp/4); SQR; - } else if (smallExp & 4) { - SQR; SQR; SQR; MUL(smallExp/8); SQR; SQR; - } else if (smallExp & 8) { - SQR; SQR; MUL(smallExp/16); SQR; SQR; SQR; - } else if (smallExp & 0x10) { - SQR; MUL(smallExp/32); SQR; SQR; SQR; SQR; - } else { - abort(); - } - } else if (window_bits == 6) { - if (!smallExp) { - SQR; SQR; SQR; SQR; SQR; SQR; - } else if (smallExp & 1) { - SQR; SQR; SQR; SQR; SQR; SQR; MUL(smallExp/2); - } else if (smallExp & 2) { - SQR; SQR; SQR; SQR; SQR; MUL(smallExp/4); SQR; - } else if (smallExp & 4) { - SQR; SQR; SQR; SQR; MUL(smallExp/8); SQR; SQR; - } else if (smallExp & 8) { - SQR; SQR; SQR; MUL(smallExp/16); SQR; SQR; SQR; - } else if (smallExp & 0x10) { - SQR; SQR; MUL(smallExp/32); SQR; SQR; SQR; SQR; - } else if (smallExp & 0x20) { - SQR; MUL(smallExp/64); SQR; SQR; SQR; SQR; SQR; - } else { - abort(); - } - } else { - abort(); + mp_digit *mResult; + double *dBuf = 0, *dm1, *dn, *dSqr, *d16Tmp, *dTmp; + double dn0; + mp_size i; + mp_err res; + int expOff; + int dSize = 0, oddPowSize, dTmpSize; + mp_int accum1; + double *oddPowers[MAX_ODD_INTS]; + + /* function for computing n0prime only works if n0 is odd */ + + MP_DIGITS(&accum1) = 0; + + for (i = 0; i < MAX_ODD_INTS; ++i) + oddPowers[i] = 0; + + MP_CHECKOK(mp_init_size(&accum1, 3 * nLen + 2)); + + mp_set(&accum1, 1); + MP_CHECKOK(s_mp_to_mont(&accum1, mmm, &accum1)); + MP_CHECKOK(s_mp_pad(&accum1, nLen)); + + oddPowSize = 2 * nLen + 1; + dTmpSize = 2 * oddPowSize; + dSize = sizeof(double) * (nLen * 4 + 1 + + ((odd_ints + 1) * oddPowSize) + dTmpSize); + dBuf = (double *)malloc(dSize); + dm1 = dBuf; /* array of d32 */ + dn = dBuf + nLen; /* array of d32 */ + dSqr = dn + nLen; /* array of d32 */ + d16Tmp = dSqr + nLen; /* array of d16 */ + dTmp = d16Tmp + oddPowSize; + + for (i = 0; i < odd_ints; ++i) { + oddPowers[i] = dTmp; + dTmp += oddPowSize; + } + mResult = (mp_digit *)(dTmp + dTmpSize); /* size is nLen + 1 */ + + /* Make dn and dn0 */ + conv_i32_to_d32(dn, MP_DIGITS(modulus), nLen); + dn0 = (double)(mmm->n0prime & 0xffff); + + /* Make dSqr */ + conv_i32_to_d32_and_d16(dm1, oddPowers[0], MP_DIGITS(montBase), nLen); + mont_mulf_noconv(mResult, dm1, oddPowers[0], + dTmp, dn, MP_DIGITS(modulus), nLen, dn0); + conv_i32_to_d32(dSqr, mResult, nLen); + + for (i = 1; i < odd_ints; ++i) { + mont_mulf_noconv(mResult, dSqr, oddPowers[i - 1], + dTmp, dn, MP_DIGITS(modulus), nLen, dn0); + conv_i32_to_d16(oddPowers[i], mResult, nLen); } - } - s_mp_copy(mResult, MP_DIGITS(&accum1), nLen); /* from, to, len */ + s_mp_copy(MP_DIGITS(&accum1), mResult, nLen); /* from, to, len */ + + for (expOff = bits_in_exponent - window_bits; expOff >= 0; expOff -= window_bits) { + mp_size smallExp; + MP_CHECKOK(mpl_get_bits(exponent, expOff, window_bits)); + smallExp = (mp_size)res; + + if (window_bits == 1) { + if (!smallExp) { + SQR; + } else if (smallExp & 1) { + SQR; + MUL(0); + } else { + abort(); + } + } else if (window_bits == 4) { + if (!smallExp) { + SQR; + SQR; + SQR; + SQR; + } else if (smallExp & 1) { + SQR; + SQR; + SQR; + SQR; + MUL(smallExp / 2); + } else if (smallExp & 2) { + SQR; + SQR; + SQR; + MUL(smallExp / 4); + SQR; + } else if (smallExp & 4) { + SQR; + SQR; + MUL(smallExp / 8); + SQR; + SQR; + } else if (smallExp & 8) { + SQR; + MUL(smallExp / 16); + SQR; + SQR; + SQR; + } else { + abort(); + } + } else if (window_bits == 5) { + if (!smallExp) { + SQR; + SQR; + SQR; + SQR; + SQR; + } else if (smallExp & 1) { + SQR; + SQR; + SQR; + SQR; + SQR; + MUL(smallExp / 2); + } else if (smallExp & 2) { + SQR; + SQR; + SQR; + SQR; + MUL(smallExp / 4); + SQR; + } else if (smallExp & 4) { + SQR; + SQR; + SQR; + MUL(smallExp / 8); + SQR; + SQR; + } else if (smallExp & 8) { + SQR; + SQR; + MUL(smallExp / 16); + SQR; + SQR; + SQR; + } else if (smallExp & 0x10) { + SQR; + MUL(smallExp / 32); + SQR; + SQR; + SQR; + SQR; + } else { + abort(); + } + } else if (window_bits == 6) { + if (!smallExp) { + SQR; + SQR; + SQR; + SQR; + SQR; + SQR; + } else if (smallExp & 1) { + SQR; + SQR; + SQR; + SQR; + SQR; + SQR; + MUL(smallExp / 2); + } else if (smallExp & 2) { + SQR; + SQR; + SQR; + SQR; + SQR; + MUL(smallExp / 4); + SQR; + } else if (smallExp & 4) { + SQR; + SQR; + SQR; + SQR; + MUL(smallExp / 8); + SQR; + SQR; + } else if (smallExp & 8) { + SQR; + SQR; + SQR; + MUL(smallExp / 16); + SQR; + SQR; + SQR; + } else if (smallExp & 0x10) { + SQR; + SQR; + MUL(smallExp / 32); + SQR; + SQR; + SQR; + SQR; + } else if (smallExp & 0x20) { + SQR; + MUL(smallExp / 64); + SQR; + SQR; + SQR; + SQR; + SQR; + } else { + abort(); + } + } else { + abort(); + } + } - res = s_mp_redc(&accum1, mmm); - mp_exch(&accum1, result); + s_mp_copy(mResult, MP_DIGITS(&accum1), nLen); /* from, to, len */ + + res = s_mp_redc(&accum1, mmm); + mp_exch(&accum1, result); CLEANUP: - mp_clear(&accum1); - if (dBuf) { - if (dSize) - memset(dBuf, 0, dSize); - free(dBuf); - } - - return res; + mp_clear(&accum1); + if (dBuf) { + if (dSize) + memset(dBuf, 0, dSize); + free(dBuf); + } + + return res; } #undef SQR #undef MUL #endif -#define SQR(a,b) \ - MP_CHECKOK( mp_sqr(a, b) );\ - MP_CHECKOK( s_mp_redc(b, mmm) ) +#define SQR(a, b) \ + MP_CHECKOK(mp_sqr(a, b)); \ + MP_CHECKOK(s_mp_redc(b, mmm)) #if defined(MP_MONT_USE_MP_MUL) -#define MUL(x,a,b) \ - MP_CHECKOK( mp_mul(a, oddPowers + (x), b) ); \ - MP_CHECKOK( s_mp_redc(b, mmm) ) +#define MUL(x, a, b) \ + MP_CHECKOK(mp_mul(a, oddPowers + (x), b)); \ + MP_CHECKOK(s_mp_redc(b, mmm)) #else -#define MUL(x,a,b) \ - MP_CHECKOK( s_mp_mul_mont(a, oddPowers + (x), b, mmm) ) +#define MUL(x, a, b) \ + MP_CHECKOK(s_mp_mul_mont(a, oddPowers + (x), b, mmm)) #endif -#define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp +#define SWAPPA \ + ptmp = pa1; \ + pa1 = pa2; \ + pa2 = ptmp /* Do modular exponentiation using integer multiply code. */ -mp_err mp_exptmod_i(const mp_int * montBase, - const mp_int * exponent, - const mp_int * modulus, - mp_int * result, - mp_mont_modulus *mmm, - int nLen, - mp_size bits_in_exponent, - mp_size window_bits, - mp_size odd_ints) +mp_err +mp_exptmod_i(const mp_int *montBase, + const mp_int *exponent, + const mp_int *modulus, + mp_int *result, + mp_mont_modulus *mmm, + int nLen, + mp_size bits_in_exponent, + mp_size window_bits, + mp_size odd_ints) { - mp_int *pa1, *pa2, *ptmp; - mp_size i; - mp_err res; - int expOff; - mp_int accum1, accum2, power2, oddPowers[MAX_ODD_INTS]; - - /* power2 = base ** 2; oddPowers[i] = base ** (2*i + 1); */ - /* oddPowers[i] = base ** (2*i + 1); */ - - MP_DIGITS(&accum1) = 0; - MP_DIGITS(&accum2) = 0; - MP_DIGITS(&power2) = 0; - for (i = 0; i < MAX_ODD_INTS; ++i) { - MP_DIGITS(oddPowers + i) = 0; - } - - MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) ); - MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) ); - - MP_CHECKOK( mp_init_copy(&oddPowers[0], montBase) ); - - mp_init_size(&power2, nLen + 2 * MP_USED(montBase) + 2); - MP_CHECKOK( mp_sqr(montBase, &power2) ); /* power2 = montBase ** 2 */ - MP_CHECKOK( s_mp_redc(&power2, mmm) ); - - for (i = 1; i < odd_ints; ++i) { - mp_init_size(oddPowers + i, nLen + 2 * MP_USED(&power2) + 2); - MP_CHECKOK( mp_mul(oddPowers + (i - 1), &power2, oddPowers + i) ); - MP_CHECKOK( s_mp_redc(oddPowers + i, mmm) ); - } - - /* set accumulator to montgomery residue of 1 */ - mp_set(&accum1, 1); - MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) ); - pa1 = &accum1; - pa2 = &accum2; - - for (expOff = bits_in_exponent - window_bits; expOff >= 0; expOff -= window_bits) { - mp_size smallExp; - MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) ); - smallExp = (mp_size)res; - - if (window_bits == 1) { - if (!smallExp) { - SQR(pa1,pa2); SWAPPA; - } else if (smallExp & 1) { - SQR(pa1,pa2); MUL(0,pa2,pa1); - } else { - abort(); - } - } else if (window_bits == 4) { - if (!smallExp) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - } else if (smallExp & 1) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - MUL(smallExp/2, pa1,pa2); SWAPPA; - } else if (smallExp & 2) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); - MUL(smallExp/4,pa2,pa1); SQR(pa1,pa2); SWAPPA; - } else if (smallExp & 4) { - SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/8,pa1,pa2); - SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA; - } else if (smallExp & 8) { - SQR(pa1,pa2); MUL(smallExp/16,pa2,pa1); SQR(pa1,pa2); - SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA; - } else { - abort(); - } - } else if (window_bits == 5) { - if (!smallExp) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - SQR(pa1,pa2); SWAPPA; - } else if (smallExp & 1) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - SQR(pa1,pa2); MUL(smallExp/2,pa2,pa1); - } else if (smallExp & 2) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - MUL(smallExp/4,pa1,pa2); SQR(pa2,pa1); - } else if (smallExp & 4) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); - MUL(smallExp/8,pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - } else if (smallExp & 8) { - SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/16,pa1,pa2); - SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - } else if (smallExp & 0x10) { - SQR(pa1,pa2); MUL(smallExp/32,pa2,pa1); SQR(pa1,pa2); - SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - } else { - abort(); - } - } else if (window_bits == 6) { - if (!smallExp) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - SQR(pa1,pa2); SQR(pa2,pa1); - } else if (smallExp & 1) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/2,pa1,pa2); SWAPPA; - } else if (smallExp & 2) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - SQR(pa1,pa2); MUL(smallExp/4,pa2,pa1); SQR(pa1,pa2); SWAPPA; - } else if (smallExp & 4) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - MUL(smallExp/8,pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA; - } else if (smallExp & 8) { - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); - MUL(smallExp/16,pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - SQR(pa1,pa2); SWAPPA; - } else if (smallExp & 0x10) { - SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/32,pa1,pa2); - SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA; - } else if (smallExp & 0x20) { - SQR(pa1,pa2); MUL(smallExp/64,pa2,pa1); SQR(pa1,pa2); - SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA; - } else { - abort(); - } - } else { - abort(); + mp_int *pa1, *pa2, *ptmp; + mp_size i; + mp_err res; + int expOff; + mp_int accum1, accum2, power2, oddPowers[MAX_ODD_INTS]; + + /* power2 = base ** 2; oddPowers[i] = base ** (2*i + 1); */ + /* oddPowers[i] = base ** (2*i + 1); */ + + MP_DIGITS(&accum1) = 0; + MP_DIGITS(&accum2) = 0; + MP_DIGITS(&power2) = 0; + for (i = 0; i < MAX_ODD_INTS; ++i) { + MP_DIGITS(oddPowers + i) = 0; } - } - res = s_mp_redc(pa1, mmm); - mp_exch(pa1, result); + MP_CHECKOK(mp_init_size(&accum1, 3 * nLen + 2)); + MP_CHECKOK(mp_init_size(&accum2, 3 * nLen + 2)); + + MP_CHECKOK(mp_init_copy(&oddPowers[0], montBase)); + + MP_CHECKOK(mp_init_size(&power2, nLen + 2 * MP_USED(montBase) + 2)); + MP_CHECKOK(mp_sqr(montBase, &power2)); /* power2 = montBase ** 2 */ + MP_CHECKOK(s_mp_redc(&power2, mmm)); + + for (i = 1; i < odd_ints; ++i) { + MP_CHECKOK(mp_init_size(oddPowers + i, nLen + 2 * MP_USED(&power2) + 2)); + MP_CHECKOK(mp_mul(oddPowers + (i - 1), &power2, oddPowers + i)); + MP_CHECKOK(s_mp_redc(oddPowers + i, mmm)); + } + + /* set accumulator to montgomery residue of 1 */ + mp_set(&accum1, 1); + MP_CHECKOK(s_mp_to_mont(&accum1, mmm, &accum1)); + pa1 = &accum1; + pa2 = &accum2; + + for (expOff = bits_in_exponent - window_bits; expOff >= 0; expOff -= window_bits) { + mp_size smallExp; + MP_CHECKOK(mpl_get_bits(exponent, expOff, window_bits)); + smallExp = (mp_size)res; + + if (window_bits == 1) { + if (!smallExp) { + SQR(pa1, pa2); + SWAPPA; + } else if (smallExp & 1) { + SQR(pa1, pa2); + MUL(0, pa2, pa1); + } else { + abort(); + } + } else if (window_bits == 4) { + if (!smallExp) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + } else if (smallExp & 1) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + MUL(smallExp / 2, pa1, pa2); + SWAPPA; + } else if (smallExp & 2) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + MUL(smallExp / 4, pa2, pa1); + SQR(pa1, pa2); + SWAPPA; + } else if (smallExp & 4) { + SQR(pa1, pa2); + SQR(pa2, pa1); + MUL(smallExp / 8, pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SWAPPA; + } else if (smallExp & 8) { + SQR(pa1, pa2); + MUL(smallExp / 16, pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SWAPPA; + } else { + abort(); + } + } else if (window_bits == 5) { + if (!smallExp) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SWAPPA; + } else if (smallExp & 1) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + MUL(smallExp / 2, pa2, pa1); + } else if (smallExp & 2) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + MUL(smallExp / 4, pa1, pa2); + SQR(pa2, pa1); + } else if (smallExp & 4) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + MUL(smallExp / 8, pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + } else if (smallExp & 8) { + SQR(pa1, pa2); + SQR(pa2, pa1); + MUL(smallExp / 16, pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + } else if (smallExp & 0x10) { + SQR(pa1, pa2); + MUL(smallExp / 32, pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + } else { + abort(); + } + } else if (window_bits == 6) { + if (!smallExp) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + } else if (smallExp & 1) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + MUL(smallExp / 2, pa1, pa2); + SWAPPA; + } else if (smallExp & 2) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + MUL(smallExp / 4, pa2, pa1); + SQR(pa1, pa2); + SWAPPA; + } else if (smallExp & 4) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + MUL(smallExp / 8, pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SWAPPA; + } else if (smallExp & 8) { + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + MUL(smallExp / 16, pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SWAPPA; + } else if (smallExp & 0x10) { + SQR(pa1, pa2); + SQR(pa2, pa1); + MUL(smallExp / 32, pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SWAPPA; + } else if (smallExp & 0x20) { + SQR(pa1, pa2); + MUL(smallExp / 64, pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SWAPPA; + } else { + abort(); + } + } else { + abort(); + } + } + + res = s_mp_redc(pa1, mmm); + mp_exch(pa1, result); CLEANUP: - mp_clear(&accum1); - mp_clear(&accum2); - mp_clear(&power2); - for (i = 0; i < odd_ints; ++i) { - mp_clear(oddPowers + i); - } - return res; + mp_clear(&accum1); + mp_clear(&accum2); + mp_clear(&power2); + for (i = 0; i < odd_ints; ++i) { + mp_clear(oddPowers + i); + } + return res; } #undef SQR #undef MUL @@ -490,33 +665,33 @@ CLEANUP: unsigned int mp_using_cache_safe_exp = 1; #endif -mp_err mp_set_safe_modexp(int value) +mp_err +mp_set_safe_modexp(int value) { #ifdef MP_USING_CACHE_SAFE_MOD_EXP - mp_using_cache_safe_exp = value; - return MP_OKAY; + mp_using_cache_safe_exp = value; + return MP_OKAY; #else - if (value == 0) { - return MP_OKAY; - } - return MP_BADARG; + if (value == 0) { + return MP_OKAY; + } + return MP_BADARG; #endif } #ifdef MP_USING_CACHE_SAFE_MOD_EXP #define WEAVE_WORD_SIZE 4 -#ifndef MP_CHAR_STORE_SLOW /* - * mpi_to_weave takes an array of bignums, a matrix in which each bignum - * occupies all the columns of a row, and transposes it into a matrix in + * mpi_to_weave takes an array of bignums, a matrix in which each bignum + * occupies all the columns of a row, and transposes it into a matrix in * which each bignum occupies a column of every row. The first row of the * input matrix becomes the first column of the output matrix. The n'th * row of input becomes the n'th column of output. The input data is said * to be "interleaved" or "woven" into the output matrix. * * The array of bignums is left in this woven form. Each time a single - * bignum value is needed, it is recreated by fetching the n'th column, + * bignum value is needed, it is recreated by fetching the n'th column, * forming a single row which is the new bignum. * * The purpose of this interleaving is make it impossible to determine which @@ -526,653 +701,441 @@ mp_err mp_set_safe_modexp(int value) * The weaving function does not transpose the entire input matrix in one call. * It transposes 4 rows of mp_ints into their respective columns of output. * - * There are two different implementations of the weaving and unweaving code - * in this file. One uses byte loads and stores. The second uses loads and - * stores of mp_weave_word size values. The weaved forms of these two - * implementations differ. Consequently, each one has its own explanation. - * - * Here is the explanation for the byte-at-a-time implementation. - * - * This implementation treats each mp_int bignum as an array of bytes, - * rather than as an array of mp_digits. It stores those bytes as a - * column of bytes in the output matrix. It doesn't care if the machine - * uses big-endian or little-endian byte ordering within mp_digits. - * The first byte of the mp_digit array becomes the first byte in the output - * column, regardless of whether that byte is the MSB or LSB of the mp_digit. + * This implementation treats each mp_int bignum as an array of mp_digits, + * It stores those bytes as a column of mp_digits in the output matrix. It + * doesn't care if the machine uses big-endian or little-endian byte ordering + * within mp_digits. * * "bignums" is an array of mp_ints. * It points to four rows, four mp_ints, a subset of a larger array of mp_ints. * - * "weaved" is the weaved output matrix. + * "weaved" is the weaved output matrix. * The first byte of bignums[0] is stored in weaved[0]. - * - * "nBignums" is the total number of bignums in the array of which "bignums" - * is a part. * - * "nDigits" is the size in mp_digits of each mp_int in the "bignums" array. - * mp_ints that use less than nDigits digits are logically padded with zeros + * "nBignums" is the total number of bignums in the array of which "bignums" + * is a part. + * + * "nDigits" is the size in mp_digits of each mp_int in the "bignums" array. + * mp_ints that use less than nDigits digits are logically padded with zeros * while being stored in the weaved array. */ -mp_err mpi_to_weave(const mp_int *bignums, - unsigned char *weaved, - mp_size nDigits, /* in each mp_int of input */ - mp_size nBignums) /* in the entire source array */ +mp_err mpi_to_weave(const mp_int *bignums, + mp_digit *weaved, + mp_size nDigits, /* in each mp_int of input */ + mp_size nBignums) /* in the entire source array */ { - mp_size i; - unsigned char * endDest = weaved + (nDigits * nBignums * sizeof(mp_digit)); + mp_size i; + mp_digit *endDest = weaved + (nDigits * nBignums); - for (i=0; i < WEAVE_WORD_SIZE; i++) { - mp_size used = MP_USED(&bignums[i]); - unsigned char *pSrc = (unsigned char *)MP_DIGITS(&bignums[i]); - unsigned char *endSrc = pSrc + (used * sizeof(mp_digit)); - unsigned char *pDest = weaved + i; + for (i = 0; i < WEAVE_WORD_SIZE; i++) { + mp_size used = MP_USED(&bignums[i]); + mp_digit *pSrc = MP_DIGITS(&bignums[i]); + mp_digit *endSrc = pSrc + used; + mp_digit *pDest = weaved + i; - ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG); - ARGCHK(used <= nDigits, MP_BADARG); + ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG); + ARGCHK(used <= nDigits, MP_BADARG); - for (; pSrc < endSrc; pSrc++) { - *pDest = *pSrc; - pDest += nBignums; - } - while (pDest < endDest) { - *pDest = 0; - pDest += nBignums; + for (; pSrc < endSrc; pSrc++) { + *pDest = *pSrc; + pDest += nBignums; + } + while (pDest < endDest) { + *pDest = 0; + pDest += nBignums; + } } - } - return MP_OKAY; + return MP_OKAY; } -/* Reverse the operation above for one mp_int. - * Reconstruct one mp_int from its column in the weaved array. - * "pSrc" points to the offset into the weave array of the bignum we - * are going to reconstruct. - */ -mp_err weave_to_mpi(mp_int *a, /* output, result */ - const unsigned char *pSrc, /* input, byte matrix */ - mp_size nDigits, /* per mp_int output */ - mp_size nBignums) /* bignums in weaved matrix */ -{ - unsigned char *pDest = (unsigned char *)MP_DIGITS(a); - unsigned char *endDest = pDest + (nDigits * sizeof(mp_digit)); - - MP_SIGN(a) = MP_ZPOS; - MP_USED(a) = nDigits; - - for (; pDest < endDest; pSrc += nBignums, pDest++) { - *pDest = *pSrc; - } - s_mp_clamp(a); - return MP_OKAY; -} - -#else - -/* Need a primitive that we know is 32 bits long... */ -/* this is true on all modern processors we know of today*/ -typedef unsigned int mp_weave_word; - /* - * on some platforms character stores into memory is very expensive since they - * generate a read/modify/write operation on the bus. On those platforms - * we need to do integer writes to the bus. Because of some unrolled code, - * in this current code the size of mp_weave_word must be four. The code that - * makes this assumption explicity is called out. (on some platforms a write - * of 4 bytes still requires a single read-modify-write operation. - * - * This function is takes the identical parameters as the function above, - * however it lays out the final array differently. Where the previous function - * treats the mpi_int as an byte array, this function treats it as an array of - * mp_digits where each digit is stored in big endian order. - * - * since we need to interleave on a byte by byte basis, we need to collect - * several mpi structures together into a single PRUint32 before we write. We - * also need to make sure the PRUint32 is arranged so that the first value of - * the first array winds up in b[0]. This means construction of that PRUint32 - * is endian specific (even though the layout of the mp_digits in the array - * is always big endian). - * - * The final data is stored as follows : - * - * Our same logical array p array, m is sizeof(mp_digit), - * N is still count and n is now b_size. If we define p[i].digit[j]0 as the - * most significant byte of the word p[i].digit[j], p[i].digit[j]1 as - * the next most significant byte of p[i].digit[j], ... and p[i].digit[j]m-1 - * is the least significant byte. - * Our array would look like: - * p[0].digit[0]0 p[1].digit[0]0 ... p[N-2].digit[0]0 p[N-1].digit[0]0 - * p[0].digit[0]1 p[1].digit[0]1 ... p[N-2].digit[0]1 p[N-1].digit[0]1 - * . . - * p[0].digit[0]m-1 p[1].digit[0]m-1 ... p[N-2].digit[0]m-1 p[N-1].digit[0]m-1 - * p[0].digit[1]0 p[1].digit[1]0 ... p[N-2].digit[1]0 p[N-1].digit[1]0 - * . . - * . . - * p[0].digit[n-1]m-2 p[1].digit[n-1]m-2 ... p[N-2].digit[n-1]m-2 p[N-1].digit[n-1]m-2 - * p[0].digit[n-1]m-1 p[1].digit[n-1]m-1 ... p[N-2].digit[n-1]m-1 p[N-1].digit[n-1]m-1 - * + * These functions return 0xffffffff if the output is true, and 0 otherwise. */ -mp_err mpi_to_weave(const mp_int *a, unsigned char *b, - mp_size b_size, mp_size count) -{ - mp_size i; - mp_digit *digitsa0; - mp_digit *digitsa1; - mp_digit *digitsa2; - mp_digit *digitsa3; - mp_size useda0; - mp_size useda1; - mp_size useda2; - mp_size useda3; - mp_weave_word *weaved = (mp_weave_word *)b; - - count = count/sizeof(mp_weave_word); - - /* this code pretty much depends on this ! */ -#if MP_ARGCHK == 2 - assert(WEAVE_WORD_SIZE == 4); - assert(sizeof(mp_weave_word) == 4); -#endif +#define CONST_TIME_MSB(x) (0L - ((x) >> (8 * sizeof(x) - 1))) +#define CONST_TIME_EQ_Z(x) CONST_TIME_MSB(~(x) & ((x)-1)) +#define CONST_TIME_EQ(a, b) CONST_TIME_EQ_Z((a) ^ (b)) - digitsa0 = MP_DIGITS(&a[0]); - digitsa1 = MP_DIGITS(&a[1]); - digitsa2 = MP_DIGITS(&a[2]); - digitsa3 = MP_DIGITS(&a[3]); - useda0 = MP_USED(&a[0]); - useda1 = MP_USED(&a[1]); - useda2 = MP_USED(&a[2]); - useda3 = MP_USED(&a[3]); - - ARGCHK(MP_SIGN(&a[0]) == MP_ZPOS, MP_BADARG); - ARGCHK(MP_SIGN(&a[1]) == MP_ZPOS, MP_BADARG); - ARGCHK(MP_SIGN(&a[2]) == MP_ZPOS, MP_BADARG); - ARGCHK(MP_SIGN(&a[3]) == MP_ZPOS, MP_BADARG); - ARGCHK(useda0 <= b_size, MP_BADARG); - ARGCHK(useda1 <= b_size, MP_BADARG); - ARGCHK(useda2 <= b_size, MP_BADARG); - ARGCHK(useda3 <= b_size, MP_BADARG); - -#define SAFE_FETCH(digit, used, word) ((word) < (used) ? (digit[word]) : 0) - - for (i=0; i < b_size; i++) { - mp_digit d0 = SAFE_FETCH(digitsa0,useda0,i); - mp_digit d1 = SAFE_FETCH(digitsa1,useda1,i); - mp_digit d2 = SAFE_FETCH(digitsa2,useda2,i); - mp_digit d3 = SAFE_FETCH(digitsa3,useda3,i); - register mp_weave_word acc; - -/* - * ONE_STEP takes the MSB of each of our current digits and places that - * byte in the appropriate position for writing to the weaved array. - * On little endian: - * b3 b2 b1 b0 - * On big endian: - * b0 b1 b2 b3 - * When the data is written it would always wind up: - * b[0] = b0 - * b[1] = b1 - * b[2] = b2 - * b[3] = b3 - * - * Once we've written the MSB, we shift the whole digit up left one - * byte, putting the Next Most Significant Byte in the MSB position, - * so we we repeat the next one step that byte will be written. - * NOTE: This code assumes sizeof(mp_weave_word) and MP_WEAVE_WORD_SIZE - * is 4. +/* Reverse the operation above for one mp_int. + * Reconstruct one mp_int from its column in the weaved array. + * Every read accesses every element of the weaved array, in order to + * avoid timing attacks based on patterns of memory accesses. */ -#ifdef MP_IS_LITTLE_ENDIAN -#define MPI_WEAVE_ONE_STEP \ - acc = (d0 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \ - acc |= (d1 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \ - acc |= (d2 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \ - acc |= (d3 >> (MP_DIGIT_BIT-32)) & 0xff000000; d3 <<= 8; /*b3*/ \ - *weaved = acc; weaved += count; -#else -#define MPI_WEAVE_ONE_STEP \ - acc = (d0 >> (MP_DIGIT_BIT-32)) & 0xff000000; d0 <<= 8; /*b0*/ \ - acc |= (d1 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \ - acc |= (d2 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \ - acc |= (d3 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \ - *weaved = acc; weaved += count; -#endif - switch (sizeof(mp_digit)) { - case 32: - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - case 16: - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - case 8: - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - case 4: - MPI_WEAVE_ONE_STEP - MPI_WEAVE_ONE_STEP - case 2: - MPI_WEAVE_ONE_STEP - case 1: - MPI_WEAVE_ONE_STEP - break; - } - } - - return MP_OKAY; -} - -/* reverse the operation above for one entry. - * b points to the offset into the weave array of the power we are - * calculating */ -mp_err weave_to_mpi(mp_int *a, const unsigned char *b, - mp_size b_size, mp_size count) +mp_err weave_to_mpi(mp_int *a, /* out, result */ + const mp_digit *weaved, /* in, byte matrix */ + mp_size index, /* which column to read */ + mp_size nDigits, /* number of mp_digits in each bignum */ + mp_size nBignums) /* width of the matrix */ { - mp_digit *pb = MP_DIGITS(a); - mp_digit *end = &pb[b_size]; - - MP_SIGN(a) = MP_ZPOS; - MP_USED(a) = b_size; - - for (; pb < end; pb++) { - register mp_digit digit; - - digit = *b << 8; b += count; -#define MPI_UNWEAVE_ONE_STEP digit |= *b; b += count; digit = digit << 8; - switch (sizeof(mp_digit)) { - case 32: - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - case 16: - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - case 8: - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - case 4: - MPI_UNWEAVE_ONE_STEP - MPI_UNWEAVE_ONE_STEP - case 2: - break; + /* these are indices, but need to be the same size as mp_digit + * because of the CONST_TIME operations */ + mp_digit i, j; + mp_digit d; + mp_digit *pDest = MP_DIGITS(a); + + MP_SIGN(a) = MP_ZPOS; + MP_USED(a) = nDigits; + + assert(weaved != NULL); + + /* Fetch the proper column in constant time, indexing over the whole array */ + for (i = 0; i < nDigits; ++i) { + d = 0; + for (j = 0; j < nBignums; ++j) { + d |= weaved[i * nBignums + j] & CONST_TIME_EQ(j, index); + } + pDest[i] = d; } - digit |= *b; b += count; - *pb = digit; - } - s_mp_clamp(a); - return MP_OKAY; + s_mp_clamp(a); + return MP_OKAY; } -#endif - -#define SQR(a,b) \ - MP_CHECKOK( mp_sqr(a, b) );\ - MP_CHECKOK( s_mp_redc(b, mmm) ) +#define SQR(a, b) \ + MP_CHECKOK(mp_sqr(a, b)); \ + MP_CHECKOK(s_mp_redc(b, mmm)) #if defined(MP_MONT_USE_MP_MUL) -#define MUL_NOWEAVE(x,a,b) \ - MP_CHECKOK( mp_mul(a, x, b) ); \ - MP_CHECKOK( s_mp_redc(b, mmm) ) +#define MUL_NOWEAVE(x, a, b) \ + MP_CHECKOK(mp_mul(a, x, b)); \ + MP_CHECKOK(s_mp_redc(b, mmm)) #else -#define MUL_NOWEAVE(x,a,b) \ - MP_CHECKOK( s_mp_mul_mont(a, x, b, mmm) ) +#define MUL_NOWEAVE(x, a, b) \ + MP_CHECKOK(s_mp_mul_mont(a, x, b, mmm)) #endif -#define MUL(x,a,b) \ - MP_CHECKOK( weave_to_mpi(&tmp, powers + (x), nLen, num_powers) ); \ - MUL_NOWEAVE(&tmp,a,b) +#define MUL(x, a, b) \ + MP_CHECKOK(weave_to_mpi(&tmp, powers, (x), nLen, num_powers)); \ + MUL_NOWEAVE(&tmp, a, b) -#define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp -#define MP_ALIGN(x,y) ((((ptrdiff_t)(x))+((y)-1))&(((ptrdiff_t)0)-(y))) +#define SWAPPA \ + ptmp = pa1; \ + pa1 = pa2; \ + pa2 = ptmp +#define MP_ALIGN(x, y) ((((ptrdiff_t)(x)) + ((y)-1)) & (((ptrdiff_t)0) - (y))) /* Do modular exponentiation using integer multiply code. */ -mp_err mp_exptmod_safe_i(const mp_int * montBase, - const mp_int * exponent, - const mp_int * modulus, - mp_int * result, - mp_mont_modulus *mmm, - int nLen, - mp_size bits_in_exponent, - mp_size window_bits, - mp_size num_powers) +mp_err +mp_exptmod_safe_i(const mp_int *montBase, + const mp_int *exponent, + const mp_int *modulus, + mp_int *result, + mp_mont_modulus *mmm, + int nLen, + mp_size bits_in_exponent, + mp_size window_bits, + mp_size num_powers) { - mp_int *pa1, *pa2, *ptmp; - mp_size i; - mp_size first_window; - mp_err res; - int expOff; - mp_int accum1, accum2, accum[WEAVE_WORD_SIZE]; - mp_int tmp; - unsigned char *powersArray = NULL; - unsigned char *powers = NULL; - - MP_DIGITS(&accum1) = 0; - MP_DIGITS(&accum2) = 0; - MP_DIGITS(&accum[0]) = 0; - MP_DIGITS(&accum[1]) = 0; - MP_DIGITS(&accum[2]) = 0; - MP_DIGITS(&accum[3]) = 0; - MP_DIGITS(&tmp) = 0; - - /* grab the first window value. This allows us to preload accumulator1 + mp_int *pa1, *pa2, *ptmp; + mp_size i; + mp_size first_window; + mp_err res; + int expOff; + mp_int accum1, accum2, accum[WEAVE_WORD_SIZE]; + mp_int tmp; + mp_digit *powersArray = NULL; + mp_digit *powers = NULL; + + MP_DIGITS(&accum1) = 0; + MP_DIGITS(&accum2) = 0; + MP_DIGITS(&accum[0]) = 0; + MP_DIGITS(&accum[1]) = 0; + MP_DIGITS(&accum[2]) = 0; + MP_DIGITS(&accum[3]) = 0; + MP_DIGITS(&tmp) = 0; + + /* grab the first window value. This allows us to preload accumulator1 * and save a conversion, some squares and a multiple*/ - MP_CHECKOK( mpl_get_bits(exponent, - bits_in_exponent-window_bits, window_bits) ); - first_window = (mp_size)res; - - MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) ); - MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) ); - - /* build the first WEAVE_WORD powers inline */ - /* if WEAVE_WORD_SIZE is not 4, this code will have to change */ - if (num_powers > 2) { - MP_CHECKOK( mp_init_size(&accum[0], 3 * nLen + 2) ); - MP_CHECKOK( mp_init_size(&accum[1], 3 * nLen + 2) ); - MP_CHECKOK( mp_init_size(&accum[2], 3 * nLen + 2) ); - MP_CHECKOK( mp_init_size(&accum[3], 3 * nLen + 2) ); - mp_set(&accum[0], 1); - MP_CHECKOK( s_mp_to_mont(&accum[0], mmm, &accum[0]) ); - MP_CHECKOK( mp_copy(montBase, &accum[1]) ); - SQR(montBase, &accum[2]); - MUL_NOWEAVE(montBase, &accum[2], &accum[3]); - powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1)); - if (!powersArray) { - res = MP_MEM; - goto CLEANUP; - } - /* powers[i] = base ** (i); */ \ - powers = (unsigned char *)MP_ALIGN(powersArray,num_powers); \ - MP_CHECKOK( mpi_to_weave(accum, powers, nLen, num_powers) ); - if (first_window < 4) { - MP_CHECKOK( mp_copy(&accum[first_window], &accum1) ); - first_window = num_powers; - } - } else { - if (first_window == 0) { - mp_set(&accum1, 1); - MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) ); - } else { - /* assert first_window == 1? */ - MP_CHECKOK( mp_copy(montBase, &accum1) ); - } - } - - /* - * calculate all the powers in the powers array. - * this adds 2**(k-1)-2 square operations over just calculating the - * odd powers where k is the window size in the two other mp_modexpt - * implementations in this file. We will get some of that - * back by not needing the first 'k' squares and one multiply for the - * first window. - * Given the value of 4 for WEAVE_WORD_SIZE, this loop will only execute if - * num_powers > 2, in which case powers will have been allocated. - */ - for (i = WEAVE_WORD_SIZE; i < num_powers; i++) { - int acc_index = i & (WEAVE_WORD_SIZE-1); /* i % WEAVE_WORD_SIZE */ - if ( i & 1 ) { - MUL_NOWEAVE(montBase, &accum[acc_index-1] , &accum[acc_index]); - /* we've filled the array do our 'per array' processing */ - if (acc_index == (WEAVE_WORD_SIZE-1)) { - MP_CHECKOK( mpi_to_weave(accum, powers + i - (WEAVE_WORD_SIZE-1), - nLen, num_powers) ); - - if (first_window <= i) { - MP_CHECKOK( mp_copy(&accum[first_window & (WEAVE_WORD_SIZE-1)], - &accum1) ); - first_window = num_powers; + MP_CHECKOK(mpl_get_bits(exponent, + bits_in_exponent - window_bits, window_bits)); + first_window = (mp_size)res; + + MP_CHECKOK(mp_init_size(&accum1, 3 * nLen + 2)); + MP_CHECKOK(mp_init_size(&accum2, 3 * nLen + 2)); + + /* build the first WEAVE_WORD powers inline */ + /* if WEAVE_WORD_SIZE is not 4, this code will have to change */ + if (num_powers > 2) { + MP_CHECKOK(mp_init_size(&accum[0], 3 * nLen + 2)); + MP_CHECKOK(mp_init_size(&accum[1], 3 * nLen + 2)); + MP_CHECKOK(mp_init_size(&accum[2], 3 * nLen + 2)); + MP_CHECKOK(mp_init_size(&accum[3], 3 * nLen + 2)); + mp_set(&accum[0], 1); + MP_CHECKOK(s_mp_to_mont(&accum[0], mmm, &accum[0])); + MP_CHECKOK(mp_copy(montBase, &accum[1])); + SQR(montBase, &accum[2]); + MUL_NOWEAVE(montBase, &accum[2], &accum[3]); + powersArray = (mp_digit *)malloc(num_powers * (nLen * sizeof(mp_digit) + 1)); + if (!powersArray) { + res = MP_MEM; + goto CLEANUP; + } + /* powers[i] = base ** (i); */ + powers = (mp_digit *)MP_ALIGN(powersArray, num_powers); + MP_CHECKOK(mpi_to_weave(accum, powers, nLen, num_powers)); + if (first_window < 4) { + MP_CHECKOK(mp_copy(&accum[first_window], &accum1)); + first_window = num_powers; } - } } else { - /* up to 8 we can find 2^i-1 in the accum array, but at 8 we our source - * and target are the same so we need to copy.. After that, the - * value is overwritten, so we need to fetch it from the stored - * weave array */ - if (i > 2* WEAVE_WORD_SIZE) { - MP_CHECKOK(weave_to_mpi(&accum2, powers+i/2, nLen, num_powers)); - SQR(&accum2, &accum[acc_index]); - } else { - int half_power_index = (i/2) & (WEAVE_WORD_SIZE-1); - if (half_power_index == acc_index) { - /* copy is cheaper than weave_to_mpi */ - MP_CHECKOK(mp_copy(&accum[half_power_index], &accum2)); - SQR(&accum2,&accum[acc_index]); - } else { - SQR(&accum[half_power_index],&accum[acc_index]); - } - } + if (first_window == 0) { + mp_set(&accum1, 1); + MP_CHECKOK(s_mp_to_mont(&accum1, mmm, &accum1)); + } else { + /* assert first_window == 1? */ + MP_CHECKOK(mp_copy(montBase, &accum1)); + } } - } - /* if the accum1 isn't set, Then there is something wrong with our logic - * above and is an internal programming error. + + /* + * calculate all the powers in the powers array. + * this adds 2**(k-1)-2 square operations over just calculating the + * odd powers where k is the window size in the two other mp_modexpt + * implementations in this file. We will get some of that + * back by not needing the first 'k' squares and one multiply for the + * first window. + * Given the value of 4 for WEAVE_WORD_SIZE, this loop will only execute if + * num_powers > 2, in which case powers will have been allocated. + */ + for (i = WEAVE_WORD_SIZE; i < num_powers; i++) { + int acc_index = i & (WEAVE_WORD_SIZE - 1); /* i % WEAVE_WORD_SIZE */ + if (i & 1) { + MUL_NOWEAVE(montBase, &accum[acc_index - 1], &accum[acc_index]); + /* we've filled the array do our 'per array' processing */ + if (acc_index == (WEAVE_WORD_SIZE - 1)) { + MP_CHECKOK(mpi_to_weave(accum, powers + i - (WEAVE_WORD_SIZE - 1), + nLen, num_powers)); + + if (first_window <= i) { + MP_CHECKOK(mp_copy(&accum[first_window & (WEAVE_WORD_SIZE - 1)], + &accum1)); + first_window = num_powers; + } + } + } else { + /* up to 8 we can find 2^i-1 in the accum array, but at 8 we our source + * and target are the same so we need to copy.. After that, the + * value is overwritten, so we need to fetch it from the stored + * weave array */ + if (i > 2 * WEAVE_WORD_SIZE) { + MP_CHECKOK(weave_to_mpi(&accum2, powers, i / 2, nLen, num_powers)); + SQR(&accum2, &accum[acc_index]); + } else { + int half_power_index = (i / 2) & (WEAVE_WORD_SIZE - 1); + if (half_power_index == acc_index) { + /* copy is cheaper than weave_to_mpi */ + MP_CHECKOK(mp_copy(&accum[half_power_index], &accum2)); + SQR(&accum2, &accum[acc_index]); + } else { + SQR(&accum[half_power_index], &accum[acc_index]); + } + } + } + } +/* if the accum1 isn't set, Then there is something wrong with our logic + * above and is an internal programming error. */ #if MP_ARGCHK == 2 - assert(MP_USED(&accum1) != 0); + assert(MP_USED(&accum1) != 0); #endif - /* set accumulator to montgomery residue of 1 */ - pa1 = &accum1; - pa2 = &accum2; - - /* tmp is not used if window_bits == 1. */ - if (window_bits != 1) { - MP_CHECKOK( mp_init_size(&tmp, 3 * nLen + 2) ); - } - - for (expOff = bits_in_exponent - window_bits*2; expOff >= 0; expOff -= window_bits) { - mp_size smallExp; - MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) ); - smallExp = (mp_size)res; - - /* handle unroll the loops */ - switch (window_bits) { - case 1: - if (!smallExp) { - SQR(pa1,pa2); SWAPPA; - } else if (smallExp & 1) { - SQR(pa1,pa2); MUL_NOWEAVE(montBase,pa2,pa1); - } else { - abort(); - } - break; - case 6: - SQR(pa1,pa2); SQR(pa2,pa1); - /* fall through */ - case 4: - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - MUL(smallExp, pa1,pa2); SWAPPA; - break; - case 5: - SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); - SQR(pa1,pa2); MUL(smallExp,pa2,pa1); - break; - default: - abort(); /* could do a loop? */ + /* set accumulator to montgomery residue of 1 */ + pa1 = &accum1; + pa2 = &accum2; + + /* tmp is not used if window_bits == 1. */ + if (window_bits != 1) { + MP_CHECKOK(mp_init_size(&tmp, 3 * nLen + 2)); + } + + for (expOff = bits_in_exponent - window_bits * 2; expOff >= 0; expOff -= window_bits) { + mp_size smallExp; + MP_CHECKOK(mpl_get_bits(exponent, expOff, window_bits)); + smallExp = (mp_size)res; + + /* handle unroll the loops */ + switch (window_bits) { + case 1: + if (!smallExp) { + SQR(pa1, pa2); + SWAPPA; + } else if (smallExp & 1) { + SQR(pa1, pa2); + MUL_NOWEAVE(montBase, pa2, pa1); + } else { + abort(); + } + break; + case 6: + SQR(pa1, pa2); + SQR(pa2, pa1); + /* fall through */ + case 4: + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + MUL(smallExp, pa1, pa2); + SWAPPA; + break; + case 5: + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + SQR(pa2, pa1); + SQR(pa1, pa2); + MUL(smallExp, pa2, pa1); + break; + default: + abort(); /* could do a loop? */ + } } - } - res = s_mp_redc(pa1, mmm); - mp_exch(pa1, result); + res = s_mp_redc(pa1, mmm); + mp_exch(pa1, result); CLEANUP: - mp_clear(&accum1); - mp_clear(&accum2); - mp_clear(&accum[0]); - mp_clear(&accum[1]); - mp_clear(&accum[2]); - mp_clear(&accum[3]); - mp_clear(&tmp); - /* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */ - free(powersArray); - return res; + mp_clear(&accum1); + mp_clear(&accum2); + mp_clear(&accum[0]); + mp_clear(&accum[1]); + mp_clear(&accum[2]); + mp_clear(&accum[3]); + mp_clear(&tmp); + /* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */ + free(powersArray); + return res; } #undef SQR #undef MUL #endif -mp_err mp_exptmod(const mp_int *inBase, const mp_int *exponent, - const mp_int *modulus, mp_int *result) +mp_err +mp_exptmod(const mp_int *inBase, const mp_int *exponent, + const mp_int *modulus, mp_int *result) { - const mp_int *base; - mp_size bits_in_exponent, i, window_bits, odd_ints; - mp_err res; - int nLen; - mp_int montBase, goodBase; - mp_mont_modulus mmm; + const mp_int *base; + mp_size bits_in_exponent, i, window_bits, odd_ints; + mp_err res; + int nLen; + mp_int montBase, goodBase; + mp_mont_modulus mmm; #ifdef MP_USING_CACHE_SAFE_MOD_EXP - static unsigned int max_window_bits; + static unsigned int max_window_bits; #endif - /* function for computing n0prime only works if n0 is odd */ - if (!mp_isodd(modulus)) - return s_mp_exptmod(inBase, exponent, modulus, result); + /* function for computing n0prime only works if n0 is odd */ + if (!mp_isodd(modulus)) + return s_mp_exptmod(inBase, exponent, modulus, result); - MP_DIGITS(&montBase) = 0; - MP_DIGITS(&goodBase) = 0; + MP_DIGITS(&montBase) = 0; + MP_DIGITS(&goodBase) = 0; - if (mp_cmp(inBase, modulus) < 0) { - base = inBase; - } else { - MP_CHECKOK( mp_init(&goodBase) ); - base = &goodBase; - MP_CHECKOK( mp_mod(inBase, modulus, &goodBase) ); - } + if (mp_cmp(inBase, modulus) < 0) { + base = inBase; + } else { + MP_CHECKOK(mp_init(&goodBase)); + base = &goodBase; + MP_CHECKOK(mp_mod(inBase, modulus, &goodBase)); + } - nLen = MP_USED(modulus); - MP_CHECKOK( mp_init_size(&montBase, 2 * nLen + 2) ); + nLen = MP_USED(modulus); + MP_CHECKOK(mp_init_size(&montBase, 2 * nLen + 2)); - mmm.N = *modulus; /* a copy of the mp_int struct */ + mmm.N = *modulus; /* a copy of the mp_int struct */ - /* compute n0', given n0, n0' = -(n0 ** -1) mod MP_RADIX - ** where n0 = least significant mp_digit of N, the modulus. - */ - mmm.n0prime = 0 - s_mp_invmod_radix( MP_DIGIT(modulus, 0) ); + /* compute n0', given n0, n0' = -(n0 ** -1) mod MP_RADIX + ** where n0 = least significant mp_digit of N, the modulus. + */ + mmm.n0prime = 0 - s_mp_invmod_radix(MP_DIGIT(modulus, 0)); - MP_CHECKOK( s_mp_to_mont(base, &mmm, &montBase) ); + MP_CHECKOK(s_mp_to_mont(base, &mmm, &montBase)); - bits_in_exponent = mpl_significant_bits(exponent); + bits_in_exponent = mpl_significant_bits(exponent); #ifdef MP_USING_CACHE_SAFE_MOD_EXP - if (mp_using_cache_safe_exp) { - if (bits_in_exponent > 780) - window_bits = 6; - else if (bits_in_exponent > 256) - window_bits = 5; - else if (bits_in_exponent > 20) - window_bits = 4; - /* RSA public key exponents are typically under 20 bits (common values - * are: 3, 17, 65537) and a 4-bit window is inefficient - */ - else - window_bits = 1; - } else + if (mp_using_cache_safe_exp) { + if (bits_in_exponent > 780) + window_bits = 6; + else if (bits_in_exponent > 256) + window_bits = 5; + else if (bits_in_exponent > 20) + window_bits = 4; + /* RSA public key exponents are typically under 20 bits (common values + * are: 3, 17, 65537) and a 4-bit window is inefficient + */ + else + window_bits = 1; + } else #endif - if (bits_in_exponent > 480) - window_bits = 6; - else if (bits_in_exponent > 160) - window_bits = 5; - else if (bits_in_exponent > 20) - window_bits = 4; - /* RSA public key exponents are typically under 20 bits (common values - * are: 3, 17, 65537) and a 4-bit window is inefficient - */ - else - window_bits = 1; + if (bits_in_exponent > 480) + window_bits = 6; + else if (bits_in_exponent > 160) + window_bits = 5; + else if (bits_in_exponent > 20) + window_bits = 4; + /* RSA public key exponents are typically under 20 bits (common values + * are: 3, 17, 65537) and a 4-bit window is inefficient + */ + else + window_bits = 1; #ifdef MP_USING_CACHE_SAFE_MOD_EXP - /* - * clamp the window size based on - * the cache line size. - */ - if (!max_window_bits) { - unsigned long cache_size = s_mpi_getProcessorLineSize(); - /* processor has no cache, use 'fast' code always */ - if (cache_size == 0) { - mp_using_cache_safe_exp = 0; - } - if ((cache_size == 0) || (cache_size >= 64)) { - max_window_bits = 6; - } else if (cache_size >= 32) { - max_window_bits = 5; - } else if (cache_size >= 16) { - max_window_bits = 4; - } else max_window_bits = 1; /* should this be an assert? */ - } - - /* clamp the window size down before we caclulate bits_in_exponent */ - if (mp_using_cache_safe_exp) { - if (window_bits > max_window_bits) { - window_bits = max_window_bits; + /* + * clamp the window size based on + * the cache line size. + */ + if (!max_window_bits) { + unsigned long cache_size = s_mpi_getProcessorLineSize(); + /* processor has no cache, use 'fast' code always */ + if (cache_size == 0) { + mp_using_cache_safe_exp = 0; + } + if ((cache_size == 0) || (cache_size >= 64)) { + max_window_bits = 6; + } else if (cache_size >= 32) { + max_window_bits = 5; + } else if (cache_size >= 16) { + max_window_bits = 4; + } else + max_window_bits = 1; /* should this be an assert? */ + } + + /* clamp the window size down before we caclulate bits_in_exponent */ + if (mp_using_cache_safe_exp) { + if (window_bits > max_window_bits) { + window_bits = max_window_bits; + } } - } #endif - odd_ints = 1 << (window_bits - 1); - i = bits_in_exponent % window_bits; - if (i != 0) { - bits_in_exponent += window_bits - i; - } + odd_ints = 1 << (window_bits - 1); + i = bits_in_exponent % window_bits; + if (i != 0) { + bits_in_exponent += window_bits - i; + } #ifdef MP_USING_MONT_MULF - if (mp_using_mont_mulf) { - MP_CHECKOK( s_mp_pad(&montBase, nLen) ); - res = mp_exptmod_f(&montBase, exponent, modulus, result, &mmm, nLen, - bits_in_exponent, window_bits, odd_ints); - } else + if (mp_using_mont_mulf) { + MP_CHECKOK(s_mp_pad(&montBase, nLen)); + res = mp_exptmod_f(&montBase, exponent, modulus, result, &mmm, nLen, + bits_in_exponent, window_bits, odd_ints); + } else #endif #ifdef MP_USING_CACHE_SAFE_MOD_EXP - if (mp_using_cache_safe_exp) { - res = mp_exptmod_safe_i(&montBase, exponent, modulus, result, &mmm, nLen, - bits_in_exponent, window_bits, 1 << window_bits); - } else + if (mp_using_cache_safe_exp) { + res = mp_exptmod_safe_i(&montBase, exponent, modulus, result, &mmm, nLen, + bits_in_exponent, window_bits, 1 << window_bits); + } else #endif - res = mp_exptmod_i(&montBase, exponent, modulus, result, &mmm, nLen, - bits_in_exponent, window_bits, odd_ints); + res = mp_exptmod_i(&montBase, exponent, modulus, result, &mmm, nLen, + bits_in_exponent, window_bits, odd_ints); CLEANUP: - mp_clear(&montBase); - mp_clear(&goodBase); - /* Don't mp_clear mmm.N because it is merely a copy of modulus. - ** Just zap it. - */ - memset(&mmm, 0, sizeof mmm); - return res; + mp_clear(&montBase); + mp_clear(&goodBase); + /* Don't mp_clear mmm.N because it is merely a copy of modulus. + ** Just zap it. + */ + memset(&mmm, 0, sizeof mmm); + return res; } diff --git a/nss/lib/freebl/mpi/mpprime.c b/nss/lib/freebl/mpi/mpprime.c index 9b97fb2..5828719 100644 --- a/nss/lib/freebl/mpi/mpprime.c +++ b/nss/lib/freebl/mpi/mpprime.c @@ -18,14 +18,14 @@ #define RANDOM() rand() -#include "primes.c" /* pull in the prime digit table */ +#include "primes.c" /* pull in the prime digit table */ -/* +/* Test if any of a given vector of digits divides a. If not, MP_NO is returned; otherwise, MP_YES is returned and 'which' is set to the index of the integer in the vector which divided a. */ -mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which); +mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which); /* {{{ mpp_divis(a, b) */ @@ -35,25 +35,26 @@ mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which); Returns MP_YES if a is divisible by b, or MP_NO if it is not. */ -mp_err mpp_divis(mp_int *a, mp_int *b) +mp_err +mpp_divis(mp_int *a, mp_int *b) { - mp_err res; - mp_int rem; + mp_err res; + mp_int rem; - if((res = mp_init(&rem)) != MP_OKAY) - return res; + if ((res = mp_init(&rem)) != MP_OKAY) + return res; - if((res = mp_mod(a, b, &rem)) != MP_OKAY) - goto CLEANUP; + if ((res = mp_mod(a, b, &rem)) != MP_OKAY) + goto CLEANUP; - if(mp_cmp_z(&rem) == 0) - res = MP_YES; - else - res = MP_NO; + if (mp_cmp_z(&rem) == 0) + res = MP_YES; + else + res = MP_NO; CLEANUP: - mp_clear(&rem); - return res; + mp_clear(&rem); + return res; } /* end mpp_divis() */ @@ -67,23 +68,24 @@ CLEANUP: Return MP_YES if a is divisible by d, or MP_NO if it is not. */ -mp_err mpp_divis_d(mp_int *a, mp_digit d) +mp_err +mpp_divis_d(mp_int *a, mp_digit d) { - mp_err res; - mp_digit rem; + mp_err res; + mp_digit rem; - ARGCHK(a != NULL, MP_BADARG); + ARGCHK(a != NULL, MP_BADARG); - if(d == 0) - return MP_NO; + if (d == 0) + return MP_NO; - if((res = mp_mod_d(a, d, &rem)) != MP_OKAY) - return res; + if ((res = mp_mod_d(a, d, &rem)) != MP_OKAY) + return res; - if(rem == 0) - return MP_YES; - else - return MP_NO; + if (rem == 0) + return MP_YES; + else + return MP_NO; } /* end mpp_divis_d() */ @@ -102,22 +104,23 @@ mp_err mpp_divis_d(mp_int *a, mp_digit d) As many digits as a currently has are filled with random digits. */ -mp_err mpp_random(mp_int *a) +mp_err +mpp_random(mp_int *a) { - mp_digit next = 0; - unsigned int ix, jx; + mp_digit next = 0; + unsigned int ix, jx; - ARGCHK(a != NULL, MP_BADARG); + ARGCHK(a != NULL, MP_BADARG); - for(ix = 0; ix < USED(a); ix++) { - for(jx = 0; jx < sizeof(mp_digit); jx++) { - next = (next << CHAR_BIT) | (RANDOM() & UCHAR_MAX); + for (ix = 0; ix < USED(a); ix++) { + for (jx = 0; jx < sizeof(mp_digit); jx++) { + next = (next << CHAR_BIT) | (RANDOM() & UCHAR_MAX); + } + DIGIT(a, ix) = next; } - DIGIT(a, ix) = next; - } - return MP_OKAY; + return MP_OKAY; } /* end mpp_random() */ @@ -125,16 +128,17 @@ mp_err mpp_random(mp_int *a) /* {{{ mpp_random_size(a, prec) */ -mp_err mpp_random_size(mp_int *a, mp_size prec) +mp_err +mpp_random_size(mp_int *a, mp_size prec) { - mp_err res; + mp_err res; - ARGCHK(a != NULL && prec > 0, MP_BADARG); - - if((res = s_mp_pad(a, prec)) != MP_OKAY) - return res; + ARGCHK(a != NULL && prec > 0, MP_BADARG); - return mpp_random(a); + if ((res = s_mp_pad(a, prec)) != MP_OKAY) + return res; + + return mpp_random(a); } /* end mpp_random_size() */ @@ -150,11 +154,12 @@ mp_err mpp_random_size(mp_int *a, mp_size prec) if it is; returns MP_NO if it is not. */ -mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which) +mp_err +mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which) { - ARGCHK(a != NULL && vec != NULL && size > 0, MP_BADARG); - - return s_mpp_divp(a, vec, size, which); + ARGCHK(a != NULL && vec != NULL && size > 0, MP_BADARG); + + return s_mpp_divp(a, vec, size, which); } /* end mpp_divis_vector() */ @@ -169,22 +174,23 @@ mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which) is, returns MP_YES and sets *np to the value of the digit that did it. If not, returns MP_NO. */ -mp_err mpp_divis_primes(mp_int *a, mp_digit *np) +mp_err +mpp_divis_primes(mp_int *a, mp_digit *np) { - int size, which; - mp_err res; + int size, which; + mp_err res; - ARGCHK(a != NULL && np != NULL, MP_BADARG); + ARGCHK(a != NULL && np != NULL, MP_BADARG); - size = (int)*np; - if(size > prime_tab_size) - size = prime_tab_size; + size = (int)*np; + if (size > prime_tab_size) + size = prime_tab_size; - res = mpp_divis_vector(a, prime_tab, size, &which); - if(res == MP_YES) - *np = prime_tab[which]; + res = mpp_divis_vector(a, prime_tab, size, &which); + if (res == MP_YES) + *np = prime_tab[which]; - return res; + return res; } /* end mpp_divis_primes() */ @@ -199,35 +205,35 @@ mp_err mpp_divis_primes(mp_int *a, mp_digit *np) equal, the test passes and we return MP_YES. Otherwise, we return MP_NO. */ -mp_err mpp_fermat(mp_int *a, mp_digit w) +mp_err +mpp_fermat(mp_int *a, mp_digit w) { - mp_int base, test; - mp_err res; - - if((res = mp_init(&base)) != MP_OKAY) - return res; + mp_int base, test; + mp_err res; - mp_set(&base, w); + if ((res = mp_init(&base)) != MP_OKAY) + return res; - if((res = mp_init(&test)) != MP_OKAY) - goto TEST; + mp_set(&base, w); - /* Compute test = base^a (mod a) */ - if((res = mp_exptmod(&base, a, a, &test)) != MP_OKAY) - goto CLEANUP; + if ((res = mp_init(&test)) != MP_OKAY) + goto TEST; - - if(mp_cmp(&base, &test) == 0) - res = MP_YES; - else - res = MP_NO; + /* Compute test = base^a (mod a) */ + if ((res = mp_exptmod(&base, a, a, &test)) != MP_OKAY) + goto CLEANUP; - CLEANUP: - mp_clear(&test); - TEST: - mp_clear(&base); + if (mp_cmp(&base, &test) == 0) + res = MP_YES; + else + res = MP_NO; + +CLEANUP: + mp_clear(&test); +TEST: + mp_clear(&base); - return res; + return res; } /* end mpp_fermat() */ @@ -235,20 +241,21 @@ mp_err mpp_fermat(mp_int *a, mp_digit w) /* Perform the fermat test on each of the primes in a list until - a) one of them shows a is not prime, or + a) one of them shows a is not prime, or b) the list is exhausted. Returns: MP_YES if it passes tests. - MP_NO if fermat test reveals it is composite - Some MP error code if some other error occurs. + MP_NO if fermat test reveals it is composite + Some MP error code if some other error occurs. */ -mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes) +mp_err +mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes) { - mp_err rv = MP_YES; + mp_err rv = MP_YES; - while (nPrimes-- > 0 && rv == MP_YES) { - rv = mpp_fermat(a, *primes++); - } - return rv; + while (nPrimes-- > 0 && rv == MP_YES) { + rv = mpp_fermat(a, *primes++); + } + return rv; } /* {{{ mpp_pprime(a, nt) */ @@ -262,285 +269,292 @@ mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes) is returned, it is probably prime (but that is not guaranteed). */ -mp_err mpp_pprime(mp_int *a, int nt) +mp_err +mpp_pprime(mp_int *a, int nt) { - mp_err res; - mp_int x, amo, m, z; /* "amo" = "a minus one" */ - int iter; - unsigned int jx; - mp_size b; - - ARGCHK(a != NULL, MP_BADARG); - - MP_DIGITS(&x) = 0; - MP_DIGITS(&amo) = 0; - MP_DIGITS(&m) = 0; - MP_DIGITS(&z) = 0; - - /* Initialize temporaries... */ - MP_CHECKOK( mp_init(&amo)); - /* Compute amo = a - 1 for what follows... */ - MP_CHECKOK( mp_sub_d(a, 1, &amo) ); - - b = mp_trailing_zeros(&amo); - if (!b) { /* a was even ? */ - res = MP_NO; - goto CLEANUP; - } - - MP_CHECKOK( mp_init_size(&x, MP_USED(a)) ); - MP_CHECKOK( mp_init(&z) ); - MP_CHECKOK( mp_init(&m) ); - MP_CHECKOK( mp_div_2d(&amo, b, &m, 0) ); - - /* Do the test nt times... */ - for(iter = 0; iter < nt; iter++) { - - /* Choose a random value for 1 < x < a */ - s_mp_pad(&x, USED(a)); - mpp_random(&x); - MP_CHECKOK( mp_mod(&x, a, &x) ); - if(mp_cmp_d(&x, 1) <= 0) { - iter--; /* don't count this iteration */ - continue; /* choose a new x */ + mp_err res; + mp_int x, amo, m, z; /* "amo" = "a minus one" */ + int iter; + unsigned int jx; + mp_size b; + + ARGCHK(a != NULL, MP_BADARG); + + MP_DIGITS(&x) = 0; + MP_DIGITS(&amo) = 0; + MP_DIGITS(&m) = 0; + MP_DIGITS(&z) = 0; + + /* Initialize temporaries... */ + MP_CHECKOK(mp_init(&amo)); + /* Compute amo = a - 1 for what follows... */ + MP_CHECKOK(mp_sub_d(a, 1, &amo)); + + b = mp_trailing_zeros(&amo); + if (!b) { /* a was even ? */ + res = MP_NO; + goto CLEANUP; } - /* Compute z = (x ** m) mod a */ - MP_CHECKOK( mp_exptmod(&x, &m, a, &z) ); - - if(mp_cmp_d(&z, 1) == 0 || mp_cmp(&z, &amo) == 0) { - res = MP_YES; - continue; - } - - res = MP_NO; /* just in case the following for loop never executes. */ - for (jx = 1; jx < b; jx++) { - /* z = z^2 (mod a) */ - MP_CHECKOK( mp_sqrmod(&z, a, &z) ); - res = MP_NO; /* previous line set res to MP_YES */ - - if(mp_cmp_d(&z, 1) == 0) { - break; - } - if(mp_cmp(&z, &amo) == 0) { - res = MP_YES; - break; - } - } /* end testing loop */ - - /* If the test passes, we will continue iterating, but a failed - test means the candidate is definitely NOT prime, so we will - immediately break out of this loop - */ - if(res == MP_NO) - break; - - } /* end iterations loop */ - + MP_CHECKOK(mp_init_size(&x, MP_USED(a))); + MP_CHECKOK(mp_init(&z)); + MP_CHECKOK(mp_init(&m)); + MP_CHECKOK(mp_div_2d(&amo, b, &m, 0)); + + /* Do the test nt times... */ + for (iter = 0; iter < nt; iter++) { + + /* Choose a random value for 1 < x < a */ + MP_CHECKOK(s_mp_pad(&x, USED(a))); + mpp_random(&x); + MP_CHECKOK(mp_mod(&x, a, &x)); + if (mp_cmp_d(&x, 1) <= 0) { + iter--; /* don't count this iteration */ + continue; /* choose a new x */ + } + + /* Compute z = (x ** m) mod a */ + MP_CHECKOK(mp_exptmod(&x, &m, a, &z)); + + if (mp_cmp_d(&z, 1) == 0 || mp_cmp(&z, &amo) == 0) { + res = MP_YES; + continue; + } + + res = MP_NO; /* just in case the following for loop never executes. */ + for (jx = 1; jx < b; jx++) { + /* z = z^2 (mod a) */ + MP_CHECKOK(mp_sqrmod(&z, a, &z)); + res = MP_NO; /* previous line set res to MP_YES */ + + if (mp_cmp_d(&z, 1) == 0) { + break; + } + if (mp_cmp(&z, &amo) == 0) { + res = MP_YES; + break; + } + } /* end testing loop */ + + /* If the test passes, we will continue iterating, but a failed + test means the candidate is definitely NOT prime, so we will + immediately break out of this loop + */ + if (res == MP_NO) + break; + + } /* end iterations loop */ + CLEANUP: - mp_clear(&m); - mp_clear(&z); - mp_clear(&x); - mp_clear(&amo); - return res; + mp_clear(&m); + mp_clear(&z); + mp_clear(&x); + mp_clear(&amo); + return res; } /* end mpp_pprime() */ /* }}} */ -/* Produce table of composites from list of primes and trial value. +/* Produce table of composites from list of primes and trial value. ** trial must be odd. List of primes must not include 2. -** sieve should have dimension >= MAXPRIME/2, where MAXPRIME is largest +** sieve should have dimension >= MAXPRIME/2, where MAXPRIME is largest ** prime in list of primes. After this function is finished, ** if sieve[i] is non-zero, then (trial + 2*i) is composite. ** Each prime used in the sieve costs one division of trial, and eliminates ** one or more values from the search space. (3 eliminates 1/3 of the values -** alone!) Each value left in the search space costs 1 or more modular +** alone!) Each value left in the search space costs 1 or more modular ** exponentations. So, these divisions are a bargain! */ -mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes, - unsigned char *sieve, mp_size nSieve) +mp_err +mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes, + unsigned char *sieve, mp_size nSieve) { - mp_err res; - mp_digit rem; - mp_size ix; - unsigned long offset; - - memset(sieve, 0, nSieve); - - for(ix = 0; ix < nPrimes; ix++) { - mp_digit prime = primes[ix]; - mp_size i; - if((res = mp_mod_d(trial, prime, &rem)) != MP_OKAY) - return res; - - if (rem == 0) { - offset = 0; - } else { - offset = prime - (rem / 2); - } - for (i = offset; i < nSieve ; i += prime) { - sieve[i] = 1; + mp_err res; + mp_digit rem; + mp_size ix; + unsigned long offset; + + memset(sieve, 0, nSieve); + + for (ix = 0; ix < nPrimes; ix++) { + mp_digit prime = primes[ix]; + mp_size i; + if ((res = mp_mod_d(trial, prime, &rem)) != MP_OKAY) + return res; + + if (rem == 0) { + offset = 0; + } else { + offset = prime - rem; + } + + for (i = offset; i < nSieve * 2; i += prime) { + if (i % 2 == 0) { + sieve[i / 2] = 1; + } + } } - } - return MP_OKAY; + return MP_OKAY; } -#define SIEVE_SIZE 32*1024 +#define SIEVE_SIZE 32 * 1024 -mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, - unsigned long * nTries) +mp_err +mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, + unsigned long *nTries) { - mp_digit np; - mp_err res; - unsigned int i = 0; - mp_int trial; - mp_int q; - mp_size num_tests; - unsigned char *sieve; - - ARGCHK(start != 0, MP_BADARG); - ARGCHK(nBits > 16, MP_RANGE); - - sieve = malloc(SIEVE_SIZE); - ARGCHK(sieve != NULL, MP_MEM); - - MP_DIGITS(&trial) = 0; - MP_DIGITS(&q) = 0; - MP_CHECKOK( mp_init(&trial) ); - MP_CHECKOK( mp_init(&q) ); - /* values taken from table 4.4, HandBook of Applied Cryptography */ - if (nBits >= 1300) { - num_tests = 2; - } else if (nBits >= 850) { - num_tests = 3; - } else if (nBits >= 650) { - num_tests = 4; - } else if (nBits >= 550) { - num_tests = 5; - } else if (nBits >= 450) { - num_tests = 6; - } else if (nBits >= 400) { - num_tests = 7; - } else if (nBits >= 350) { - num_tests = 8; - } else if (nBits >= 300) { - num_tests = 9; - } else if (nBits >= 250) { - num_tests = 12; - } else if (nBits >= 200) { - num_tests = 15; - } else if (nBits >= 150) { - num_tests = 18; - } else if (nBits >= 100) { - num_tests = 27; - } else - num_tests = 50; - - if (strong) - --nBits; - MP_CHECKOK( mpl_set_bit(start, nBits - 1, 1) ); - MP_CHECKOK( mpl_set_bit(start, 0, 1) ); - for (i = mpl_significant_bits(start) - 1; i >= nBits; --i) { - MP_CHECKOK( mpl_set_bit(start, i, 0) ); - } - /* start sieveing with prime value of 3. */ - MP_CHECKOK(mpp_sieve(start, prime_tab + 1, prime_tab_size - 1, - sieve, SIEVE_SIZE) ); + mp_digit np; + mp_err res; + unsigned int i = 0; + mp_int trial; + mp_int q; + mp_size num_tests; + unsigned char *sieve; + + ARGCHK(start != 0, MP_BADARG); + ARGCHK(nBits > 16, MP_RANGE); + + sieve = malloc(SIEVE_SIZE); + ARGCHK(sieve != NULL, MP_MEM); + + MP_DIGITS(&trial) = 0; + MP_DIGITS(&q) = 0; + MP_CHECKOK(mp_init(&trial)); + MP_CHECKOK(mp_init(&q)); + /* values originally taken from table 4.4, + * HandBook of Applied Cryptography, augmented by FIPS-186 + * requirements, Table C.2 and C.3 */ + if (nBits >= 2000) { + num_tests = 3; + } else if (nBits >= 1536) { + num_tests = 4; + } else if (nBits >= 1024) { + num_tests = 5; + } else if (nBits >= 550) { + num_tests = 6; + } else if (nBits >= 450) { + num_tests = 7; + } else if (nBits >= 400) { + num_tests = 8; + } else if (nBits >= 350) { + num_tests = 9; + } else if (nBits >= 300) { + num_tests = 10; + } else if (nBits >= 250) { + num_tests = 20; + } else if (nBits >= 200) { + num_tests = 41; + } else if (nBits >= 100) { + num_tests = 38; /* funny anomaly in the FIPS tables, for aux primes, the + * required more iterations for larger aux primes */ + } else + num_tests = 50; + + if (strong) + --nBits; + MP_CHECKOK(mpl_set_bit(start, nBits - 1, 1)); + MP_CHECKOK(mpl_set_bit(start, 0, 1)); + for (i = mpl_significant_bits(start) - 1; i >= nBits; --i) { + MP_CHECKOK(mpl_set_bit(start, i, 0)); + } + /* start sieveing with prime value of 3. */ + MP_CHECKOK(mpp_sieve(start, prime_tab + 1, prime_tab_size - 1, + sieve, SIEVE_SIZE)); #ifdef DEBUG_SIEVE - res = 0; - for (i = 0; i < SIEVE_SIZE; ++i) { - if (!sieve[i]) - ++res; - } - fprintf(stderr,"sieve found %d potential primes.\n", res); -#define FPUTC(x,y) fputc(x,y) + res = 0; + for (i = 0; i < SIEVE_SIZE; ++i) { + if (!sieve[i]) + ++res; + } + fprintf(stderr, "sieve found %d potential primes.\n", res); +#define FPUTC(x, y) fputc(x, y) #else -#define FPUTC(x,y) +#define FPUTC(x, y) #endif - res = MP_NO; - for(i = 0; i < SIEVE_SIZE; ++i) { - if (sieve[i]) /* this number is composite */ - continue; - MP_CHECKOK( mp_add_d(start, 2 * i, &trial) ); - FPUTC('.', stderr); - /* run a Fermat test */ - res = mpp_fermat(&trial, 2); - if (res != MP_OKAY) { - if (res == MP_NO) - continue; /* was composite */ - goto CLEANUP; - } - - FPUTC('+', stderr); - /* If that passed, run some Miller-Rabin tests */ - res = mpp_pprime(&trial, num_tests); - if (res != MP_OKAY) { - if (res == MP_NO) - continue; /* was composite */ - goto CLEANUP; - } - FPUTC('!', stderr); - - if (!strong) - break; /* success !! */ - - /* At this point, we have strong evidence that our candidate - is itself prime. If we want a strong prime, we need now - to test q = 2p + 1 for primality... - */ - MP_CHECKOK( mp_mul_2(&trial, &q) ); - MP_CHECKOK( mp_add_d(&q, 1, &q) ); - - /* Test q for small prime divisors ... */ - np = prime_tab_size; - res = mpp_divis_primes(&q, &np); - if (res == MP_YES) { /* is composite */ - mp_clear(&q); - continue; - } - if (res != MP_NO) - goto CLEANUP; - - /* And test with Fermat, as with its parent ... */ - res = mpp_fermat(&q, 2); - if (res != MP_YES) { - mp_clear(&q); - if (res == MP_NO) - continue; /* was composite */ - goto CLEANUP; - } - - /* And test with Miller-Rabin, as with its parent ... */ - res = mpp_pprime(&q, num_tests); - if (res != MP_YES) { - mp_clear(&q); - if (res == MP_NO) - continue; /* was composite */ - goto CLEANUP; - } - - /* If it passed, we've got a winner */ - mp_exch(&q, &trial); - mp_clear(&q); - break; - - } /* end of loop through sieved values */ - if (res == MP_YES) - mp_exch(&trial, start); + res = MP_NO; + for (i = 0; i < SIEVE_SIZE; ++i) { + if (sieve[i]) /* this number is composite */ + continue; + MP_CHECKOK(mp_add_d(start, 2 * i, &trial)); + FPUTC('.', stderr); + /* run a Fermat test */ + res = mpp_fermat(&trial, 2); + if (res != MP_OKAY) { + if (res == MP_NO) + continue; /* was composite */ + goto CLEANUP; + } + + FPUTC('+', stderr); + /* If that passed, run some Miller-Rabin tests */ + res = mpp_pprime(&trial, num_tests); + if (res != MP_OKAY) { + if (res == MP_NO) + continue; /* was composite */ + goto CLEANUP; + } + FPUTC('!', stderr); + + if (!strong) + break; /* success !! */ + + /* At this point, we have strong evidence that our candidate + is itself prime. If we want a strong prime, we need now + to test q = 2p + 1 for primality... + */ + MP_CHECKOK(mp_mul_2(&trial, &q)); + MP_CHECKOK(mp_add_d(&q, 1, &q)); + + /* Test q for small prime divisors ... */ + np = prime_tab_size; + res = mpp_divis_primes(&q, &np); + if (res == MP_YES) { /* is composite */ + mp_clear(&q); + continue; + } + if (res != MP_NO) + goto CLEANUP; + + /* And test with Fermat, as with its parent ... */ + res = mpp_fermat(&q, 2); + if (res != MP_YES) { + mp_clear(&q); + if (res == MP_NO) + continue; /* was composite */ + goto CLEANUP; + } + + /* And test with Miller-Rabin, as with its parent ... */ + res = mpp_pprime(&q, num_tests); + if (res != MP_YES) { + mp_clear(&q); + if (res == MP_NO) + continue; /* was composite */ + goto CLEANUP; + } + + /* If it passed, we've got a winner */ + mp_exch(&q, &trial); + mp_clear(&q); + break; + + } /* end of loop through sieved values */ + if (res == MP_YES) + mp_exch(&trial, start); CLEANUP: - mp_clear(&trial); - mp_clear(&q); - if (nTries) - *nTries += i; - if (sieve != NULL) { - memset(sieve, 0, SIEVE_SIZE); - free (sieve); - } - return res; + mp_clear(&trial); + mp_clear(&q); + if (nTries) + *nTries += i; + if (sieve != NULL) { + memset(sieve, 0, SIEVE_SIZE); + free(sieve); + } + return res; } /*========================================================================*/ @@ -549,32 +563,33 @@ CLEANUP: /* {{{ s_mpp_divp(a, vec, size, which) */ -/* +/* Test for divisibility by members of a vector of digits. Returns MP_NO if a is not divisible by any of them; returns MP_YES and sets 'which' to the index of the offender, if it is. Will stop on the first digit against which a is divisible. */ -mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which) +mp_err +s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which) { - mp_err res; - mp_digit rem; + mp_err res; + mp_digit rem; - int ix; + int ix; - for(ix = 0; ix < size; ix++) { - if((res = mp_mod_d(a, vec[ix], &rem)) != MP_OKAY) - return res; + for (ix = 0; ix < size; ix++) { + if ((res = mp_mod_d(a, vec[ix], &rem)) != MP_OKAY) + return res; - if(rem == 0) { - if(which) - *which = ix; - return MP_YES; + if (rem == 0) { + if (which) + *which = ix; + return MP_YES; + } } - } - return MP_NO; + return MP_NO; } /* end s_mpp_divp() */ diff --git a/nss/lib/freebl/mpi/mpprime.h b/nss/lib/freebl/mpi/mpprime.h index 805e0db..c47c618 100644 --- a/nss/lib/freebl/mpi/mpprime.h +++ b/nss/lib/freebl/mpi/mpprime.h @@ -13,26 +13,26 @@ #include "mpi.h" -extern const int prime_tab_size; /* number of primes available */ +extern const int prime_tab_size; /* number of primes available */ extern const mp_digit prime_tab[]; /* Tests for divisibility */ -mp_err mpp_divis(mp_int *a, mp_int *b); -mp_err mpp_divis_d(mp_int *a, mp_digit d); +mp_err mpp_divis(mp_int *a, mp_int *b); +mp_err mpp_divis_d(mp_int *a, mp_digit d); /* Random selection */ -mp_err mpp_random(mp_int *a); -mp_err mpp_random_size(mp_int *a, mp_size prec); +mp_err mpp_random(mp_int *a); +mp_err mpp_random_size(mp_int *a, mp_size prec); /* Pseudo-primality testing */ -mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which); -mp_err mpp_divis_primes(mp_int *a, mp_digit *np); -mp_err mpp_fermat(mp_int *a, mp_digit w); +mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which); +mp_err mpp_divis_primes(mp_int *a, mp_digit *np); +mp_err mpp_fermat(mp_int *a, mp_digit w); mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes); -mp_err mpp_pprime(mp_int *a, int nt); -mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes, - unsigned char *sieve, mp_size nSieve); +mp_err mpp_pprime(mp_int *a, int nt); +mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes, + unsigned char *sieve, mp_size nSieve); mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, - unsigned long * nTries); + unsigned long *nTries); #endif /* end _H_MP_PRIME_ */ diff --git a/nss/lib/freebl/mpi/mpv_sparc.c b/nss/lib/freebl/mpi/mpv_sparc.c index 07319b6..423311b 100644 --- a/nss/lib/freebl/mpi/mpv_sparc.c +++ b/nss/lib/freebl/mpi/mpv_sparc.c @@ -6,215 +6,216 @@ /***************************************************************/ -typedef int t_s32; -typedef unsigned int t_u32; +typedef int t_s32; +typedef unsigned int t_u32; #if defined(__sparcv9) -typedef long t_s64; -typedef unsigned long t_u64; +typedef long t_s64; +typedef unsigned long t_u64; #else -typedef long long t_s64; -typedef unsigned long long t_u64; +typedef long long t_s64; +typedef unsigned long long t_u64; #endif -typedef double t_d64; +typedef double t_d64; /***************************************************************/ typedef union { - t_d64 d64; - struct { - t_s32 i0; - t_s32 i1; - } i32s; + t_d64 d64; + struct { + t_s32 i0; + t_s32 i1; + } i32s; } d64_2_i32; /***************************************************************/ -#define BUFF_SIZE 256 +#define BUFF_SIZE 256 -#define A_BITS 19 -#define A_MASK ((1 << A_BITS) - 1) +#define A_BITS 19 +#define A_MASK ((1 << A_BITS) - 1) /***************************************************************/ static t_u64 mask_cnst[] = { - 0x8000000080000000ull + 0x8000000080000000ull }; /***************************************************************/ #define DEF_VARS(N) \ - t_d64 *py = (t_d64*)y; \ - t_d64 mask = *((t_d64*)mask_cnst); \ - t_d64 ca = (1u << 31) - 1; \ - t_d64 da = (t_d64)a; \ - t_s64 buff[N], s; \ - d64_2_i32 dy + t_d64 *py = (t_d64 *)y; \ + t_d64 mask = *((t_d64 *)mask_cnst); \ + t_d64 ca = (1u << 31) - 1; \ + t_d64 da = (t_d64)a; \ + t_s64 buff[N], s; \ + d64_2_i32 dy /***************************************************************/ -#define MUL_U32_S64_2(i) \ - dy.d64 = vis_fxnor(mask, py[i]); \ - buff[2*(i) ] = (ca - (t_d64)dy.i32s.i0) * da; \ - buff[2*(i)+1] = (ca - (t_d64)dy.i32s.i1) * da +#define MUL_U32_S64_2(i) \ + dy.d64 = vis_fxnor(mask, py[i]); \ + buff[2 * (i)] = (ca - (t_d64)dy.i32s.i0) * da; \ + buff[2 * (i) + 1] = (ca - (t_d64)dy.i32s.i1) * da -#define MUL_U32_S64_2_D(i) \ - dy.d64 = vis_fxnor(mask, py[i]); \ - d0 = ca - (t_d64)dy.i32s.i0; \ - d1 = ca - (t_d64)dy.i32s.i1; \ - buff[4*(i) ] = (t_s64)(d0 * da); \ - buff[4*(i)+1] = (t_s64)(d0 * db); \ - buff[4*(i)+2] = (t_s64)(d1 * da); \ - buff[4*(i)+3] = (t_s64)(d1 * db) +#define MUL_U32_S64_2_D(i) \ + dy.d64 = vis_fxnor(mask, py[i]); \ + d0 = ca - (t_d64)dy.i32s.i0; \ + d1 = ca - (t_d64)dy.i32s.i1; \ + buff[4 * (i)] = (t_s64)(d0 * da); \ + buff[4 * (i) + 1] = (t_s64)(d0 * db); \ + buff[4 * (i) + 2] = (t_s64)(d1 * da); \ + buff[4 * (i) + 3] = (t_s64)(d1 * db) /***************************************************************/ -#define ADD_S64_U32(i) \ - s = buff[i] + x[i] + c; \ - z[i] = s; \ - c = (s >> 32) +#define ADD_S64_U32(i) \ + s = buff[i] + x[i] + c; \ + z[i] = s; \ + c = (s >> 32) -#define ADD_S64_U32_D(i) \ - s = buff[2*(i)] +(((t_s64)(buff[2*(i)+1]))<<A_BITS) + x[i] + uc; \ - z[i] = s; \ - uc = ((t_u64)s >> 32) +#define ADD_S64_U32_D(i) \ + s = buff[2 * (i)] + (((t_s64)(buff[2 * (i) + 1])) << A_BITS) + x[i] + uc; \ + z[i] = s; \ + uc = ((t_u64)s >> 32) /***************************************************************/ -#define MUL_U32_S64_8(i) \ - MUL_U32_S64_2(i); \ - MUL_U32_S64_2(i+1); \ - MUL_U32_S64_2(i+2); \ - MUL_U32_S64_2(i+3) +#define MUL_U32_S64_8(i) \ + MUL_U32_S64_2(i); \ + MUL_U32_S64_2(i + 1); \ + MUL_U32_S64_2(i + 2); \ + MUL_U32_S64_2(i + 3) -#define MUL_U32_S64_D_8(i) \ - MUL_U32_S64_2_D(i); \ - MUL_U32_S64_2_D(i+1); \ - MUL_U32_S64_2_D(i+2); \ - MUL_U32_S64_2_D(i+3) +#define MUL_U32_S64_D_8(i) \ + MUL_U32_S64_2_D(i); \ + MUL_U32_S64_2_D(i + 1); \ + MUL_U32_S64_2_D(i + 2); \ + MUL_U32_S64_2_D(i + 3) /***************************************************************/ -#define ADD_S64_U32_8(i) \ - ADD_S64_U32(i); \ - ADD_S64_U32(i+1); \ - ADD_S64_U32(i+2); \ - ADD_S64_U32(i+3); \ - ADD_S64_U32(i+4); \ - ADD_S64_U32(i+5); \ - ADD_S64_U32(i+6); \ - ADD_S64_U32(i+7) - -#define ADD_S64_U32_D_8(i) \ - ADD_S64_U32_D(i); \ - ADD_S64_U32_D(i+1); \ - ADD_S64_U32_D(i+2); \ - ADD_S64_U32_D(i+3); \ - ADD_S64_U32_D(i+4); \ - ADD_S64_U32_D(i+5); \ - ADD_S64_U32_D(i+6); \ - ADD_S64_U32_D(i+7) +#define ADD_S64_U32_8(i) \ + ADD_S64_U32(i); \ + ADD_S64_U32(i + 1); \ + ADD_S64_U32(i + 2); \ + ADD_S64_U32(i + 3); \ + ADD_S64_U32(i + 4); \ + ADD_S64_U32(i + 5); \ + ADD_S64_U32(i + 6); \ + ADD_S64_U32(i + 7) + +#define ADD_S64_U32_D_8(i) \ + ADD_S64_U32_D(i); \ + ADD_S64_U32_D(i + 1); \ + ADD_S64_U32_D(i + 2); \ + ADD_S64_U32_D(i + 3); \ + ADD_S64_U32_D(i + 4); \ + ADD_S64_U32_D(i + 5); \ + ADD_S64_U32_D(i + 6); \ + ADD_S64_U32_D(i + 7) /***************************************************************/ -t_u32 mul_add(t_u32 *z, t_u32 *x, t_u32 *y, int n, t_u32 a) +t_u32 +mul_add(t_u32 *z, t_u32 *x, t_u32 *y, int n, t_u32 a) { - if (a < (1 << A_BITS)) { + if (a < (1 << A_BITS)) { - if (n == 8) { - DEF_VARS(8); - t_s32 c = 0; + if (n == 8) { + DEF_VARS(8); + t_s32 c = 0; - MUL_U32_S64_8(0); - ADD_S64_U32_8(0); + MUL_U32_S64_8(0); + ADD_S64_U32_8(0); - return c; + return c; - } else if (n == 16) { - DEF_VARS(16); - t_s32 c = 0; + } else if (n == 16) { + DEF_VARS(16); + t_s32 c = 0; - MUL_U32_S64_8(0); - MUL_U32_S64_8(4); - ADD_S64_U32_8(0); - ADD_S64_U32_8(8); + MUL_U32_S64_8(0); + MUL_U32_S64_8(4); + ADD_S64_U32_8(0); + ADD_S64_U32_8(8); - return c; + return c; - } else { - DEF_VARS(BUFF_SIZE); - t_s32 i, c = 0; + } else { + DEF_VARS(BUFF_SIZE); + t_s32 i, c = 0; #pragma pipeloop(0) - for (i = 0; i < (n+1)/2; i ++) { - MUL_U32_S64_2(i); - } + for (i = 0; i < (n + 1) / 2; i++) { + MUL_U32_S64_2(i); + } #pragma pipeloop(0) - for (i = 0; i < n; i ++) { - ADD_S64_U32(i); - } - - return c; + for (i = 0; i < n; i++) { + ADD_S64_U32(i); + } - } - } else { + return c; + } + } else { - if (n == 8) { - DEF_VARS(2*8); - t_d64 d0, d1, db; - t_u32 uc = 0; + if (n == 8) { + DEF_VARS(2 * 8); + t_d64 d0, d1, db; + t_u32 uc = 0; - da = (t_d64)(a & A_MASK); - db = (t_d64)(a >> A_BITS); + da = (t_d64)(a & A_MASK); + db = (t_d64)(a >> A_BITS); - MUL_U32_S64_D_8(0); - ADD_S64_U32_D_8(0); + MUL_U32_S64_D_8(0); + ADD_S64_U32_D_8(0); - return uc; + return uc; - } else if (n == 16) { - DEF_VARS(2*16); - t_d64 d0, d1, db; - t_u32 uc = 0; + } else if (n == 16) { + DEF_VARS(2 * 16); + t_d64 d0, d1, db; + t_u32 uc = 0; - da = (t_d64)(a & A_MASK); - db = (t_d64)(a >> A_BITS); + da = (t_d64)(a & A_MASK); + db = (t_d64)(a >> A_BITS); - MUL_U32_S64_D_8(0); - MUL_U32_S64_D_8(4); - ADD_S64_U32_D_8(0); - ADD_S64_U32_D_8(8); + MUL_U32_S64_D_8(0); + MUL_U32_S64_D_8(4); + ADD_S64_U32_D_8(0); + ADD_S64_U32_D_8(8); - return uc; + return uc; - } else { - DEF_VARS(2*BUFF_SIZE); - t_d64 d0, d1, db; - t_u32 i, uc = 0; + } else { + DEF_VARS(2 * BUFF_SIZE); + t_d64 d0, d1, db; + t_u32 i, uc = 0; - da = (t_d64)(a & A_MASK); - db = (t_d64)(a >> A_BITS); + da = (t_d64)(a & A_MASK); + db = (t_d64)(a >> A_BITS); #pragma pipeloop(0) - for (i = 0; i < (n+1)/2; i ++) { - MUL_U32_S64_2_D(i); - } + for (i = 0; i < (n + 1) / 2; i++) { + MUL_U32_S64_2_D(i); + } #pragma pipeloop(0) - for (i = 0; i < n; i ++) { - ADD_S64_U32_D(i); - } + for (i = 0; i < n; i++) { + ADD_S64_U32_D(i); + } - return uc; + return uc; + } } - } } /***************************************************************/ -t_u32 mul_add_inp(t_u32 *x, t_u32 *y, int n, t_u32 a) +t_u32 +mul_add_inp(t_u32 *x, t_u32 *y, int n, t_u32 a) { - return mul_add(x, x, y, n, a); + return mul_add(x, x, y, n, a); } /***************************************************************/ diff --git a/nss/lib/freebl/mpi/mpvalpha.c b/nss/lib/freebl/mpi/mpvalpha.c index 943064d..94e86ee 100644 --- a/nss/lib/freebl/mpi/mpvalpha.c +++ b/nss/lib/freebl/mpi/mpvalpha.c @@ -5,104 +5,104 @@ #include "mpi-priv.h" #include <c_asm.h> +#define MP_MUL_DxD(a, b, Phi, Plo) \ + { \ + Plo = asm("mulq %a0, %a1, %v0", a, b); \ + Phi = asm("umulh %a0, %a1, %v0", a, b); \ + } -#define MP_MUL_DxD(a, b, Phi, Plo) \ - { Plo = asm ("mulq %a0, %a1, %v0", a, b); \ - Phi = asm ("umulh %a0, %a1, %v0", a, b); } \ - -/* This is empty for the loop in s_mpv_mul_d */ +/* This is empty for the loop in s_mpv_mul_d */ #define CARRY_ADD -#define ONE_MUL \ - a_i = *a++; \ - MP_MUL_DxD(a_i, b, a1b1, a0b0); \ - a0b0 += carry; \ - if (a0b0 < carry) \ - ++a1b1; \ - CARRY_ADD \ - *c++ = a0b0; \ - carry = a1b1; \ - -#define FOUR_MUL \ - ONE_MUL \ - ONE_MUL \ - ONE_MUL \ - ONE_MUL \ - -#define SIXTEEN_MUL \ - FOUR_MUL \ - FOUR_MUL \ - FOUR_MUL \ - FOUR_MUL \ - -#define THIRTYTWO_MUL \ - SIXTEEN_MUL \ - SIXTEEN_MUL \ - -#define ONETWENTYEIGHT_MUL \ - THIRTYTWO_MUL \ - THIRTYTWO_MUL \ - THIRTYTWO_MUL \ - THIRTYTWO_MUL \ - - -#define EXPAND_256(CALL) \ - mp_digit carry = 0; \ - mp_digit a_i; \ - mp_digit a0b0, a1b1; \ - if (a_len &255) { \ - if (a_len &1) { \ - ONE_MUL \ - } \ - if (a_len &2) { \ - ONE_MUL \ - ONE_MUL \ - } \ - if (a_len &4) { \ - FOUR_MUL \ - } \ - if (a_len &8) { \ - FOUR_MUL \ - FOUR_MUL \ - } \ - if (a_len & 16 ) { \ - SIXTEEN_MUL \ - } \ - if (a_len & 32 ) { \ - THIRTYTWO_MUL \ - } \ - if (a_len & 64 ) { \ - THIRTYTWO_MUL \ - THIRTYTWO_MUL \ - } \ - if (a_len & 128) { \ - ONETWENTYEIGHT_MUL \ - } \ - a_len = a_len & (-256); \ - } \ - if (a_len>=256 ) { \ - carry = CALL(a, a_len, b, c, carry); \ - c += a_len; \ - } \ - -#define FUNC_NAME(NAME) \ -mp_digit NAME(const mp_digit *a, \ - mp_size a_len, \ - mp_digit b, mp_digit *c, \ - mp_digit carry) \ - -#define DECLARE_MUL_256(FNAME) \ -FUNC_NAME(FNAME) \ -{ \ - mp_digit a_i; \ - mp_digit a0b0, a1b1; \ - while (a_len) { \ - ONETWENTYEIGHT_MUL \ - ONETWENTYEIGHT_MUL \ - a_len-= 256; \ - } \ - return carry; \ -} \ +#define ONE_MUL \ + a_i = *a++; \ + MP_MUL_DxD(a_i, b, a1b1, a0b0); \ + a0b0 += carry; \ + if (a0b0 < carry) \ + ++a1b1; \ + CARRY_ADD \ + *c++ = a0b0; \ + carry = a1b1; + +#define FOUR_MUL \ + ONE_MUL \ + ONE_MUL \ + ONE_MUL \ + ONE_MUL + +#define SIXTEEN_MUL \ + FOUR_MUL \ + FOUR_MUL \ + FOUR_MUL \ + FOUR_MUL + +#define THIRTYTWO_MUL \ + SIXTEEN_MUL \ + SIXTEEN_MUL + +#define ONETWENTYEIGHT_MUL \ + THIRTYTWO_MUL \ + THIRTYTWO_MUL \ + THIRTYTWO_MUL \ + THIRTYTWO_MUL + +#define EXPAND_256(CALL) \ + mp_digit carry = 0; \ + mp_digit a_i; \ + mp_digit a0b0, a1b1; \ + if (a_len & 255) { \ + if (a_len & 1) { \ + ONE_MUL \ + } \ + if (a_len & 2) { \ + ONE_MUL \ + ONE_MUL \ + } \ + if (a_len & 4) { \ + FOUR_MUL \ + } \ + if (a_len & 8) { \ + FOUR_MUL \ + FOUR_MUL \ + } \ + if (a_len & 16) { \ + SIXTEEN_MUL \ + } \ + if (a_len & 32) { \ + THIRTYTWO_MUL \ + } \ + if (a_len & 64) { \ + THIRTYTWO_MUL \ + THIRTYTWO_MUL \ + } \ + if (a_len & 128) { \ + ONETWENTYEIGHT_MUL \ + } \ + a_len = a_len & (-256); \ + } \ + if (a_len >= 256) { \ + carry = CALL(a, a_len, b, c, carry); \ + c += a_len; \ + } + +#define FUNC_NAME(NAME) \ + mp_digit NAME(const mp_digit *a, \ + mp_size a_len, \ + mp_digit b, mp_digit *c, \ + mp_digit carry) + +#define DECLARE_MUL_256(FNAME) \ + FUNC_NAME(FNAME) \ + { \ + mp_digit a_i; \ + mp_digit a0b0, a1b1; \ + while (a_len) { \ + ONETWENTYEIGHT_MUL \ + ONETWENTYEIGHT_MUL \ + a_len -= 256; \ + } \ + return carry; \ + } /* Expanding the loop in s_mpv_mul_d appeared to slow down the (admittedly) small number of tests (i.e., timetest) used to @@ -110,33 +110,34 @@ FUNC_NAME(FNAME) \ #define DO_NOT_EXPAND 1 /* Need forward declaration so it can be instantiated after - the routine that uses it; this helps locality somewhat */ + the routine that uses it; this helps locality somewhat */ #if !defined(DO_NOT_EXPAND) FUNC_NAME(s_mpv_mul_d_MUL256); #endif /* c = a * b */ -void s_mpv_mul_d(const mp_digit *a, mp_size a_len, - mp_digit b, mp_digit *c) +void +s_mpv_mul_d(const mp_digit *a, mp_size a_len, + mp_digit b, mp_digit *c) { #if defined(DO_NOT_EXPAND) - mp_digit carry = 0; - while (a_len--) { - mp_digit a_i = *a++; - mp_digit a0b0, a1b1; - - MP_MUL_DxD(a_i, b, a1b1, a0b0); - - a0b0 += carry; - if (a0b0 < carry) - ++a1b1; - *c++ = a0b0; - carry = a1b1; - } + mp_digit carry = 0; + while (a_len--) { + mp_digit a_i = *a++; + mp_digit a0b0, a1b1; + + MP_MUL_DxD(a_i, b, a1b1, a0b0); + + a0b0 += carry; + if (a0b0 < carry) + ++a1b1; + *c++ = a0b0; + carry = a1b1; + } #else - EXPAND_256(s_mpv_mul_d_MUL256) + EXPAND_256(s_mpv_mul_d_MUL256) #endif - *c = carry; + *c = carry; } #if !defined(DO_NOT_EXPAND) @@ -145,21 +146,22 @@ DECLARE_MUL_256(s_mpv_mul_d_MUL256) #undef CARRY_ADD /* This is redefined for the loop in s_mpv_mul_d_add */ -#define CARRY_ADD \ - a0b0 += a_i = *c; \ - if (a0b0 < a_i) \ - ++a1b1; \ +#define CARRY_ADD \ + a0b0 += a_i = *c; \ + if (a0b0 < a_i) \ + ++a1b1; /* Need forward declaration so it can be instantiated between the - two routines that use it; this helps locality somewhat */ + two routines that use it; this helps locality somewhat */ FUNC_NAME(s_mpv_mul_d_add_MUL256); /* c += a * b */ -void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, - mp_digit b, mp_digit *c) +void +s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, + mp_digit b, mp_digit *c) { - EXPAND_256(s_mpv_mul_d_add_MUL256) - *c = carry; + EXPAND_256(s_mpv_mul_d_add_MUL256) + *c = carry; } /* Instantiate multiply 256 routine here */ @@ -167,15 +169,15 @@ DECLARE_MUL_256(s_mpv_mul_d_add_MUL256) /* Presently, this is only used by the Montgomery arithmetic code. */ /* c += a * b */ -void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, - mp_digit b, mp_digit *c) +void +s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, + mp_digit b, mp_digit *c) { - EXPAND_256(s_mpv_mul_d_add_MUL256) - while (carry) { - mp_digit c_i = *c; - carry += c_i; - *c++ = carry; - carry = carry < c_i; - } + EXPAND_256(s_mpv_mul_d_add_MUL256) + while (carry) { + mp_digit c_i = *c; + carry += c_i; + *c++ = carry; + carry = carry < c_i; + } } - diff --git a/nss/lib/freebl/mpi/mulsqr.c b/nss/lib/freebl/mpi/mulsqr.c index 702ad24..461d40a 100644 --- a/nss/lib/freebl/mpi/mulsqr.c +++ b/nss/lib/freebl/mpi/mulsqr.c @@ -10,74 +10,75 @@ #include <limits.h> #include <time.h> -#define MP_SQUARE 1 /* make sure squaring code is included */ +#define MP_SQUARE 1 /* make sure squaring code is included */ #include "mpi.h" #include "mpprime.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ntests, prec, ix; - unsigned int seed; - clock_t start, stop; - double multime, sqrtime; - mp_int a, c; - - seed = (unsigned int)time(NULL); - - if(argc < 3) { - fprintf(stderr, "Usage: %s <ntests> <nbits>\n", argv[0]); - return 1; - } - - if((ntests = abs(atoi(argv[1]))) == 0) { - fprintf(stderr, "%s: must request at least 1 test.\n", argv[0]); - return 1; - } - if((prec = abs(atoi(argv[2]))) < CHAR_BIT) { - fprintf(stderr, "%s: must request at least %d bits.\n", argv[0], - CHAR_BIT); - return 1; - } - - prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT; - - mp_init_size(&a, prec); - mp_init_size(&c, 2 * prec); - - /* Test multiplication by self */ - srand(seed); - start = clock(); - for(ix = 0; ix < ntests; ix++) { - mpp_random_size(&a, prec); - mp_mul(&a, &a, &c); - } - stop = clock(); - - multime = (double)(stop - start) / CLOCKS_PER_SEC; - - /* Test squaring */ - srand(seed); - start = clock(); - for(ix = 0; ix < ntests; ix++) { - mpp_random_size(&a, prec); - mp_sqr(&a, &c); - } - stop = clock(); - - sqrtime = (double)(stop - start) / CLOCKS_PER_SEC; - - printf("Multiply: %.4f\n", multime); - printf("Square: %.4f\n", sqrtime); - if(multime < sqrtime) { - printf("Speedup: %.1f%%\n", 100.0 * (1.0 - multime / sqrtime)); - printf("Prefer: multiply\n"); - } else { - printf("Speedup: %.1f%%\n", 100.0 * (1.0 - sqrtime / multime)); - printf("Prefer: square\n"); - } - - mp_clear(&a); mp_clear(&c); - return 0; - + int ntests, prec, ix; + unsigned int seed; + clock_t start, stop; + double multime, sqrtime; + mp_int a, c; + + seed = (unsigned int)time(NULL); + + if (argc < 3) { + fprintf(stderr, "Usage: %s <ntests> <nbits>\n", argv[0]); + return 1; + } + + if ((ntests = abs(atoi(argv[1]))) == 0) { + fprintf(stderr, "%s: must request at least 1 test.\n", argv[0]); + return 1; + } + if ((prec = abs(atoi(argv[2]))) < CHAR_BIT) { + fprintf(stderr, "%s: must request at least %d bits.\n", argv[0], + CHAR_BIT); + return 1; + } + + prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT; + + mp_init_size(&a, prec); + mp_init_size(&c, 2 * prec); + + /* Test multiplication by self */ + srand(seed); + start = clock(); + for (ix = 0; ix < ntests; ix++) { + mpp_random_size(&a, prec); + mp_mul(&a, &a, &c); + } + stop = clock(); + + multime = (double)(stop - start) / CLOCKS_PER_SEC; + + /* Test squaring */ + srand(seed); + start = clock(); + for (ix = 0; ix < ntests; ix++) { + mpp_random_size(&a, prec); + mp_sqr(&a, &c); + } + stop = clock(); + + sqrtime = (double)(stop - start) / CLOCKS_PER_SEC; + + printf("Multiply: %.4f\n", multime); + printf("Square: %.4f\n", sqrtime); + if (multime < sqrtime) { + printf("Speedup: %.1f%%\n", 100.0 * (1.0 - multime / sqrtime)); + printf("Prefer: multiply\n"); + } else { + printf("Speedup: %.1f%%\n", 100.0 * (1.0 - sqrtime / multime)); + printf("Prefer: square\n"); + } + + mp_clear(&a); + mp_clear(&c); + return 0; } diff --git a/nss/lib/freebl/mpi/primes.c b/nss/lib/freebl/mpi/primes.c index 58536ad..c8bd93f 100644 --- a/nss/lib/freebl/mpi/primes.c +++ b/nss/lib/freebl/mpi/primes.c @@ -1,6 +1,6 @@ /* * These tables of primes wwere generated using the 'sieve' program - * (sieve.c) and converted to this format with 'ptab.pl'. + * (sieve.c) and converted to this format with 'ptab.pl'. * * The 'small' table is just the first 128 primes. The 'large' table * is a table of all the prime values that will fit into a single @@ -17,826 +17,825 @@ #endif const int prime_tab_size = MP_PRIME_TAB_SIZE; -const mp_digit prime_tab[] = { - 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, - 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, - 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, - 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083, - 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, - 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, - 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, - 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, - 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, - 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, - 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, - 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, - 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, - 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, - 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, - 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, -#if ! SMALL_TABLE - 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, - 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, - 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, - 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, - 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, - 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, - 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, - 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, - 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, - 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, - 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, - 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, - 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, - 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, - 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, - 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653, - 0x0655, 0x065B, 0x0665, 0x0679, 0x067F, 0x0683, 0x0685, 0x069D, - 0x06A1, 0x06A3, 0x06AD, 0x06B9, 0x06BB, 0x06C5, 0x06CD, 0x06D3, - 0x06D9, 0x06DF, 0x06F1, 0x06F7, 0x06FB, 0x06FD, 0x0709, 0x0713, - 0x071F, 0x0727, 0x0737, 0x0745, 0x074B, 0x074F, 0x0751, 0x0755, - 0x0757, 0x0761, 0x076D, 0x0773, 0x0779, 0x078B, 0x078D, 0x079D, - 0x079F, 0x07B5, 0x07BB, 0x07C3, 0x07C9, 0x07CD, 0x07CF, 0x07D3, - 0x07DB, 0x07E1, 0x07EB, 0x07ED, 0x07F7, 0x0805, 0x080F, 0x0815, - 0x0821, 0x0823, 0x0827, 0x0829, 0x0833, 0x083F, 0x0841, 0x0851, - 0x0853, 0x0859, 0x085D, 0x085F, 0x0869, 0x0871, 0x0883, 0x089B, - 0x089F, 0x08A5, 0x08AD, 0x08BD, 0x08BF, 0x08C3, 0x08CB, 0x08DB, - 0x08DD, 0x08E1, 0x08E9, 0x08EF, 0x08F5, 0x08F9, 0x0905, 0x0907, - 0x091D, 0x0923, 0x0925, 0x092B, 0x092F, 0x0935, 0x0943, 0x0949, - 0x094D, 0x094F, 0x0955, 0x0959, 0x095F, 0x096B, 0x0971, 0x0977, - 0x0985, 0x0989, 0x098F, 0x099B, 0x09A3, 0x09A9, 0x09AD, 0x09C7, - 0x09D9, 0x09E3, 0x09EB, 0x09EF, 0x09F5, 0x09F7, 0x09FD, 0x0A13, - 0x0A1F, 0x0A21, 0x0A31, 0x0A39, 0x0A3D, 0x0A49, 0x0A57, 0x0A61, - 0x0A63, 0x0A67, 0x0A6F, 0x0A75, 0x0A7B, 0x0A7F, 0x0A81, 0x0A85, - 0x0A8B, 0x0A93, 0x0A97, 0x0A99, 0x0A9F, 0x0AA9, 0x0AAB, 0x0AB5, - 0x0ABD, 0x0AC1, 0x0ACF, 0x0AD9, 0x0AE5, 0x0AE7, 0x0AED, 0x0AF1, - 0x0AF3, 0x0B03, 0x0B11, 0x0B15, 0x0B1B, 0x0B23, 0x0B29, 0x0B2D, - 0x0B3F, 0x0B47, 0x0B51, 0x0B57, 0x0B5D, 0x0B65, 0x0B6F, 0x0B7B, - 0x0B89, 0x0B8D, 0x0B93, 0x0B99, 0x0B9B, 0x0BB7, 0x0BB9, 0x0BC3, - 0x0BCB, 0x0BCF, 0x0BDD, 0x0BE1, 0x0BE9, 0x0BF5, 0x0BFB, 0x0C07, - 0x0C0B, 0x0C11, 0x0C25, 0x0C2F, 0x0C31, 0x0C41, 0x0C5B, 0x0C5F, - 0x0C61, 0x0C6D, 0x0C73, 0x0C77, 0x0C83, 0x0C89, 0x0C91, 0x0C95, - 0x0C9D, 0x0CB3, 0x0CB5, 0x0CB9, 0x0CBB, 0x0CC7, 0x0CE3, 0x0CE5, - 0x0CEB, 0x0CF1, 0x0CF7, 0x0CFB, 0x0D01, 0x0D03, 0x0D0F, 0x0D13, - 0x0D1F, 0x0D21, 0x0D2B, 0x0D2D, 0x0D3D, 0x0D3F, 0x0D4F, 0x0D55, - 0x0D69, 0x0D79, 0x0D81, 0x0D85, 0x0D87, 0x0D8B, 0x0D8D, 0x0DA3, - 0x0DAB, 0x0DB7, 0x0DBD, 0x0DC7, 0x0DC9, 0x0DCD, 0x0DD3, 0x0DD5, - 0x0DDB, 0x0DE5, 0x0DE7, 0x0DF3, 0x0DFD, 0x0DFF, 0x0E09, 0x0E17, - 0x0E1D, 0x0E21, 0x0E27, 0x0E2F, 0x0E35, 0x0E3B, 0x0E4B, 0x0E57, - 0x0E59, 0x0E5D, 0x0E6B, 0x0E71, 0x0E75, 0x0E7D, 0x0E87, 0x0E8F, - 0x0E95, 0x0E9B, 0x0EB1, 0x0EB7, 0x0EB9, 0x0EC3, 0x0ED1, 0x0ED5, - 0x0EDB, 0x0EED, 0x0EEF, 0x0EF9, 0x0F07, 0x0F0B, 0x0F0D, 0x0F17, - 0x0F25, 0x0F29, 0x0F31, 0x0F43, 0x0F47, 0x0F4D, 0x0F4F, 0x0F53, - 0x0F59, 0x0F5B, 0x0F67, 0x0F6B, 0x0F7F, 0x0F95, 0x0FA1, 0x0FA3, - 0x0FA7, 0x0FAD, 0x0FB3, 0x0FB5, 0x0FBB, 0x0FD1, 0x0FD3, 0x0FD9, - 0x0FE9, 0x0FEF, 0x0FFB, 0x0FFD, 0x1003, 0x100F, 0x101F, 0x1021, - 0x1025, 0x102B, 0x1039, 0x103D, 0x103F, 0x1051, 0x1069, 0x1073, - 0x1079, 0x107B, 0x1085, 0x1087, 0x1091, 0x1093, 0x109D, 0x10A3, - 0x10A5, 0x10AF, 0x10B1, 0x10BB, 0x10C1, 0x10C9, 0x10E7, 0x10F1, - 0x10F3, 0x10FD, 0x1105, 0x110B, 0x1115, 0x1127, 0x112D, 0x1139, - 0x1145, 0x1147, 0x1159, 0x115F, 0x1163, 0x1169, 0x116F, 0x1181, - 0x1183, 0x118D, 0x119B, 0x11A1, 0x11A5, 0x11A7, 0x11AB, 0x11C3, - 0x11C5, 0x11D1, 0x11D7, 0x11E7, 0x11EF, 0x11F5, 0x11FB, 0x120D, - 0x121D, 0x121F, 0x1223, 0x1229, 0x122B, 0x1231, 0x1237, 0x1241, - 0x1247, 0x1253, 0x125F, 0x1271, 0x1273, 0x1279, 0x127D, 0x128F, - 0x1297, 0x12AF, 0x12B3, 0x12B5, 0x12B9, 0x12BF, 0x12C1, 0x12CD, - 0x12D1, 0x12DF, 0x12FD, 0x1307, 0x130D, 0x1319, 0x1327, 0x132D, - 0x1337, 0x1343, 0x1345, 0x1349, 0x134F, 0x1357, 0x135D, 0x1367, - 0x1369, 0x136D, 0x137B, 0x1381, 0x1387, 0x138B, 0x1391, 0x1393, - 0x139D, 0x139F, 0x13AF, 0x13BB, 0x13C3, 0x13D5, 0x13D9, 0x13DF, - 0x13EB, 0x13ED, 0x13F3, 0x13F9, 0x13FF, 0x141B, 0x1421, 0x142F, - 0x1433, 0x143B, 0x1445, 0x144D, 0x1459, 0x146B, 0x146F, 0x1471, - 0x1475, 0x148D, 0x1499, 0x149F, 0x14A1, 0x14B1, 0x14B7, 0x14BD, - 0x14CB, 0x14D5, 0x14E3, 0x14E7, 0x1505, 0x150B, 0x1511, 0x1517, - 0x151F, 0x1525, 0x1529, 0x152B, 0x1537, 0x153D, 0x1541, 0x1543, - 0x1549, 0x155F, 0x1565, 0x1567, 0x156B, 0x157D, 0x157F, 0x1583, - 0x158F, 0x1591, 0x1597, 0x159B, 0x15B5, 0x15BB, 0x15C1, 0x15C5, - 0x15CD, 0x15D7, 0x15F7, 0x1607, 0x1609, 0x160F, 0x1613, 0x1615, - 0x1619, 0x161B, 0x1625, 0x1633, 0x1639, 0x163D, 0x1645, 0x164F, - 0x1655, 0x1669, 0x166D, 0x166F, 0x1675, 0x1693, 0x1697, 0x169F, - 0x16A9, 0x16AF, 0x16B5, 0x16BD, 0x16C3, 0x16CF, 0x16D3, 0x16D9, - 0x16DB, 0x16E1, 0x16E5, 0x16EB, 0x16ED, 0x16F7, 0x16F9, 0x1709, - 0x170F, 0x1723, 0x1727, 0x1733, 0x1741, 0x175D, 0x1763, 0x1777, - 0x177B, 0x178D, 0x1795, 0x179B, 0x179F, 0x17A5, 0x17B3, 0x17B9, - 0x17BF, 0x17C9, 0x17CB, 0x17D5, 0x17E1, 0x17E9, 0x17F3, 0x17F5, - 0x17FF, 0x1807, 0x1813, 0x181D, 0x1835, 0x1837, 0x183B, 0x1843, - 0x1849, 0x184D, 0x1855, 0x1867, 0x1871, 0x1877, 0x187D, 0x187F, - 0x1885, 0x188F, 0x189B, 0x189D, 0x18A7, 0x18AD, 0x18B3, 0x18B9, - 0x18C1, 0x18C7, 0x18D1, 0x18D7, 0x18D9, 0x18DF, 0x18E5, 0x18EB, - 0x18F5, 0x18FD, 0x1915, 0x191B, 0x1931, 0x1933, 0x1945, 0x1949, - 0x1951, 0x195B, 0x1979, 0x1981, 0x1993, 0x1997, 0x1999, 0x19A3, - 0x19A9, 0x19AB, 0x19B1, 0x19B5, 0x19C7, 0x19CF, 0x19DB, 0x19ED, - 0x19FD, 0x1A03, 0x1A05, 0x1A11, 0x1A17, 0x1A21, 0x1A23, 0x1A2D, - 0x1A2F, 0x1A35, 0x1A3F, 0x1A4D, 0x1A51, 0x1A69, 0x1A6B, 0x1A7B, - 0x1A7D, 0x1A87, 0x1A89, 0x1A93, 0x1AA7, 0x1AAB, 0x1AAD, 0x1AB1, - 0x1AB9, 0x1AC9, 0x1ACF, 0x1AD5, 0x1AD7, 0x1AE3, 0x1AF3, 0x1AFB, - 0x1AFF, 0x1B05, 0x1B23, 0x1B25, 0x1B2F, 0x1B31, 0x1B37, 0x1B3B, - 0x1B41, 0x1B47, 0x1B4F, 0x1B55, 0x1B59, 0x1B65, 0x1B6B, 0x1B73, - 0x1B7F, 0x1B83, 0x1B91, 0x1B9D, 0x1BA7, 0x1BBF, 0x1BC5, 0x1BD1, - 0x1BD7, 0x1BD9, 0x1BEF, 0x1BF7, 0x1C09, 0x1C13, 0x1C19, 0x1C27, - 0x1C2B, 0x1C2D, 0x1C33, 0x1C3D, 0x1C45, 0x1C4B, 0x1C4F, 0x1C55, - 0x1C73, 0x1C81, 0x1C8B, 0x1C8D, 0x1C99, 0x1CA3, 0x1CA5, 0x1CB5, - 0x1CB7, 0x1CC9, 0x1CE1, 0x1CF3, 0x1CF9, 0x1D09, 0x1D1B, 0x1D21, - 0x1D23, 0x1D35, 0x1D39, 0x1D3F, 0x1D41, 0x1D4B, 0x1D53, 0x1D5D, - 0x1D63, 0x1D69, 0x1D71, 0x1D75, 0x1D7B, 0x1D7D, 0x1D87, 0x1D89, - 0x1D95, 0x1D99, 0x1D9F, 0x1DA5, 0x1DA7, 0x1DB3, 0x1DB7, 0x1DC5, - 0x1DD7, 0x1DDB, 0x1DE1, 0x1DF5, 0x1DF9, 0x1E01, 0x1E07, 0x1E0B, - 0x1E13, 0x1E17, 0x1E25, 0x1E2B, 0x1E2F, 0x1E3D, 0x1E49, 0x1E4D, - 0x1E4F, 0x1E6D, 0x1E71, 0x1E89, 0x1E8F, 0x1E95, 0x1EA1, 0x1EAD, - 0x1EBB, 0x1EC1, 0x1EC5, 0x1EC7, 0x1ECB, 0x1EDD, 0x1EE3, 0x1EEF, - 0x1EF7, 0x1EFD, 0x1F01, 0x1F0D, 0x1F0F, 0x1F1B, 0x1F39, 0x1F49, - 0x1F4B, 0x1F51, 0x1F67, 0x1F75, 0x1F7B, 0x1F85, 0x1F91, 0x1F97, - 0x1F99, 0x1F9D, 0x1FA5, 0x1FAF, 0x1FB5, 0x1FBB, 0x1FD3, 0x1FE1, - 0x1FE7, 0x1FEB, 0x1FF3, 0x1FFF, 0x2011, 0x201B, 0x201D, 0x2027, - 0x2029, 0x202D, 0x2033, 0x2047, 0x204D, 0x2051, 0x205F, 0x2063, - 0x2065, 0x2069, 0x2077, 0x207D, 0x2089, 0x20A1, 0x20AB, 0x20B1, - 0x20B9, 0x20C3, 0x20C5, 0x20E3, 0x20E7, 0x20ED, 0x20EF, 0x20FB, - 0x20FF, 0x210D, 0x2113, 0x2135, 0x2141, 0x2149, 0x214F, 0x2159, - 0x215B, 0x215F, 0x2173, 0x217D, 0x2185, 0x2195, 0x2197, 0x21A1, - 0x21AF, 0x21B3, 0x21B5, 0x21C1, 0x21C7, 0x21D7, 0x21DD, 0x21E5, - 0x21E9, 0x21F1, 0x21F5, 0x21FB, 0x2203, 0x2209, 0x220F, 0x221B, - 0x2221, 0x2225, 0x222B, 0x2231, 0x2239, 0x224B, 0x224F, 0x2263, - 0x2267, 0x2273, 0x2275, 0x227F, 0x2285, 0x2287, 0x2291, 0x229D, - 0x229F, 0x22A3, 0x22B7, 0x22BD, 0x22DB, 0x22E1, 0x22E5, 0x22ED, - 0x22F7, 0x2303, 0x2309, 0x230B, 0x2327, 0x2329, 0x232F, 0x2333, - 0x2335, 0x2345, 0x2351, 0x2353, 0x2359, 0x2363, 0x236B, 0x2383, - 0x238F, 0x2395, 0x23A7, 0x23AD, 0x23B1, 0x23BF, 0x23C5, 0x23C9, - 0x23D5, 0x23DD, 0x23E3, 0x23EF, 0x23F3, 0x23F9, 0x2405, 0x240B, - 0x2417, 0x2419, 0x2429, 0x243D, 0x2441, 0x2443, 0x244D, 0x245F, - 0x2467, 0x246B, 0x2479, 0x247D, 0x247F, 0x2485, 0x249B, 0x24A1, - 0x24AF, 0x24B5, 0x24BB, 0x24C5, 0x24CB, 0x24CD, 0x24D7, 0x24D9, - 0x24DD, 0x24DF, 0x24F5, 0x24F7, 0x24FB, 0x2501, 0x2507, 0x2513, - 0x2519, 0x2527, 0x2531, 0x253D, 0x2543, 0x254B, 0x254F, 0x2573, - 0x2581, 0x258D, 0x2593, 0x2597, 0x259D, 0x259F, 0x25AB, 0x25B1, - 0x25BD, 0x25CD, 0x25CF, 0x25D9, 0x25E1, 0x25F7, 0x25F9, 0x2605, - 0x260B, 0x260F, 0x2615, 0x2627, 0x2629, 0x2635, 0x263B, 0x263F, - 0x264B, 0x2653, 0x2659, 0x2665, 0x2669, 0x266F, 0x267B, 0x2681, - 0x2683, 0x268F, 0x269B, 0x269F, 0x26AD, 0x26B3, 0x26C3, 0x26C9, - 0x26CB, 0x26D5, 0x26DD, 0x26EF, 0x26F5, 0x2717, 0x2719, 0x2735, - 0x2737, 0x274D, 0x2753, 0x2755, 0x275F, 0x276B, 0x276D, 0x2773, - 0x2777, 0x277F, 0x2795, 0x279B, 0x279D, 0x27A7, 0x27AF, 0x27B3, - 0x27B9, 0x27C1, 0x27C5, 0x27D1, 0x27E3, 0x27EF, 0x2803, 0x2807, - 0x280D, 0x2813, 0x281B, 0x281F, 0x2821, 0x2831, 0x283D, 0x283F, - 0x2849, 0x2851, 0x285B, 0x285D, 0x2861, 0x2867, 0x2875, 0x2881, - 0x2897, 0x289F, 0x28BB, 0x28BD, 0x28C1, 0x28D5, 0x28D9, 0x28DB, - 0x28DF, 0x28ED, 0x28F7, 0x2903, 0x2905, 0x2911, 0x2921, 0x2923, - 0x293F, 0x2947, 0x295D, 0x2965, 0x2969, 0x296F, 0x2975, 0x2983, - 0x2987, 0x298F, 0x299B, 0x29A1, 0x29A7, 0x29AB, 0x29BF, 0x29C3, - 0x29D5, 0x29D7, 0x29E3, 0x29E9, 0x29ED, 0x29F3, 0x2A01, 0x2A13, - 0x2A1D, 0x2A25, 0x2A2F, 0x2A4F, 0x2A55, 0x2A5F, 0x2A65, 0x2A6B, - 0x2A6D, 0x2A73, 0x2A83, 0x2A89, 0x2A8B, 0x2A97, 0x2A9D, 0x2AB9, - 0x2ABB, 0x2AC5, 0x2ACD, 0x2ADD, 0x2AE3, 0x2AEB, 0x2AF1, 0x2AFB, - 0x2B13, 0x2B27, 0x2B31, 0x2B33, 0x2B3D, 0x2B3F, 0x2B4B, 0x2B4F, - 0x2B55, 0x2B69, 0x2B6D, 0x2B6F, 0x2B7B, 0x2B8D, 0x2B97, 0x2B99, - 0x2BA3, 0x2BA5, 0x2BA9, 0x2BBD, 0x2BCD, 0x2BE7, 0x2BEB, 0x2BF3, - 0x2BF9, 0x2BFD, 0x2C09, 0x2C0F, 0x2C17, 0x2C23, 0x2C2F, 0x2C35, - 0x2C39, 0x2C41, 0x2C57, 0x2C59, 0x2C69, 0x2C77, 0x2C81, 0x2C87, - 0x2C93, 0x2C9F, 0x2CAD, 0x2CB3, 0x2CB7, 0x2CCB, 0x2CCF, 0x2CDB, - 0x2CE1, 0x2CE3, 0x2CE9, 0x2CEF, 0x2CFF, 0x2D07, 0x2D1D, 0x2D1F, - 0x2D3B, 0x2D43, 0x2D49, 0x2D4D, 0x2D61, 0x2D65, 0x2D71, 0x2D89, - 0x2D9D, 0x2DA1, 0x2DA9, 0x2DB3, 0x2DB5, 0x2DC5, 0x2DC7, 0x2DD3, - 0x2DDF, 0x2E01, 0x2E03, 0x2E07, 0x2E0D, 0x2E19, 0x2E1F, 0x2E25, - 0x2E2D, 0x2E33, 0x2E37, 0x2E39, 0x2E3F, 0x2E57, 0x2E5B, 0x2E6F, - 0x2E79, 0x2E7F, 0x2E85, 0x2E93, 0x2E97, 0x2E9D, 0x2EA3, 0x2EA5, - 0x2EB1, 0x2EB7, 0x2EC1, 0x2EC3, 0x2ECD, 0x2ED3, 0x2EE7, 0x2EEB, - 0x2F05, 0x2F09, 0x2F0B, 0x2F11, 0x2F27, 0x2F29, 0x2F41, 0x2F45, - 0x2F4B, 0x2F4D, 0x2F51, 0x2F57, 0x2F6F, 0x2F75, 0x2F7D, 0x2F81, - 0x2F83, 0x2FA5, 0x2FAB, 0x2FB3, 0x2FC3, 0x2FCF, 0x2FD1, 0x2FDB, - 0x2FDD, 0x2FE7, 0x2FED, 0x2FF5, 0x2FF9, 0x3001, 0x300D, 0x3023, - 0x3029, 0x3037, 0x303B, 0x3055, 0x3059, 0x305B, 0x3067, 0x3071, - 0x3079, 0x307D, 0x3085, 0x3091, 0x3095, 0x30A3, 0x30A9, 0x30B9, - 0x30BF, 0x30C7, 0x30CB, 0x30D1, 0x30D7, 0x30DF, 0x30E5, 0x30EF, - 0x30FB, 0x30FD, 0x3103, 0x3109, 0x3119, 0x3121, 0x3127, 0x312D, - 0x3139, 0x3143, 0x3145, 0x314B, 0x315D, 0x3161, 0x3167, 0x316D, - 0x3173, 0x317F, 0x3191, 0x3199, 0x319F, 0x31A9, 0x31B1, 0x31C3, - 0x31C7, 0x31D5, 0x31DB, 0x31ED, 0x31F7, 0x31FF, 0x3209, 0x3215, - 0x3217, 0x321D, 0x3229, 0x3235, 0x3259, 0x325D, 0x3263, 0x326B, - 0x326F, 0x3275, 0x3277, 0x327B, 0x328D, 0x3299, 0x329F, 0x32A7, - 0x32AD, 0x32B3, 0x32B7, 0x32C9, 0x32CB, 0x32CF, 0x32D1, 0x32E9, - 0x32ED, 0x32F3, 0x32F9, 0x3307, 0x3325, 0x332B, 0x332F, 0x3335, - 0x3341, 0x3347, 0x335B, 0x335F, 0x3367, 0x336B, 0x3373, 0x3379, - 0x337F, 0x3383, 0x33A1, 0x33A3, 0x33AD, 0x33B9, 0x33C1, 0x33CB, - 0x33D3, 0x33EB, 0x33F1, 0x33FD, 0x3401, 0x340F, 0x3413, 0x3419, - 0x341B, 0x3437, 0x3445, 0x3455, 0x3457, 0x3463, 0x3469, 0x346D, - 0x3481, 0x348B, 0x3491, 0x3497, 0x349D, 0x34A5, 0x34AF, 0x34BB, - 0x34C9, 0x34D3, 0x34E1, 0x34F1, 0x34FF, 0x3509, 0x3517, 0x351D, - 0x352D, 0x3533, 0x353B, 0x3541, 0x3551, 0x3565, 0x356F, 0x3571, - 0x3577, 0x357B, 0x357D, 0x3581, 0x358D, 0x358F, 0x3599, 0x359B, - 0x35A1, 0x35B7, 0x35BD, 0x35BF, 0x35C3, 0x35D5, 0x35DD, 0x35E7, - 0x35EF, 0x3605, 0x3607, 0x3611, 0x3623, 0x3631, 0x3635, 0x3637, - 0x363B, 0x364D, 0x364F, 0x3653, 0x3659, 0x3661, 0x366B, 0x366D, - 0x368B, 0x368F, 0x36AD, 0x36AF, 0x36B9, 0x36BB, 0x36CD, 0x36D1, - 0x36E3, 0x36E9, 0x36F7, 0x3701, 0x3703, 0x3707, 0x371B, 0x373F, - 0x3745, 0x3749, 0x374F, 0x375D, 0x3761, 0x3775, 0x377F, 0x378D, - 0x37A3, 0x37A9, 0x37AB, 0x37C9, 0x37D5, 0x37DF, 0x37F1, 0x37F3, - 0x37F7, 0x3805, 0x380B, 0x3821, 0x3833, 0x3835, 0x3841, 0x3847, - 0x384B, 0x3853, 0x3857, 0x385F, 0x3865, 0x386F, 0x3871, 0x387D, - 0x388F, 0x3899, 0x38A7, 0x38B7, 0x38C5, 0x38C9, 0x38CF, 0x38D5, - 0x38D7, 0x38DD, 0x38E1, 0x38E3, 0x38FF, 0x3901, 0x391D, 0x3923, - 0x3925, 0x3929, 0x392F, 0x393D, 0x3941, 0x394D, 0x395B, 0x396B, - 0x3979, 0x397D, 0x3983, 0x398B, 0x3991, 0x3995, 0x399B, 0x39A1, - 0x39A7, 0x39AF, 0x39B3, 0x39BB, 0x39BF, 0x39CD, 0x39DD, 0x39E5, - 0x39EB, 0x39EF, 0x39FB, 0x3A03, 0x3A13, 0x3A15, 0x3A1F, 0x3A27, - 0x3A2B, 0x3A31, 0x3A4B, 0x3A51, 0x3A5B, 0x3A63, 0x3A67, 0x3A6D, - 0x3A79, 0x3A87, 0x3AA5, 0x3AA9, 0x3AB7, 0x3ACD, 0x3AD5, 0x3AE1, - 0x3AE5, 0x3AEB, 0x3AF3, 0x3AFD, 0x3B03, 0x3B11, 0x3B1B, 0x3B21, - 0x3B23, 0x3B2D, 0x3B39, 0x3B45, 0x3B53, 0x3B59, 0x3B5F, 0x3B71, - 0x3B7B, 0x3B81, 0x3B89, 0x3B9B, 0x3B9F, 0x3BA5, 0x3BA7, 0x3BAD, - 0x3BB7, 0x3BB9, 0x3BC3, 0x3BCB, 0x3BD1, 0x3BD7, 0x3BE1, 0x3BE3, - 0x3BF5, 0x3BFF, 0x3C01, 0x3C0D, 0x3C11, 0x3C17, 0x3C1F, 0x3C29, - 0x3C35, 0x3C43, 0x3C4F, 0x3C53, 0x3C5B, 0x3C65, 0x3C6B, 0x3C71, - 0x3C85, 0x3C89, 0x3C97, 0x3CA7, 0x3CB5, 0x3CBF, 0x3CC7, 0x3CD1, - 0x3CDD, 0x3CDF, 0x3CF1, 0x3CF7, 0x3D03, 0x3D0D, 0x3D19, 0x3D1B, - 0x3D1F, 0x3D21, 0x3D2D, 0x3D33, 0x3D37, 0x3D3F, 0x3D43, 0x3D6F, - 0x3D73, 0x3D75, 0x3D79, 0x3D7B, 0x3D85, 0x3D91, 0x3D97, 0x3D9D, - 0x3DAB, 0x3DAF, 0x3DB5, 0x3DBB, 0x3DC1, 0x3DC9, 0x3DCF, 0x3DF3, - 0x3E05, 0x3E09, 0x3E0F, 0x3E11, 0x3E1D, 0x3E23, 0x3E29, 0x3E2F, - 0x3E33, 0x3E41, 0x3E57, 0x3E63, 0x3E65, 0x3E77, 0x3E81, 0x3E87, - 0x3EA1, 0x3EB9, 0x3EBD, 0x3EBF, 0x3EC3, 0x3EC5, 0x3EC9, 0x3ED7, - 0x3EDB, 0x3EE1, 0x3EE7, 0x3EEF, 0x3EFF, 0x3F0B, 0x3F0D, 0x3F37, - 0x3F3B, 0x3F3D, 0x3F41, 0x3F59, 0x3F5F, 0x3F65, 0x3F67, 0x3F79, - 0x3F7D, 0x3F8B, 0x3F91, 0x3FAD, 0x3FBF, 0x3FCD, 0x3FD3, 0x3FDD, - 0x3FE9, 0x3FEB, 0x3FF1, 0x3FFD, 0x401B, 0x4021, 0x4025, 0x402B, - 0x4031, 0x403F, 0x4043, 0x4045, 0x405D, 0x4061, 0x4067, 0x406D, - 0x4087, 0x4091, 0x40A3, 0x40A9, 0x40B1, 0x40B7, 0x40BD, 0x40DB, - 0x40DF, 0x40EB, 0x40F7, 0x40F9, 0x4109, 0x410B, 0x4111, 0x4115, - 0x4121, 0x4133, 0x4135, 0x413B, 0x413F, 0x4159, 0x4165, 0x416B, - 0x4177, 0x417B, 0x4193, 0x41AB, 0x41B7, 0x41BD, 0x41BF, 0x41CB, - 0x41E7, 0x41EF, 0x41F3, 0x41F9, 0x4205, 0x4207, 0x4219, 0x421F, - 0x4223, 0x4229, 0x422F, 0x4243, 0x4253, 0x4255, 0x425B, 0x4261, - 0x4273, 0x427D, 0x4283, 0x4285, 0x4289, 0x4291, 0x4297, 0x429D, - 0x42B5, 0x42C5, 0x42CB, 0x42D3, 0x42DD, 0x42E3, 0x42F1, 0x4307, - 0x430F, 0x431F, 0x4325, 0x4327, 0x4333, 0x4337, 0x4339, 0x434F, - 0x4357, 0x4369, 0x438B, 0x438D, 0x4393, 0x43A5, 0x43A9, 0x43AF, - 0x43B5, 0x43BD, 0x43C7, 0x43CF, 0x43E1, 0x43E7, 0x43EB, 0x43ED, - 0x43F1, 0x43F9, 0x4409, 0x440B, 0x4417, 0x4423, 0x4429, 0x443B, - 0x443F, 0x4445, 0x444B, 0x4451, 0x4453, 0x4459, 0x4465, 0x446F, - 0x4483, 0x448F, 0x44A1, 0x44A5, 0x44AB, 0x44AD, 0x44BD, 0x44BF, - 0x44C9, 0x44D7, 0x44DB, 0x44F9, 0x44FB, 0x4505, 0x4511, 0x4513, - 0x452B, 0x4531, 0x4541, 0x4549, 0x4553, 0x4555, 0x4561, 0x4577, - 0x457D, 0x457F, 0x458F, 0x45A3, 0x45AD, 0x45AF, 0x45BB, 0x45C7, - 0x45D9, 0x45E3, 0x45EF, 0x45F5, 0x45F7, 0x4601, 0x4603, 0x4609, - 0x4613, 0x4625, 0x4627, 0x4633, 0x4639, 0x463D, 0x4643, 0x4645, - 0x465D, 0x4679, 0x467B, 0x467F, 0x4681, 0x468B, 0x468D, 0x469D, - 0x46A9, 0x46B1, 0x46C7, 0x46C9, 0x46CF, 0x46D3, 0x46D5, 0x46DF, - 0x46E5, 0x46F9, 0x4705, 0x470F, 0x4717, 0x4723, 0x4729, 0x472F, - 0x4735, 0x4739, 0x474B, 0x474D, 0x4751, 0x475D, 0x476F, 0x4771, - 0x477D, 0x4783, 0x4787, 0x4789, 0x4799, 0x47A5, 0x47B1, 0x47BF, - 0x47C3, 0x47CB, 0x47DD, 0x47E1, 0x47ED, 0x47FB, 0x4801, 0x4807, - 0x480B, 0x4813, 0x4819, 0x481D, 0x4831, 0x483D, 0x4847, 0x4855, - 0x4859, 0x485B, 0x486B, 0x486D, 0x4879, 0x4897, 0x489B, 0x48A1, - 0x48B9, 0x48CD, 0x48E5, 0x48EF, 0x48F7, 0x4903, 0x490D, 0x4919, - 0x491F, 0x492B, 0x4937, 0x493D, 0x4945, 0x4955, 0x4963, 0x4969, - 0x496D, 0x4973, 0x4997, 0x49AB, 0x49B5, 0x49D3, 0x49DF, 0x49E1, - 0x49E5, 0x49E7, 0x4A03, 0x4A0F, 0x4A1D, 0x4A23, 0x4A39, 0x4A41, - 0x4A45, 0x4A57, 0x4A5D, 0x4A6B, 0x4A7D, 0x4A81, 0x4A87, 0x4A89, - 0x4A8F, 0x4AB1, 0x4AC3, 0x4AC5, 0x4AD5, 0x4ADB, 0x4AED, 0x4AEF, - 0x4B07, 0x4B0B, 0x4B0D, 0x4B13, 0x4B1F, 0x4B25, 0x4B31, 0x4B3B, - 0x4B43, 0x4B49, 0x4B59, 0x4B65, 0x4B6D, 0x4B77, 0x4B85, 0x4BAD, - 0x4BB3, 0x4BB5, 0x4BBB, 0x4BBF, 0x4BCB, 0x4BD9, 0x4BDD, 0x4BDF, - 0x4BE3, 0x4BE5, 0x4BE9, 0x4BF1, 0x4BF7, 0x4C01, 0x4C07, 0x4C0D, - 0x4C0F, 0x4C15, 0x4C1B, 0x4C21, 0x4C2D, 0x4C33, 0x4C4B, 0x4C55, - 0x4C57, 0x4C61, 0x4C67, 0x4C73, 0x4C79, 0x4C7F, 0x4C8D, 0x4C93, - 0x4C99, 0x4CCD, 0x4CE1, 0x4CE7, 0x4CF1, 0x4CF3, 0x4CFD, 0x4D05, - 0x4D0F, 0x4D1B, 0x4D27, 0x4D29, 0x4D2F, 0x4D33, 0x4D41, 0x4D51, - 0x4D59, 0x4D65, 0x4D6B, 0x4D81, 0x4D83, 0x4D8D, 0x4D95, 0x4D9B, - 0x4DB1, 0x4DB3, 0x4DC9, 0x4DCF, 0x4DD7, 0x4DE1, 0x4DED, 0x4DF9, - 0x4DFB, 0x4E05, 0x4E0B, 0x4E17, 0x4E19, 0x4E1D, 0x4E2B, 0x4E35, - 0x4E37, 0x4E3D, 0x4E4F, 0x4E53, 0x4E5F, 0x4E67, 0x4E79, 0x4E85, - 0x4E8B, 0x4E91, 0x4E95, 0x4E9B, 0x4EA1, 0x4EAF, 0x4EB3, 0x4EB5, - 0x4EC1, 0x4ECD, 0x4ED1, 0x4ED7, 0x4EE9, 0x4EFB, 0x4F07, 0x4F09, - 0x4F19, 0x4F25, 0x4F2D, 0x4F3F, 0x4F49, 0x4F63, 0x4F67, 0x4F6D, - 0x4F75, 0x4F7B, 0x4F81, 0x4F85, 0x4F87, 0x4F91, 0x4FA5, 0x4FA9, - 0x4FAF, 0x4FB7, 0x4FBB, 0x4FCF, 0x4FD9, 0x4FDB, 0x4FFD, 0x4FFF, - 0x5003, 0x501B, 0x501D, 0x5029, 0x5035, 0x503F, 0x5045, 0x5047, - 0x5053, 0x5071, 0x5077, 0x5083, 0x5093, 0x509F, 0x50A1, 0x50B7, - 0x50C9, 0x50D5, 0x50E3, 0x50ED, 0x50EF, 0x50FB, 0x5107, 0x510B, - 0x510D, 0x5111, 0x5117, 0x5123, 0x5125, 0x5135, 0x5147, 0x5149, - 0x5171, 0x5179, 0x5189, 0x518F, 0x5197, 0x51A1, 0x51A3, 0x51A7, - 0x51B9, 0x51C1, 0x51CB, 0x51D3, 0x51DF, 0x51E3, 0x51F5, 0x51F7, - 0x5209, 0x5213, 0x5215, 0x5219, 0x521B, 0x521F, 0x5227, 0x5243, - 0x5245, 0x524B, 0x5261, 0x526D, 0x5273, 0x5281, 0x5293, 0x5297, - 0x529D, 0x52A5, 0x52AB, 0x52B1, 0x52BB, 0x52C3, 0x52C7, 0x52C9, - 0x52DB, 0x52E5, 0x52EB, 0x52FF, 0x5315, 0x531D, 0x5323, 0x5341, - 0x5345, 0x5347, 0x534B, 0x535D, 0x5363, 0x5381, 0x5383, 0x5387, - 0x538F, 0x5395, 0x5399, 0x539F, 0x53AB, 0x53B9, 0x53DB, 0x53E9, - 0x53EF, 0x53F3, 0x53F5, 0x53FB, 0x53FF, 0x540D, 0x5411, 0x5413, - 0x5419, 0x5435, 0x5437, 0x543B, 0x5441, 0x5449, 0x5453, 0x5455, - 0x545F, 0x5461, 0x546B, 0x546D, 0x5471, 0x548F, 0x5491, 0x549D, - 0x54A9, 0x54B3, 0x54C5, 0x54D1, 0x54DF, 0x54E9, 0x54EB, 0x54F7, - 0x54FD, 0x5507, 0x550D, 0x551B, 0x5527, 0x552B, 0x5539, 0x553D, - 0x554F, 0x5551, 0x555B, 0x5563, 0x5567, 0x556F, 0x5579, 0x5585, - 0x5597, 0x55A9, 0x55B1, 0x55B7, 0x55C9, 0x55D9, 0x55E7, 0x55ED, - 0x55F3, 0x55FD, 0x560B, 0x560F, 0x5615, 0x5617, 0x5623, 0x562F, - 0x5633, 0x5639, 0x563F, 0x564B, 0x564D, 0x565D, 0x565F, 0x566B, - 0x5671, 0x5675, 0x5683, 0x5689, 0x568D, 0x568F, 0x569B, 0x56AD, - 0x56B1, 0x56D5, 0x56E7, 0x56F3, 0x56FF, 0x5701, 0x5705, 0x5707, - 0x570B, 0x5713, 0x571F, 0x5723, 0x5747, 0x574D, 0x575F, 0x5761, - 0x576D, 0x5777, 0x577D, 0x5789, 0x57A1, 0x57A9, 0x57AF, 0x57B5, - 0x57C5, 0x57D1, 0x57D3, 0x57E5, 0x57EF, 0x5803, 0x580D, 0x580F, - 0x5815, 0x5827, 0x582B, 0x582D, 0x5855, 0x585B, 0x585D, 0x586D, - 0x586F, 0x5873, 0x587B, 0x588D, 0x5897, 0x58A3, 0x58A9, 0x58AB, - 0x58B5, 0x58BD, 0x58C1, 0x58C7, 0x58D3, 0x58D5, 0x58DF, 0x58F1, - 0x58F9, 0x58FF, 0x5903, 0x5917, 0x591B, 0x5921, 0x5945, 0x594B, - 0x594D, 0x5957, 0x595D, 0x5975, 0x597B, 0x5989, 0x5999, 0x599F, - 0x59B1, 0x59B3, 0x59BD, 0x59D1, 0x59DB, 0x59E3, 0x59E9, 0x59ED, - 0x59F3, 0x59F5, 0x59FF, 0x5A01, 0x5A0D, 0x5A11, 0x5A13, 0x5A17, - 0x5A1F, 0x5A29, 0x5A2F, 0x5A3B, 0x5A4D, 0x5A5B, 0x5A67, 0x5A77, - 0x5A7F, 0x5A85, 0x5A95, 0x5A9D, 0x5AA1, 0x5AA3, 0x5AA9, 0x5ABB, - 0x5AD3, 0x5AE5, 0x5AEF, 0x5AFB, 0x5AFD, 0x5B01, 0x5B0F, 0x5B19, - 0x5B1F, 0x5B25, 0x5B2B, 0x5B3D, 0x5B49, 0x5B4B, 0x5B67, 0x5B79, - 0x5B87, 0x5B97, 0x5BA3, 0x5BB1, 0x5BC9, 0x5BD5, 0x5BEB, 0x5BF1, - 0x5BF3, 0x5BFD, 0x5C05, 0x5C09, 0x5C0B, 0x5C0F, 0x5C1D, 0x5C29, - 0x5C2F, 0x5C33, 0x5C39, 0x5C47, 0x5C4B, 0x5C4D, 0x5C51, 0x5C6F, - 0x5C75, 0x5C77, 0x5C7D, 0x5C87, 0x5C89, 0x5CA7, 0x5CBD, 0x5CBF, - 0x5CC3, 0x5CC9, 0x5CD1, 0x5CD7, 0x5CDD, 0x5CED, 0x5CF9, 0x5D05, - 0x5D0B, 0x5D13, 0x5D17, 0x5D19, 0x5D31, 0x5D3D, 0x5D41, 0x5D47, - 0x5D4F, 0x5D55, 0x5D5B, 0x5D65, 0x5D67, 0x5D6D, 0x5D79, 0x5D95, - 0x5DA3, 0x5DA9, 0x5DAD, 0x5DB9, 0x5DC1, 0x5DC7, 0x5DD3, 0x5DD7, - 0x5DDD, 0x5DEB, 0x5DF1, 0x5DFD, 0x5E07, 0x5E0D, 0x5E13, 0x5E1B, - 0x5E21, 0x5E27, 0x5E2B, 0x5E2D, 0x5E31, 0x5E39, 0x5E45, 0x5E49, - 0x5E57, 0x5E69, 0x5E73, 0x5E75, 0x5E85, 0x5E8B, 0x5E9F, 0x5EA5, - 0x5EAF, 0x5EB7, 0x5EBB, 0x5ED9, 0x5EFD, 0x5F09, 0x5F11, 0x5F27, - 0x5F33, 0x5F35, 0x5F3B, 0x5F47, 0x5F57, 0x5F5D, 0x5F63, 0x5F65, - 0x5F77, 0x5F7B, 0x5F95, 0x5F99, 0x5FA1, 0x5FB3, 0x5FBD, 0x5FC5, - 0x5FCF, 0x5FD5, 0x5FE3, 0x5FE7, 0x5FFB, 0x6011, 0x6023, 0x602F, - 0x6037, 0x6053, 0x605F, 0x6065, 0x606B, 0x6073, 0x6079, 0x6085, - 0x609D, 0x60AD, 0x60BB, 0x60BF, 0x60CD, 0x60D9, 0x60DF, 0x60E9, - 0x60F5, 0x6109, 0x610F, 0x6113, 0x611B, 0x612D, 0x6139, 0x614B, - 0x6155, 0x6157, 0x615B, 0x616F, 0x6179, 0x6187, 0x618B, 0x6191, - 0x6193, 0x619D, 0x61B5, 0x61C7, 0x61C9, 0x61CD, 0x61E1, 0x61F1, - 0x61FF, 0x6209, 0x6217, 0x621D, 0x6221, 0x6227, 0x623B, 0x6241, - 0x624B, 0x6251, 0x6253, 0x625F, 0x6265, 0x6283, 0x628D, 0x6295, - 0x629B, 0x629F, 0x62A5, 0x62AD, 0x62D5, 0x62D7, 0x62DB, 0x62DD, - 0x62E9, 0x62FB, 0x62FF, 0x6305, 0x630D, 0x6317, 0x631D, 0x632F, - 0x6341, 0x6343, 0x634F, 0x635F, 0x6367, 0x636D, 0x6371, 0x6377, - 0x637D, 0x637F, 0x63B3, 0x63C1, 0x63C5, 0x63D9, 0x63E9, 0x63EB, - 0x63EF, 0x63F5, 0x6401, 0x6403, 0x6409, 0x6415, 0x6421, 0x6427, - 0x642B, 0x6439, 0x6443, 0x6449, 0x644F, 0x645D, 0x6467, 0x6475, - 0x6485, 0x648D, 0x6493, 0x649F, 0x64A3, 0x64AB, 0x64C1, 0x64C7, - 0x64C9, 0x64DB, 0x64F1, 0x64F7, 0x64F9, 0x650B, 0x6511, 0x6521, - 0x652F, 0x6539, 0x653F, 0x654B, 0x654D, 0x6553, 0x6557, 0x655F, - 0x6571, 0x657D, 0x658D, 0x658F, 0x6593, 0x65A1, 0x65A5, 0x65AD, - 0x65B9, 0x65C5, 0x65E3, 0x65F3, 0x65FB, 0x65FF, 0x6601, 0x6607, - 0x661D, 0x6629, 0x6631, 0x663B, 0x6641, 0x6647, 0x664D, 0x665B, - 0x6661, 0x6673, 0x667D, 0x6689, 0x668B, 0x6695, 0x6697, 0x669B, - 0x66B5, 0x66B9, 0x66C5, 0x66CD, 0x66D1, 0x66E3, 0x66EB, 0x66F5, - 0x6703, 0x6713, 0x6719, 0x671F, 0x6727, 0x6731, 0x6737, 0x673F, - 0x6745, 0x6751, 0x675B, 0x676F, 0x6779, 0x6781, 0x6785, 0x6791, - 0x67AB, 0x67BD, 0x67C1, 0x67CD, 0x67DF, 0x67E5, 0x6803, 0x6809, - 0x6811, 0x6817, 0x682D, 0x6839, 0x683B, 0x683F, 0x6845, 0x684B, - 0x684D, 0x6857, 0x6859, 0x685D, 0x6863, 0x6869, 0x686B, 0x6871, - 0x6887, 0x6899, 0x689F, 0x68B1, 0x68BD, 0x68C5, 0x68D1, 0x68D7, - 0x68E1, 0x68ED, 0x68EF, 0x68FF, 0x6901, 0x690B, 0x690D, 0x6917, - 0x6929, 0x692F, 0x6943, 0x6947, 0x6949, 0x694F, 0x6965, 0x696B, - 0x6971, 0x6983, 0x6989, 0x6997, 0x69A3, 0x69B3, 0x69B5, 0x69BB, - 0x69C1, 0x69C5, 0x69D3, 0x69DF, 0x69E3, 0x69E5, 0x69F7, 0x6A07, - 0x6A2B, 0x6A37, 0x6A3D, 0x6A4B, 0x6A67, 0x6A69, 0x6A75, 0x6A7B, - 0x6A87, 0x6A8D, 0x6A91, 0x6A93, 0x6AA3, 0x6AC1, 0x6AC9, 0x6AE1, - 0x6AE7, 0x6B05, 0x6B0F, 0x6B11, 0x6B23, 0x6B27, 0x6B2D, 0x6B39, - 0x6B41, 0x6B57, 0x6B59, 0x6B5F, 0x6B75, 0x6B87, 0x6B89, 0x6B93, - 0x6B95, 0x6B9F, 0x6BBD, 0x6BBF, 0x6BDB, 0x6BE1, 0x6BEF, 0x6BFF, - 0x6C05, 0x6C19, 0x6C29, 0x6C2B, 0x6C31, 0x6C35, 0x6C55, 0x6C59, - 0x6C5B, 0x6C5F, 0x6C65, 0x6C67, 0x6C73, 0x6C77, 0x6C7D, 0x6C83, - 0x6C8F, 0x6C91, 0x6C97, 0x6C9B, 0x6CA1, 0x6CA9, 0x6CAF, 0x6CB3, - 0x6CC7, 0x6CCB, 0x6CEB, 0x6CF5, 0x6CFD, 0x6D0D, 0x6D0F, 0x6D25, - 0x6D27, 0x6D2B, 0x6D31, 0x6D39, 0x6D3F, 0x6D4F, 0x6D5D, 0x6D61, - 0x6D73, 0x6D7B, 0x6D7F, 0x6D93, 0x6D99, 0x6DA5, 0x6DB1, 0x6DB7, - 0x6DC1, 0x6DC3, 0x6DCD, 0x6DCF, 0x6DDB, 0x6DF7, 0x6E03, 0x6E15, - 0x6E17, 0x6E29, 0x6E33, 0x6E3B, 0x6E45, 0x6E75, 0x6E77, 0x6E7B, - 0x6E81, 0x6E89, 0x6E93, 0x6E95, 0x6E9F, 0x6EBD, 0x6EBF, 0x6EE3, - 0x6EE9, 0x6EF3, 0x6EF9, 0x6EFB, 0x6F0D, 0x6F11, 0x6F17, 0x6F1F, - 0x6F2F, 0x6F3D, 0x6F4D, 0x6F53, 0x6F61, 0x6F65, 0x6F79, 0x6F7D, - 0x6F83, 0x6F85, 0x6F8F, 0x6F9B, 0x6F9D, 0x6FA3, 0x6FAF, 0x6FB5, - 0x6FBB, 0x6FBF, 0x6FCB, 0x6FCD, 0x6FD3, 0x6FD7, 0x6FE3, 0x6FE9, - 0x6FF1, 0x6FF5, 0x6FF7, 0x6FFD, 0x700F, 0x7019, 0x701F, 0x7027, - 0x7033, 0x7039, 0x704F, 0x7051, 0x7057, 0x7063, 0x7075, 0x7079, - 0x7087, 0x708D, 0x7091, 0x70A5, 0x70AB, 0x70BB, 0x70C3, 0x70C7, - 0x70CF, 0x70E5, 0x70ED, 0x70F9, 0x70FF, 0x7105, 0x7115, 0x7121, - 0x7133, 0x7151, 0x7159, 0x715D, 0x715F, 0x7163, 0x7169, 0x7183, - 0x7187, 0x7195, 0x71AD, 0x71C3, 0x71C9, 0x71CB, 0x71D1, 0x71DB, - 0x71E1, 0x71EF, 0x71F5, 0x71FB, 0x7207, 0x7211, 0x7217, 0x7219, - 0x7225, 0x722F, 0x723B, 0x7243, 0x7255, 0x7267, 0x7271, 0x7277, - 0x727F, 0x728F, 0x7295, 0x729B, 0x72A3, 0x72B3, 0x72C7, 0x72CB, - 0x72CD, 0x72D7, 0x72D9, 0x72E3, 0x72EF, 0x72F5, 0x72FD, 0x7303, - 0x730D, 0x7321, 0x732B, 0x733D, 0x7357, 0x735B, 0x7361, 0x737F, - 0x7381, 0x7385, 0x738D, 0x7393, 0x739F, 0x73AB, 0x73BD, 0x73C1, - 0x73C9, 0x73DF, 0x73E5, 0x73E7, 0x73F3, 0x7415, 0x741B, 0x742D, - 0x7439, 0x743F, 0x7441, 0x745D, 0x746B, 0x747B, 0x7489, 0x748D, - 0x749B, 0x74A7, 0x74AB, 0x74B1, 0x74B7, 0x74B9, 0x74DD, 0x74E1, - 0x74E7, 0x74FB, 0x7507, 0x751F, 0x7525, 0x753B, 0x753D, 0x754D, - 0x755F, 0x756B, 0x7577, 0x7589, 0x758B, 0x7591, 0x7597, 0x759D, - 0x75A1, 0x75A7, 0x75B5, 0x75B9, 0x75BB, 0x75D1, 0x75D9, 0x75E5, - 0x75EB, 0x75F5, 0x75FB, 0x7603, 0x760F, 0x7621, 0x762D, 0x7633, - 0x763D, 0x763F, 0x7655, 0x7663, 0x7669, 0x766F, 0x7673, 0x7685, - 0x768B, 0x769F, 0x76B5, 0x76B7, 0x76C3, 0x76DB, 0x76DF, 0x76F1, - 0x7703, 0x7705, 0x771B, 0x771D, 0x7721, 0x772D, 0x7735, 0x7741, - 0x774B, 0x7759, 0x775D, 0x775F, 0x7771, 0x7781, 0x77A7, 0x77AD, - 0x77B3, 0x77B9, 0x77C5, 0x77CF, 0x77D5, 0x77E1, 0x77E9, 0x77EF, - 0x77F3, 0x77F9, 0x7807, 0x7825, 0x782B, 0x7835, 0x783D, 0x7853, - 0x7859, 0x7861, 0x786D, 0x7877, 0x7879, 0x7883, 0x7885, 0x788B, - 0x7895, 0x7897, 0x78A1, 0x78AD, 0x78BF, 0x78D3, 0x78D9, 0x78DD, - 0x78E5, 0x78FB, 0x7901, 0x7907, 0x7925, 0x792B, 0x7939, 0x793F, - 0x794B, 0x7957, 0x795D, 0x7967, 0x7969, 0x7973, 0x7991, 0x7993, - 0x79A3, 0x79AB, 0x79AF, 0x79B1, 0x79B7, 0x79C9, 0x79CD, 0x79CF, - 0x79D5, 0x79D9, 0x79F3, 0x79F7, 0x79FF, 0x7A05, 0x7A0F, 0x7A11, - 0x7A15, 0x7A1B, 0x7A23, 0x7A27, 0x7A2D, 0x7A4B, 0x7A57, 0x7A59, - 0x7A5F, 0x7A65, 0x7A69, 0x7A7D, 0x7A93, 0x7A9B, 0x7A9F, 0x7AA1, - 0x7AA5, 0x7AED, 0x7AF5, 0x7AF9, 0x7B01, 0x7B17, 0x7B19, 0x7B1D, - 0x7B2B, 0x7B35, 0x7B37, 0x7B3B, 0x7B4F, 0x7B55, 0x7B5F, 0x7B71, - 0x7B77, 0x7B8B, 0x7B9B, 0x7BA1, 0x7BA9, 0x7BAF, 0x7BB3, 0x7BC7, - 0x7BD3, 0x7BE9, 0x7BEB, 0x7BEF, 0x7BF1, 0x7BFD, 0x7C07, 0x7C19, - 0x7C1B, 0x7C31, 0x7C37, 0x7C49, 0x7C67, 0x7C69, 0x7C73, 0x7C81, - 0x7C8B, 0x7C93, 0x7CA3, 0x7CD5, 0x7CDB, 0x7CE5, 0x7CED, 0x7CF7, - 0x7D03, 0x7D09, 0x7D1B, 0x7D1D, 0x7D33, 0x7D39, 0x7D3B, 0x7D3F, - 0x7D45, 0x7D4D, 0x7D53, 0x7D59, 0x7D63, 0x7D75, 0x7D77, 0x7D8D, - 0x7D8F, 0x7D9F, 0x7DAD, 0x7DB7, 0x7DBD, 0x7DBF, 0x7DCB, 0x7DD5, - 0x7DE9, 0x7DED, 0x7DFB, 0x7E01, 0x7E05, 0x7E29, 0x7E2B, 0x7E2F, - 0x7E35, 0x7E41, 0x7E43, 0x7E47, 0x7E55, 0x7E61, 0x7E67, 0x7E6B, - 0x7E71, 0x7E73, 0x7E79, 0x7E7D, 0x7E91, 0x7E9B, 0x7E9D, 0x7EA7, - 0x7EAD, 0x7EB9, 0x7EBB, 0x7ED3, 0x7EDF, 0x7EEB, 0x7EF1, 0x7EF7, - 0x7EFB, 0x7F13, 0x7F15, 0x7F19, 0x7F31, 0x7F33, 0x7F39, 0x7F3D, - 0x7F43, 0x7F4B, 0x7F5B, 0x7F61, 0x7F63, 0x7F6D, 0x7F79, 0x7F87, - 0x7F8D, 0x7FAF, 0x7FB5, 0x7FC3, 0x7FC9, 0x7FCD, 0x7FCF, 0x7FED, - 0x8003, 0x800B, 0x800F, 0x8015, 0x801D, 0x8021, 0x8023, 0x803F, - 0x8041, 0x8047, 0x804B, 0x8065, 0x8077, 0x808D, 0x808F, 0x8095, - 0x80A5, 0x80AB, 0x80AD, 0x80BD, 0x80C9, 0x80CB, 0x80D7, 0x80DB, - 0x80E1, 0x80E7, 0x80F5, 0x80FF, 0x8105, 0x810D, 0x8119, 0x811D, - 0x812F, 0x8131, 0x813B, 0x8143, 0x8153, 0x8159, 0x815F, 0x817D, - 0x817F, 0x8189, 0x819B, 0x819D, 0x81A7, 0x81AF, 0x81B3, 0x81BB, - 0x81C7, 0x81DF, 0x8207, 0x8209, 0x8215, 0x821F, 0x8225, 0x8231, - 0x8233, 0x823F, 0x8243, 0x8245, 0x8249, 0x824F, 0x8261, 0x826F, - 0x827B, 0x8281, 0x8285, 0x8293, 0x82B1, 0x82B5, 0x82BD, 0x82C7, - 0x82CF, 0x82D5, 0x82DF, 0x82F1, 0x82F9, 0x82FD, 0x830B, 0x831B, - 0x8321, 0x8329, 0x832D, 0x8333, 0x8335, 0x833F, 0x8341, 0x834D, - 0x8351, 0x8353, 0x8357, 0x835D, 0x8365, 0x8369, 0x836F, 0x838F, - 0x83A7, 0x83B1, 0x83B9, 0x83CB, 0x83D5, 0x83D7, 0x83DD, 0x83E7, - 0x83E9, 0x83ED, 0x83FF, 0x8405, 0x8411, 0x8413, 0x8423, 0x8425, - 0x843B, 0x8441, 0x8447, 0x844F, 0x8461, 0x8465, 0x8477, 0x8483, - 0x848B, 0x8491, 0x8495, 0x84A9, 0x84AF, 0x84CD, 0x84E3, 0x84EF, - 0x84F1, 0x84F7, 0x8509, 0x850D, 0x854B, 0x854F, 0x8551, 0x855D, - 0x8563, 0x856D, 0x856F, 0x857B, 0x8587, 0x85A3, 0x85A5, 0x85A9, - 0x85B7, 0x85CD, 0x85D3, 0x85D5, 0x85DB, 0x85E1, 0x85EB, 0x85F9, - 0x85FD, 0x85FF, 0x8609, 0x860F, 0x8617, 0x8621, 0x862F, 0x8639, - 0x863F, 0x8641, 0x864D, 0x8663, 0x8675, 0x867D, 0x8687, 0x8699, - 0x86A5, 0x86A7, 0x86B3, 0x86B7, 0x86C3, 0x86C5, 0x86CF, 0x86D1, - 0x86D7, 0x86E9, 0x86EF, 0x86F5, 0x8717, 0x871D, 0x871F, 0x872B, - 0x872F, 0x8735, 0x8747, 0x8759, 0x875B, 0x876B, 0x8771, 0x8777, - 0x877F, 0x8785, 0x878F, 0x87A1, 0x87A9, 0x87B3, 0x87BB, 0x87C5, - 0x87C7, 0x87CB, 0x87DD, 0x87F7, 0x8803, 0x8819, 0x881B, 0x881F, - 0x8821, 0x8837, 0x883D, 0x8843, 0x8851, 0x8861, 0x8867, 0x887B, - 0x8885, 0x8891, 0x8893, 0x88A5, 0x88CF, 0x88D3, 0x88EB, 0x88ED, - 0x88F3, 0x88FD, 0x8909, 0x890B, 0x8911, 0x891B, 0x8923, 0x8927, - 0x892D, 0x8939, 0x8945, 0x894D, 0x8951, 0x8957, 0x8963, 0x8981, - 0x8995, 0x899B, 0x89B3, 0x89B9, 0x89C3, 0x89CF, 0x89D1, 0x89DB, - 0x89EF, 0x89F5, 0x89FB, 0x89FF, 0x8A0B, 0x8A19, 0x8A23, 0x8A35, - 0x8A41, 0x8A49, 0x8A4F, 0x8A5B, 0x8A5F, 0x8A6D, 0x8A77, 0x8A79, - 0x8A85, 0x8AA3, 0x8AB3, 0x8AB5, 0x8AC1, 0x8AC7, 0x8ACB, 0x8ACD, - 0x8AD1, 0x8AD7, 0x8AF1, 0x8AF5, 0x8B07, 0x8B09, 0x8B0D, 0x8B13, - 0x8B21, 0x8B57, 0x8B5D, 0x8B91, 0x8B93, 0x8BA3, 0x8BA9, 0x8BAF, - 0x8BBB, 0x8BD5, 0x8BD9, 0x8BDB, 0x8BE1, 0x8BF7, 0x8BFD, 0x8BFF, - 0x8C0B, 0x8C17, 0x8C1D, 0x8C27, 0x8C39, 0x8C3B, 0x8C47, 0x8C53, - 0x8C5D, 0x8C6F, 0x8C7B, 0x8C81, 0x8C89, 0x8C8F, 0x8C99, 0x8C9F, - 0x8CA7, 0x8CAB, 0x8CAD, 0x8CB1, 0x8CC5, 0x8CDD, 0x8CE3, 0x8CE9, - 0x8CF3, 0x8D01, 0x8D0B, 0x8D0D, 0x8D23, 0x8D29, 0x8D37, 0x8D41, - 0x8D5B, 0x8D5F, 0x8D71, 0x8D79, 0x8D85, 0x8D91, 0x8D9B, 0x8DA7, - 0x8DAD, 0x8DB5, 0x8DC5, 0x8DCB, 0x8DD3, 0x8DD9, 0x8DDF, 0x8DF5, - 0x8DF7, 0x8E01, 0x8E15, 0x8E1F, 0x8E25, 0x8E51, 0x8E63, 0x8E69, - 0x8E73, 0x8E75, 0x8E79, 0x8E7F, 0x8E8D, 0x8E91, 0x8EAB, 0x8EAF, - 0x8EB1, 0x8EBD, 0x8EC7, 0x8ECF, 0x8ED3, 0x8EDB, 0x8EE7, 0x8EEB, - 0x8EF7, 0x8EFF, 0x8F15, 0x8F1D, 0x8F23, 0x8F2D, 0x8F3F, 0x8F45, - 0x8F4B, 0x8F53, 0x8F59, 0x8F65, 0x8F69, 0x8F71, 0x8F83, 0x8F8D, - 0x8F99, 0x8F9F, 0x8FAB, 0x8FAD, 0x8FB3, 0x8FB7, 0x8FB9, 0x8FC9, - 0x8FD5, 0x8FE1, 0x8FEF, 0x8FF9, 0x9007, 0x900D, 0x9017, 0x9023, - 0x9025, 0x9031, 0x9037, 0x903B, 0x9041, 0x9043, 0x904F, 0x9053, - 0x906D, 0x9073, 0x9085, 0x908B, 0x9095, 0x909B, 0x909D, 0x90AF, - 0x90B9, 0x90C1, 0x90C5, 0x90DF, 0x90E9, 0x90FD, 0x9103, 0x9113, - 0x9127, 0x9133, 0x913D, 0x9145, 0x914F, 0x9151, 0x9161, 0x9167, - 0x917B, 0x9185, 0x9199, 0x919D, 0x91BB, 0x91BD, 0x91C1, 0x91C9, - 0x91D9, 0x91DB, 0x91ED, 0x91F1, 0x91F3, 0x91F9, 0x9203, 0x9215, - 0x9221, 0x922F, 0x9241, 0x9247, 0x9257, 0x926B, 0x9271, 0x9275, - 0x927D, 0x9283, 0x9287, 0x928D, 0x9299, 0x92A1, 0x92AB, 0x92AD, - 0x92B9, 0x92BF, 0x92C3, 0x92C5, 0x92CB, 0x92D5, 0x92D7, 0x92E7, - 0x92F3, 0x9301, 0x930B, 0x9311, 0x9319, 0x931F, 0x933B, 0x933D, - 0x9343, 0x9355, 0x9373, 0x9395, 0x9397, 0x93A7, 0x93B3, 0x93B5, - 0x93C7, 0x93D7, 0x93DD, 0x93E5, 0x93EF, 0x93F7, 0x9401, 0x9409, - 0x9413, 0x943F, 0x9445, 0x944B, 0x944F, 0x9463, 0x9467, 0x9469, - 0x946D, 0x947B, 0x9497, 0x949F, 0x94A5, 0x94B5, 0x94C3, 0x94E1, - 0x94E7, 0x9505, 0x9509, 0x9517, 0x9521, 0x9527, 0x952D, 0x9535, - 0x9539, 0x954B, 0x9557, 0x955D, 0x955F, 0x9575, 0x9581, 0x9589, - 0x958F, 0x959B, 0x959F, 0x95AD, 0x95B1, 0x95B7, 0x95B9, 0x95BD, - 0x95CF, 0x95E3, 0x95E9, 0x95F9, 0x961F, 0x962F, 0x9631, 0x9635, - 0x963B, 0x963D, 0x9665, 0x968F, 0x969D, 0x96A1, 0x96A7, 0x96A9, - 0x96C1, 0x96CB, 0x96D1, 0x96D3, 0x96E5, 0x96EF, 0x96FB, 0x96FD, - 0x970D, 0x970F, 0x9715, 0x9725, 0x972B, 0x9733, 0x9737, 0x9739, - 0x9743, 0x9749, 0x9751, 0x975B, 0x975D, 0x976F, 0x977F, 0x9787, - 0x9793, 0x97A5, 0x97B1, 0x97B7, 0x97C3, 0x97CD, 0x97D3, 0x97D9, - 0x97EB, 0x97F7, 0x9805, 0x9809, 0x980B, 0x9815, 0x9829, 0x982F, - 0x983B, 0x9841, 0x9851, 0x986B, 0x986F, 0x9881, 0x9883, 0x9887, - 0x98A7, 0x98B1, 0x98B9, 0x98BF, 0x98C3, 0x98C9, 0x98CF, 0x98DD, - 0x98E3, 0x98F5, 0x98F9, 0x98FB, 0x990D, 0x9917, 0x991F, 0x9929, - 0x9931, 0x993B, 0x993D, 0x9941, 0x9947, 0x9949, 0x9953, 0x997D, - 0x9985, 0x9991, 0x9995, 0x999B, 0x99AD, 0x99AF, 0x99BF, 0x99C7, - 0x99CB, 0x99CD, 0x99D7, 0x99E5, 0x99F1, 0x99FB, 0x9A0F, 0x9A13, - 0x9A1B, 0x9A25, 0x9A4B, 0x9A4F, 0x9A55, 0x9A57, 0x9A61, 0x9A75, - 0x9A7F, 0x9A8B, 0x9A91, 0x9A9D, 0x9AB7, 0x9AC3, 0x9AC7, 0x9ACF, - 0x9AEB, 0x9AF3, 0x9AF7, 0x9AFF, 0x9B17, 0x9B1D, 0x9B27, 0x9B2F, - 0x9B35, 0x9B45, 0x9B51, 0x9B59, 0x9B63, 0x9B6F, 0x9B77, 0x9B8D, - 0x9B93, 0x9B95, 0x9B9F, 0x9BA1, 0x9BA7, 0x9BB1, 0x9BB7, 0x9BBD, - 0x9BC5, 0x9BCB, 0x9BCF, 0x9BDD, 0x9BF9, 0x9C01, 0x9C11, 0x9C23, - 0x9C2B, 0x9C2F, 0x9C35, 0x9C49, 0x9C4D, 0x9C5F, 0x9C65, 0x9C67, - 0x9C7F, 0x9C97, 0x9C9D, 0x9CA3, 0x9CAF, 0x9CBB, 0x9CBF, 0x9CC1, - 0x9CD7, 0x9CD9, 0x9CE3, 0x9CE9, 0x9CF1, 0x9CFD, 0x9D01, 0x9D15, - 0x9D27, 0x9D2D, 0x9D31, 0x9D3D, 0x9D55, 0x9D5B, 0x9D61, 0x9D97, - 0x9D9F, 0x9DA5, 0x9DA9, 0x9DC3, 0x9DE7, 0x9DEB, 0x9DED, 0x9DF1, - 0x9E0B, 0x9E17, 0x9E23, 0x9E27, 0x9E2D, 0x9E33, 0x9E3B, 0x9E47, - 0x9E51, 0x9E53, 0x9E5F, 0x9E6F, 0x9E81, 0x9E87, 0x9E8F, 0x9E95, - 0x9EA1, 0x9EB3, 0x9EBD, 0x9EBF, 0x9EF5, 0x9EF9, 0x9EFB, 0x9F05, - 0x9F23, 0x9F2F, 0x9F37, 0x9F3B, 0x9F43, 0x9F53, 0x9F61, 0x9F6D, - 0x9F73, 0x9F77, 0x9F7D, 0x9F89, 0x9F8F, 0x9F91, 0x9F95, 0x9FA3, - 0x9FAF, 0x9FB3, 0x9FC1, 0x9FC7, 0x9FDF, 0x9FE5, 0x9FEB, 0x9FF5, - 0xA001, 0xA00D, 0xA021, 0xA033, 0xA039, 0xA03F, 0xA04F, 0xA057, - 0xA05B, 0xA061, 0xA075, 0xA079, 0xA099, 0xA09D, 0xA0AB, 0xA0B5, - 0xA0B7, 0xA0BD, 0xA0C9, 0xA0D9, 0xA0DB, 0xA0DF, 0xA0E5, 0xA0F1, - 0xA0F3, 0xA0FD, 0xA105, 0xA10B, 0xA10F, 0xA111, 0xA11B, 0xA129, - 0xA12F, 0xA135, 0xA141, 0xA153, 0xA175, 0xA17D, 0xA187, 0xA18D, - 0xA1A5, 0xA1AB, 0xA1AD, 0xA1B7, 0xA1C3, 0xA1C5, 0xA1E3, 0xA1ED, - 0xA1FB, 0xA207, 0xA213, 0xA223, 0xA229, 0xA22F, 0xA231, 0xA243, - 0xA247, 0xA24D, 0xA26B, 0xA279, 0xA27D, 0xA283, 0xA289, 0xA28B, - 0xA291, 0xA295, 0xA29B, 0xA2A9, 0xA2AF, 0xA2B3, 0xA2BB, 0xA2C5, - 0xA2D1, 0xA2D7, 0xA2F7, 0xA301, 0xA309, 0xA31F, 0xA321, 0xA32B, - 0xA331, 0xA349, 0xA351, 0xA355, 0xA373, 0xA379, 0xA37B, 0xA387, - 0xA397, 0xA39F, 0xA3A5, 0xA3A9, 0xA3AF, 0xA3B7, 0xA3C7, 0xA3D5, - 0xA3DB, 0xA3E1, 0xA3E5, 0xA3E7, 0xA3F1, 0xA3FD, 0xA3FF, 0xA40F, - 0xA41D, 0xA421, 0xA423, 0xA427, 0xA43B, 0xA44D, 0xA457, 0xA459, - 0xA463, 0xA469, 0xA475, 0xA493, 0xA49B, 0xA4AD, 0xA4B9, 0xA4C3, - 0xA4C5, 0xA4CB, 0xA4D1, 0xA4D5, 0xA4E1, 0xA4ED, 0xA4EF, 0xA4F3, - 0xA4FF, 0xA511, 0xA529, 0xA52B, 0xA535, 0xA53B, 0xA543, 0xA553, - 0xA55B, 0xA561, 0xA56D, 0xA577, 0xA585, 0xA58B, 0xA597, 0xA59D, - 0xA5A3, 0xA5A7, 0xA5A9, 0xA5C1, 0xA5C5, 0xA5CB, 0xA5D3, 0xA5D9, - 0xA5DD, 0xA5DF, 0xA5E3, 0xA5E9, 0xA5F7, 0xA5FB, 0xA603, 0xA60D, - 0xA625, 0xA63D, 0xA649, 0xA64B, 0xA651, 0xA65D, 0xA673, 0xA691, - 0xA693, 0xA699, 0xA6AB, 0xA6B5, 0xA6BB, 0xA6C1, 0xA6C9, 0xA6CD, - 0xA6CF, 0xA6D5, 0xA6DF, 0xA6E7, 0xA6F1, 0xA6F7, 0xA6FF, 0xA70F, - 0xA715, 0xA723, 0xA729, 0xA72D, 0xA745, 0xA74D, 0xA757, 0xA759, - 0xA765, 0xA76B, 0xA76F, 0xA793, 0xA795, 0xA7AB, 0xA7B1, 0xA7B9, - 0xA7BF, 0xA7C9, 0xA7D1, 0xA7D7, 0xA7E3, 0xA7ED, 0xA7FB, 0xA805, - 0xA80B, 0xA81D, 0xA829, 0xA82B, 0xA837, 0xA83B, 0xA855, 0xA85F, - 0xA86D, 0xA87D, 0xA88F, 0xA897, 0xA8A9, 0xA8B5, 0xA8C1, 0xA8C7, - 0xA8D7, 0xA8E5, 0xA8FD, 0xA907, 0xA913, 0xA91B, 0xA931, 0xA937, - 0xA939, 0xA943, 0xA97F, 0xA985, 0xA987, 0xA98B, 0xA993, 0xA9A3, - 0xA9B1, 0xA9BB, 0xA9C1, 0xA9D9, 0xA9DF, 0xA9EB, 0xA9FD, 0xAA15, - 0xAA17, 0xAA35, 0xAA39, 0xAA3B, 0xAA47, 0xAA4D, 0xAA57, 0xAA59, - 0xAA5D, 0xAA6B, 0xAA71, 0xAA81, 0xAA83, 0xAA8D, 0xAA95, 0xAAAB, - 0xAABF, 0xAAC5, 0xAAC9, 0xAAE9, 0xAAEF, 0xAB01, 0xAB05, 0xAB07, - 0xAB0B, 0xAB0D, 0xAB11, 0xAB19, 0xAB4D, 0xAB5B, 0xAB71, 0xAB73, - 0xAB89, 0xAB9D, 0xABA7, 0xABAF, 0xABB9, 0xABBB, 0xABC1, 0xABC5, - 0xABD3, 0xABD7, 0xABDD, 0xABF1, 0xABF5, 0xABFB, 0xABFD, 0xAC09, - 0xAC15, 0xAC1B, 0xAC27, 0xAC37, 0xAC39, 0xAC45, 0xAC4F, 0xAC57, - 0xAC5B, 0xAC61, 0xAC63, 0xAC7F, 0xAC8B, 0xAC93, 0xAC9D, 0xACA9, - 0xACAB, 0xACAF, 0xACBD, 0xACD9, 0xACE1, 0xACE7, 0xACEB, 0xACED, - 0xACF1, 0xACF7, 0xACF9, 0xAD05, 0xAD3F, 0xAD45, 0xAD53, 0xAD5D, - 0xAD5F, 0xAD65, 0xAD81, 0xADA1, 0xADA5, 0xADC3, 0xADCB, 0xADD1, - 0xADD5, 0xADDB, 0xADE7, 0xADF3, 0xADF5, 0xADF9, 0xADFF, 0xAE05, - 0xAE13, 0xAE23, 0xAE2B, 0xAE49, 0xAE4D, 0xAE4F, 0xAE59, 0xAE61, - 0xAE67, 0xAE6B, 0xAE71, 0xAE8B, 0xAE8F, 0xAE9B, 0xAE9D, 0xAEA7, - 0xAEB9, 0xAEC5, 0xAED1, 0xAEE3, 0xAEE5, 0xAEE9, 0xAEF5, 0xAEFD, - 0xAF09, 0xAF13, 0xAF27, 0xAF2B, 0xAF33, 0xAF43, 0xAF4F, 0xAF57, - 0xAF5D, 0xAF6D, 0xAF75, 0xAF7F, 0xAF8B, 0xAF99, 0xAF9F, 0xAFA3, - 0xAFAB, 0xAFB7, 0xAFBB, 0xAFCF, 0xAFD5, 0xAFFD, 0xB005, 0xB015, - 0xB01B, 0xB03F, 0xB041, 0xB047, 0xB04B, 0xB051, 0xB053, 0xB069, - 0xB07B, 0xB07D, 0xB087, 0xB08D, 0xB0B1, 0xB0BF, 0xB0CB, 0xB0CF, - 0xB0E1, 0xB0E9, 0xB0ED, 0xB0FB, 0xB105, 0xB107, 0xB111, 0xB119, - 0xB11D, 0xB11F, 0xB131, 0xB141, 0xB14D, 0xB15B, 0xB165, 0xB173, - 0xB179, 0xB17F, 0xB1A9, 0xB1B3, 0xB1B9, 0xB1BF, 0xB1D3, 0xB1DD, - 0xB1E5, 0xB1F1, 0xB1F5, 0xB201, 0xB213, 0xB215, 0xB21F, 0xB22D, - 0xB23F, 0xB249, 0xB25B, 0xB263, 0xB269, 0xB26D, 0xB27B, 0xB281, - 0xB28B, 0xB2A9, 0xB2B7, 0xB2BD, 0xB2C3, 0xB2C7, 0xB2D3, 0xB2F9, - 0xB2FD, 0xB2FF, 0xB303, 0xB309, 0xB311, 0xB31D, 0xB327, 0xB32D, - 0xB33F, 0xB345, 0xB377, 0xB37D, 0xB381, 0xB387, 0xB393, 0xB39B, - 0xB3A5, 0xB3C5, 0xB3CB, 0xB3E1, 0xB3E3, 0xB3ED, 0xB3F9, 0xB40B, - 0xB40D, 0xB413, 0xB417, 0xB435, 0xB43D, 0xB443, 0xB449, 0xB45B, - 0xB465, 0xB467, 0xB46B, 0xB477, 0xB48B, 0xB495, 0xB49D, 0xB4B5, - 0xB4BF, 0xB4C1, 0xB4C7, 0xB4DD, 0xB4E3, 0xB4E5, 0xB4F7, 0xB501, - 0xB50D, 0xB50F, 0xB52D, 0xB53F, 0xB54B, 0xB567, 0xB569, 0xB56F, - 0xB573, 0xB579, 0xB587, 0xB58D, 0xB599, 0xB5A3, 0xB5AB, 0xB5AF, - 0xB5BB, 0xB5D5, 0xB5DF, 0xB5E7, 0xB5ED, 0xB5FD, 0xB5FF, 0xB609, - 0xB61B, 0xB629, 0xB62F, 0xB633, 0xB639, 0xB647, 0xB657, 0xB659, - 0xB65F, 0xB663, 0xB66F, 0xB683, 0xB687, 0xB69B, 0xB69F, 0xB6A5, - 0xB6B1, 0xB6B3, 0xB6D7, 0xB6DB, 0xB6E1, 0xB6E3, 0xB6ED, 0xB6EF, - 0xB705, 0xB70D, 0xB713, 0xB71D, 0xB729, 0xB735, 0xB747, 0xB755, - 0xB76D, 0xB791, 0xB795, 0xB7A9, 0xB7C1, 0xB7CB, 0xB7D1, 0xB7D3, - 0xB7EF, 0xB7F5, 0xB807, 0xB80F, 0xB813, 0xB819, 0xB821, 0xB827, - 0xB82B, 0xB82D, 0xB839, 0xB855, 0xB867, 0xB875, 0xB885, 0xB893, - 0xB8A5, 0xB8AF, 0xB8B7, 0xB8BD, 0xB8C1, 0xB8C7, 0xB8CD, 0xB8D5, - 0xB8EB, 0xB8F7, 0xB8F9, 0xB903, 0xB915, 0xB91B, 0xB91D, 0xB92F, - 0xB939, 0xB93B, 0xB947, 0xB951, 0xB963, 0xB983, 0xB989, 0xB98D, - 0xB993, 0xB999, 0xB9A1, 0xB9A7, 0xB9AD, 0xB9B7, 0xB9CB, 0xB9D1, - 0xB9DD, 0xB9E7, 0xB9EF, 0xB9F9, 0xBA07, 0xBA0D, 0xBA17, 0xBA25, - 0xBA29, 0xBA2B, 0xBA41, 0xBA53, 0xBA55, 0xBA5F, 0xBA61, 0xBA65, - 0xBA79, 0xBA7D, 0xBA7F, 0xBAA1, 0xBAA3, 0xBAAF, 0xBAB5, 0xBABF, - 0xBAC1, 0xBACB, 0xBADD, 0xBAE3, 0xBAF1, 0xBAFD, 0xBB09, 0xBB1F, - 0xBB27, 0xBB2D, 0xBB3D, 0xBB43, 0xBB4B, 0xBB4F, 0xBB5B, 0xBB61, - 0xBB69, 0xBB6D, 0xBB91, 0xBB97, 0xBB9D, 0xBBB1, 0xBBC9, 0xBBCF, - 0xBBDB, 0xBBED, 0xBBF7, 0xBBF9, 0xBC03, 0xBC1D, 0xBC23, 0xBC33, - 0xBC3B, 0xBC41, 0xBC45, 0xBC5D, 0xBC6F, 0xBC77, 0xBC83, 0xBC8F, - 0xBC99, 0xBCAB, 0xBCB7, 0xBCB9, 0xBCD1, 0xBCD5, 0xBCE1, 0xBCF3, - 0xBCFF, 0xBD0D, 0xBD17, 0xBD19, 0xBD1D, 0xBD35, 0xBD41, 0xBD4F, - 0xBD59, 0xBD5F, 0xBD61, 0xBD67, 0xBD6B, 0xBD71, 0xBD8B, 0xBD8F, - 0xBD95, 0xBD9B, 0xBD9D, 0xBDB3, 0xBDBB, 0xBDCD, 0xBDD1, 0xBDE3, - 0xBDEB, 0xBDEF, 0xBE07, 0xBE09, 0xBE15, 0xBE21, 0xBE25, 0xBE27, - 0xBE5B, 0xBE5D, 0xBE6F, 0xBE75, 0xBE79, 0xBE7F, 0xBE8B, 0xBE8D, - 0xBE93, 0xBE9F, 0xBEA9, 0xBEB1, 0xBEB5, 0xBEB7, 0xBECF, 0xBED9, - 0xBEDB, 0xBEE5, 0xBEE7, 0xBEF3, 0xBEF9, 0xBF0B, 0xBF33, 0xBF39, - 0xBF4D, 0xBF5D, 0xBF5F, 0xBF6B, 0xBF71, 0xBF7B, 0xBF87, 0xBF89, - 0xBF8D, 0xBF93, 0xBFA1, 0xBFAD, 0xBFB9, 0xBFCF, 0xBFD5, 0xBFDD, - 0xBFE1, 0xBFE3, 0xBFF3, 0xC005, 0xC011, 0xC013, 0xC019, 0xC029, - 0xC02F, 0xC031, 0xC037, 0xC03B, 0xC047, 0xC065, 0xC06D, 0xC07D, - 0xC07F, 0xC091, 0xC09B, 0xC0B3, 0xC0B5, 0xC0BB, 0xC0D3, 0xC0D7, - 0xC0D9, 0xC0EF, 0xC0F1, 0xC101, 0xC103, 0xC109, 0xC115, 0xC119, - 0xC12B, 0xC133, 0xC137, 0xC145, 0xC149, 0xC15B, 0xC173, 0xC179, - 0xC17B, 0xC181, 0xC18B, 0xC18D, 0xC197, 0xC1BD, 0xC1C3, 0xC1CD, - 0xC1DB, 0xC1E1, 0xC1E7, 0xC1FF, 0xC203, 0xC205, 0xC211, 0xC221, - 0xC22F, 0xC23F, 0xC24B, 0xC24D, 0xC253, 0xC25D, 0xC277, 0xC27B, - 0xC27D, 0xC289, 0xC28F, 0xC293, 0xC29F, 0xC2A7, 0xC2B3, 0xC2BD, - 0xC2CF, 0xC2D5, 0xC2E3, 0xC2FF, 0xC301, 0xC307, 0xC311, 0xC313, - 0xC317, 0xC325, 0xC347, 0xC349, 0xC34F, 0xC365, 0xC367, 0xC371, - 0xC37F, 0xC383, 0xC385, 0xC395, 0xC39D, 0xC3A7, 0xC3AD, 0xC3B5, - 0xC3BF, 0xC3C7, 0xC3CB, 0xC3D1, 0xC3D3, 0xC3E3, 0xC3E9, 0xC3EF, - 0xC401, 0xC41F, 0xC42D, 0xC433, 0xC437, 0xC455, 0xC457, 0xC461, - 0xC46F, 0xC473, 0xC487, 0xC491, 0xC499, 0xC49D, 0xC4A5, 0xC4B7, - 0xC4BB, 0xC4C9, 0xC4CF, 0xC4D3, 0xC4EB, 0xC4F1, 0xC4F7, 0xC509, - 0xC51B, 0xC51D, 0xC541, 0xC547, 0xC551, 0xC55F, 0xC56B, 0xC56F, - 0xC575, 0xC577, 0xC595, 0xC59B, 0xC59F, 0xC5A1, 0xC5A7, 0xC5C3, - 0xC5D7, 0xC5DB, 0xC5EF, 0xC5FB, 0xC613, 0xC623, 0xC635, 0xC641, - 0xC64F, 0xC655, 0xC659, 0xC665, 0xC685, 0xC691, 0xC697, 0xC6A1, - 0xC6A9, 0xC6B3, 0xC6B9, 0xC6CB, 0xC6CD, 0xC6DD, 0xC6EB, 0xC6F1, - 0xC707, 0xC70D, 0xC719, 0xC71B, 0xC72D, 0xC731, 0xC739, 0xC757, - 0xC763, 0xC767, 0xC773, 0xC775, 0xC77F, 0xC7A5, 0xC7BB, 0xC7BD, - 0xC7C1, 0xC7CF, 0xC7D5, 0xC7E1, 0xC7F9, 0xC7FD, 0xC7FF, 0xC803, - 0xC811, 0xC81D, 0xC827, 0xC829, 0xC839, 0xC83F, 0xC853, 0xC857, - 0xC86B, 0xC881, 0xC88D, 0xC88F, 0xC893, 0xC895, 0xC8A1, 0xC8B7, - 0xC8CF, 0xC8D5, 0xC8DB, 0xC8DD, 0xC8E3, 0xC8E7, 0xC8ED, 0xC8EF, - 0xC8F9, 0xC905, 0xC911, 0xC917, 0xC919, 0xC91F, 0xC92F, 0xC937, - 0xC93D, 0xC941, 0xC953, 0xC95F, 0xC96B, 0xC979, 0xC97D, 0xC989, - 0xC98F, 0xC997, 0xC99D, 0xC9AF, 0xC9B5, 0xC9BF, 0xC9CB, 0xC9D9, - 0xC9DF, 0xC9E3, 0xC9EB, 0xCA01, 0xCA07, 0xCA09, 0xCA25, 0xCA37, - 0xCA39, 0xCA4B, 0xCA55, 0xCA5B, 0xCA69, 0xCA73, 0xCA75, 0xCA7F, - 0xCA8D, 0xCA93, 0xCA9D, 0xCA9F, 0xCAB5, 0xCABB, 0xCAC3, 0xCAC9, - 0xCAD9, 0xCAE5, 0xCAED, 0xCB03, 0xCB05, 0xCB09, 0xCB17, 0xCB29, - 0xCB35, 0xCB3B, 0xCB53, 0xCB59, 0xCB63, 0xCB65, 0xCB71, 0xCB87, - 0xCB99, 0xCB9F, 0xCBB3, 0xCBB9, 0xCBC3, 0xCBD1, 0xCBD5, 0xCBD7, - 0xCBDD, 0xCBE9, 0xCBFF, 0xCC0D, 0xCC19, 0xCC1D, 0xCC23, 0xCC2B, - 0xCC41, 0xCC43, 0xCC4D, 0xCC59, 0xCC61, 0xCC89, 0xCC8B, 0xCC91, - 0xCC9B, 0xCCA3, 0xCCA7, 0xCCD1, 0xCCE5, 0xCCE9, 0xCD09, 0xCD15, - 0xCD1F, 0xCD25, 0xCD31, 0xCD3D, 0xCD3F, 0xCD49, 0xCD51, 0xCD57, - 0xCD5B, 0xCD63, 0xCD67, 0xCD81, 0xCD93, 0xCD97, 0xCD9F, 0xCDBB, - 0xCDC1, 0xCDD3, 0xCDD9, 0xCDE5, 0xCDE7, 0xCDF1, 0xCDF7, 0xCDFD, - 0xCE0B, 0xCE15, 0xCE21, 0xCE2F, 0xCE47, 0xCE4D, 0xCE51, 0xCE65, - 0xCE7B, 0xCE7D, 0xCE8F, 0xCE93, 0xCE99, 0xCEA5, 0xCEA7, 0xCEB7, - 0xCEC9, 0xCED7, 0xCEDD, 0xCEE3, 0xCEE7, 0xCEED, 0xCEF5, 0xCF07, - 0xCF0B, 0xCF19, 0xCF37, 0xCF3B, 0xCF4D, 0xCF55, 0xCF5F, 0xCF61, - 0xCF65, 0xCF6D, 0xCF79, 0xCF7D, 0xCF89, 0xCF9B, 0xCF9D, 0xCFA9, - 0xCFB3, 0xCFB5, 0xCFC5, 0xCFCD, 0xCFD1, 0xCFEF, 0xCFF1, 0xCFF7, - 0xD013, 0xD015, 0xD01F, 0xD021, 0xD033, 0xD03D, 0xD04B, 0xD04F, - 0xD069, 0xD06F, 0xD081, 0xD085, 0xD099, 0xD09F, 0xD0A3, 0xD0AB, - 0xD0BD, 0xD0C1, 0xD0CD, 0xD0E7, 0xD0FF, 0xD103, 0xD117, 0xD12D, - 0xD12F, 0xD141, 0xD157, 0xD159, 0xD15D, 0xD169, 0xD16B, 0xD171, - 0xD177, 0xD17D, 0xD181, 0xD187, 0xD195, 0xD199, 0xD1B1, 0xD1BD, - 0xD1C3, 0xD1D5, 0xD1D7, 0xD1E3, 0xD1FF, 0xD20D, 0xD211, 0xD217, - 0xD21F, 0xD235, 0xD23B, 0xD247, 0xD259, 0xD261, 0xD265, 0xD279, - 0xD27F, 0xD283, 0xD289, 0xD28B, 0xD29D, 0xD2A3, 0xD2A7, 0xD2B3, - 0xD2BF, 0xD2C7, 0xD2E3, 0xD2E9, 0xD2F1, 0xD2FB, 0xD2FD, 0xD315, - 0xD321, 0xD32B, 0xD343, 0xD34B, 0xD355, 0xD369, 0xD375, 0xD37B, - 0xD387, 0xD393, 0xD397, 0xD3A5, 0xD3B1, 0xD3C9, 0xD3EB, 0xD3FD, - 0xD405, 0xD40F, 0xD415, 0xD427, 0xD42F, 0xD433, 0xD43B, 0xD44B, - 0xD459, 0xD45F, 0xD463, 0xD469, 0xD481, 0xD483, 0xD489, 0xD48D, - 0xD493, 0xD495, 0xD4A5, 0xD4AB, 0xD4B1, 0xD4C5, 0xD4DD, 0xD4E1, - 0xD4E3, 0xD4E7, 0xD4F5, 0xD4F9, 0xD50B, 0xD50D, 0xD513, 0xD51F, - 0xD523, 0xD531, 0xD535, 0xD537, 0xD549, 0xD559, 0xD55F, 0xD565, - 0xD567, 0xD577, 0xD58B, 0xD591, 0xD597, 0xD5B5, 0xD5B9, 0xD5C1, - 0xD5C7, 0xD5DF, 0xD5EF, 0xD5F5, 0xD5FB, 0xD603, 0xD60F, 0xD62D, - 0xD631, 0xD643, 0xD655, 0xD65D, 0xD661, 0xD67B, 0xD685, 0xD687, - 0xD69D, 0xD6A5, 0xD6AF, 0xD6BD, 0xD6C3, 0xD6C7, 0xD6D9, 0xD6E1, - 0xD6ED, 0xD709, 0xD70B, 0xD711, 0xD715, 0xD721, 0xD727, 0xD73F, - 0xD745, 0xD74D, 0xD757, 0xD76B, 0xD77B, 0xD783, 0xD7A1, 0xD7A7, - 0xD7AD, 0xD7B1, 0xD7B3, 0xD7BD, 0xD7CB, 0xD7D1, 0xD7DB, 0xD7FB, - 0xD811, 0xD823, 0xD825, 0xD829, 0xD82B, 0xD82F, 0xD837, 0xD84D, - 0xD855, 0xD867, 0xD873, 0xD88F, 0xD891, 0xD8A1, 0xD8AD, 0xD8BF, - 0xD8CD, 0xD8D7, 0xD8E9, 0xD8F5, 0xD8FB, 0xD91B, 0xD925, 0xD933, - 0xD939, 0xD943, 0xD945, 0xD94F, 0xD951, 0xD957, 0xD96D, 0xD96F, - 0xD973, 0xD979, 0xD981, 0xD98B, 0xD991, 0xD99F, 0xD9A5, 0xD9A9, - 0xD9B5, 0xD9D3, 0xD9EB, 0xD9F1, 0xD9F7, 0xD9FF, 0xDA05, 0xDA09, - 0xDA0B, 0xDA0F, 0xDA15, 0xDA1D, 0xDA23, 0xDA29, 0xDA3F, 0xDA51, - 0xDA59, 0xDA5D, 0xDA5F, 0xDA71, 0xDA77, 0xDA7B, 0xDA7D, 0xDA8D, - 0xDA9F, 0xDAB3, 0xDABD, 0xDAC3, 0xDAC9, 0xDAE7, 0xDAE9, 0xDAF5, - 0xDB11, 0xDB17, 0xDB1D, 0xDB23, 0xDB25, 0xDB31, 0xDB3B, 0xDB43, - 0xDB55, 0xDB67, 0xDB6B, 0xDB73, 0xDB85, 0xDB8F, 0xDB91, 0xDBAD, - 0xDBAF, 0xDBB9, 0xDBC7, 0xDBCB, 0xDBCD, 0xDBEB, 0xDBF7, 0xDC0D, - 0xDC27, 0xDC31, 0xDC39, 0xDC3F, 0xDC49, 0xDC51, 0xDC61, 0xDC6F, - 0xDC75, 0xDC7B, 0xDC85, 0xDC93, 0xDC99, 0xDC9D, 0xDC9F, 0xDCA9, - 0xDCB5, 0xDCB7, 0xDCBD, 0xDCC7, 0xDCCF, 0xDCD3, 0xDCD5, 0xDCDF, - 0xDCF9, 0xDD0F, 0xDD15, 0xDD17, 0xDD23, 0xDD35, 0xDD39, 0xDD53, - 0xDD57, 0xDD5F, 0xDD69, 0xDD6F, 0xDD7D, 0xDD87, 0xDD89, 0xDD9B, - 0xDDA1, 0xDDAB, 0xDDBF, 0xDDC5, 0xDDCB, 0xDDCF, 0xDDE7, 0xDDE9, - 0xDDED, 0xDDF5, 0xDDFB, 0xDE0B, 0xDE19, 0xDE29, 0xDE3B, 0xDE3D, - 0xDE41, 0xDE4D, 0xDE4F, 0xDE59, 0xDE5B, 0xDE61, 0xDE6D, 0xDE77, - 0xDE7D, 0xDE83, 0xDE97, 0xDE9D, 0xDEA1, 0xDEA7, 0xDECD, 0xDED1, - 0xDED7, 0xDEE3, 0xDEF1, 0xDEF5, 0xDF01, 0xDF09, 0xDF13, 0xDF1F, - 0xDF2B, 0xDF33, 0xDF37, 0xDF3D, 0xDF4B, 0xDF55, 0xDF5B, 0xDF67, - 0xDF69, 0xDF73, 0xDF85, 0xDF87, 0xDF99, 0xDFA3, 0xDFAB, 0xDFB5, - 0xDFB7, 0xDFC3, 0xDFC7, 0xDFD5, 0xDFF1, 0xDFF3, 0xE003, 0xE005, - 0xE017, 0xE01D, 0xE027, 0xE02D, 0xE035, 0xE045, 0xE053, 0xE071, - 0xE07B, 0xE08F, 0xE095, 0xE09F, 0xE0B7, 0xE0B9, 0xE0D5, 0xE0D7, - 0xE0E3, 0xE0F3, 0xE0F9, 0xE101, 0xE125, 0xE129, 0xE131, 0xE135, - 0xE143, 0xE14F, 0xE159, 0xE161, 0xE16D, 0xE171, 0xE177, 0xE17F, - 0xE183, 0xE189, 0xE197, 0xE1AD, 0xE1B5, 0xE1BB, 0xE1BF, 0xE1C1, - 0xE1CB, 0xE1D1, 0xE1E5, 0xE1EF, 0xE1F7, 0xE1FD, 0xE203, 0xE219, - 0xE22B, 0xE22D, 0xE23D, 0xE243, 0xE257, 0xE25B, 0xE275, 0xE279, - 0xE287, 0xE29D, 0xE2AB, 0xE2AF, 0xE2BB, 0xE2C1, 0xE2C9, 0xE2CD, - 0xE2D3, 0xE2D9, 0xE2F3, 0xE2FD, 0xE2FF, 0xE311, 0xE323, 0xE327, - 0xE329, 0xE339, 0xE33B, 0xE34D, 0xE351, 0xE357, 0xE35F, 0xE363, - 0xE369, 0xE375, 0xE377, 0xE37D, 0xE383, 0xE39F, 0xE3C5, 0xE3C9, - 0xE3D1, 0xE3E1, 0xE3FB, 0xE3FF, 0xE401, 0xE40B, 0xE417, 0xE419, - 0xE423, 0xE42B, 0xE431, 0xE43B, 0xE447, 0xE449, 0xE453, 0xE455, - 0xE46D, 0xE471, 0xE48F, 0xE4A9, 0xE4AF, 0xE4B5, 0xE4C7, 0xE4CD, - 0xE4D3, 0xE4E9, 0xE4EB, 0xE4F5, 0xE507, 0xE521, 0xE525, 0xE537, - 0xE53F, 0xE545, 0xE54B, 0xE557, 0xE567, 0xE56D, 0xE575, 0xE585, - 0xE58B, 0xE593, 0xE5A3, 0xE5A5, 0xE5CF, 0xE609, 0xE611, 0xE615, - 0xE61B, 0xE61D, 0xE621, 0xE629, 0xE639, 0xE63F, 0xE653, 0xE657, - 0xE663, 0xE66F, 0xE675, 0xE681, 0xE683, 0xE68D, 0xE68F, 0xE695, - 0xE6AB, 0xE6AD, 0xE6B7, 0xE6BD, 0xE6C5, 0xE6CB, 0xE6D5, 0xE6E3, - 0xE6E9, 0xE6EF, 0xE6F3, 0xE705, 0xE70D, 0xE717, 0xE71F, 0xE72F, - 0xE73D, 0xE747, 0xE749, 0xE753, 0xE755, 0xE761, 0xE767, 0xE76B, - 0xE77F, 0xE789, 0xE791, 0xE7C5, 0xE7CD, 0xE7D7, 0xE7DD, 0xE7DF, - 0xE7E9, 0xE7F1, 0xE7FB, 0xE801, 0xE807, 0xE80F, 0xE819, 0xE81B, - 0xE831, 0xE833, 0xE837, 0xE83D, 0xE84B, 0xE84F, 0xE851, 0xE869, - 0xE875, 0xE879, 0xE893, 0xE8A5, 0xE8A9, 0xE8AF, 0xE8BD, 0xE8DB, - 0xE8E1, 0xE8E5, 0xE8EB, 0xE8ED, 0xE903, 0xE90B, 0xE90F, 0xE915, - 0xE917, 0xE92D, 0xE933, 0xE93B, 0xE94B, 0xE951, 0xE95F, 0xE963, - 0xE969, 0xE97B, 0xE983, 0xE98F, 0xE995, 0xE9A1, 0xE9B9, 0xE9D7, - 0xE9E7, 0xE9EF, 0xEA11, 0xEA19, 0xEA2F, 0xEA35, 0xEA43, 0xEA4D, - 0xEA5F, 0xEA6D, 0xEA71, 0xEA7D, 0xEA85, 0xEA89, 0xEAAD, 0xEAB3, - 0xEAB9, 0xEABB, 0xEAC5, 0xEAC7, 0xEACB, 0xEADF, 0xEAE5, 0xEAEB, - 0xEAF5, 0xEB01, 0xEB07, 0xEB09, 0xEB31, 0xEB39, 0xEB3F, 0xEB5B, - 0xEB61, 0xEB63, 0xEB6F, 0xEB81, 0xEB85, 0xEB9D, 0xEBAB, 0xEBB1, - 0xEBB7, 0xEBC1, 0xEBD5, 0xEBDF, 0xEBED, 0xEBFD, 0xEC0B, 0xEC1B, - 0xEC21, 0xEC29, 0xEC4D, 0xEC51, 0xEC5D, 0xEC69, 0xEC6F, 0xEC7B, - 0xECAD, 0xECB9, 0xECBF, 0xECC3, 0xECC9, 0xECCF, 0xECD7, 0xECDD, - 0xECE7, 0xECE9, 0xECF3, 0xECF5, 0xED07, 0xED11, 0xED1F, 0xED2F, - 0xED37, 0xED3D, 0xED41, 0xED55, 0xED59, 0xED5B, 0xED65, 0xED6B, - 0xED79, 0xED8B, 0xED95, 0xEDBB, 0xEDC5, 0xEDD7, 0xEDD9, 0xEDE3, - 0xEDE5, 0xEDF1, 0xEDF5, 0xEDF7, 0xEDFB, 0xEE09, 0xEE0F, 0xEE19, - 0xEE21, 0xEE49, 0xEE4F, 0xEE63, 0xEE67, 0xEE73, 0xEE7B, 0xEE81, - 0xEEA3, 0xEEAB, 0xEEC1, 0xEEC9, 0xEED5, 0xEEDF, 0xEEE1, 0xEEF1, - 0xEF1B, 0xEF27, 0xEF2F, 0xEF45, 0xEF4D, 0xEF63, 0xEF6B, 0xEF71, - 0xEF93, 0xEF95, 0xEF9B, 0xEF9F, 0xEFAD, 0xEFB3, 0xEFC3, 0xEFC5, - 0xEFDB, 0xEFE1, 0xEFE9, 0xF001, 0xF017, 0xF01D, 0xF01F, 0xF02B, - 0xF02F, 0xF035, 0xF043, 0xF047, 0xF04F, 0xF067, 0xF06B, 0xF071, - 0xF077, 0xF079, 0xF08F, 0xF0A3, 0xF0A9, 0xF0AD, 0xF0BB, 0xF0BF, - 0xF0C5, 0xF0CB, 0xF0D3, 0xF0D9, 0xF0E3, 0xF0E9, 0xF0F1, 0xF0F7, - 0xF107, 0xF115, 0xF11B, 0xF121, 0xF137, 0xF13D, 0xF155, 0xF175, - 0xF17B, 0xF18D, 0xF193, 0xF1A5, 0xF1AF, 0xF1B7, 0xF1D5, 0xF1E7, - 0xF1ED, 0xF1FD, 0xF209, 0xF20F, 0xF21B, 0xF21D, 0xF223, 0xF227, - 0xF233, 0xF23B, 0xF241, 0xF257, 0xF25F, 0xF265, 0xF269, 0xF277, - 0xF281, 0xF293, 0xF2A7, 0xF2B1, 0xF2B3, 0xF2B9, 0xF2BD, 0xF2BF, - 0xF2DB, 0xF2ED, 0xF2EF, 0xF2F9, 0xF2FF, 0xF305, 0xF30B, 0xF319, - 0xF341, 0xF359, 0xF35B, 0xF35F, 0xF367, 0xF373, 0xF377, 0xF38B, - 0xF38F, 0xF3AF, 0xF3C1, 0xF3D1, 0xF3D7, 0xF3FB, 0xF403, 0xF409, - 0xF40D, 0xF413, 0xF421, 0xF425, 0xF42B, 0xF445, 0xF44B, 0xF455, - 0xF463, 0xF475, 0xF47F, 0xF485, 0xF48B, 0xF499, 0xF4A3, 0xF4A9, - 0xF4AF, 0xF4BD, 0xF4C3, 0xF4DB, 0xF4DF, 0xF4ED, 0xF503, 0xF50B, - 0xF517, 0xF521, 0xF529, 0xF535, 0xF547, 0xF551, 0xF563, 0xF56B, - 0xF583, 0xF58D, 0xF595, 0xF599, 0xF5B1, 0xF5B7, 0xF5C9, 0xF5CF, - 0xF5D1, 0xF5DB, 0xF5F9, 0xF5FB, 0xF605, 0xF607, 0xF60B, 0xF60D, - 0xF635, 0xF637, 0xF653, 0xF65B, 0xF661, 0xF667, 0xF679, 0xF67F, - 0xF689, 0xF697, 0xF69B, 0xF6AD, 0xF6CB, 0xF6DD, 0xF6DF, 0xF6EB, - 0xF709, 0xF70F, 0xF72D, 0xF731, 0xF743, 0xF74F, 0xF751, 0xF755, - 0xF763, 0xF769, 0xF773, 0xF779, 0xF781, 0xF787, 0xF791, 0xF79D, - 0xF79F, 0xF7A5, 0xF7B1, 0xF7BB, 0xF7BD, 0xF7CF, 0xF7D3, 0xF7E7, - 0xF7EB, 0xF7F1, 0xF7FF, 0xF805, 0xF80B, 0xF821, 0xF827, 0xF82D, - 0xF835, 0xF847, 0xF859, 0xF863, 0xF865, 0xF86F, 0xF871, 0xF877, - 0xF87B, 0xF881, 0xF88D, 0xF89F, 0xF8A1, 0xF8AB, 0xF8B3, 0xF8B7, - 0xF8C9, 0xF8CB, 0xF8D1, 0xF8D7, 0xF8DD, 0xF8E7, 0xF8EF, 0xF8F9, - 0xF8FF, 0xF911, 0xF91D, 0xF925, 0xF931, 0xF937, 0xF93B, 0xF941, - 0xF94F, 0xF95F, 0xF961, 0xF96D, 0xF971, 0xF977, 0xF99D, 0xF9A3, - 0xF9A9, 0xF9B9, 0xF9CD, 0xF9E9, 0xF9FD, 0xFA07, 0xFA0D, 0xFA13, - 0xFA21, 0xFA25, 0xFA3F, 0xFA43, 0xFA51, 0xFA5B, 0xFA6D, 0xFA7B, - 0xFA97, 0xFA99, 0xFA9D, 0xFAAB, 0xFABB, 0xFABD, 0xFAD9, 0xFADF, - 0xFAE7, 0xFAED, 0xFB0F, 0xFB17, 0xFB1B, 0xFB2D, 0xFB2F, 0xFB3F, - 0xFB47, 0xFB4D, 0xFB75, 0xFB7D, 0xFB8F, 0xFB93, 0xFBB1, 0xFBB7, - 0xFBC3, 0xFBC5, 0xFBE3, 0xFBE9, 0xFBF3, 0xFC01, 0xFC29, 0xFC37, - 0xFC41, 0xFC43, 0xFC4F, 0xFC59, 0xFC61, 0xFC65, 0xFC6D, 0xFC73, - 0xFC79, 0xFC95, 0xFC97, 0xFC9B, 0xFCA7, 0xFCB5, 0xFCC5, 0xFCCD, - 0xFCEB, 0xFCFB, 0xFD0D, 0xFD0F, 0xFD19, 0xFD2B, 0xFD31, 0xFD51, - 0xFD55, 0xFD67, 0xFD6D, 0xFD6F, 0xFD7B, 0xFD85, 0xFD97, 0xFD99, - 0xFD9F, 0xFDA9, 0xFDB7, 0xFDC9, 0xFDE5, 0xFDEB, 0xFDF3, 0xFE03, - 0xFE05, 0xFE09, 0xFE1D, 0xFE27, 0xFE2F, 0xFE41, 0xFE4B, 0xFE4D, - 0xFE57, 0xFE5F, 0xFE63, 0xFE69, 0xFE75, 0xFE7B, 0xFE8F, 0xFE93, - 0xFE95, 0xFE9B, 0xFE9F, 0xFEB3, 0xFEBD, 0xFED7, 0xFEE9, 0xFEF3, - 0xFEF5, 0xFF07, 0xFF0D, 0xFF1D, 0xFF2B, 0xFF2F, 0xFF49, 0xFF4D, - 0xFF5B, 0xFF65, 0xFF71, 0xFF7F, 0xFF85, 0xFF8B, 0xFF8F, 0xFF9D, - 0xFFA7, 0xFFA9, 0xFFC7, 0xFFD9, 0xFFEF, 0xFFF1, +const mp_digit prime_tab[] = { + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, +#if !SMALL_TABLE + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653, + 0x0655, 0x065B, 0x0665, 0x0679, 0x067F, 0x0683, 0x0685, 0x069D, + 0x06A1, 0x06A3, 0x06AD, 0x06B9, 0x06BB, 0x06C5, 0x06CD, 0x06D3, + 0x06D9, 0x06DF, 0x06F1, 0x06F7, 0x06FB, 0x06FD, 0x0709, 0x0713, + 0x071F, 0x0727, 0x0737, 0x0745, 0x074B, 0x074F, 0x0751, 0x0755, + 0x0757, 0x0761, 0x076D, 0x0773, 0x0779, 0x078B, 0x078D, 0x079D, + 0x079F, 0x07B5, 0x07BB, 0x07C3, 0x07C9, 0x07CD, 0x07CF, 0x07D3, + 0x07DB, 0x07E1, 0x07EB, 0x07ED, 0x07F7, 0x0805, 0x080F, 0x0815, + 0x0821, 0x0823, 0x0827, 0x0829, 0x0833, 0x083F, 0x0841, 0x0851, + 0x0853, 0x0859, 0x085D, 0x085F, 0x0869, 0x0871, 0x0883, 0x089B, + 0x089F, 0x08A5, 0x08AD, 0x08BD, 0x08BF, 0x08C3, 0x08CB, 0x08DB, + 0x08DD, 0x08E1, 0x08E9, 0x08EF, 0x08F5, 0x08F9, 0x0905, 0x0907, + 0x091D, 0x0923, 0x0925, 0x092B, 0x092F, 0x0935, 0x0943, 0x0949, + 0x094D, 0x094F, 0x0955, 0x0959, 0x095F, 0x096B, 0x0971, 0x0977, + 0x0985, 0x0989, 0x098F, 0x099B, 0x09A3, 0x09A9, 0x09AD, 0x09C7, + 0x09D9, 0x09E3, 0x09EB, 0x09EF, 0x09F5, 0x09F7, 0x09FD, 0x0A13, + 0x0A1F, 0x0A21, 0x0A31, 0x0A39, 0x0A3D, 0x0A49, 0x0A57, 0x0A61, + 0x0A63, 0x0A67, 0x0A6F, 0x0A75, 0x0A7B, 0x0A7F, 0x0A81, 0x0A85, + 0x0A8B, 0x0A93, 0x0A97, 0x0A99, 0x0A9F, 0x0AA9, 0x0AAB, 0x0AB5, + 0x0ABD, 0x0AC1, 0x0ACF, 0x0AD9, 0x0AE5, 0x0AE7, 0x0AED, 0x0AF1, + 0x0AF3, 0x0B03, 0x0B11, 0x0B15, 0x0B1B, 0x0B23, 0x0B29, 0x0B2D, + 0x0B3F, 0x0B47, 0x0B51, 0x0B57, 0x0B5D, 0x0B65, 0x0B6F, 0x0B7B, + 0x0B89, 0x0B8D, 0x0B93, 0x0B99, 0x0B9B, 0x0BB7, 0x0BB9, 0x0BC3, + 0x0BCB, 0x0BCF, 0x0BDD, 0x0BE1, 0x0BE9, 0x0BF5, 0x0BFB, 0x0C07, + 0x0C0B, 0x0C11, 0x0C25, 0x0C2F, 0x0C31, 0x0C41, 0x0C5B, 0x0C5F, + 0x0C61, 0x0C6D, 0x0C73, 0x0C77, 0x0C83, 0x0C89, 0x0C91, 0x0C95, + 0x0C9D, 0x0CB3, 0x0CB5, 0x0CB9, 0x0CBB, 0x0CC7, 0x0CE3, 0x0CE5, + 0x0CEB, 0x0CF1, 0x0CF7, 0x0CFB, 0x0D01, 0x0D03, 0x0D0F, 0x0D13, + 0x0D1F, 0x0D21, 0x0D2B, 0x0D2D, 0x0D3D, 0x0D3F, 0x0D4F, 0x0D55, + 0x0D69, 0x0D79, 0x0D81, 0x0D85, 0x0D87, 0x0D8B, 0x0D8D, 0x0DA3, + 0x0DAB, 0x0DB7, 0x0DBD, 0x0DC7, 0x0DC9, 0x0DCD, 0x0DD3, 0x0DD5, + 0x0DDB, 0x0DE5, 0x0DE7, 0x0DF3, 0x0DFD, 0x0DFF, 0x0E09, 0x0E17, + 0x0E1D, 0x0E21, 0x0E27, 0x0E2F, 0x0E35, 0x0E3B, 0x0E4B, 0x0E57, + 0x0E59, 0x0E5D, 0x0E6B, 0x0E71, 0x0E75, 0x0E7D, 0x0E87, 0x0E8F, + 0x0E95, 0x0E9B, 0x0EB1, 0x0EB7, 0x0EB9, 0x0EC3, 0x0ED1, 0x0ED5, + 0x0EDB, 0x0EED, 0x0EEF, 0x0EF9, 0x0F07, 0x0F0B, 0x0F0D, 0x0F17, + 0x0F25, 0x0F29, 0x0F31, 0x0F43, 0x0F47, 0x0F4D, 0x0F4F, 0x0F53, + 0x0F59, 0x0F5B, 0x0F67, 0x0F6B, 0x0F7F, 0x0F95, 0x0FA1, 0x0FA3, + 0x0FA7, 0x0FAD, 0x0FB3, 0x0FB5, 0x0FBB, 0x0FD1, 0x0FD3, 0x0FD9, + 0x0FE9, 0x0FEF, 0x0FFB, 0x0FFD, 0x1003, 0x100F, 0x101F, 0x1021, + 0x1025, 0x102B, 0x1039, 0x103D, 0x103F, 0x1051, 0x1069, 0x1073, + 0x1079, 0x107B, 0x1085, 0x1087, 0x1091, 0x1093, 0x109D, 0x10A3, + 0x10A5, 0x10AF, 0x10B1, 0x10BB, 0x10C1, 0x10C9, 0x10E7, 0x10F1, + 0x10F3, 0x10FD, 0x1105, 0x110B, 0x1115, 0x1127, 0x112D, 0x1139, + 0x1145, 0x1147, 0x1159, 0x115F, 0x1163, 0x1169, 0x116F, 0x1181, + 0x1183, 0x118D, 0x119B, 0x11A1, 0x11A5, 0x11A7, 0x11AB, 0x11C3, + 0x11C5, 0x11D1, 0x11D7, 0x11E7, 0x11EF, 0x11F5, 0x11FB, 0x120D, + 0x121D, 0x121F, 0x1223, 0x1229, 0x122B, 0x1231, 0x1237, 0x1241, + 0x1247, 0x1253, 0x125F, 0x1271, 0x1273, 0x1279, 0x127D, 0x128F, + 0x1297, 0x12AF, 0x12B3, 0x12B5, 0x12B9, 0x12BF, 0x12C1, 0x12CD, + 0x12D1, 0x12DF, 0x12FD, 0x1307, 0x130D, 0x1319, 0x1327, 0x132D, + 0x1337, 0x1343, 0x1345, 0x1349, 0x134F, 0x1357, 0x135D, 0x1367, + 0x1369, 0x136D, 0x137B, 0x1381, 0x1387, 0x138B, 0x1391, 0x1393, + 0x139D, 0x139F, 0x13AF, 0x13BB, 0x13C3, 0x13D5, 0x13D9, 0x13DF, + 0x13EB, 0x13ED, 0x13F3, 0x13F9, 0x13FF, 0x141B, 0x1421, 0x142F, + 0x1433, 0x143B, 0x1445, 0x144D, 0x1459, 0x146B, 0x146F, 0x1471, + 0x1475, 0x148D, 0x1499, 0x149F, 0x14A1, 0x14B1, 0x14B7, 0x14BD, + 0x14CB, 0x14D5, 0x14E3, 0x14E7, 0x1505, 0x150B, 0x1511, 0x1517, + 0x151F, 0x1525, 0x1529, 0x152B, 0x1537, 0x153D, 0x1541, 0x1543, + 0x1549, 0x155F, 0x1565, 0x1567, 0x156B, 0x157D, 0x157F, 0x1583, + 0x158F, 0x1591, 0x1597, 0x159B, 0x15B5, 0x15BB, 0x15C1, 0x15C5, + 0x15CD, 0x15D7, 0x15F7, 0x1607, 0x1609, 0x160F, 0x1613, 0x1615, + 0x1619, 0x161B, 0x1625, 0x1633, 0x1639, 0x163D, 0x1645, 0x164F, + 0x1655, 0x1669, 0x166D, 0x166F, 0x1675, 0x1693, 0x1697, 0x169F, + 0x16A9, 0x16AF, 0x16B5, 0x16BD, 0x16C3, 0x16CF, 0x16D3, 0x16D9, + 0x16DB, 0x16E1, 0x16E5, 0x16EB, 0x16ED, 0x16F7, 0x16F9, 0x1709, + 0x170F, 0x1723, 0x1727, 0x1733, 0x1741, 0x175D, 0x1763, 0x1777, + 0x177B, 0x178D, 0x1795, 0x179B, 0x179F, 0x17A5, 0x17B3, 0x17B9, + 0x17BF, 0x17C9, 0x17CB, 0x17D5, 0x17E1, 0x17E9, 0x17F3, 0x17F5, + 0x17FF, 0x1807, 0x1813, 0x181D, 0x1835, 0x1837, 0x183B, 0x1843, + 0x1849, 0x184D, 0x1855, 0x1867, 0x1871, 0x1877, 0x187D, 0x187F, + 0x1885, 0x188F, 0x189B, 0x189D, 0x18A7, 0x18AD, 0x18B3, 0x18B9, + 0x18C1, 0x18C7, 0x18D1, 0x18D7, 0x18D9, 0x18DF, 0x18E5, 0x18EB, + 0x18F5, 0x18FD, 0x1915, 0x191B, 0x1931, 0x1933, 0x1945, 0x1949, + 0x1951, 0x195B, 0x1979, 0x1981, 0x1993, 0x1997, 0x1999, 0x19A3, + 0x19A9, 0x19AB, 0x19B1, 0x19B5, 0x19C7, 0x19CF, 0x19DB, 0x19ED, + 0x19FD, 0x1A03, 0x1A05, 0x1A11, 0x1A17, 0x1A21, 0x1A23, 0x1A2D, + 0x1A2F, 0x1A35, 0x1A3F, 0x1A4D, 0x1A51, 0x1A69, 0x1A6B, 0x1A7B, + 0x1A7D, 0x1A87, 0x1A89, 0x1A93, 0x1AA7, 0x1AAB, 0x1AAD, 0x1AB1, + 0x1AB9, 0x1AC9, 0x1ACF, 0x1AD5, 0x1AD7, 0x1AE3, 0x1AF3, 0x1AFB, + 0x1AFF, 0x1B05, 0x1B23, 0x1B25, 0x1B2F, 0x1B31, 0x1B37, 0x1B3B, + 0x1B41, 0x1B47, 0x1B4F, 0x1B55, 0x1B59, 0x1B65, 0x1B6B, 0x1B73, + 0x1B7F, 0x1B83, 0x1B91, 0x1B9D, 0x1BA7, 0x1BBF, 0x1BC5, 0x1BD1, + 0x1BD7, 0x1BD9, 0x1BEF, 0x1BF7, 0x1C09, 0x1C13, 0x1C19, 0x1C27, + 0x1C2B, 0x1C2D, 0x1C33, 0x1C3D, 0x1C45, 0x1C4B, 0x1C4F, 0x1C55, + 0x1C73, 0x1C81, 0x1C8B, 0x1C8D, 0x1C99, 0x1CA3, 0x1CA5, 0x1CB5, + 0x1CB7, 0x1CC9, 0x1CE1, 0x1CF3, 0x1CF9, 0x1D09, 0x1D1B, 0x1D21, + 0x1D23, 0x1D35, 0x1D39, 0x1D3F, 0x1D41, 0x1D4B, 0x1D53, 0x1D5D, + 0x1D63, 0x1D69, 0x1D71, 0x1D75, 0x1D7B, 0x1D7D, 0x1D87, 0x1D89, + 0x1D95, 0x1D99, 0x1D9F, 0x1DA5, 0x1DA7, 0x1DB3, 0x1DB7, 0x1DC5, + 0x1DD7, 0x1DDB, 0x1DE1, 0x1DF5, 0x1DF9, 0x1E01, 0x1E07, 0x1E0B, + 0x1E13, 0x1E17, 0x1E25, 0x1E2B, 0x1E2F, 0x1E3D, 0x1E49, 0x1E4D, + 0x1E4F, 0x1E6D, 0x1E71, 0x1E89, 0x1E8F, 0x1E95, 0x1EA1, 0x1EAD, + 0x1EBB, 0x1EC1, 0x1EC5, 0x1EC7, 0x1ECB, 0x1EDD, 0x1EE3, 0x1EEF, + 0x1EF7, 0x1EFD, 0x1F01, 0x1F0D, 0x1F0F, 0x1F1B, 0x1F39, 0x1F49, + 0x1F4B, 0x1F51, 0x1F67, 0x1F75, 0x1F7B, 0x1F85, 0x1F91, 0x1F97, + 0x1F99, 0x1F9D, 0x1FA5, 0x1FAF, 0x1FB5, 0x1FBB, 0x1FD3, 0x1FE1, + 0x1FE7, 0x1FEB, 0x1FF3, 0x1FFF, 0x2011, 0x201B, 0x201D, 0x2027, + 0x2029, 0x202D, 0x2033, 0x2047, 0x204D, 0x2051, 0x205F, 0x2063, + 0x2065, 0x2069, 0x2077, 0x207D, 0x2089, 0x20A1, 0x20AB, 0x20B1, + 0x20B9, 0x20C3, 0x20C5, 0x20E3, 0x20E7, 0x20ED, 0x20EF, 0x20FB, + 0x20FF, 0x210D, 0x2113, 0x2135, 0x2141, 0x2149, 0x214F, 0x2159, + 0x215B, 0x215F, 0x2173, 0x217D, 0x2185, 0x2195, 0x2197, 0x21A1, + 0x21AF, 0x21B3, 0x21B5, 0x21C1, 0x21C7, 0x21D7, 0x21DD, 0x21E5, + 0x21E9, 0x21F1, 0x21F5, 0x21FB, 0x2203, 0x2209, 0x220F, 0x221B, + 0x2221, 0x2225, 0x222B, 0x2231, 0x2239, 0x224B, 0x224F, 0x2263, + 0x2267, 0x2273, 0x2275, 0x227F, 0x2285, 0x2287, 0x2291, 0x229D, + 0x229F, 0x22A3, 0x22B7, 0x22BD, 0x22DB, 0x22E1, 0x22E5, 0x22ED, + 0x22F7, 0x2303, 0x2309, 0x230B, 0x2327, 0x2329, 0x232F, 0x2333, + 0x2335, 0x2345, 0x2351, 0x2353, 0x2359, 0x2363, 0x236B, 0x2383, + 0x238F, 0x2395, 0x23A7, 0x23AD, 0x23B1, 0x23BF, 0x23C5, 0x23C9, + 0x23D5, 0x23DD, 0x23E3, 0x23EF, 0x23F3, 0x23F9, 0x2405, 0x240B, + 0x2417, 0x2419, 0x2429, 0x243D, 0x2441, 0x2443, 0x244D, 0x245F, + 0x2467, 0x246B, 0x2479, 0x247D, 0x247F, 0x2485, 0x249B, 0x24A1, + 0x24AF, 0x24B5, 0x24BB, 0x24C5, 0x24CB, 0x24CD, 0x24D7, 0x24D9, + 0x24DD, 0x24DF, 0x24F5, 0x24F7, 0x24FB, 0x2501, 0x2507, 0x2513, + 0x2519, 0x2527, 0x2531, 0x253D, 0x2543, 0x254B, 0x254F, 0x2573, + 0x2581, 0x258D, 0x2593, 0x2597, 0x259D, 0x259F, 0x25AB, 0x25B1, + 0x25BD, 0x25CD, 0x25CF, 0x25D9, 0x25E1, 0x25F7, 0x25F9, 0x2605, + 0x260B, 0x260F, 0x2615, 0x2627, 0x2629, 0x2635, 0x263B, 0x263F, + 0x264B, 0x2653, 0x2659, 0x2665, 0x2669, 0x266F, 0x267B, 0x2681, + 0x2683, 0x268F, 0x269B, 0x269F, 0x26AD, 0x26B3, 0x26C3, 0x26C9, + 0x26CB, 0x26D5, 0x26DD, 0x26EF, 0x26F5, 0x2717, 0x2719, 0x2735, + 0x2737, 0x274D, 0x2753, 0x2755, 0x275F, 0x276B, 0x276D, 0x2773, + 0x2777, 0x277F, 0x2795, 0x279B, 0x279D, 0x27A7, 0x27AF, 0x27B3, + 0x27B9, 0x27C1, 0x27C5, 0x27D1, 0x27E3, 0x27EF, 0x2803, 0x2807, + 0x280D, 0x2813, 0x281B, 0x281F, 0x2821, 0x2831, 0x283D, 0x283F, + 0x2849, 0x2851, 0x285B, 0x285D, 0x2861, 0x2867, 0x2875, 0x2881, + 0x2897, 0x289F, 0x28BB, 0x28BD, 0x28C1, 0x28D5, 0x28D9, 0x28DB, + 0x28DF, 0x28ED, 0x28F7, 0x2903, 0x2905, 0x2911, 0x2921, 0x2923, + 0x293F, 0x2947, 0x295D, 0x2965, 0x2969, 0x296F, 0x2975, 0x2983, + 0x2987, 0x298F, 0x299B, 0x29A1, 0x29A7, 0x29AB, 0x29BF, 0x29C3, + 0x29D5, 0x29D7, 0x29E3, 0x29E9, 0x29ED, 0x29F3, 0x2A01, 0x2A13, + 0x2A1D, 0x2A25, 0x2A2F, 0x2A4F, 0x2A55, 0x2A5F, 0x2A65, 0x2A6B, + 0x2A6D, 0x2A73, 0x2A83, 0x2A89, 0x2A8B, 0x2A97, 0x2A9D, 0x2AB9, + 0x2ABB, 0x2AC5, 0x2ACD, 0x2ADD, 0x2AE3, 0x2AEB, 0x2AF1, 0x2AFB, + 0x2B13, 0x2B27, 0x2B31, 0x2B33, 0x2B3D, 0x2B3F, 0x2B4B, 0x2B4F, + 0x2B55, 0x2B69, 0x2B6D, 0x2B6F, 0x2B7B, 0x2B8D, 0x2B97, 0x2B99, + 0x2BA3, 0x2BA5, 0x2BA9, 0x2BBD, 0x2BCD, 0x2BE7, 0x2BEB, 0x2BF3, + 0x2BF9, 0x2BFD, 0x2C09, 0x2C0F, 0x2C17, 0x2C23, 0x2C2F, 0x2C35, + 0x2C39, 0x2C41, 0x2C57, 0x2C59, 0x2C69, 0x2C77, 0x2C81, 0x2C87, + 0x2C93, 0x2C9F, 0x2CAD, 0x2CB3, 0x2CB7, 0x2CCB, 0x2CCF, 0x2CDB, + 0x2CE1, 0x2CE3, 0x2CE9, 0x2CEF, 0x2CFF, 0x2D07, 0x2D1D, 0x2D1F, + 0x2D3B, 0x2D43, 0x2D49, 0x2D4D, 0x2D61, 0x2D65, 0x2D71, 0x2D89, + 0x2D9D, 0x2DA1, 0x2DA9, 0x2DB3, 0x2DB5, 0x2DC5, 0x2DC7, 0x2DD3, + 0x2DDF, 0x2E01, 0x2E03, 0x2E07, 0x2E0D, 0x2E19, 0x2E1F, 0x2E25, + 0x2E2D, 0x2E33, 0x2E37, 0x2E39, 0x2E3F, 0x2E57, 0x2E5B, 0x2E6F, + 0x2E79, 0x2E7F, 0x2E85, 0x2E93, 0x2E97, 0x2E9D, 0x2EA3, 0x2EA5, + 0x2EB1, 0x2EB7, 0x2EC1, 0x2EC3, 0x2ECD, 0x2ED3, 0x2EE7, 0x2EEB, + 0x2F05, 0x2F09, 0x2F0B, 0x2F11, 0x2F27, 0x2F29, 0x2F41, 0x2F45, + 0x2F4B, 0x2F4D, 0x2F51, 0x2F57, 0x2F6F, 0x2F75, 0x2F7D, 0x2F81, + 0x2F83, 0x2FA5, 0x2FAB, 0x2FB3, 0x2FC3, 0x2FCF, 0x2FD1, 0x2FDB, + 0x2FDD, 0x2FE7, 0x2FED, 0x2FF5, 0x2FF9, 0x3001, 0x300D, 0x3023, + 0x3029, 0x3037, 0x303B, 0x3055, 0x3059, 0x305B, 0x3067, 0x3071, + 0x3079, 0x307D, 0x3085, 0x3091, 0x3095, 0x30A3, 0x30A9, 0x30B9, + 0x30BF, 0x30C7, 0x30CB, 0x30D1, 0x30D7, 0x30DF, 0x30E5, 0x30EF, + 0x30FB, 0x30FD, 0x3103, 0x3109, 0x3119, 0x3121, 0x3127, 0x312D, + 0x3139, 0x3143, 0x3145, 0x314B, 0x315D, 0x3161, 0x3167, 0x316D, + 0x3173, 0x317F, 0x3191, 0x3199, 0x319F, 0x31A9, 0x31B1, 0x31C3, + 0x31C7, 0x31D5, 0x31DB, 0x31ED, 0x31F7, 0x31FF, 0x3209, 0x3215, + 0x3217, 0x321D, 0x3229, 0x3235, 0x3259, 0x325D, 0x3263, 0x326B, + 0x326F, 0x3275, 0x3277, 0x327B, 0x328D, 0x3299, 0x329F, 0x32A7, + 0x32AD, 0x32B3, 0x32B7, 0x32C9, 0x32CB, 0x32CF, 0x32D1, 0x32E9, + 0x32ED, 0x32F3, 0x32F9, 0x3307, 0x3325, 0x332B, 0x332F, 0x3335, + 0x3341, 0x3347, 0x335B, 0x335F, 0x3367, 0x336B, 0x3373, 0x3379, + 0x337F, 0x3383, 0x33A1, 0x33A3, 0x33AD, 0x33B9, 0x33C1, 0x33CB, + 0x33D3, 0x33EB, 0x33F1, 0x33FD, 0x3401, 0x340F, 0x3413, 0x3419, + 0x341B, 0x3437, 0x3445, 0x3455, 0x3457, 0x3463, 0x3469, 0x346D, + 0x3481, 0x348B, 0x3491, 0x3497, 0x349D, 0x34A5, 0x34AF, 0x34BB, + 0x34C9, 0x34D3, 0x34E1, 0x34F1, 0x34FF, 0x3509, 0x3517, 0x351D, + 0x352D, 0x3533, 0x353B, 0x3541, 0x3551, 0x3565, 0x356F, 0x3571, + 0x3577, 0x357B, 0x357D, 0x3581, 0x358D, 0x358F, 0x3599, 0x359B, + 0x35A1, 0x35B7, 0x35BD, 0x35BF, 0x35C3, 0x35D5, 0x35DD, 0x35E7, + 0x35EF, 0x3605, 0x3607, 0x3611, 0x3623, 0x3631, 0x3635, 0x3637, + 0x363B, 0x364D, 0x364F, 0x3653, 0x3659, 0x3661, 0x366B, 0x366D, + 0x368B, 0x368F, 0x36AD, 0x36AF, 0x36B9, 0x36BB, 0x36CD, 0x36D1, + 0x36E3, 0x36E9, 0x36F7, 0x3701, 0x3703, 0x3707, 0x371B, 0x373F, + 0x3745, 0x3749, 0x374F, 0x375D, 0x3761, 0x3775, 0x377F, 0x378D, + 0x37A3, 0x37A9, 0x37AB, 0x37C9, 0x37D5, 0x37DF, 0x37F1, 0x37F3, + 0x37F7, 0x3805, 0x380B, 0x3821, 0x3833, 0x3835, 0x3841, 0x3847, + 0x384B, 0x3853, 0x3857, 0x385F, 0x3865, 0x386F, 0x3871, 0x387D, + 0x388F, 0x3899, 0x38A7, 0x38B7, 0x38C5, 0x38C9, 0x38CF, 0x38D5, + 0x38D7, 0x38DD, 0x38E1, 0x38E3, 0x38FF, 0x3901, 0x391D, 0x3923, + 0x3925, 0x3929, 0x392F, 0x393D, 0x3941, 0x394D, 0x395B, 0x396B, + 0x3979, 0x397D, 0x3983, 0x398B, 0x3991, 0x3995, 0x399B, 0x39A1, + 0x39A7, 0x39AF, 0x39B3, 0x39BB, 0x39BF, 0x39CD, 0x39DD, 0x39E5, + 0x39EB, 0x39EF, 0x39FB, 0x3A03, 0x3A13, 0x3A15, 0x3A1F, 0x3A27, + 0x3A2B, 0x3A31, 0x3A4B, 0x3A51, 0x3A5B, 0x3A63, 0x3A67, 0x3A6D, + 0x3A79, 0x3A87, 0x3AA5, 0x3AA9, 0x3AB7, 0x3ACD, 0x3AD5, 0x3AE1, + 0x3AE5, 0x3AEB, 0x3AF3, 0x3AFD, 0x3B03, 0x3B11, 0x3B1B, 0x3B21, + 0x3B23, 0x3B2D, 0x3B39, 0x3B45, 0x3B53, 0x3B59, 0x3B5F, 0x3B71, + 0x3B7B, 0x3B81, 0x3B89, 0x3B9B, 0x3B9F, 0x3BA5, 0x3BA7, 0x3BAD, + 0x3BB7, 0x3BB9, 0x3BC3, 0x3BCB, 0x3BD1, 0x3BD7, 0x3BE1, 0x3BE3, + 0x3BF5, 0x3BFF, 0x3C01, 0x3C0D, 0x3C11, 0x3C17, 0x3C1F, 0x3C29, + 0x3C35, 0x3C43, 0x3C4F, 0x3C53, 0x3C5B, 0x3C65, 0x3C6B, 0x3C71, + 0x3C85, 0x3C89, 0x3C97, 0x3CA7, 0x3CB5, 0x3CBF, 0x3CC7, 0x3CD1, + 0x3CDD, 0x3CDF, 0x3CF1, 0x3CF7, 0x3D03, 0x3D0D, 0x3D19, 0x3D1B, + 0x3D1F, 0x3D21, 0x3D2D, 0x3D33, 0x3D37, 0x3D3F, 0x3D43, 0x3D6F, + 0x3D73, 0x3D75, 0x3D79, 0x3D7B, 0x3D85, 0x3D91, 0x3D97, 0x3D9D, + 0x3DAB, 0x3DAF, 0x3DB5, 0x3DBB, 0x3DC1, 0x3DC9, 0x3DCF, 0x3DF3, + 0x3E05, 0x3E09, 0x3E0F, 0x3E11, 0x3E1D, 0x3E23, 0x3E29, 0x3E2F, + 0x3E33, 0x3E41, 0x3E57, 0x3E63, 0x3E65, 0x3E77, 0x3E81, 0x3E87, + 0x3EA1, 0x3EB9, 0x3EBD, 0x3EBF, 0x3EC3, 0x3EC5, 0x3EC9, 0x3ED7, + 0x3EDB, 0x3EE1, 0x3EE7, 0x3EEF, 0x3EFF, 0x3F0B, 0x3F0D, 0x3F37, + 0x3F3B, 0x3F3D, 0x3F41, 0x3F59, 0x3F5F, 0x3F65, 0x3F67, 0x3F79, + 0x3F7D, 0x3F8B, 0x3F91, 0x3FAD, 0x3FBF, 0x3FCD, 0x3FD3, 0x3FDD, + 0x3FE9, 0x3FEB, 0x3FF1, 0x3FFD, 0x401B, 0x4021, 0x4025, 0x402B, + 0x4031, 0x403F, 0x4043, 0x4045, 0x405D, 0x4061, 0x4067, 0x406D, + 0x4087, 0x4091, 0x40A3, 0x40A9, 0x40B1, 0x40B7, 0x40BD, 0x40DB, + 0x40DF, 0x40EB, 0x40F7, 0x40F9, 0x4109, 0x410B, 0x4111, 0x4115, + 0x4121, 0x4133, 0x4135, 0x413B, 0x413F, 0x4159, 0x4165, 0x416B, + 0x4177, 0x417B, 0x4193, 0x41AB, 0x41B7, 0x41BD, 0x41BF, 0x41CB, + 0x41E7, 0x41EF, 0x41F3, 0x41F9, 0x4205, 0x4207, 0x4219, 0x421F, + 0x4223, 0x4229, 0x422F, 0x4243, 0x4253, 0x4255, 0x425B, 0x4261, + 0x4273, 0x427D, 0x4283, 0x4285, 0x4289, 0x4291, 0x4297, 0x429D, + 0x42B5, 0x42C5, 0x42CB, 0x42D3, 0x42DD, 0x42E3, 0x42F1, 0x4307, + 0x430F, 0x431F, 0x4325, 0x4327, 0x4333, 0x4337, 0x4339, 0x434F, + 0x4357, 0x4369, 0x438B, 0x438D, 0x4393, 0x43A5, 0x43A9, 0x43AF, + 0x43B5, 0x43BD, 0x43C7, 0x43CF, 0x43E1, 0x43E7, 0x43EB, 0x43ED, + 0x43F1, 0x43F9, 0x4409, 0x440B, 0x4417, 0x4423, 0x4429, 0x443B, + 0x443F, 0x4445, 0x444B, 0x4451, 0x4453, 0x4459, 0x4465, 0x446F, + 0x4483, 0x448F, 0x44A1, 0x44A5, 0x44AB, 0x44AD, 0x44BD, 0x44BF, + 0x44C9, 0x44D7, 0x44DB, 0x44F9, 0x44FB, 0x4505, 0x4511, 0x4513, + 0x452B, 0x4531, 0x4541, 0x4549, 0x4553, 0x4555, 0x4561, 0x4577, + 0x457D, 0x457F, 0x458F, 0x45A3, 0x45AD, 0x45AF, 0x45BB, 0x45C7, + 0x45D9, 0x45E3, 0x45EF, 0x45F5, 0x45F7, 0x4601, 0x4603, 0x4609, + 0x4613, 0x4625, 0x4627, 0x4633, 0x4639, 0x463D, 0x4643, 0x4645, + 0x465D, 0x4679, 0x467B, 0x467F, 0x4681, 0x468B, 0x468D, 0x469D, + 0x46A9, 0x46B1, 0x46C7, 0x46C9, 0x46CF, 0x46D3, 0x46D5, 0x46DF, + 0x46E5, 0x46F9, 0x4705, 0x470F, 0x4717, 0x4723, 0x4729, 0x472F, + 0x4735, 0x4739, 0x474B, 0x474D, 0x4751, 0x475D, 0x476F, 0x4771, + 0x477D, 0x4783, 0x4787, 0x4789, 0x4799, 0x47A5, 0x47B1, 0x47BF, + 0x47C3, 0x47CB, 0x47DD, 0x47E1, 0x47ED, 0x47FB, 0x4801, 0x4807, + 0x480B, 0x4813, 0x4819, 0x481D, 0x4831, 0x483D, 0x4847, 0x4855, + 0x4859, 0x485B, 0x486B, 0x486D, 0x4879, 0x4897, 0x489B, 0x48A1, + 0x48B9, 0x48CD, 0x48E5, 0x48EF, 0x48F7, 0x4903, 0x490D, 0x4919, + 0x491F, 0x492B, 0x4937, 0x493D, 0x4945, 0x4955, 0x4963, 0x4969, + 0x496D, 0x4973, 0x4997, 0x49AB, 0x49B5, 0x49D3, 0x49DF, 0x49E1, + 0x49E5, 0x49E7, 0x4A03, 0x4A0F, 0x4A1D, 0x4A23, 0x4A39, 0x4A41, + 0x4A45, 0x4A57, 0x4A5D, 0x4A6B, 0x4A7D, 0x4A81, 0x4A87, 0x4A89, + 0x4A8F, 0x4AB1, 0x4AC3, 0x4AC5, 0x4AD5, 0x4ADB, 0x4AED, 0x4AEF, + 0x4B07, 0x4B0B, 0x4B0D, 0x4B13, 0x4B1F, 0x4B25, 0x4B31, 0x4B3B, + 0x4B43, 0x4B49, 0x4B59, 0x4B65, 0x4B6D, 0x4B77, 0x4B85, 0x4BAD, + 0x4BB3, 0x4BB5, 0x4BBB, 0x4BBF, 0x4BCB, 0x4BD9, 0x4BDD, 0x4BDF, + 0x4BE3, 0x4BE5, 0x4BE9, 0x4BF1, 0x4BF7, 0x4C01, 0x4C07, 0x4C0D, + 0x4C0F, 0x4C15, 0x4C1B, 0x4C21, 0x4C2D, 0x4C33, 0x4C4B, 0x4C55, + 0x4C57, 0x4C61, 0x4C67, 0x4C73, 0x4C79, 0x4C7F, 0x4C8D, 0x4C93, + 0x4C99, 0x4CCD, 0x4CE1, 0x4CE7, 0x4CF1, 0x4CF3, 0x4CFD, 0x4D05, + 0x4D0F, 0x4D1B, 0x4D27, 0x4D29, 0x4D2F, 0x4D33, 0x4D41, 0x4D51, + 0x4D59, 0x4D65, 0x4D6B, 0x4D81, 0x4D83, 0x4D8D, 0x4D95, 0x4D9B, + 0x4DB1, 0x4DB3, 0x4DC9, 0x4DCF, 0x4DD7, 0x4DE1, 0x4DED, 0x4DF9, + 0x4DFB, 0x4E05, 0x4E0B, 0x4E17, 0x4E19, 0x4E1D, 0x4E2B, 0x4E35, + 0x4E37, 0x4E3D, 0x4E4F, 0x4E53, 0x4E5F, 0x4E67, 0x4E79, 0x4E85, + 0x4E8B, 0x4E91, 0x4E95, 0x4E9B, 0x4EA1, 0x4EAF, 0x4EB3, 0x4EB5, + 0x4EC1, 0x4ECD, 0x4ED1, 0x4ED7, 0x4EE9, 0x4EFB, 0x4F07, 0x4F09, + 0x4F19, 0x4F25, 0x4F2D, 0x4F3F, 0x4F49, 0x4F63, 0x4F67, 0x4F6D, + 0x4F75, 0x4F7B, 0x4F81, 0x4F85, 0x4F87, 0x4F91, 0x4FA5, 0x4FA9, + 0x4FAF, 0x4FB7, 0x4FBB, 0x4FCF, 0x4FD9, 0x4FDB, 0x4FFD, 0x4FFF, + 0x5003, 0x501B, 0x501D, 0x5029, 0x5035, 0x503F, 0x5045, 0x5047, + 0x5053, 0x5071, 0x5077, 0x5083, 0x5093, 0x509F, 0x50A1, 0x50B7, + 0x50C9, 0x50D5, 0x50E3, 0x50ED, 0x50EF, 0x50FB, 0x5107, 0x510B, + 0x510D, 0x5111, 0x5117, 0x5123, 0x5125, 0x5135, 0x5147, 0x5149, + 0x5171, 0x5179, 0x5189, 0x518F, 0x5197, 0x51A1, 0x51A3, 0x51A7, + 0x51B9, 0x51C1, 0x51CB, 0x51D3, 0x51DF, 0x51E3, 0x51F5, 0x51F7, + 0x5209, 0x5213, 0x5215, 0x5219, 0x521B, 0x521F, 0x5227, 0x5243, + 0x5245, 0x524B, 0x5261, 0x526D, 0x5273, 0x5281, 0x5293, 0x5297, + 0x529D, 0x52A5, 0x52AB, 0x52B1, 0x52BB, 0x52C3, 0x52C7, 0x52C9, + 0x52DB, 0x52E5, 0x52EB, 0x52FF, 0x5315, 0x531D, 0x5323, 0x5341, + 0x5345, 0x5347, 0x534B, 0x535D, 0x5363, 0x5381, 0x5383, 0x5387, + 0x538F, 0x5395, 0x5399, 0x539F, 0x53AB, 0x53B9, 0x53DB, 0x53E9, + 0x53EF, 0x53F3, 0x53F5, 0x53FB, 0x53FF, 0x540D, 0x5411, 0x5413, + 0x5419, 0x5435, 0x5437, 0x543B, 0x5441, 0x5449, 0x5453, 0x5455, + 0x545F, 0x5461, 0x546B, 0x546D, 0x5471, 0x548F, 0x5491, 0x549D, + 0x54A9, 0x54B3, 0x54C5, 0x54D1, 0x54DF, 0x54E9, 0x54EB, 0x54F7, + 0x54FD, 0x5507, 0x550D, 0x551B, 0x5527, 0x552B, 0x5539, 0x553D, + 0x554F, 0x5551, 0x555B, 0x5563, 0x5567, 0x556F, 0x5579, 0x5585, + 0x5597, 0x55A9, 0x55B1, 0x55B7, 0x55C9, 0x55D9, 0x55E7, 0x55ED, + 0x55F3, 0x55FD, 0x560B, 0x560F, 0x5615, 0x5617, 0x5623, 0x562F, + 0x5633, 0x5639, 0x563F, 0x564B, 0x564D, 0x565D, 0x565F, 0x566B, + 0x5671, 0x5675, 0x5683, 0x5689, 0x568D, 0x568F, 0x569B, 0x56AD, + 0x56B1, 0x56D5, 0x56E7, 0x56F3, 0x56FF, 0x5701, 0x5705, 0x5707, + 0x570B, 0x5713, 0x571F, 0x5723, 0x5747, 0x574D, 0x575F, 0x5761, + 0x576D, 0x5777, 0x577D, 0x5789, 0x57A1, 0x57A9, 0x57AF, 0x57B5, + 0x57C5, 0x57D1, 0x57D3, 0x57E5, 0x57EF, 0x5803, 0x580D, 0x580F, + 0x5815, 0x5827, 0x582B, 0x582D, 0x5855, 0x585B, 0x585D, 0x586D, + 0x586F, 0x5873, 0x587B, 0x588D, 0x5897, 0x58A3, 0x58A9, 0x58AB, + 0x58B5, 0x58BD, 0x58C1, 0x58C7, 0x58D3, 0x58D5, 0x58DF, 0x58F1, + 0x58F9, 0x58FF, 0x5903, 0x5917, 0x591B, 0x5921, 0x5945, 0x594B, + 0x594D, 0x5957, 0x595D, 0x5975, 0x597B, 0x5989, 0x5999, 0x599F, + 0x59B1, 0x59B3, 0x59BD, 0x59D1, 0x59DB, 0x59E3, 0x59E9, 0x59ED, + 0x59F3, 0x59F5, 0x59FF, 0x5A01, 0x5A0D, 0x5A11, 0x5A13, 0x5A17, + 0x5A1F, 0x5A29, 0x5A2F, 0x5A3B, 0x5A4D, 0x5A5B, 0x5A67, 0x5A77, + 0x5A7F, 0x5A85, 0x5A95, 0x5A9D, 0x5AA1, 0x5AA3, 0x5AA9, 0x5ABB, + 0x5AD3, 0x5AE5, 0x5AEF, 0x5AFB, 0x5AFD, 0x5B01, 0x5B0F, 0x5B19, + 0x5B1F, 0x5B25, 0x5B2B, 0x5B3D, 0x5B49, 0x5B4B, 0x5B67, 0x5B79, + 0x5B87, 0x5B97, 0x5BA3, 0x5BB1, 0x5BC9, 0x5BD5, 0x5BEB, 0x5BF1, + 0x5BF3, 0x5BFD, 0x5C05, 0x5C09, 0x5C0B, 0x5C0F, 0x5C1D, 0x5C29, + 0x5C2F, 0x5C33, 0x5C39, 0x5C47, 0x5C4B, 0x5C4D, 0x5C51, 0x5C6F, + 0x5C75, 0x5C77, 0x5C7D, 0x5C87, 0x5C89, 0x5CA7, 0x5CBD, 0x5CBF, + 0x5CC3, 0x5CC9, 0x5CD1, 0x5CD7, 0x5CDD, 0x5CED, 0x5CF9, 0x5D05, + 0x5D0B, 0x5D13, 0x5D17, 0x5D19, 0x5D31, 0x5D3D, 0x5D41, 0x5D47, + 0x5D4F, 0x5D55, 0x5D5B, 0x5D65, 0x5D67, 0x5D6D, 0x5D79, 0x5D95, + 0x5DA3, 0x5DA9, 0x5DAD, 0x5DB9, 0x5DC1, 0x5DC7, 0x5DD3, 0x5DD7, + 0x5DDD, 0x5DEB, 0x5DF1, 0x5DFD, 0x5E07, 0x5E0D, 0x5E13, 0x5E1B, + 0x5E21, 0x5E27, 0x5E2B, 0x5E2D, 0x5E31, 0x5E39, 0x5E45, 0x5E49, + 0x5E57, 0x5E69, 0x5E73, 0x5E75, 0x5E85, 0x5E8B, 0x5E9F, 0x5EA5, + 0x5EAF, 0x5EB7, 0x5EBB, 0x5ED9, 0x5EFD, 0x5F09, 0x5F11, 0x5F27, + 0x5F33, 0x5F35, 0x5F3B, 0x5F47, 0x5F57, 0x5F5D, 0x5F63, 0x5F65, + 0x5F77, 0x5F7B, 0x5F95, 0x5F99, 0x5FA1, 0x5FB3, 0x5FBD, 0x5FC5, + 0x5FCF, 0x5FD5, 0x5FE3, 0x5FE7, 0x5FFB, 0x6011, 0x6023, 0x602F, + 0x6037, 0x6053, 0x605F, 0x6065, 0x606B, 0x6073, 0x6079, 0x6085, + 0x609D, 0x60AD, 0x60BB, 0x60BF, 0x60CD, 0x60D9, 0x60DF, 0x60E9, + 0x60F5, 0x6109, 0x610F, 0x6113, 0x611B, 0x612D, 0x6139, 0x614B, + 0x6155, 0x6157, 0x615B, 0x616F, 0x6179, 0x6187, 0x618B, 0x6191, + 0x6193, 0x619D, 0x61B5, 0x61C7, 0x61C9, 0x61CD, 0x61E1, 0x61F1, + 0x61FF, 0x6209, 0x6217, 0x621D, 0x6221, 0x6227, 0x623B, 0x6241, + 0x624B, 0x6251, 0x6253, 0x625F, 0x6265, 0x6283, 0x628D, 0x6295, + 0x629B, 0x629F, 0x62A5, 0x62AD, 0x62D5, 0x62D7, 0x62DB, 0x62DD, + 0x62E9, 0x62FB, 0x62FF, 0x6305, 0x630D, 0x6317, 0x631D, 0x632F, + 0x6341, 0x6343, 0x634F, 0x635F, 0x6367, 0x636D, 0x6371, 0x6377, + 0x637D, 0x637F, 0x63B3, 0x63C1, 0x63C5, 0x63D9, 0x63E9, 0x63EB, + 0x63EF, 0x63F5, 0x6401, 0x6403, 0x6409, 0x6415, 0x6421, 0x6427, + 0x642B, 0x6439, 0x6443, 0x6449, 0x644F, 0x645D, 0x6467, 0x6475, + 0x6485, 0x648D, 0x6493, 0x649F, 0x64A3, 0x64AB, 0x64C1, 0x64C7, + 0x64C9, 0x64DB, 0x64F1, 0x64F7, 0x64F9, 0x650B, 0x6511, 0x6521, + 0x652F, 0x6539, 0x653F, 0x654B, 0x654D, 0x6553, 0x6557, 0x655F, + 0x6571, 0x657D, 0x658D, 0x658F, 0x6593, 0x65A1, 0x65A5, 0x65AD, + 0x65B9, 0x65C5, 0x65E3, 0x65F3, 0x65FB, 0x65FF, 0x6601, 0x6607, + 0x661D, 0x6629, 0x6631, 0x663B, 0x6641, 0x6647, 0x664D, 0x665B, + 0x6661, 0x6673, 0x667D, 0x6689, 0x668B, 0x6695, 0x6697, 0x669B, + 0x66B5, 0x66B9, 0x66C5, 0x66CD, 0x66D1, 0x66E3, 0x66EB, 0x66F5, + 0x6703, 0x6713, 0x6719, 0x671F, 0x6727, 0x6731, 0x6737, 0x673F, + 0x6745, 0x6751, 0x675B, 0x676F, 0x6779, 0x6781, 0x6785, 0x6791, + 0x67AB, 0x67BD, 0x67C1, 0x67CD, 0x67DF, 0x67E5, 0x6803, 0x6809, + 0x6811, 0x6817, 0x682D, 0x6839, 0x683B, 0x683F, 0x6845, 0x684B, + 0x684D, 0x6857, 0x6859, 0x685D, 0x6863, 0x6869, 0x686B, 0x6871, + 0x6887, 0x6899, 0x689F, 0x68B1, 0x68BD, 0x68C5, 0x68D1, 0x68D7, + 0x68E1, 0x68ED, 0x68EF, 0x68FF, 0x6901, 0x690B, 0x690D, 0x6917, + 0x6929, 0x692F, 0x6943, 0x6947, 0x6949, 0x694F, 0x6965, 0x696B, + 0x6971, 0x6983, 0x6989, 0x6997, 0x69A3, 0x69B3, 0x69B5, 0x69BB, + 0x69C1, 0x69C5, 0x69D3, 0x69DF, 0x69E3, 0x69E5, 0x69F7, 0x6A07, + 0x6A2B, 0x6A37, 0x6A3D, 0x6A4B, 0x6A67, 0x6A69, 0x6A75, 0x6A7B, + 0x6A87, 0x6A8D, 0x6A91, 0x6A93, 0x6AA3, 0x6AC1, 0x6AC9, 0x6AE1, + 0x6AE7, 0x6B05, 0x6B0F, 0x6B11, 0x6B23, 0x6B27, 0x6B2D, 0x6B39, + 0x6B41, 0x6B57, 0x6B59, 0x6B5F, 0x6B75, 0x6B87, 0x6B89, 0x6B93, + 0x6B95, 0x6B9F, 0x6BBD, 0x6BBF, 0x6BDB, 0x6BE1, 0x6BEF, 0x6BFF, + 0x6C05, 0x6C19, 0x6C29, 0x6C2B, 0x6C31, 0x6C35, 0x6C55, 0x6C59, + 0x6C5B, 0x6C5F, 0x6C65, 0x6C67, 0x6C73, 0x6C77, 0x6C7D, 0x6C83, + 0x6C8F, 0x6C91, 0x6C97, 0x6C9B, 0x6CA1, 0x6CA9, 0x6CAF, 0x6CB3, + 0x6CC7, 0x6CCB, 0x6CEB, 0x6CF5, 0x6CFD, 0x6D0D, 0x6D0F, 0x6D25, + 0x6D27, 0x6D2B, 0x6D31, 0x6D39, 0x6D3F, 0x6D4F, 0x6D5D, 0x6D61, + 0x6D73, 0x6D7B, 0x6D7F, 0x6D93, 0x6D99, 0x6DA5, 0x6DB1, 0x6DB7, + 0x6DC1, 0x6DC3, 0x6DCD, 0x6DCF, 0x6DDB, 0x6DF7, 0x6E03, 0x6E15, + 0x6E17, 0x6E29, 0x6E33, 0x6E3B, 0x6E45, 0x6E75, 0x6E77, 0x6E7B, + 0x6E81, 0x6E89, 0x6E93, 0x6E95, 0x6E9F, 0x6EBD, 0x6EBF, 0x6EE3, + 0x6EE9, 0x6EF3, 0x6EF9, 0x6EFB, 0x6F0D, 0x6F11, 0x6F17, 0x6F1F, + 0x6F2F, 0x6F3D, 0x6F4D, 0x6F53, 0x6F61, 0x6F65, 0x6F79, 0x6F7D, + 0x6F83, 0x6F85, 0x6F8F, 0x6F9B, 0x6F9D, 0x6FA3, 0x6FAF, 0x6FB5, + 0x6FBB, 0x6FBF, 0x6FCB, 0x6FCD, 0x6FD3, 0x6FD7, 0x6FE3, 0x6FE9, + 0x6FF1, 0x6FF5, 0x6FF7, 0x6FFD, 0x700F, 0x7019, 0x701F, 0x7027, + 0x7033, 0x7039, 0x704F, 0x7051, 0x7057, 0x7063, 0x7075, 0x7079, + 0x7087, 0x708D, 0x7091, 0x70A5, 0x70AB, 0x70BB, 0x70C3, 0x70C7, + 0x70CF, 0x70E5, 0x70ED, 0x70F9, 0x70FF, 0x7105, 0x7115, 0x7121, + 0x7133, 0x7151, 0x7159, 0x715D, 0x715F, 0x7163, 0x7169, 0x7183, + 0x7187, 0x7195, 0x71AD, 0x71C3, 0x71C9, 0x71CB, 0x71D1, 0x71DB, + 0x71E1, 0x71EF, 0x71F5, 0x71FB, 0x7207, 0x7211, 0x7217, 0x7219, + 0x7225, 0x722F, 0x723B, 0x7243, 0x7255, 0x7267, 0x7271, 0x7277, + 0x727F, 0x728F, 0x7295, 0x729B, 0x72A3, 0x72B3, 0x72C7, 0x72CB, + 0x72CD, 0x72D7, 0x72D9, 0x72E3, 0x72EF, 0x72F5, 0x72FD, 0x7303, + 0x730D, 0x7321, 0x732B, 0x733D, 0x7357, 0x735B, 0x7361, 0x737F, + 0x7381, 0x7385, 0x738D, 0x7393, 0x739F, 0x73AB, 0x73BD, 0x73C1, + 0x73C9, 0x73DF, 0x73E5, 0x73E7, 0x73F3, 0x7415, 0x741B, 0x742D, + 0x7439, 0x743F, 0x7441, 0x745D, 0x746B, 0x747B, 0x7489, 0x748D, + 0x749B, 0x74A7, 0x74AB, 0x74B1, 0x74B7, 0x74B9, 0x74DD, 0x74E1, + 0x74E7, 0x74FB, 0x7507, 0x751F, 0x7525, 0x753B, 0x753D, 0x754D, + 0x755F, 0x756B, 0x7577, 0x7589, 0x758B, 0x7591, 0x7597, 0x759D, + 0x75A1, 0x75A7, 0x75B5, 0x75B9, 0x75BB, 0x75D1, 0x75D9, 0x75E5, + 0x75EB, 0x75F5, 0x75FB, 0x7603, 0x760F, 0x7621, 0x762D, 0x7633, + 0x763D, 0x763F, 0x7655, 0x7663, 0x7669, 0x766F, 0x7673, 0x7685, + 0x768B, 0x769F, 0x76B5, 0x76B7, 0x76C3, 0x76DB, 0x76DF, 0x76F1, + 0x7703, 0x7705, 0x771B, 0x771D, 0x7721, 0x772D, 0x7735, 0x7741, + 0x774B, 0x7759, 0x775D, 0x775F, 0x7771, 0x7781, 0x77A7, 0x77AD, + 0x77B3, 0x77B9, 0x77C5, 0x77CF, 0x77D5, 0x77E1, 0x77E9, 0x77EF, + 0x77F3, 0x77F9, 0x7807, 0x7825, 0x782B, 0x7835, 0x783D, 0x7853, + 0x7859, 0x7861, 0x786D, 0x7877, 0x7879, 0x7883, 0x7885, 0x788B, + 0x7895, 0x7897, 0x78A1, 0x78AD, 0x78BF, 0x78D3, 0x78D9, 0x78DD, + 0x78E5, 0x78FB, 0x7901, 0x7907, 0x7925, 0x792B, 0x7939, 0x793F, + 0x794B, 0x7957, 0x795D, 0x7967, 0x7969, 0x7973, 0x7991, 0x7993, + 0x79A3, 0x79AB, 0x79AF, 0x79B1, 0x79B7, 0x79C9, 0x79CD, 0x79CF, + 0x79D5, 0x79D9, 0x79F3, 0x79F7, 0x79FF, 0x7A05, 0x7A0F, 0x7A11, + 0x7A15, 0x7A1B, 0x7A23, 0x7A27, 0x7A2D, 0x7A4B, 0x7A57, 0x7A59, + 0x7A5F, 0x7A65, 0x7A69, 0x7A7D, 0x7A93, 0x7A9B, 0x7A9F, 0x7AA1, + 0x7AA5, 0x7AED, 0x7AF5, 0x7AF9, 0x7B01, 0x7B17, 0x7B19, 0x7B1D, + 0x7B2B, 0x7B35, 0x7B37, 0x7B3B, 0x7B4F, 0x7B55, 0x7B5F, 0x7B71, + 0x7B77, 0x7B8B, 0x7B9B, 0x7BA1, 0x7BA9, 0x7BAF, 0x7BB3, 0x7BC7, + 0x7BD3, 0x7BE9, 0x7BEB, 0x7BEF, 0x7BF1, 0x7BFD, 0x7C07, 0x7C19, + 0x7C1B, 0x7C31, 0x7C37, 0x7C49, 0x7C67, 0x7C69, 0x7C73, 0x7C81, + 0x7C8B, 0x7C93, 0x7CA3, 0x7CD5, 0x7CDB, 0x7CE5, 0x7CED, 0x7CF7, + 0x7D03, 0x7D09, 0x7D1B, 0x7D1D, 0x7D33, 0x7D39, 0x7D3B, 0x7D3F, + 0x7D45, 0x7D4D, 0x7D53, 0x7D59, 0x7D63, 0x7D75, 0x7D77, 0x7D8D, + 0x7D8F, 0x7D9F, 0x7DAD, 0x7DB7, 0x7DBD, 0x7DBF, 0x7DCB, 0x7DD5, + 0x7DE9, 0x7DED, 0x7DFB, 0x7E01, 0x7E05, 0x7E29, 0x7E2B, 0x7E2F, + 0x7E35, 0x7E41, 0x7E43, 0x7E47, 0x7E55, 0x7E61, 0x7E67, 0x7E6B, + 0x7E71, 0x7E73, 0x7E79, 0x7E7D, 0x7E91, 0x7E9B, 0x7E9D, 0x7EA7, + 0x7EAD, 0x7EB9, 0x7EBB, 0x7ED3, 0x7EDF, 0x7EEB, 0x7EF1, 0x7EF7, + 0x7EFB, 0x7F13, 0x7F15, 0x7F19, 0x7F31, 0x7F33, 0x7F39, 0x7F3D, + 0x7F43, 0x7F4B, 0x7F5B, 0x7F61, 0x7F63, 0x7F6D, 0x7F79, 0x7F87, + 0x7F8D, 0x7FAF, 0x7FB5, 0x7FC3, 0x7FC9, 0x7FCD, 0x7FCF, 0x7FED, + 0x8003, 0x800B, 0x800F, 0x8015, 0x801D, 0x8021, 0x8023, 0x803F, + 0x8041, 0x8047, 0x804B, 0x8065, 0x8077, 0x808D, 0x808F, 0x8095, + 0x80A5, 0x80AB, 0x80AD, 0x80BD, 0x80C9, 0x80CB, 0x80D7, 0x80DB, + 0x80E1, 0x80E7, 0x80F5, 0x80FF, 0x8105, 0x810D, 0x8119, 0x811D, + 0x812F, 0x8131, 0x813B, 0x8143, 0x8153, 0x8159, 0x815F, 0x817D, + 0x817F, 0x8189, 0x819B, 0x819D, 0x81A7, 0x81AF, 0x81B3, 0x81BB, + 0x81C7, 0x81DF, 0x8207, 0x8209, 0x8215, 0x821F, 0x8225, 0x8231, + 0x8233, 0x823F, 0x8243, 0x8245, 0x8249, 0x824F, 0x8261, 0x826F, + 0x827B, 0x8281, 0x8285, 0x8293, 0x82B1, 0x82B5, 0x82BD, 0x82C7, + 0x82CF, 0x82D5, 0x82DF, 0x82F1, 0x82F9, 0x82FD, 0x830B, 0x831B, + 0x8321, 0x8329, 0x832D, 0x8333, 0x8335, 0x833F, 0x8341, 0x834D, + 0x8351, 0x8353, 0x8357, 0x835D, 0x8365, 0x8369, 0x836F, 0x838F, + 0x83A7, 0x83B1, 0x83B9, 0x83CB, 0x83D5, 0x83D7, 0x83DD, 0x83E7, + 0x83E9, 0x83ED, 0x83FF, 0x8405, 0x8411, 0x8413, 0x8423, 0x8425, + 0x843B, 0x8441, 0x8447, 0x844F, 0x8461, 0x8465, 0x8477, 0x8483, + 0x848B, 0x8491, 0x8495, 0x84A9, 0x84AF, 0x84CD, 0x84E3, 0x84EF, + 0x84F1, 0x84F7, 0x8509, 0x850D, 0x854B, 0x854F, 0x8551, 0x855D, + 0x8563, 0x856D, 0x856F, 0x857B, 0x8587, 0x85A3, 0x85A5, 0x85A9, + 0x85B7, 0x85CD, 0x85D3, 0x85D5, 0x85DB, 0x85E1, 0x85EB, 0x85F9, + 0x85FD, 0x85FF, 0x8609, 0x860F, 0x8617, 0x8621, 0x862F, 0x8639, + 0x863F, 0x8641, 0x864D, 0x8663, 0x8675, 0x867D, 0x8687, 0x8699, + 0x86A5, 0x86A7, 0x86B3, 0x86B7, 0x86C3, 0x86C5, 0x86CF, 0x86D1, + 0x86D7, 0x86E9, 0x86EF, 0x86F5, 0x8717, 0x871D, 0x871F, 0x872B, + 0x872F, 0x8735, 0x8747, 0x8759, 0x875B, 0x876B, 0x8771, 0x8777, + 0x877F, 0x8785, 0x878F, 0x87A1, 0x87A9, 0x87B3, 0x87BB, 0x87C5, + 0x87C7, 0x87CB, 0x87DD, 0x87F7, 0x8803, 0x8819, 0x881B, 0x881F, + 0x8821, 0x8837, 0x883D, 0x8843, 0x8851, 0x8861, 0x8867, 0x887B, + 0x8885, 0x8891, 0x8893, 0x88A5, 0x88CF, 0x88D3, 0x88EB, 0x88ED, + 0x88F3, 0x88FD, 0x8909, 0x890B, 0x8911, 0x891B, 0x8923, 0x8927, + 0x892D, 0x8939, 0x8945, 0x894D, 0x8951, 0x8957, 0x8963, 0x8981, + 0x8995, 0x899B, 0x89B3, 0x89B9, 0x89C3, 0x89CF, 0x89D1, 0x89DB, + 0x89EF, 0x89F5, 0x89FB, 0x89FF, 0x8A0B, 0x8A19, 0x8A23, 0x8A35, + 0x8A41, 0x8A49, 0x8A4F, 0x8A5B, 0x8A5F, 0x8A6D, 0x8A77, 0x8A79, + 0x8A85, 0x8AA3, 0x8AB3, 0x8AB5, 0x8AC1, 0x8AC7, 0x8ACB, 0x8ACD, + 0x8AD1, 0x8AD7, 0x8AF1, 0x8AF5, 0x8B07, 0x8B09, 0x8B0D, 0x8B13, + 0x8B21, 0x8B57, 0x8B5D, 0x8B91, 0x8B93, 0x8BA3, 0x8BA9, 0x8BAF, + 0x8BBB, 0x8BD5, 0x8BD9, 0x8BDB, 0x8BE1, 0x8BF7, 0x8BFD, 0x8BFF, + 0x8C0B, 0x8C17, 0x8C1D, 0x8C27, 0x8C39, 0x8C3B, 0x8C47, 0x8C53, + 0x8C5D, 0x8C6F, 0x8C7B, 0x8C81, 0x8C89, 0x8C8F, 0x8C99, 0x8C9F, + 0x8CA7, 0x8CAB, 0x8CAD, 0x8CB1, 0x8CC5, 0x8CDD, 0x8CE3, 0x8CE9, + 0x8CF3, 0x8D01, 0x8D0B, 0x8D0D, 0x8D23, 0x8D29, 0x8D37, 0x8D41, + 0x8D5B, 0x8D5F, 0x8D71, 0x8D79, 0x8D85, 0x8D91, 0x8D9B, 0x8DA7, + 0x8DAD, 0x8DB5, 0x8DC5, 0x8DCB, 0x8DD3, 0x8DD9, 0x8DDF, 0x8DF5, + 0x8DF7, 0x8E01, 0x8E15, 0x8E1F, 0x8E25, 0x8E51, 0x8E63, 0x8E69, + 0x8E73, 0x8E75, 0x8E79, 0x8E7F, 0x8E8D, 0x8E91, 0x8EAB, 0x8EAF, + 0x8EB1, 0x8EBD, 0x8EC7, 0x8ECF, 0x8ED3, 0x8EDB, 0x8EE7, 0x8EEB, + 0x8EF7, 0x8EFF, 0x8F15, 0x8F1D, 0x8F23, 0x8F2D, 0x8F3F, 0x8F45, + 0x8F4B, 0x8F53, 0x8F59, 0x8F65, 0x8F69, 0x8F71, 0x8F83, 0x8F8D, + 0x8F99, 0x8F9F, 0x8FAB, 0x8FAD, 0x8FB3, 0x8FB7, 0x8FB9, 0x8FC9, + 0x8FD5, 0x8FE1, 0x8FEF, 0x8FF9, 0x9007, 0x900D, 0x9017, 0x9023, + 0x9025, 0x9031, 0x9037, 0x903B, 0x9041, 0x9043, 0x904F, 0x9053, + 0x906D, 0x9073, 0x9085, 0x908B, 0x9095, 0x909B, 0x909D, 0x90AF, + 0x90B9, 0x90C1, 0x90C5, 0x90DF, 0x90E9, 0x90FD, 0x9103, 0x9113, + 0x9127, 0x9133, 0x913D, 0x9145, 0x914F, 0x9151, 0x9161, 0x9167, + 0x917B, 0x9185, 0x9199, 0x919D, 0x91BB, 0x91BD, 0x91C1, 0x91C9, + 0x91D9, 0x91DB, 0x91ED, 0x91F1, 0x91F3, 0x91F9, 0x9203, 0x9215, + 0x9221, 0x922F, 0x9241, 0x9247, 0x9257, 0x926B, 0x9271, 0x9275, + 0x927D, 0x9283, 0x9287, 0x928D, 0x9299, 0x92A1, 0x92AB, 0x92AD, + 0x92B9, 0x92BF, 0x92C3, 0x92C5, 0x92CB, 0x92D5, 0x92D7, 0x92E7, + 0x92F3, 0x9301, 0x930B, 0x9311, 0x9319, 0x931F, 0x933B, 0x933D, + 0x9343, 0x9355, 0x9373, 0x9395, 0x9397, 0x93A7, 0x93B3, 0x93B5, + 0x93C7, 0x93D7, 0x93DD, 0x93E5, 0x93EF, 0x93F7, 0x9401, 0x9409, + 0x9413, 0x943F, 0x9445, 0x944B, 0x944F, 0x9463, 0x9467, 0x9469, + 0x946D, 0x947B, 0x9497, 0x949F, 0x94A5, 0x94B5, 0x94C3, 0x94E1, + 0x94E7, 0x9505, 0x9509, 0x9517, 0x9521, 0x9527, 0x952D, 0x9535, + 0x9539, 0x954B, 0x9557, 0x955D, 0x955F, 0x9575, 0x9581, 0x9589, + 0x958F, 0x959B, 0x959F, 0x95AD, 0x95B1, 0x95B7, 0x95B9, 0x95BD, + 0x95CF, 0x95E3, 0x95E9, 0x95F9, 0x961F, 0x962F, 0x9631, 0x9635, + 0x963B, 0x963D, 0x9665, 0x968F, 0x969D, 0x96A1, 0x96A7, 0x96A9, + 0x96C1, 0x96CB, 0x96D1, 0x96D3, 0x96E5, 0x96EF, 0x96FB, 0x96FD, + 0x970D, 0x970F, 0x9715, 0x9725, 0x972B, 0x9733, 0x9737, 0x9739, + 0x9743, 0x9749, 0x9751, 0x975B, 0x975D, 0x976F, 0x977F, 0x9787, + 0x9793, 0x97A5, 0x97B1, 0x97B7, 0x97C3, 0x97CD, 0x97D3, 0x97D9, + 0x97EB, 0x97F7, 0x9805, 0x9809, 0x980B, 0x9815, 0x9829, 0x982F, + 0x983B, 0x9841, 0x9851, 0x986B, 0x986F, 0x9881, 0x9883, 0x9887, + 0x98A7, 0x98B1, 0x98B9, 0x98BF, 0x98C3, 0x98C9, 0x98CF, 0x98DD, + 0x98E3, 0x98F5, 0x98F9, 0x98FB, 0x990D, 0x9917, 0x991F, 0x9929, + 0x9931, 0x993B, 0x993D, 0x9941, 0x9947, 0x9949, 0x9953, 0x997D, + 0x9985, 0x9991, 0x9995, 0x999B, 0x99AD, 0x99AF, 0x99BF, 0x99C7, + 0x99CB, 0x99CD, 0x99D7, 0x99E5, 0x99F1, 0x99FB, 0x9A0F, 0x9A13, + 0x9A1B, 0x9A25, 0x9A4B, 0x9A4F, 0x9A55, 0x9A57, 0x9A61, 0x9A75, + 0x9A7F, 0x9A8B, 0x9A91, 0x9A9D, 0x9AB7, 0x9AC3, 0x9AC7, 0x9ACF, + 0x9AEB, 0x9AF3, 0x9AF7, 0x9AFF, 0x9B17, 0x9B1D, 0x9B27, 0x9B2F, + 0x9B35, 0x9B45, 0x9B51, 0x9B59, 0x9B63, 0x9B6F, 0x9B77, 0x9B8D, + 0x9B93, 0x9B95, 0x9B9F, 0x9BA1, 0x9BA7, 0x9BB1, 0x9BB7, 0x9BBD, + 0x9BC5, 0x9BCB, 0x9BCF, 0x9BDD, 0x9BF9, 0x9C01, 0x9C11, 0x9C23, + 0x9C2B, 0x9C2F, 0x9C35, 0x9C49, 0x9C4D, 0x9C5F, 0x9C65, 0x9C67, + 0x9C7F, 0x9C97, 0x9C9D, 0x9CA3, 0x9CAF, 0x9CBB, 0x9CBF, 0x9CC1, + 0x9CD7, 0x9CD9, 0x9CE3, 0x9CE9, 0x9CF1, 0x9CFD, 0x9D01, 0x9D15, + 0x9D27, 0x9D2D, 0x9D31, 0x9D3D, 0x9D55, 0x9D5B, 0x9D61, 0x9D97, + 0x9D9F, 0x9DA5, 0x9DA9, 0x9DC3, 0x9DE7, 0x9DEB, 0x9DED, 0x9DF1, + 0x9E0B, 0x9E17, 0x9E23, 0x9E27, 0x9E2D, 0x9E33, 0x9E3B, 0x9E47, + 0x9E51, 0x9E53, 0x9E5F, 0x9E6F, 0x9E81, 0x9E87, 0x9E8F, 0x9E95, + 0x9EA1, 0x9EB3, 0x9EBD, 0x9EBF, 0x9EF5, 0x9EF9, 0x9EFB, 0x9F05, + 0x9F23, 0x9F2F, 0x9F37, 0x9F3B, 0x9F43, 0x9F53, 0x9F61, 0x9F6D, + 0x9F73, 0x9F77, 0x9F7D, 0x9F89, 0x9F8F, 0x9F91, 0x9F95, 0x9FA3, + 0x9FAF, 0x9FB3, 0x9FC1, 0x9FC7, 0x9FDF, 0x9FE5, 0x9FEB, 0x9FF5, + 0xA001, 0xA00D, 0xA021, 0xA033, 0xA039, 0xA03F, 0xA04F, 0xA057, + 0xA05B, 0xA061, 0xA075, 0xA079, 0xA099, 0xA09D, 0xA0AB, 0xA0B5, + 0xA0B7, 0xA0BD, 0xA0C9, 0xA0D9, 0xA0DB, 0xA0DF, 0xA0E5, 0xA0F1, + 0xA0F3, 0xA0FD, 0xA105, 0xA10B, 0xA10F, 0xA111, 0xA11B, 0xA129, + 0xA12F, 0xA135, 0xA141, 0xA153, 0xA175, 0xA17D, 0xA187, 0xA18D, + 0xA1A5, 0xA1AB, 0xA1AD, 0xA1B7, 0xA1C3, 0xA1C5, 0xA1E3, 0xA1ED, + 0xA1FB, 0xA207, 0xA213, 0xA223, 0xA229, 0xA22F, 0xA231, 0xA243, + 0xA247, 0xA24D, 0xA26B, 0xA279, 0xA27D, 0xA283, 0xA289, 0xA28B, + 0xA291, 0xA295, 0xA29B, 0xA2A9, 0xA2AF, 0xA2B3, 0xA2BB, 0xA2C5, + 0xA2D1, 0xA2D7, 0xA2F7, 0xA301, 0xA309, 0xA31F, 0xA321, 0xA32B, + 0xA331, 0xA349, 0xA351, 0xA355, 0xA373, 0xA379, 0xA37B, 0xA387, + 0xA397, 0xA39F, 0xA3A5, 0xA3A9, 0xA3AF, 0xA3B7, 0xA3C7, 0xA3D5, + 0xA3DB, 0xA3E1, 0xA3E5, 0xA3E7, 0xA3F1, 0xA3FD, 0xA3FF, 0xA40F, + 0xA41D, 0xA421, 0xA423, 0xA427, 0xA43B, 0xA44D, 0xA457, 0xA459, + 0xA463, 0xA469, 0xA475, 0xA493, 0xA49B, 0xA4AD, 0xA4B9, 0xA4C3, + 0xA4C5, 0xA4CB, 0xA4D1, 0xA4D5, 0xA4E1, 0xA4ED, 0xA4EF, 0xA4F3, + 0xA4FF, 0xA511, 0xA529, 0xA52B, 0xA535, 0xA53B, 0xA543, 0xA553, + 0xA55B, 0xA561, 0xA56D, 0xA577, 0xA585, 0xA58B, 0xA597, 0xA59D, + 0xA5A3, 0xA5A7, 0xA5A9, 0xA5C1, 0xA5C5, 0xA5CB, 0xA5D3, 0xA5D9, + 0xA5DD, 0xA5DF, 0xA5E3, 0xA5E9, 0xA5F7, 0xA5FB, 0xA603, 0xA60D, + 0xA625, 0xA63D, 0xA649, 0xA64B, 0xA651, 0xA65D, 0xA673, 0xA691, + 0xA693, 0xA699, 0xA6AB, 0xA6B5, 0xA6BB, 0xA6C1, 0xA6C9, 0xA6CD, + 0xA6CF, 0xA6D5, 0xA6DF, 0xA6E7, 0xA6F1, 0xA6F7, 0xA6FF, 0xA70F, + 0xA715, 0xA723, 0xA729, 0xA72D, 0xA745, 0xA74D, 0xA757, 0xA759, + 0xA765, 0xA76B, 0xA76F, 0xA793, 0xA795, 0xA7AB, 0xA7B1, 0xA7B9, + 0xA7BF, 0xA7C9, 0xA7D1, 0xA7D7, 0xA7E3, 0xA7ED, 0xA7FB, 0xA805, + 0xA80B, 0xA81D, 0xA829, 0xA82B, 0xA837, 0xA83B, 0xA855, 0xA85F, + 0xA86D, 0xA87D, 0xA88F, 0xA897, 0xA8A9, 0xA8B5, 0xA8C1, 0xA8C7, + 0xA8D7, 0xA8E5, 0xA8FD, 0xA907, 0xA913, 0xA91B, 0xA931, 0xA937, + 0xA939, 0xA943, 0xA97F, 0xA985, 0xA987, 0xA98B, 0xA993, 0xA9A3, + 0xA9B1, 0xA9BB, 0xA9C1, 0xA9D9, 0xA9DF, 0xA9EB, 0xA9FD, 0xAA15, + 0xAA17, 0xAA35, 0xAA39, 0xAA3B, 0xAA47, 0xAA4D, 0xAA57, 0xAA59, + 0xAA5D, 0xAA6B, 0xAA71, 0xAA81, 0xAA83, 0xAA8D, 0xAA95, 0xAAAB, + 0xAABF, 0xAAC5, 0xAAC9, 0xAAE9, 0xAAEF, 0xAB01, 0xAB05, 0xAB07, + 0xAB0B, 0xAB0D, 0xAB11, 0xAB19, 0xAB4D, 0xAB5B, 0xAB71, 0xAB73, + 0xAB89, 0xAB9D, 0xABA7, 0xABAF, 0xABB9, 0xABBB, 0xABC1, 0xABC5, + 0xABD3, 0xABD7, 0xABDD, 0xABF1, 0xABF5, 0xABFB, 0xABFD, 0xAC09, + 0xAC15, 0xAC1B, 0xAC27, 0xAC37, 0xAC39, 0xAC45, 0xAC4F, 0xAC57, + 0xAC5B, 0xAC61, 0xAC63, 0xAC7F, 0xAC8B, 0xAC93, 0xAC9D, 0xACA9, + 0xACAB, 0xACAF, 0xACBD, 0xACD9, 0xACE1, 0xACE7, 0xACEB, 0xACED, + 0xACF1, 0xACF7, 0xACF9, 0xAD05, 0xAD3F, 0xAD45, 0xAD53, 0xAD5D, + 0xAD5F, 0xAD65, 0xAD81, 0xADA1, 0xADA5, 0xADC3, 0xADCB, 0xADD1, + 0xADD5, 0xADDB, 0xADE7, 0xADF3, 0xADF5, 0xADF9, 0xADFF, 0xAE05, + 0xAE13, 0xAE23, 0xAE2B, 0xAE49, 0xAE4D, 0xAE4F, 0xAE59, 0xAE61, + 0xAE67, 0xAE6B, 0xAE71, 0xAE8B, 0xAE8F, 0xAE9B, 0xAE9D, 0xAEA7, + 0xAEB9, 0xAEC5, 0xAED1, 0xAEE3, 0xAEE5, 0xAEE9, 0xAEF5, 0xAEFD, + 0xAF09, 0xAF13, 0xAF27, 0xAF2B, 0xAF33, 0xAF43, 0xAF4F, 0xAF57, + 0xAF5D, 0xAF6D, 0xAF75, 0xAF7F, 0xAF8B, 0xAF99, 0xAF9F, 0xAFA3, + 0xAFAB, 0xAFB7, 0xAFBB, 0xAFCF, 0xAFD5, 0xAFFD, 0xB005, 0xB015, + 0xB01B, 0xB03F, 0xB041, 0xB047, 0xB04B, 0xB051, 0xB053, 0xB069, + 0xB07B, 0xB07D, 0xB087, 0xB08D, 0xB0B1, 0xB0BF, 0xB0CB, 0xB0CF, + 0xB0E1, 0xB0E9, 0xB0ED, 0xB0FB, 0xB105, 0xB107, 0xB111, 0xB119, + 0xB11D, 0xB11F, 0xB131, 0xB141, 0xB14D, 0xB15B, 0xB165, 0xB173, + 0xB179, 0xB17F, 0xB1A9, 0xB1B3, 0xB1B9, 0xB1BF, 0xB1D3, 0xB1DD, + 0xB1E5, 0xB1F1, 0xB1F5, 0xB201, 0xB213, 0xB215, 0xB21F, 0xB22D, + 0xB23F, 0xB249, 0xB25B, 0xB263, 0xB269, 0xB26D, 0xB27B, 0xB281, + 0xB28B, 0xB2A9, 0xB2B7, 0xB2BD, 0xB2C3, 0xB2C7, 0xB2D3, 0xB2F9, + 0xB2FD, 0xB2FF, 0xB303, 0xB309, 0xB311, 0xB31D, 0xB327, 0xB32D, + 0xB33F, 0xB345, 0xB377, 0xB37D, 0xB381, 0xB387, 0xB393, 0xB39B, + 0xB3A5, 0xB3C5, 0xB3CB, 0xB3E1, 0xB3E3, 0xB3ED, 0xB3F9, 0xB40B, + 0xB40D, 0xB413, 0xB417, 0xB435, 0xB43D, 0xB443, 0xB449, 0xB45B, + 0xB465, 0xB467, 0xB46B, 0xB477, 0xB48B, 0xB495, 0xB49D, 0xB4B5, + 0xB4BF, 0xB4C1, 0xB4C7, 0xB4DD, 0xB4E3, 0xB4E5, 0xB4F7, 0xB501, + 0xB50D, 0xB50F, 0xB52D, 0xB53F, 0xB54B, 0xB567, 0xB569, 0xB56F, + 0xB573, 0xB579, 0xB587, 0xB58D, 0xB599, 0xB5A3, 0xB5AB, 0xB5AF, + 0xB5BB, 0xB5D5, 0xB5DF, 0xB5E7, 0xB5ED, 0xB5FD, 0xB5FF, 0xB609, + 0xB61B, 0xB629, 0xB62F, 0xB633, 0xB639, 0xB647, 0xB657, 0xB659, + 0xB65F, 0xB663, 0xB66F, 0xB683, 0xB687, 0xB69B, 0xB69F, 0xB6A5, + 0xB6B1, 0xB6B3, 0xB6D7, 0xB6DB, 0xB6E1, 0xB6E3, 0xB6ED, 0xB6EF, + 0xB705, 0xB70D, 0xB713, 0xB71D, 0xB729, 0xB735, 0xB747, 0xB755, + 0xB76D, 0xB791, 0xB795, 0xB7A9, 0xB7C1, 0xB7CB, 0xB7D1, 0xB7D3, + 0xB7EF, 0xB7F5, 0xB807, 0xB80F, 0xB813, 0xB819, 0xB821, 0xB827, + 0xB82B, 0xB82D, 0xB839, 0xB855, 0xB867, 0xB875, 0xB885, 0xB893, + 0xB8A5, 0xB8AF, 0xB8B7, 0xB8BD, 0xB8C1, 0xB8C7, 0xB8CD, 0xB8D5, + 0xB8EB, 0xB8F7, 0xB8F9, 0xB903, 0xB915, 0xB91B, 0xB91D, 0xB92F, + 0xB939, 0xB93B, 0xB947, 0xB951, 0xB963, 0xB983, 0xB989, 0xB98D, + 0xB993, 0xB999, 0xB9A1, 0xB9A7, 0xB9AD, 0xB9B7, 0xB9CB, 0xB9D1, + 0xB9DD, 0xB9E7, 0xB9EF, 0xB9F9, 0xBA07, 0xBA0D, 0xBA17, 0xBA25, + 0xBA29, 0xBA2B, 0xBA41, 0xBA53, 0xBA55, 0xBA5F, 0xBA61, 0xBA65, + 0xBA79, 0xBA7D, 0xBA7F, 0xBAA1, 0xBAA3, 0xBAAF, 0xBAB5, 0xBABF, + 0xBAC1, 0xBACB, 0xBADD, 0xBAE3, 0xBAF1, 0xBAFD, 0xBB09, 0xBB1F, + 0xBB27, 0xBB2D, 0xBB3D, 0xBB43, 0xBB4B, 0xBB4F, 0xBB5B, 0xBB61, + 0xBB69, 0xBB6D, 0xBB91, 0xBB97, 0xBB9D, 0xBBB1, 0xBBC9, 0xBBCF, + 0xBBDB, 0xBBED, 0xBBF7, 0xBBF9, 0xBC03, 0xBC1D, 0xBC23, 0xBC33, + 0xBC3B, 0xBC41, 0xBC45, 0xBC5D, 0xBC6F, 0xBC77, 0xBC83, 0xBC8F, + 0xBC99, 0xBCAB, 0xBCB7, 0xBCB9, 0xBCD1, 0xBCD5, 0xBCE1, 0xBCF3, + 0xBCFF, 0xBD0D, 0xBD17, 0xBD19, 0xBD1D, 0xBD35, 0xBD41, 0xBD4F, + 0xBD59, 0xBD5F, 0xBD61, 0xBD67, 0xBD6B, 0xBD71, 0xBD8B, 0xBD8F, + 0xBD95, 0xBD9B, 0xBD9D, 0xBDB3, 0xBDBB, 0xBDCD, 0xBDD1, 0xBDE3, + 0xBDEB, 0xBDEF, 0xBE07, 0xBE09, 0xBE15, 0xBE21, 0xBE25, 0xBE27, + 0xBE5B, 0xBE5D, 0xBE6F, 0xBE75, 0xBE79, 0xBE7F, 0xBE8B, 0xBE8D, + 0xBE93, 0xBE9F, 0xBEA9, 0xBEB1, 0xBEB5, 0xBEB7, 0xBECF, 0xBED9, + 0xBEDB, 0xBEE5, 0xBEE7, 0xBEF3, 0xBEF9, 0xBF0B, 0xBF33, 0xBF39, + 0xBF4D, 0xBF5D, 0xBF5F, 0xBF6B, 0xBF71, 0xBF7B, 0xBF87, 0xBF89, + 0xBF8D, 0xBF93, 0xBFA1, 0xBFAD, 0xBFB9, 0xBFCF, 0xBFD5, 0xBFDD, + 0xBFE1, 0xBFE3, 0xBFF3, 0xC005, 0xC011, 0xC013, 0xC019, 0xC029, + 0xC02F, 0xC031, 0xC037, 0xC03B, 0xC047, 0xC065, 0xC06D, 0xC07D, + 0xC07F, 0xC091, 0xC09B, 0xC0B3, 0xC0B5, 0xC0BB, 0xC0D3, 0xC0D7, + 0xC0D9, 0xC0EF, 0xC0F1, 0xC101, 0xC103, 0xC109, 0xC115, 0xC119, + 0xC12B, 0xC133, 0xC137, 0xC145, 0xC149, 0xC15B, 0xC173, 0xC179, + 0xC17B, 0xC181, 0xC18B, 0xC18D, 0xC197, 0xC1BD, 0xC1C3, 0xC1CD, + 0xC1DB, 0xC1E1, 0xC1E7, 0xC1FF, 0xC203, 0xC205, 0xC211, 0xC221, + 0xC22F, 0xC23F, 0xC24B, 0xC24D, 0xC253, 0xC25D, 0xC277, 0xC27B, + 0xC27D, 0xC289, 0xC28F, 0xC293, 0xC29F, 0xC2A7, 0xC2B3, 0xC2BD, + 0xC2CF, 0xC2D5, 0xC2E3, 0xC2FF, 0xC301, 0xC307, 0xC311, 0xC313, + 0xC317, 0xC325, 0xC347, 0xC349, 0xC34F, 0xC365, 0xC367, 0xC371, + 0xC37F, 0xC383, 0xC385, 0xC395, 0xC39D, 0xC3A7, 0xC3AD, 0xC3B5, + 0xC3BF, 0xC3C7, 0xC3CB, 0xC3D1, 0xC3D3, 0xC3E3, 0xC3E9, 0xC3EF, + 0xC401, 0xC41F, 0xC42D, 0xC433, 0xC437, 0xC455, 0xC457, 0xC461, + 0xC46F, 0xC473, 0xC487, 0xC491, 0xC499, 0xC49D, 0xC4A5, 0xC4B7, + 0xC4BB, 0xC4C9, 0xC4CF, 0xC4D3, 0xC4EB, 0xC4F1, 0xC4F7, 0xC509, + 0xC51B, 0xC51D, 0xC541, 0xC547, 0xC551, 0xC55F, 0xC56B, 0xC56F, + 0xC575, 0xC577, 0xC595, 0xC59B, 0xC59F, 0xC5A1, 0xC5A7, 0xC5C3, + 0xC5D7, 0xC5DB, 0xC5EF, 0xC5FB, 0xC613, 0xC623, 0xC635, 0xC641, + 0xC64F, 0xC655, 0xC659, 0xC665, 0xC685, 0xC691, 0xC697, 0xC6A1, + 0xC6A9, 0xC6B3, 0xC6B9, 0xC6CB, 0xC6CD, 0xC6DD, 0xC6EB, 0xC6F1, + 0xC707, 0xC70D, 0xC719, 0xC71B, 0xC72D, 0xC731, 0xC739, 0xC757, + 0xC763, 0xC767, 0xC773, 0xC775, 0xC77F, 0xC7A5, 0xC7BB, 0xC7BD, + 0xC7C1, 0xC7CF, 0xC7D5, 0xC7E1, 0xC7F9, 0xC7FD, 0xC7FF, 0xC803, + 0xC811, 0xC81D, 0xC827, 0xC829, 0xC839, 0xC83F, 0xC853, 0xC857, + 0xC86B, 0xC881, 0xC88D, 0xC88F, 0xC893, 0xC895, 0xC8A1, 0xC8B7, + 0xC8CF, 0xC8D5, 0xC8DB, 0xC8DD, 0xC8E3, 0xC8E7, 0xC8ED, 0xC8EF, + 0xC8F9, 0xC905, 0xC911, 0xC917, 0xC919, 0xC91F, 0xC92F, 0xC937, + 0xC93D, 0xC941, 0xC953, 0xC95F, 0xC96B, 0xC979, 0xC97D, 0xC989, + 0xC98F, 0xC997, 0xC99D, 0xC9AF, 0xC9B5, 0xC9BF, 0xC9CB, 0xC9D9, + 0xC9DF, 0xC9E3, 0xC9EB, 0xCA01, 0xCA07, 0xCA09, 0xCA25, 0xCA37, + 0xCA39, 0xCA4B, 0xCA55, 0xCA5B, 0xCA69, 0xCA73, 0xCA75, 0xCA7F, + 0xCA8D, 0xCA93, 0xCA9D, 0xCA9F, 0xCAB5, 0xCABB, 0xCAC3, 0xCAC9, + 0xCAD9, 0xCAE5, 0xCAED, 0xCB03, 0xCB05, 0xCB09, 0xCB17, 0xCB29, + 0xCB35, 0xCB3B, 0xCB53, 0xCB59, 0xCB63, 0xCB65, 0xCB71, 0xCB87, + 0xCB99, 0xCB9F, 0xCBB3, 0xCBB9, 0xCBC3, 0xCBD1, 0xCBD5, 0xCBD7, + 0xCBDD, 0xCBE9, 0xCBFF, 0xCC0D, 0xCC19, 0xCC1D, 0xCC23, 0xCC2B, + 0xCC41, 0xCC43, 0xCC4D, 0xCC59, 0xCC61, 0xCC89, 0xCC8B, 0xCC91, + 0xCC9B, 0xCCA3, 0xCCA7, 0xCCD1, 0xCCE5, 0xCCE9, 0xCD09, 0xCD15, + 0xCD1F, 0xCD25, 0xCD31, 0xCD3D, 0xCD3F, 0xCD49, 0xCD51, 0xCD57, + 0xCD5B, 0xCD63, 0xCD67, 0xCD81, 0xCD93, 0xCD97, 0xCD9F, 0xCDBB, + 0xCDC1, 0xCDD3, 0xCDD9, 0xCDE5, 0xCDE7, 0xCDF1, 0xCDF7, 0xCDFD, + 0xCE0B, 0xCE15, 0xCE21, 0xCE2F, 0xCE47, 0xCE4D, 0xCE51, 0xCE65, + 0xCE7B, 0xCE7D, 0xCE8F, 0xCE93, 0xCE99, 0xCEA5, 0xCEA7, 0xCEB7, + 0xCEC9, 0xCED7, 0xCEDD, 0xCEE3, 0xCEE7, 0xCEED, 0xCEF5, 0xCF07, + 0xCF0B, 0xCF19, 0xCF37, 0xCF3B, 0xCF4D, 0xCF55, 0xCF5F, 0xCF61, + 0xCF65, 0xCF6D, 0xCF79, 0xCF7D, 0xCF89, 0xCF9B, 0xCF9D, 0xCFA9, + 0xCFB3, 0xCFB5, 0xCFC5, 0xCFCD, 0xCFD1, 0xCFEF, 0xCFF1, 0xCFF7, + 0xD013, 0xD015, 0xD01F, 0xD021, 0xD033, 0xD03D, 0xD04B, 0xD04F, + 0xD069, 0xD06F, 0xD081, 0xD085, 0xD099, 0xD09F, 0xD0A3, 0xD0AB, + 0xD0BD, 0xD0C1, 0xD0CD, 0xD0E7, 0xD0FF, 0xD103, 0xD117, 0xD12D, + 0xD12F, 0xD141, 0xD157, 0xD159, 0xD15D, 0xD169, 0xD16B, 0xD171, + 0xD177, 0xD17D, 0xD181, 0xD187, 0xD195, 0xD199, 0xD1B1, 0xD1BD, + 0xD1C3, 0xD1D5, 0xD1D7, 0xD1E3, 0xD1FF, 0xD20D, 0xD211, 0xD217, + 0xD21F, 0xD235, 0xD23B, 0xD247, 0xD259, 0xD261, 0xD265, 0xD279, + 0xD27F, 0xD283, 0xD289, 0xD28B, 0xD29D, 0xD2A3, 0xD2A7, 0xD2B3, + 0xD2BF, 0xD2C7, 0xD2E3, 0xD2E9, 0xD2F1, 0xD2FB, 0xD2FD, 0xD315, + 0xD321, 0xD32B, 0xD343, 0xD34B, 0xD355, 0xD369, 0xD375, 0xD37B, + 0xD387, 0xD393, 0xD397, 0xD3A5, 0xD3B1, 0xD3C9, 0xD3EB, 0xD3FD, + 0xD405, 0xD40F, 0xD415, 0xD427, 0xD42F, 0xD433, 0xD43B, 0xD44B, + 0xD459, 0xD45F, 0xD463, 0xD469, 0xD481, 0xD483, 0xD489, 0xD48D, + 0xD493, 0xD495, 0xD4A5, 0xD4AB, 0xD4B1, 0xD4C5, 0xD4DD, 0xD4E1, + 0xD4E3, 0xD4E7, 0xD4F5, 0xD4F9, 0xD50B, 0xD50D, 0xD513, 0xD51F, + 0xD523, 0xD531, 0xD535, 0xD537, 0xD549, 0xD559, 0xD55F, 0xD565, + 0xD567, 0xD577, 0xD58B, 0xD591, 0xD597, 0xD5B5, 0xD5B9, 0xD5C1, + 0xD5C7, 0xD5DF, 0xD5EF, 0xD5F5, 0xD5FB, 0xD603, 0xD60F, 0xD62D, + 0xD631, 0xD643, 0xD655, 0xD65D, 0xD661, 0xD67B, 0xD685, 0xD687, + 0xD69D, 0xD6A5, 0xD6AF, 0xD6BD, 0xD6C3, 0xD6C7, 0xD6D9, 0xD6E1, + 0xD6ED, 0xD709, 0xD70B, 0xD711, 0xD715, 0xD721, 0xD727, 0xD73F, + 0xD745, 0xD74D, 0xD757, 0xD76B, 0xD77B, 0xD783, 0xD7A1, 0xD7A7, + 0xD7AD, 0xD7B1, 0xD7B3, 0xD7BD, 0xD7CB, 0xD7D1, 0xD7DB, 0xD7FB, + 0xD811, 0xD823, 0xD825, 0xD829, 0xD82B, 0xD82F, 0xD837, 0xD84D, + 0xD855, 0xD867, 0xD873, 0xD88F, 0xD891, 0xD8A1, 0xD8AD, 0xD8BF, + 0xD8CD, 0xD8D7, 0xD8E9, 0xD8F5, 0xD8FB, 0xD91B, 0xD925, 0xD933, + 0xD939, 0xD943, 0xD945, 0xD94F, 0xD951, 0xD957, 0xD96D, 0xD96F, + 0xD973, 0xD979, 0xD981, 0xD98B, 0xD991, 0xD99F, 0xD9A5, 0xD9A9, + 0xD9B5, 0xD9D3, 0xD9EB, 0xD9F1, 0xD9F7, 0xD9FF, 0xDA05, 0xDA09, + 0xDA0B, 0xDA0F, 0xDA15, 0xDA1D, 0xDA23, 0xDA29, 0xDA3F, 0xDA51, + 0xDA59, 0xDA5D, 0xDA5F, 0xDA71, 0xDA77, 0xDA7B, 0xDA7D, 0xDA8D, + 0xDA9F, 0xDAB3, 0xDABD, 0xDAC3, 0xDAC9, 0xDAE7, 0xDAE9, 0xDAF5, + 0xDB11, 0xDB17, 0xDB1D, 0xDB23, 0xDB25, 0xDB31, 0xDB3B, 0xDB43, + 0xDB55, 0xDB67, 0xDB6B, 0xDB73, 0xDB85, 0xDB8F, 0xDB91, 0xDBAD, + 0xDBAF, 0xDBB9, 0xDBC7, 0xDBCB, 0xDBCD, 0xDBEB, 0xDBF7, 0xDC0D, + 0xDC27, 0xDC31, 0xDC39, 0xDC3F, 0xDC49, 0xDC51, 0xDC61, 0xDC6F, + 0xDC75, 0xDC7B, 0xDC85, 0xDC93, 0xDC99, 0xDC9D, 0xDC9F, 0xDCA9, + 0xDCB5, 0xDCB7, 0xDCBD, 0xDCC7, 0xDCCF, 0xDCD3, 0xDCD5, 0xDCDF, + 0xDCF9, 0xDD0F, 0xDD15, 0xDD17, 0xDD23, 0xDD35, 0xDD39, 0xDD53, + 0xDD57, 0xDD5F, 0xDD69, 0xDD6F, 0xDD7D, 0xDD87, 0xDD89, 0xDD9B, + 0xDDA1, 0xDDAB, 0xDDBF, 0xDDC5, 0xDDCB, 0xDDCF, 0xDDE7, 0xDDE9, + 0xDDED, 0xDDF5, 0xDDFB, 0xDE0B, 0xDE19, 0xDE29, 0xDE3B, 0xDE3D, + 0xDE41, 0xDE4D, 0xDE4F, 0xDE59, 0xDE5B, 0xDE61, 0xDE6D, 0xDE77, + 0xDE7D, 0xDE83, 0xDE97, 0xDE9D, 0xDEA1, 0xDEA7, 0xDECD, 0xDED1, + 0xDED7, 0xDEE3, 0xDEF1, 0xDEF5, 0xDF01, 0xDF09, 0xDF13, 0xDF1F, + 0xDF2B, 0xDF33, 0xDF37, 0xDF3D, 0xDF4B, 0xDF55, 0xDF5B, 0xDF67, + 0xDF69, 0xDF73, 0xDF85, 0xDF87, 0xDF99, 0xDFA3, 0xDFAB, 0xDFB5, + 0xDFB7, 0xDFC3, 0xDFC7, 0xDFD5, 0xDFF1, 0xDFF3, 0xE003, 0xE005, + 0xE017, 0xE01D, 0xE027, 0xE02D, 0xE035, 0xE045, 0xE053, 0xE071, + 0xE07B, 0xE08F, 0xE095, 0xE09F, 0xE0B7, 0xE0B9, 0xE0D5, 0xE0D7, + 0xE0E3, 0xE0F3, 0xE0F9, 0xE101, 0xE125, 0xE129, 0xE131, 0xE135, + 0xE143, 0xE14F, 0xE159, 0xE161, 0xE16D, 0xE171, 0xE177, 0xE17F, + 0xE183, 0xE189, 0xE197, 0xE1AD, 0xE1B5, 0xE1BB, 0xE1BF, 0xE1C1, + 0xE1CB, 0xE1D1, 0xE1E5, 0xE1EF, 0xE1F7, 0xE1FD, 0xE203, 0xE219, + 0xE22B, 0xE22D, 0xE23D, 0xE243, 0xE257, 0xE25B, 0xE275, 0xE279, + 0xE287, 0xE29D, 0xE2AB, 0xE2AF, 0xE2BB, 0xE2C1, 0xE2C9, 0xE2CD, + 0xE2D3, 0xE2D9, 0xE2F3, 0xE2FD, 0xE2FF, 0xE311, 0xE323, 0xE327, + 0xE329, 0xE339, 0xE33B, 0xE34D, 0xE351, 0xE357, 0xE35F, 0xE363, + 0xE369, 0xE375, 0xE377, 0xE37D, 0xE383, 0xE39F, 0xE3C5, 0xE3C9, + 0xE3D1, 0xE3E1, 0xE3FB, 0xE3FF, 0xE401, 0xE40B, 0xE417, 0xE419, + 0xE423, 0xE42B, 0xE431, 0xE43B, 0xE447, 0xE449, 0xE453, 0xE455, + 0xE46D, 0xE471, 0xE48F, 0xE4A9, 0xE4AF, 0xE4B5, 0xE4C7, 0xE4CD, + 0xE4D3, 0xE4E9, 0xE4EB, 0xE4F5, 0xE507, 0xE521, 0xE525, 0xE537, + 0xE53F, 0xE545, 0xE54B, 0xE557, 0xE567, 0xE56D, 0xE575, 0xE585, + 0xE58B, 0xE593, 0xE5A3, 0xE5A5, 0xE5CF, 0xE609, 0xE611, 0xE615, + 0xE61B, 0xE61D, 0xE621, 0xE629, 0xE639, 0xE63F, 0xE653, 0xE657, + 0xE663, 0xE66F, 0xE675, 0xE681, 0xE683, 0xE68D, 0xE68F, 0xE695, + 0xE6AB, 0xE6AD, 0xE6B7, 0xE6BD, 0xE6C5, 0xE6CB, 0xE6D5, 0xE6E3, + 0xE6E9, 0xE6EF, 0xE6F3, 0xE705, 0xE70D, 0xE717, 0xE71F, 0xE72F, + 0xE73D, 0xE747, 0xE749, 0xE753, 0xE755, 0xE761, 0xE767, 0xE76B, + 0xE77F, 0xE789, 0xE791, 0xE7C5, 0xE7CD, 0xE7D7, 0xE7DD, 0xE7DF, + 0xE7E9, 0xE7F1, 0xE7FB, 0xE801, 0xE807, 0xE80F, 0xE819, 0xE81B, + 0xE831, 0xE833, 0xE837, 0xE83D, 0xE84B, 0xE84F, 0xE851, 0xE869, + 0xE875, 0xE879, 0xE893, 0xE8A5, 0xE8A9, 0xE8AF, 0xE8BD, 0xE8DB, + 0xE8E1, 0xE8E5, 0xE8EB, 0xE8ED, 0xE903, 0xE90B, 0xE90F, 0xE915, + 0xE917, 0xE92D, 0xE933, 0xE93B, 0xE94B, 0xE951, 0xE95F, 0xE963, + 0xE969, 0xE97B, 0xE983, 0xE98F, 0xE995, 0xE9A1, 0xE9B9, 0xE9D7, + 0xE9E7, 0xE9EF, 0xEA11, 0xEA19, 0xEA2F, 0xEA35, 0xEA43, 0xEA4D, + 0xEA5F, 0xEA6D, 0xEA71, 0xEA7D, 0xEA85, 0xEA89, 0xEAAD, 0xEAB3, + 0xEAB9, 0xEABB, 0xEAC5, 0xEAC7, 0xEACB, 0xEADF, 0xEAE5, 0xEAEB, + 0xEAF5, 0xEB01, 0xEB07, 0xEB09, 0xEB31, 0xEB39, 0xEB3F, 0xEB5B, + 0xEB61, 0xEB63, 0xEB6F, 0xEB81, 0xEB85, 0xEB9D, 0xEBAB, 0xEBB1, + 0xEBB7, 0xEBC1, 0xEBD5, 0xEBDF, 0xEBED, 0xEBFD, 0xEC0B, 0xEC1B, + 0xEC21, 0xEC29, 0xEC4D, 0xEC51, 0xEC5D, 0xEC69, 0xEC6F, 0xEC7B, + 0xECAD, 0xECB9, 0xECBF, 0xECC3, 0xECC9, 0xECCF, 0xECD7, 0xECDD, + 0xECE7, 0xECE9, 0xECF3, 0xECF5, 0xED07, 0xED11, 0xED1F, 0xED2F, + 0xED37, 0xED3D, 0xED41, 0xED55, 0xED59, 0xED5B, 0xED65, 0xED6B, + 0xED79, 0xED8B, 0xED95, 0xEDBB, 0xEDC5, 0xEDD7, 0xEDD9, 0xEDE3, + 0xEDE5, 0xEDF1, 0xEDF5, 0xEDF7, 0xEDFB, 0xEE09, 0xEE0F, 0xEE19, + 0xEE21, 0xEE49, 0xEE4F, 0xEE63, 0xEE67, 0xEE73, 0xEE7B, 0xEE81, + 0xEEA3, 0xEEAB, 0xEEC1, 0xEEC9, 0xEED5, 0xEEDF, 0xEEE1, 0xEEF1, + 0xEF1B, 0xEF27, 0xEF2F, 0xEF45, 0xEF4D, 0xEF63, 0xEF6B, 0xEF71, + 0xEF93, 0xEF95, 0xEF9B, 0xEF9F, 0xEFAD, 0xEFB3, 0xEFC3, 0xEFC5, + 0xEFDB, 0xEFE1, 0xEFE9, 0xF001, 0xF017, 0xF01D, 0xF01F, 0xF02B, + 0xF02F, 0xF035, 0xF043, 0xF047, 0xF04F, 0xF067, 0xF06B, 0xF071, + 0xF077, 0xF079, 0xF08F, 0xF0A3, 0xF0A9, 0xF0AD, 0xF0BB, 0xF0BF, + 0xF0C5, 0xF0CB, 0xF0D3, 0xF0D9, 0xF0E3, 0xF0E9, 0xF0F1, 0xF0F7, + 0xF107, 0xF115, 0xF11B, 0xF121, 0xF137, 0xF13D, 0xF155, 0xF175, + 0xF17B, 0xF18D, 0xF193, 0xF1A5, 0xF1AF, 0xF1B7, 0xF1D5, 0xF1E7, + 0xF1ED, 0xF1FD, 0xF209, 0xF20F, 0xF21B, 0xF21D, 0xF223, 0xF227, + 0xF233, 0xF23B, 0xF241, 0xF257, 0xF25F, 0xF265, 0xF269, 0xF277, + 0xF281, 0xF293, 0xF2A7, 0xF2B1, 0xF2B3, 0xF2B9, 0xF2BD, 0xF2BF, + 0xF2DB, 0xF2ED, 0xF2EF, 0xF2F9, 0xF2FF, 0xF305, 0xF30B, 0xF319, + 0xF341, 0xF359, 0xF35B, 0xF35F, 0xF367, 0xF373, 0xF377, 0xF38B, + 0xF38F, 0xF3AF, 0xF3C1, 0xF3D1, 0xF3D7, 0xF3FB, 0xF403, 0xF409, + 0xF40D, 0xF413, 0xF421, 0xF425, 0xF42B, 0xF445, 0xF44B, 0xF455, + 0xF463, 0xF475, 0xF47F, 0xF485, 0xF48B, 0xF499, 0xF4A3, 0xF4A9, + 0xF4AF, 0xF4BD, 0xF4C3, 0xF4DB, 0xF4DF, 0xF4ED, 0xF503, 0xF50B, + 0xF517, 0xF521, 0xF529, 0xF535, 0xF547, 0xF551, 0xF563, 0xF56B, + 0xF583, 0xF58D, 0xF595, 0xF599, 0xF5B1, 0xF5B7, 0xF5C9, 0xF5CF, + 0xF5D1, 0xF5DB, 0xF5F9, 0xF5FB, 0xF605, 0xF607, 0xF60B, 0xF60D, + 0xF635, 0xF637, 0xF653, 0xF65B, 0xF661, 0xF667, 0xF679, 0xF67F, + 0xF689, 0xF697, 0xF69B, 0xF6AD, 0xF6CB, 0xF6DD, 0xF6DF, 0xF6EB, + 0xF709, 0xF70F, 0xF72D, 0xF731, 0xF743, 0xF74F, 0xF751, 0xF755, + 0xF763, 0xF769, 0xF773, 0xF779, 0xF781, 0xF787, 0xF791, 0xF79D, + 0xF79F, 0xF7A5, 0xF7B1, 0xF7BB, 0xF7BD, 0xF7CF, 0xF7D3, 0xF7E7, + 0xF7EB, 0xF7F1, 0xF7FF, 0xF805, 0xF80B, 0xF821, 0xF827, 0xF82D, + 0xF835, 0xF847, 0xF859, 0xF863, 0xF865, 0xF86F, 0xF871, 0xF877, + 0xF87B, 0xF881, 0xF88D, 0xF89F, 0xF8A1, 0xF8AB, 0xF8B3, 0xF8B7, + 0xF8C9, 0xF8CB, 0xF8D1, 0xF8D7, 0xF8DD, 0xF8E7, 0xF8EF, 0xF8F9, + 0xF8FF, 0xF911, 0xF91D, 0xF925, 0xF931, 0xF937, 0xF93B, 0xF941, + 0xF94F, 0xF95F, 0xF961, 0xF96D, 0xF971, 0xF977, 0xF99D, 0xF9A3, + 0xF9A9, 0xF9B9, 0xF9CD, 0xF9E9, 0xF9FD, 0xFA07, 0xFA0D, 0xFA13, + 0xFA21, 0xFA25, 0xFA3F, 0xFA43, 0xFA51, 0xFA5B, 0xFA6D, 0xFA7B, + 0xFA97, 0xFA99, 0xFA9D, 0xFAAB, 0xFABB, 0xFABD, 0xFAD9, 0xFADF, + 0xFAE7, 0xFAED, 0xFB0F, 0xFB17, 0xFB1B, 0xFB2D, 0xFB2F, 0xFB3F, + 0xFB47, 0xFB4D, 0xFB75, 0xFB7D, 0xFB8F, 0xFB93, 0xFBB1, 0xFBB7, + 0xFBC3, 0xFBC5, 0xFBE3, 0xFBE9, 0xFBF3, 0xFC01, 0xFC29, 0xFC37, + 0xFC41, 0xFC43, 0xFC4F, 0xFC59, 0xFC61, 0xFC65, 0xFC6D, 0xFC73, + 0xFC79, 0xFC95, 0xFC97, 0xFC9B, 0xFCA7, 0xFCB5, 0xFCC5, 0xFCCD, + 0xFCEB, 0xFCFB, 0xFD0D, 0xFD0F, 0xFD19, 0xFD2B, 0xFD31, 0xFD51, + 0xFD55, 0xFD67, 0xFD6D, 0xFD6F, 0xFD7B, 0xFD85, 0xFD97, 0xFD99, + 0xFD9F, 0xFDA9, 0xFDB7, 0xFDC9, 0xFDE5, 0xFDEB, 0xFDF3, 0xFE03, + 0xFE05, 0xFE09, 0xFE1D, 0xFE27, 0xFE2F, 0xFE41, 0xFE4B, 0xFE4D, + 0xFE57, 0xFE5F, 0xFE63, 0xFE69, 0xFE75, 0xFE7B, 0xFE8F, 0xFE93, + 0xFE95, 0xFE9B, 0xFE9F, 0xFEB3, 0xFEBD, 0xFED7, 0xFEE9, 0xFEF3, + 0xFEF5, 0xFF07, 0xFF0D, 0xFF1D, 0xFF2B, 0xFF2F, 0xFF49, 0xFF4D, + 0xFF5B, 0xFF65, 0xFF71, 0xFF7F, 0xFF85, 0xFF8B, 0xFF8F, 0xFF9D, + 0xFFA7, 0xFFA9, 0xFFC7, 0xFFD9, 0xFFEF, 0xFFF1, #endif }; - diff --git a/nss/lib/freebl/mpi/target.mk b/nss/lib/freebl/mpi/target.mk index dbd2fb9..dd74564 100644 --- a/nss/lib/freebl/mpi/target.mk +++ b/nss/lib/freebl/mpi/target.mk @@ -171,7 +171,7 @@ ifeq ($(TARGET),x86LINUX) #Linux AS_OBJS = mpi_x86.o MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D -MPICMN += -DMP_MONT_USE_MP_MUL -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN +MPICMN += -DMP_MONT_USE_MP_MUL -DMP_IS_LITTLE_ENDIAN CFLAGS= -O2 -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \ -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \ -DXP_UNIX -UDEBUG -DNDEBUG -D_REENTRANT $(MPICMN) @@ -193,7 +193,7 @@ ifeq ($(TARGET),AMD64SOLARIS) ASFLAGS += -xarch=generic64 AS_OBJS = mpi_amd64.o mpi_amd64_sun.o MP_CONFIG = -DMP_ASSEMBLY_MULTIPLY -DMPI_AMD64 -MP_CONFIG += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN +MP_CONFIG += -DMP_IS_LITTLE_ENDIAN CFLAGS = -xarch=generic64 -xO4 -I. -DMP_API_COMPATIBLE -DMP_IOFUNC $(MP_CONFIG) MPICMN += $(MP_CONFIG) diff --git a/nss/lib/freebl/mpi/test-arrays.txt b/nss/lib/freebl/mpi/test-arrays.txt index 76c4e3e..6c8908c 100644 --- a/nss/lib/freebl/mpi/test-arrays.txt +++ b/nss/lib/freebl/mpi/test-arrays.txt @@ -33,7 +33,6 @@ divide:test_div:test full division expt-digit:test_expt_d:test digit exponentiation expt:test_expt:test full exponentiation expt-2:test_2expt:test power-of-two exponentiation -square-root:test_sqrt:test integer square root function modulo-digit:test_mod_d:test digit modular reduction modulo:test_mod:test full modular reduction mod-add:test_addmod:test modular addition diff --git a/nss/lib/freebl/mpi/test-info.c b/nss/lib/freebl/mpi/test-info.c deleted file mode 100644 index bf6fecf..0000000 --- a/nss/lib/freebl/mpi/test-info.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * test-info.c - * - * Arbitrary precision integer arithmetic library - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Table mapping test suite names to index numbers */ -const int g_count = 42; -const char *g_names[] = { - "list", /* print out a list of the available test suites */ - "copy", /* test assignment of mp-int structures */ - "exchange", /* test exchange of mp-int structures */ - "zero", /* test zeroing of an mp-int */ - "set", /* test setting an mp-int to a small constant */ - "absolute-value", /* test the absolute value function */ - "negate", /* test the arithmetic negation function */ - "add-digit", /* test digit addition */ - "add", /* test full addition */ - "subtract-digit", /* test digit subtraction */ - "subtract", /* test full subtraction */ - "multiply-digit", /* test digit multiplication */ - "multiply", /* test full multiplication */ - "square", /* test full squaring function */ - "divide-digit", /* test digit division */ - "divide-2", /* test division by two */ - "divide-2d", /* test division & remainder by 2^d */ - "divide", /* test full division */ - "expt-digit", /* test digit exponentiation */ - "expt", /* test full exponentiation */ - "expt-2", /* test power-of-two exponentiation */ - "square-root", /* test integer square root function */ - "modulo-digit", /* test digit modular reduction */ - "modulo", /* test full modular reduction */ - "mod-add", /* test modular addition */ - "mod-subtract", /* test modular subtraction */ - "mod-multiply", /* test modular multiplication */ - "mod-square", /* test modular squaring function */ - "mod-expt", /* test full modular exponentiation */ - "mod-expt-digit", /* test digit modular exponentiation */ - "mod-inverse", /* test modular inverse function */ - "compare-digit", /* test digit comparison function */ - "compare-zero", /* test zero comparison function */ - "compare", /* test general signed comparison */ - "compare-magnitude", /* test general magnitude comparison */ - "parity", /* test parity comparison functions */ - "gcd", /* test greatest common divisor functions */ - "lcm", /* test least common multiple function */ - "conversion", /* test general radix conversion facilities */ - "binary", /* test raw output format */ - "pprime", /* test probabilistic primality tester */ - "fermat" /* test Fermat pseudoprimality tester */ -}; - -/* Test function prototypes */ -int test_list(void); -int test_copy(void); -int test_exch(void); -int test_zero(void); -int test_set(void); -int test_abs(void); -int test_neg(void); -int test_add_d(void); -int test_add(void); -int test_sub_d(void); -int test_sub(void); -int test_mul_d(void); -int test_mul(void); -int test_sqr(void); -int test_div_d(void); -int test_div_2(void); -int test_div_2d(void); -int test_div(void); -int test_expt_d(void); -int test_expt(void); -int test_2expt(void); -int test_sqrt(void); -int test_mod_d(void); -int test_mod(void); -int test_addmod(void); -int test_submod(void); -int test_mulmod(void); -int test_sqrmod(void); -int test_exptmod(void); -int test_exptmod_d(void); -int test_invmod(void); -int test_cmp_d(void); -int test_cmp_z(void); -int test_cmp(void); -int test_cmp_mag(void); -int test_parity(void); -int test_gcd(void); -int test_lcm(void); -int test_convert(void); -int test_raw(void); -int test_pprime(void); -int test_fermat(void); - -/* Table mapping index numbers to functions */ -int (*g_tests[])(void) = { - test_list, test_copy, test_exch, test_zero, - test_set, test_abs, test_neg, test_add_d, - test_add, test_sub_d, test_sub, test_mul_d, - test_mul, test_sqr, test_div_d, test_div_2, - test_div_2d, test_div, test_expt_d, test_expt, - test_2expt, test_sqrt, test_mod_d, test_mod, - test_addmod, test_submod, test_mulmod, test_sqrmod, - test_exptmod, test_exptmod_d, test_invmod, test_cmp_d, - test_cmp_z, test_cmp, test_cmp_mag, test_parity, - test_gcd, test_lcm, test_convert, test_raw, - test_pprime, test_fermat -}; - -/* Table mapping index numbers to descriptions */ -const char *g_descs[] = { - "print out a list of the available test suites", - "test assignment of mp-int structures", - "test exchange of mp-int structures", - "test zeroing of an mp-int", - "test setting an mp-int to a small constant", - "test the absolute value function", - "test the arithmetic negation function", - "test digit addition", - "test full addition", - "test digit subtraction", - "test full subtraction", - "test digit multiplication", - "test full multiplication", - "test full squaring function", - "test digit division", - "test division by two", - "test division & remainder by 2^d", - "test full division", - "test digit exponentiation", - "test full exponentiation", - "test power-of-two exponentiation", - "test integer square root function", - "test digit modular reduction", - "test full modular reduction", - "test modular addition", - "test modular subtraction", - "test modular multiplication", - "test modular squaring function", - "test full modular exponentiation", - "test digit modular exponentiation", - "test modular inverse function", - "test digit comparison function", - "test zero comparison function", - "test general signed comparison", - "test general magnitude comparison", - "test parity comparison functions", - "test greatest common divisor functions", - "test least common multiple function", - "test general radix conversion facilities", - "test raw output format", - "test probabilistic primality tester", - "test Fermat pseudoprimality tester" -}; - diff --git a/nss/lib/freebl/mpi/tests/mptest-1.c b/nss/lib/freebl/mpi/tests/mptest-1.c index 1c24fdf..4491346 100644 --- a/nss/lib/freebl/mpi/tests/mptest-1.c +++ b/nss/lib/freebl/mpi/tests/mptest-1.c @@ -20,23 +20,24 @@ #include "mpi.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix; - mp_int mp; + int ix; + mp_int mp; #ifdef MAC_CW_SIOUX - argc = ccommand(&argv); + argc = ccommand(&argv); #endif - mp_init(&mp); - - for(ix = 1; ix < argc; ix++) { - mp_read_radix(&mp, argv[ix], 10); - mp_print(&mp, stdout); - fputc('\n', stdout); - } + mp_init(&mp); - mp_clear(&mp); - return 0; + for (ix = 1; ix < argc; ix++) { + mp_read_radix(&mp, argv[ix], 10); + mp_print(&mp, stdout); + fputc('\n', stdout); + } + + mp_clear(&mp); + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-2.c b/nss/lib/freebl/mpi/tests/mptest-2.c index ea1161e..1505e6a 100644 --- a/nss/lib/freebl/mpi/tests/mptest-2.c +++ b/nss/lib/freebl/mpi/tests/mptest-2.c @@ -15,39 +15,48 @@ #include "mpi.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a, b, c; - - if(argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } - - printf("Test 2: Basic addition and subtraction\n\n"); - - mp_init(&a); - mp_init(&b); - - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - - mp_init(&c); - printf("c = a + b\n"); - - mp_add(&a, &b, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - - printf("c = a - b\n"); - - mp_sub(&a, &b, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); - - return 0; + mp_int a, b, c; + + if (argc < 3) { + fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); + return 1; + } + + printf("Test 2: Basic addition and subtraction\n\n"); + + mp_init(&a); + mp_init(&b); + + mp_read_radix(&a, argv[1], 10); + mp_read_radix(&b, argv[2], 10); + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + + mp_init(&c); + printf("c = a + b\n"); + + mp_add(&a, &b, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + printf("c = a - b\n"); + + mp_sub(&a, &b, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + mp_clear(&c); + mp_clear(&b); + mp_clear(&a); + + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-3.c b/nss/lib/freebl/mpi/tests/mptest-3.c index 4636a25..86fb246 100644 --- a/nss/lib/freebl/mpi/tests/mptest-3.c +++ b/nss/lib/freebl/mpi/tests/mptest-3.c @@ -17,82 +17,89 @@ #include "mpi.h" -#define SQRT 1 /* define nonzero to get square-root test */ -#define EXPT 0 /* define nonzero to get exponentiate test */ +#define EXPT 0 /* define nonzero to get exponentiate test */ -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix; - mp_int a, b, c, d; - mp_digit r; - mp_err res; - - if(argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } - - printf("Test 3: Multiplication and division\n\n"); - srand(time(NULL)); - - mp_init(&a); - mp_init(&b); - - mp_read_variable_radix(&a, argv[1], 10); - mp_read_variable_radix(&b, argv[2], 10); - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - - mp_init(&c); - printf("\nc = a * b\n"); - - mp_mul(&a, &b, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - - printf("\nc = b * 32523\n"); - - mp_mul_d(&b, 32523, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - - mp_init(&d); - printf("\nc = a / b, d = a mod b\n"); - - mp_div(&a, &b, &c, &d); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - printf("d = "); mp_print(&d, stdout); fputc('\n', stdout); - - ix = rand() % 256; - printf("\nc = a / %d, r = a mod %d\n", ix, ix); - mp_div_d(&a, (mp_digit)ix, &c, &r); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - printf("r = %04X\n", r); + int ix; + mp_int a, b, c, d; + mp_digit r; + mp_err res; + + if (argc < 3) { + fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); + return 1; + } + + printf("Test 3: Multiplication and division\n\n"); + srand(time(NULL)); + + mp_init(&a); + mp_init(&b); + + mp_read_variable_radix(&a, argv[1], 10); + mp_read_variable_radix(&b, argv[2], 10); + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + + mp_init(&c); + printf("\nc = a * b\n"); + + mp_mul(&a, &b, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + printf("\nc = b * 32523\n"); + + mp_mul_d(&b, 32523, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + mp_init(&d); + printf("\nc = a / b, d = a mod b\n"); + + mp_div(&a, &b, &c, &d); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + printf("d = "); + mp_print(&d, stdout); + fputc('\n', stdout); + + ix = rand() % 256; + printf("\nc = a / %d, r = a mod %d\n", ix, ix); + mp_div_d(&a, (mp_digit)ix, &c, &r); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + printf("r = %04X\n", r); #if EXPT - printf("\nc = a ** b\n"); - mp_expt(&a, &b, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("\nc = a ** b\n"); + mp_expt(&a, &b, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); #endif - ix = rand() % 256; - printf("\nc = 2^%d\n", ix); - mp_2expt(&c, ix); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - -#if SQRT - printf("\nc = sqrt(a)\n"); - if((res = mp_sqrt(&a, &c)) != MP_OKAY) { - printf("mp_sqrt: %s\n", mp_strerror(res)); - } else { - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - mp_sqr(&c, &c); - printf("c^2 = "); mp_print(&c, stdout); fputc('\n', stdout); - } -#endif + ix = rand() % 256; + printf("\nc = 2^%d\n", ix); + mp_2expt(&c, ix); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); - mp_clear(&d); - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); + mp_clear(&d); + mp_clear(&c); + mp_clear(&b); + mp_clear(&a); - return 0; + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-3a.c b/nss/lib/freebl/mpi/tests/mptest-3a.c index c496aa6..c6cea70 100644 --- a/nss/lib/freebl/mpi/tests/mptest-3a.c +++ b/nss/lib/freebl/mpi/tests/mptest-3a.c @@ -18,94 +18,106 @@ #include "mpi.h" #include "mpprime.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix, num, prec = 8; - double d1, d2; - clock_t start, finish; - time_t seed; - mp_int a, c, d; - - seed = time(NULL); - - if(argc < 2) { - fprintf(stderr, "Usage: %s <num-tests> [<precision>]\n", argv[0]); - return 1; - } - - if((num = atoi(argv[1])) < 0) - num = -num; - - if(!num) { - fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]); - return 1; - } - - if(argc > 2) { - if((prec = atoi(argv[2])) <= 0) - prec = 8; - else - prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT; - } - - printf("Test 3a: Multiplication vs squaring timing test\n" - "Precision: %d digits (%u bits)\n" - "# of tests: %d\n\n", prec, prec * DIGIT_BIT, num); - - mp_init_size(&a, prec); - - mp_init(&c); mp_init(&d); - - printf("Verifying accuracy ... \n"); - srand((unsigned int)seed); - for(ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mp_mul(&a, &a, &c); - mp_sqr(&a, &d); - - if(mp_cmp(&c, &d) != 0) { - printf("Error! Results not accurate:\n"); - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - printf("d = "); mp_print(&d, stdout); fputc('\n', stdout); - mp_sub(&c, &d, &d); - printf("dif "); mp_print(&d, stdout); fputc('\n', stdout); - mp_clear(&c); mp_clear(&d); - mp_clear(&a); - return 1; + int ix, num, prec = 8; + double d1, d2; + clock_t start, finish; + time_t seed; + mp_int a, c, d; + + seed = time(NULL); + + if (argc < 2) { + fprintf(stderr, "Usage: %s <num-tests> [<precision>]\n", argv[0]); + return 1; + } + + if ((num = atoi(argv[1])) < 0) + num = -num; + + if (!num) { + fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]); + return 1; + } + + if (argc > 2) { + if ((prec = atoi(argv[2])) <= 0) + prec = 8; + else + prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT; + } + + printf("Test 3a: Multiplication vs squaring timing test\n" + "Precision: %d digits (%u bits)\n" + "# of tests: %d\n\n", + prec, prec * DIGIT_BIT, num); + + mp_init_size(&a, prec); + + mp_init(&c); + mp_init(&d); + + printf("Verifying accuracy ... \n"); + srand((unsigned int)seed); + for (ix = 0; ix < num; ix++) { + mpp_random_size(&a, prec); + mp_mul(&a, &a, &c); + mp_sqr(&a, &d); + + if (mp_cmp(&c, &d) != 0) { + printf("Error! Results not accurate:\n"); + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + printf("d = "); + mp_print(&d, stdout); + fputc('\n', stdout); + mp_sub(&c, &d, &d); + printf("dif "); + mp_print(&d, stdout); + fputc('\n', stdout); + mp_clear(&c); + mp_clear(&d); + mp_clear(&a); + return 1; + } } - } - printf("Accuracy is confirmed for the %d test samples\n", num); - mp_clear(&d); - - printf("Testing squaring ... \n"); - srand((unsigned int)seed); - start = clock(); - for(ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mp_sqr(&a, &c); - } - finish = clock(); - - d2 = (double)(finish - start) / CLOCKS_PER_SEC; - - printf("Testing multiplication ... \n"); - srand((unsigned int)seed); - start = clock(); - for(ix = 0; ix < num; ix++) { - mpp_random(&a); - mp_mul(&a, &a, &c); - } - finish = clock(); - - d1 = (double)(finish - start) / CLOCKS_PER_SEC; - - printf("Multiplication time: %.3f sec (%.3f each)\n", d1, d1 / num); - printf("Squaring time: %.3f sec (%.3f each)\n", d2, d2 / num); - printf("Improvement: %.2f%%\n", (1.0 - (d2 / d1)) * 100.0); - - mp_clear(&c); - mp_clear(&a); - - return 0; + printf("Accuracy is confirmed for the %d test samples\n", num); + mp_clear(&d); + + printf("Testing squaring ... \n"); + srand((unsigned int)seed); + start = clock(); + for (ix = 0; ix < num; ix++) { + mpp_random_size(&a, prec); + mp_sqr(&a, &c); + } + finish = clock(); + + d2 = (double)(finish - start) / CLOCKS_PER_SEC; + + printf("Testing multiplication ... \n"); + srand((unsigned int)seed); + start = clock(); + for (ix = 0; ix < num; ix++) { + mpp_random(&a); + mp_mul(&a, &a, &c); + } + finish = clock(); + + d1 = (double)(finish - start) / CLOCKS_PER_SEC; + + printf("Multiplication time: %.3f sec (%.3f each)\n", d1, d1 / num); + printf("Squaring time: %.3f sec (%.3f each)\n", d2, d2 / num); + printf("Improvement: %.2f%%\n", (1.0 - (d2 / d1)) * 100.0); + + mp_clear(&c); + mp_clear(&a); + + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-4.c b/nss/lib/freebl/mpi/tests/mptest-4.c index 3001739..0f326ac 100644 --- a/nss/lib/freebl/mpi/tests/mptest-4.c +++ b/nss/lib/freebl/mpi/tests/mptest-4.c @@ -15,79 +15,97 @@ #include "mpi.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix; - mp_int a, b, c, m; - mp_digit r; + int ix; + mp_int a, b, c, m; + mp_digit r; - if(argc < 4) { - fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]); - return 1; - } + if (argc < 4) { + fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]); + return 1; + } - printf("Test 4: Modular arithmetic\n\n"); + printf("Test 4: Modular arithmetic\n\n"); - mp_init(&a); - mp_init(&b); - mp_init(&m); + mp_init(&a); + mp_init(&b); + mp_init(&m); - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); - mp_read_radix(&m, argv[3], 10); - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - printf("m = "); mp_print(&m, stdout); fputc('\n', stdout); - - mp_init(&c); - printf("\nc = a (mod m)\n"); + mp_read_radix(&a, argv[1], 10); + mp_read_radix(&b, argv[2], 10); + mp_read_radix(&m, argv[3], 10); + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + printf("m = "); + mp_print(&m, stdout); + fputc('\n', stdout); - mp_mod(&a, &m, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + mp_init(&c); + printf("\nc = a (mod m)\n"); - printf("\nc = b (mod m)\n"); + mp_mod(&a, &m, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); - mp_mod(&b, &m, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("\nc = b (mod m)\n"); - printf("\nc = b (mod 1853)\n"); + mp_mod(&b, &m, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); - mp_mod_d(&b, 1853, &r); - printf("c = %04X\n", r); + printf("\nc = b (mod 1853)\n"); - printf("\nc = (a + b) mod m\n"); + mp_mod_d(&b, 1853, &r); + printf("c = %04X\n", r); - mp_addmod(&a, &b, &m, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("\nc = (a + b) mod m\n"); - printf("\nc = (a - b) mod m\n"); + mp_addmod(&a, &b, &m, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); - mp_submod(&a, &b, &m, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("\nc = (a - b) mod m\n"); - printf("\nc = (a * b) mod m\n"); + mp_submod(&a, &b, &m, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); - mp_mulmod(&a, &b, &m, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("\nc = (a * b) mod m\n"); - printf("\nc = (a ** b) mod m\n"); + mp_mulmod(&a, &b, &m, &c); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); - mp_exptmod(&a, &b, &m, &c); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("\nc = (a ** b) mod m\n"); - printf("\nIn-place modular squaring test:\n"); - for(ix = 0; ix < 5; ix++) { - printf("a = (a * a) mod m a = "); - mp_sqrmod(&a, &m, &a); - mp_print(&a, stdout); + mp_exptmod(&a, &b, &m, &c); + printf("c = "); + mp_print(&c, stdout); fputc('\n', stdout); - } - - mp_clear(&c); - mp_clear(&m); - mp_clear(&b); - mp_clear(&a); + printf("\nIn-place modular squaring test:\n"); + for (ix = 0; ix < 5; ix++) { + printf("a = (a * a) mod m a = "); + mp_sqrmod(&a, &m, &a); + mp_print(&a, stdout); + fputc('\n', stdout); + } + + mp_clear(&c); + mp_clear(&m); + mp_clear(&b); + mp_clear(&a); - return 0; + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-4a.c b/nss/lib/freebl/mpi/tests/mptest-4a.c index 46d4a4d..0c8e188 100644 --- a/nss/lib/freebl/mpi/tests/mptest-4a.c +++ b/nss/lib/freebl/mpi/tests/mptest-4a.c @@ -1,5 +1,5 @@ -/* - * mptest4a - modular exponentiation speed test +/* + * mptest4a - modular exponentiation speed test * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -17,89 +17,93 @@ #include "mpprime.h" typedef struct { - unsigned int sec; - unsigned int usec; + unsigned int sec; + unsigned int usec; } instant_t; -instant_t now(void) +instant_t +now(void) { - struct timeval clk; - instant_t res; + struct timeval clk; + instant_t res; - res.sec = res.usec = 0; + res.sec = res.usec = 0; - if(gettimeofday(&clk, NULL) != 0) - return res; + if (gettimeofday(&clk, NULL) != 0) + return res; - res.sec = clk.tv_sec; - res.usec = clk.tv_usec; + res.sec = clk.tv_sec; + res.usec = clk.tv_usec; - return res; + return res; } extern mp_err s_mp_pad(); -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix, num, prec = 8; - unsigned int d; - instant_t start, finish; - time_t seed; - mp_int a, m, c; - - seed = time(NULL); - - if(argc < 2) { - fprintf(stderr, "Usage: %s <num-tests> [<precision>]\n", argv[0]); - return 1; - } - - if((num = atoi(argv[1])) < 0) - num = -num; - - if(!num) { - fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]); - return 1; - } - - if(argc > 2) { - if((prec = atoi(argv[2])) <= 0) - prec = 8; - } - - printf("Test 3a: Modular exponentiation timing test\n" - "Precision: %d digits (%d bits)\n" - "# of tests: %d\n\n", prec, prec * DIGIT_BIT, num); - - mp_init_size(&a, prec); - mp_init_size(&m, prec); - mp_init_size(&c, prec); - s_mp_pad(&a, prec); - s_mp_pad(&m, prec); - s_mp_pad(&c, prec); - - printf("Testing modular exponentiation ... \n"); - srand((unsigned int)seed); - - start = now(); - for(ix = 0; ix < num; ix++) { - mpp_random(&a); - mpp_random(&c); - mpp_random(&m); - mp_exptmod(&a, &c, &m, &c); - } - finish = now(); - - d = (finish.sec - start.sec) * 1000000; - d -= start.usec; d += finish.usec; - - printf("Total time elapsed: %u usec\n", d); - printf("Time per exponentiation: %u usec (%.3f sec)\n", - (d / num), (double)(d / num) / 1000000); - - mp_clear(&c); - mp_clear(&a); - mp_clear(&m); - - return 0; + int ix, num, prec = 8; + unsigned int d; + instant_t start, finish; + time_t seed; + mp_int a, m, c; + + seed = time(NULL); + + if (argc < 2) { + fprintf(stderr, "Usage: %s <num-tests> [<precision>]\n", argv[0]); + return 1; + } + + if ((num = atoi(argv[1])) < 0) + num = -num; + + if (!num) { + fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]); + return 1; + } + + if (argc > 2) { + if ((prec = atoi(argv[2])) <= 0) + prec = 8; + } + + printf("Test 3a: Modular exponentiation timing test\n" + "Precision: %d digits (%d bits)\n" + "# of tests: %d\n\n", + prec, prec * DIGIT_BIT, num); + + mp_init_size(&a, prec); + mp_init_size(&m, prec); + mp_init_size(&c, prec); + s_mp_pad(&a, prec); + s_mp_pad(&m, prec); + s_mp_pad(&c, prec); + + printf("Testing modular exponentiation ... \n"); + srand((unsigned int)seed); + + start = now(); + for (ix = 0; ix < num; ix++) { + mpp_random(&a); + mpp_random(&c); + mpp_random(&m); + mp_exptmod(&a, &c, &m, &c); + } + finish = now(); + + d = (finish.sec - start.sec) * 1000000; + d -= start.usec; + d += finish.usec; + + printf("Total time elapsed: %u usec\n", d); + printf("Time per exponentiation: %u usec (%.3f sec)\n", + (d / num), (double)(d / num) / 1000000); + + mp_clear(&c); + mp_clear(&a); + mp_clear(&m); + + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-4b.c b/nss/lib/freebl/mpi/tests/mptest-4b.c index b8e15ba..1bb2f91 100644 --- a/nss/lib/freebl/mpi/tests/mptest-4b.c +++ b/nss/lib/freebl/mpi/tests/mptest-4b.c @@ -19,84 +19,89 @@ #include "mpi.h" #include "mpprime.h" -char *g_prime = - "34BD53C07350E817CCD49721020F1754527959C421C1533244769D4CF060A8B1C3DA" - "25094BE723FB1E2369B55FEEBBE0FAC16425161BF82684062B5EC5D7D47D1B23C117" - "0FA19745E44A55E148314E582EB813AC9EE5126295E2E380CACC2F6D206B293E5ED9" - "23B54EE961A8C69CD625CE4EC38B70C649D7F014432AEF3A1C93"; +char *g_prime = + "34BD53C07350E817CCD49721020F1754527959C421C1533244769D4CF060A8B1C3DA" + "25094BE723FB1E2369B55FEEBBE0FAC16425161BF82684062B5EC5D7D47D1B23C117" + "0FA19745E44A55E148314E582EB813AC9EE5126295E2E380CACC2F6D206B293E5ED9" + "23B54EE961A8C69CD625CE4EC38B70C649D7F014432AEF3A1C93"; char *g_gen = "5"; typedef struct { - unsigned int sec; - unsigned int usec; + unsigned int sec; + unsigned int usec; } instant_t; -instant_t now(void) +instant_t +now(void) { - struct timeval clk; - instant_t res; + struct timeval clk; + instant_t res; - res.sec = res.usec = 0; + res.sec = res.usec = 0; - if(gettimeofday(&clk, NULL) != 0) - return res; + if (gettimeofday(&clk, NULL) != 0) + return res; - res.sec = clk.tv_sec; - res.usec = clk.tv_usec; + res.sec = clk.tv_sec; + res.usec = clk.tv_usec; - return res; + return res; } extern mp_err s_mp_pad(); -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - instant_t start, finish; - mp_int prime, gen, expt, res; - unsigned int ix, diff; - int num; + instant_t start, finish; + mp_int prime, gen, expt, res; + unsigned int ix, diff; + int num; - srand(time(NULL)); + srand(time(NULL)); - if(argc < 2) { - fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]); - return 1; - } + if (argc < 2) { + fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]); + return 1; + } - if((num = atoi(argv[1])) < 0) - num = -num; + if ((num = atoi(argv[1])) < 0) + num = -num; - if(num == 0) - ++num; + if (num == 0) + ++num; - mp_init(&prime); mp_init(&gen); mp_init(&res); - mp_read_radix(&prime, g_prime, 16); - mp_read_radix(&gen, g_gen, 16); + mp_init(&prime); + mp_init(&gen); + mp_init(&res); + mp_read_radix(&prime, g_prime, 16); + mp_read_radix(&gen, g_gen, 16); - mp_init_size(&expt, USED(&prime) - 1); - s_mp_pad(&expt, USED(&prime) - 1); + mp_init_size(&expt, USED(&prime) - 1); + s_mp_pad(&expt, USED(&prime) - 1); - printf("Testing %d modular exponentations ... \n", num); + printf("Testing %d modular exponentations ... \n", num); - start = now(); - for(ix = 0; ix < num; ix++) { - mpp_random(&expt); - mp_exptmod(&gen, &expt, &prime, &res); - } - finish = now(); + start = now(); + for (ix = 0; ix < num; ix++) { + mpp_random(&expt); + mp_exptmod(&gen, &expt, &prime, &res); + } + finish = now(); - diff = (finish.sec - start.sec) * 1000000; - diff += finish.usec; diff -= start.usec; + diff = (finish.sec - start.sec) * 1000000; + diff += finish.usec; + diff -= start.usec; - printf("%d operations took %u usec (%.3f sec)\n", - num, diff, (double)diff / 1000000.0); - printf("That is %.3f sec per operation.\n", - ((double)diff / 1000000.0) / num); + printf("%d operations took %u usec (%.3f sec)\n", + num, diff, (double)diff / 1000000.0); + printf("That is %.3f sec per operation.\n", + ((double)diff / 1000000.0) / num); - mp_clear(&expt); - mp_clear(&res); - mp_clear(&gen); - mp_clear(&prime); + mp_clear(&expt); + mp_clear(&res); + mp_clear(&gen); + mp_clear(&prime); - return 0; + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-5.c b/nss/lib/freebl/mpi/tests/mptest-5.c index 73e8901..dff3ed4 100644 --- a/nss/lib/freebl/mpi/tests/mptest-5.c +++ b/nss/lib/freebl/mpi/tests/mptest-5.c @@ -15,56 +15,71 @@ #include "mpi.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a, b, c, x, y; + mp_int a, b, c, x, y; - if(argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } + if (argc < 3) { + fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); + return 1; + } - printf("Test 5: Number theoretic functions\n\n"); + printf("Test 5: Number theoretic functions\n\n"); - mp_init(&a); - mp_init(&b); + mp_init(&a); + mp_init(&b); - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); + mp_read_radix(&a, argv[1], 10); + mp_read_radix(&b, argv[2], 10); - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - - mp_init(&c); - printf("\nc = (a, b)\n"); + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); - mp_gcd(&a, &b, &c); - printf("Euclid: c = "); mp_print(&c, stdout); fputc('\n', stdout); -/* - mp_bgcd(&a, &b, &c); - printf("Binary: c = "); mp_print(&c, stdout); fputc('\n', stdout); -*/ - mp_init(&x); - mp_init(&y); - printf("\nc = (a, b) = ax + by\n"); + mp_init(&c); + printf("\nc = (a, b)\n"); + + mp_gcd(&a, &b, &c); + printf("Euclid: c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + /* + mp_bgcd(&a, &b, &c); + printf("Binary: c = "); mp_print(&c, stdout); fputc('\n', stdout); + */ + mp_init(&x); + mp_init(&y); + printf("\nc = (a, b) = ax + by\n"); - mp_xgcd(&a, &b, &c, &x, &y); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - printf("x = "); mp_print(&x, stdout); fputc('\n', stdout); - printf("y = "); mp_print(&y, stdout); fputc('\n', stdout); + mp_xgcd(&a, &b, &c, &x, &y); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + printf("x = "); + mp_print(&x, stdout); + fputc('\n', stdout); + printf("y = "); + mp_print(&y, stdout); + fputc('\n', stdout); - printf("\nc = a^-1 (mod b)\n"); - if(mp_invmod(&a, &b, &c) == MP_UNDEF) { - printf("a has no inverse mod b\n"); - } else { - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - } + printf("\nc = a^-1 (mod b)\n"); + if (mp_invmod(&a, &b, &c) == MP_UNDEF) { + printf("a has no inverse mod b\n"); + } else { + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + } - mp_clear(&y); - mp_clear(&x); - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); + mp_clear(&y); + mp_clear(&x); + mp_clear(&c); + mp_clear(&b); + mp_clear(&a); - return 0; + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-5a.c b/nss/lib/freebl/mpi/tests/mptest-5a.c index c7b29f7..c410a6a 100644 --- a/nss/lib/freebl/mpi/tests/mptest-5a.c +++ b/nss/lib/freebl/mpi/tests/mptest-5a.c @@ -20,113 +20,128 @@ #include "mpprime.h" typedef struct { - unsigned int sec; - unsigned int usec; + unsigned int sec; + unsigned int usec; } instant_t; -instant_t now(void) +instant_t +now(void) { - struct timeval clk; - instant_t res; + struct timeval clk; + instant_t res; - res.sec = res.usec = 0; + res.sec = res.usec = 0; - if(gettimeofday(&clk, NULL) != 0) - return res; + if (gettimeofday(&clk, NULL) != 0) + return res; - res.sec = clk.tv_sec; - res.usec = clk.tv_usec; + res.sec = clk.tv_sec; + res.usec = clk.tv_usec; - return res; + return res; } #define PRECISION 16 -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix, num, prec = PRECISION; - mp_int a, b, c, d; - instant_t start, finish; - time_t seed; - unsigned int d1, d2; - - seed = time(NULL); - - if(argc < 2) { - fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]); - return 1; - } - - if((num = atoi(argv[1])) < 0) - num = -num; - - printf("Test 5a: Euclid vs. Binary, a GCD speed test\n\n" - "Number of tests: %d\n" - "Precision: %d digits\n\n", num, prec); - - mp_init_size(&a, prec); - mp_init_size(&b, prec); - mp_init(&c); - mp_init(&d); - - printf("Verifying accuracy ... \n"); - srand((unsigned int)seed); - for(ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mpp_random_size(&b, prec); - - mp_gcd(&a, &b, &c); - mp_bgcd(&a, &b, &d); - - if(mp_cmp(&c, &d) != 0) { - printf("Error! Results not accurate:\n"); - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - printf("d = "); mp_print(&d, stdout); fputc('\n', stdout); - - mp_clear(&a); mp_clear(&b); mp_clear(&c); mp_clear(&d); - return 1; + int ix, num, prec = PRECISION; + mp_int a, b, c, d; + instant_t start, finish; + time_t seed; + unsigned int d1, d2; + + seed = time(NULL); + + if (argc < 2) { + fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]); + return 1; + } + + if ((num = atoi(argv[1])) < 0) + num = -num; + + printf("Test 5a: Euclid vs. Binary, a GCD speed test\n\n" + "Number of tests: %d\n" + "Precision: %d digits\n\n", + num, prec); + + mp_init_size(&a, prec); + mp_init_size(&b, prec); + mp_init(&c); + mp_init(&d); + + printf("Verifying accuracy ... \n"); + srand((unsigned int)seed); + for (ix = 0; ix < num; ix++) { + mpp_random_size(&a, prec); + mpp_random_size(&b, prec); + + mp_gcd(&a, &b, &c); + mp_bgcd(&a, &b, &d); + + if (mp_cmp(&c, &d) != 0) { + printf("Error! Results not accurate:\n"); + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + printf("d = "); + mp_print(&d, stdout); + fputc('\n', stdout); + + mp_clear(&a); + mp_clear(&b); + mp_clear(&c); + mp_clear(&d); + return 1; + } } - } - mp_clear(&d); - printf("Accuracy confirmed for the %d test samples\n", num); - - printf("Testing Euclid ... \n"); - srand((unsigned int)seed); - start = now(); - for(ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mpp_random_size(&b, prec); - mp_gcd(&a, &b, &c); - - } - finish = now(); - - d1 = (finish.sec - start.sec) * 1000000; - d1 -= start.usec; d1 += finish.usec; - - printf("Testing binary ... \n"); - srand((unsigned int)seed); - start = now(); - for(ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mpp_random_size(&b, prec); - mp_bgcd(&a, &b, &c); - } - finish = now(); - - d2 = (finish.sec - start.sec) * 1000000; - d2 -= start.usec; d2 += finish.usec; - - printf("Euclidean algorithm time: %u usec\n", d1); - printf("Binary algorithm time: %u usec\n", d2); - printf("Improvement: %.2f%%\n", - (1.0 - ((double)d2 / (double)d1)) * 100.0); - - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); - - return 0; + mp_clear(&d); + printf("Accuracy confirmed for the %d test samples\n", num); + + printf("Testing Euclid ... \n"); + srand((unsigned int)seed); + start = now(); + for (ix = 0; ix < num; ix++) { + mpp_random_size(&a, prec); + mpp_random_size(&b, prec); + mp_gcd(&a, &b, &c); + } + finish = now(); + + d1 = (finish.sec - start.sec) * 1000000; + d1 -= start.usec; + d1 += finish.usec; + + printf("Testing binary ... \n"); + srand((unsigned int)seed); + start = now(); + for (ix = 0; ix < num; ix++) { + mpp_random_size(&a, prec); + mpp_random_size(&b, prec); + mp_bgcd(&a, &b, &c); + } + finish = now(); + + d2 = (finish.sec - start.sec) * 1000000; + d2 -= start.usec; + d2 += finish.usec; + + printf("Euclidean algorithm time: %u usec\n", d1); + printf("Binary algorithm time: %u usec\n", d2); + printf("Improvement: %.2f%%\n", + (1.0 - ((double)d2 / (double)d1)) * 100.0); + + mp_clear(&c); + mp_clear(&b); + mp_clear(&a); + + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-6.c b/nss/lib/freebl/mpi/tests/mptest-6.c index d39b3d4..4febf39 100644 --- a/nss/lib/freebl/mpi/tests/mptest-6.c +++ b/nss/lib/freebl/mpi/tests/mptest-6.c @@ -15,64 +15,64 @@ #include "mpi.h" -void print_buf(FILE *ofp, char *buf, int len) +void +print_buf(FILE *ofp, char *buf, int len) { - int ix, brk = 0; + int ix, brk = 0; - for(ix = 0; ix < len; ix++) { - fprintf(ofp, "%02X ", buf[ix]); + for (ix = 0; ix < len; ix++) { + fprintf(ofp, "%02X ", buf[ix]); - brk = (brk + 1) & 0xF; - if(!brk) - fputc('\n', ofp); - } - - if(brk) - fputc('\n', ofp); + brk = (brk + 1) & 0xF; + if (!brk) + fputc('\n', ofp); + } + if (brk) + fputc('\n', ofp); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix, size; - mp_int a; - char *buf; + int ix, size; + mp_int a; + char *buf; - if(argc < 2) { - fprintf(stderr, "Usage: %s <a>\n", argv[0]); - return 1; - } + if (argc < 2) { + fprintf(stderr, "Usage: %s <a>\n", argv[0]); + return 1; + } - printf("Test 6: Output functions\n\n"); + printf("Test 6: Output functions\n\n"); - mp_init(&a); + mp_init(&a); - mp_read_radix(&a, argv[1], 10); + mp_read_radix(&a, argv[1], 10); - printf("\nConverting to a string:\n"); + printf("\nConverting to a string:\n"); - printf("Rx Size Representation\n"); - for(ix = 2; ix <= MAX_RADIX; ix++) { - size = mp_radix_size(&a, ix); + printf("Rx Size Representation\n"); + for (ix = 2; ix <= MAX_RADIX; ix++) { + size = mp_radix_size(&a, ix); - buf = calloc(size, sizeof(char)); - mp_toradix(&a, buf, ix); - printf("%2d: %3d: %s\n", ix, size, buf); - free(buf); + buf = calloc(size, sizeof(char)); + mp_toradix(&a, buf, ix); + printf("%2d: %3d: %s\n", ix, size, buf); + free(buf); + } - } + printf("\nRaw output:\n"); + size = mp_raw_size(&a); + buf = calloc(size, sizeof(char)); - printf("\nRaw output:\n"); - size = mp_raw_size(&a); - buf = calloc(size, sizeof(char)); + printf("Size: %d bytes\n", size); - printf("Size: %d bytes\n", size); + mp_toraw(&a, buf); + print_buf(stdout, buf, size); + free(buf); - mp_toraw(&a, buf); - print_buf(stdout, buf, size); - free(buf); - - mp_clear(&a); + mp_clear(&a); - return 0; + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-7.c b/nss/lib/freebl/mpi/tests/mptest-7.c index bc86029..1e83fbf 100644 --- a/nss/lib/freebl/mpi/tests/mptest-7.c +++ b/nss/lib/freebl/mpi/tests/mptest-7.c @@ -19,56 +19,67 @@ #include "mpprime.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_digit num; - mp_int a, b; - - srand(time(NULL)); - - if(argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } - - printf("Test 7: Random & divisibility tests\n\n"); - - mp_init(&a); - mp_init(&b); - - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); - - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - - if(mpp_divis(&a, &b) == MP_YES) - printf("a is divisible by b\n"); - else - printf("a is not divisible by b\n"); - - if(mpp_divis(&b, &a) == MP_YES) - printf("b is divisible by a\n"); - else - printf("b is not divisible by a\n"); - - printf("\nb = mpp_random()\n"); - mpp_random(&b); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - mpp_random(&b); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - mpp_random(&b); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - - printf("\nTesting a for divisibility by first 170 primes\n"); - num = 170; - if(mpp_divis_primes(&a, &num) == MP_YES) - printf("It is divisible by at least one of them\n"); - else - printf("It is not divisible by any of them\n"); - - mp_clear(&b); - mp_clear(&a); - - return 0; + mp_digit num; + mp_int a, b; + + srand(time(NULL)); + + if (argc < 3) { + fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); + return 1; + } + + printf("Test 7: Random & divisibility tests\n\n"); + + mp_init(&a); + mp_init(&b); + + mp_read_radix(&a, argv[1], 10); + mp_read_radix(&b, argv[2], 10); + + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + + if (mpp_divis(&a, &b) == MP_YES) + printf("a is divisible by b\n"); + else + printf("a is not divisible by b\n"); + + if (mpp_divis(&b, &a) == MP_YES) + printf("b is divisible by a\n"); + else + printf("b is not divisible by a\n"); + + printf("\nb = mpp_random()\n"); + mpp_random(&b); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + mpp_random(&b); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + mpp_random(&b); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + + printf("\nTesting a for divisibility by first 170 primes\n"); + num = 170; + if (mpp_divis_primes(&a, &num) == MP_YES) + printf("It is divisible by at least one of them\n"); + else + printf("It is not divisible by any of them\n"); + + mp_clear(&b); + mp_clear(&a); + + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-8.c b/nss/lib/freebl/mpi/tests/mptest-8.c index 8be438c..a9d3aff 100644 --- a/nss/lib/freebl/mpi/tests/mptest-8.c +++ b/nss/lib/freebl/mpi/tests/mptest-8.c @@ -19,47 +19,50 @@ #include "mpprime.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix; - mp_digit num; - mp_int a; + int ix; + mp_digit num; + mp_int a; - srand(time(NULL)); + srand(time(NULL)); - if(argc < 2) { - fprintf(stderr, "Usage: %s <a>\n", argv[0]); - return 1; - } + if (argc < 2) { + fprintf(stderr, "Usage: %s <a>\n", argv[0]); + return 1; + } - printf("Test 8: Probabilistic primality testing\n\n"); + printf("Test 8: Probabilistic primality testing\n\n"); - mp_init(&a); + mp_init(&a); - mp_read_radix(&a, argv[1], 10); + mp_read_radix(&a, argv[1], 10); - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); - printf("\nChecking for divisibility by small primes ... \n"); - num = 170; - if(mpp_divis_primes(&a, &num) == MP_YES) { - printf("it is not prime\n"); - goto CLEANUP; - } - printf("Passed that test (not divisible by any small primes).\n"); + printf("\nChecking for divisibility by small primes ... \n"); + num = 170; + if (mpp_divis_primes(&a, &num) == MP_YES) { + printf("it is not prime\n"); + goto CLEANUP; + } + printf("Passed that test (not divisible by any small primes).\n"); - for(ix = 0; ix < 10; ix++) { - printf("\nPerforming Rabin-Miller test, iteration %d\n", ix + 1); + for (ix = 0; ix < 10; ix++) { + printf("\nPerforming Rabin-Miller test, iteration %d\n", ix + 1); - if(mpp_pprime(&a, 5) == MP_NO) { - printf("it is not prime\n"); - goto CLEANUP; + if (mpp_pprime(&a, 5) == MP_NO) { + printf("it is not prime\n"); + goto CLEANUP; + } } - } - printf("All tests passed; a is probably prime\n"); + printf("All tests passed; a is probably prime\n"); CLEANUP: - mp_clear(&a); + mp_clear(&a); - return 0; + return 0; } diff --git a/nss/lib/freebl/mpi/tests/mptest-9.c b/nss/lib/freebl/mpi/tests/mptest-9.c index 210adca..133264e 100644 --- a/nss/lib/freebl/mpi/tests/mptest-9.c +++ b/nss/lib/freebl/mpi/tests/mptest-9.c @@ -17,67 +17,93 @@ #include "mpi.h" #include "mplogic.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a, b, c; - int pco; - mp_err res; - - printf("Test 9: Logical functions\n\n"); - - if(argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } - - mp_init(&a); mp_init(&b); mp_init(&c); - mp_read_radix(&a, argv[1], 16); - mp_read_radix(&b, argv[2], 16); - - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - - mpl_not(&a, &c); - printf("~a = "); mp_print(&c, stdout); fputc('\n', stdout); - - mpl_and(&a, &b, &c); - printf("a & b = "); mp_print(&c, stdout); fputc('\n', stdout); - - mpl_or(&a, &b, &c); - printf("a | b = "); mp_print(&c, stdout); fputc('\n', stdout); - - mpl_xor(&a, &b, &c); - printf("a ^ b = "); mp_print(&c, stdout); fputc('\n', stdout); - - mpl_rsh(&a, &c, 1); - printf("a >> 1 = "); mp_print(&c, stdout); fputc('\n', stdout); - mpl_rsh(&a, &c, 5); - printf("a >> 5 = "); mp_print(&c, stdout); fputc('\n', stdout); - mpl_rsh(&a, &c, 16); - printf("a >> 16 = "); mp_print(&c, stdout); fputc('\n', stdout); - - mpl_lsh(&a, &c, 1); - printf("a << 1 = "); mp_print(&c, stdout); fputc('\n', stdout); - mpl_lsh(&a, &c, 5); - printf("a << 5 = "); mp_print(&c, stdout); fputc('\n', stdout); - mpl_lsh(&a, &c, 16); - printf("a << 16 = "); mp_print(&c, stdout); fputc('\n', stdout); - - mpl_num_set(&a, &pco); - printf("population(a) = %d\n", pco); - mpl_num_set(&b, &pco); - printf("population(b) = %d\n", pco); - - res = mpl_parity(&a); - if(res == MP_EVEN) - printf("a has even parity\n"); - else - printf("a has odd parity\n"); - - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); - - return 0; + mp_int a, b, c; + int pco; + mp_err res; + + printf("Test 9: Logical functions\n\n"); + + if (argc < 3) { + fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); + return 1; + } + + mp_init(&a); + mp_init(&b); + mp_init(&c); + mp_read_radix(&a, argv[1], 16); + mp_read_radix(&b, argv[2], 16); + + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + + mpl_not(&a, &c); + printf("~a = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + mpl_and(&a, &b, &c); + printf("a & b = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + mpl_or(&a, &b, &c); + printf("a | b = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + mpl_xor(&a, &b, &c); + printf("a ^ b = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + mpl_rsh(&a, &c, 1); + printf("a >> 1 = "); + mp_print(&c, stdout); + fputc('\n', stdout); + mpl_rsh(&a, &c, 5); + printf("a >> 5 = "); + mp_print(&c, stdout); + fputc('\n', stdout); + mpl_rsh(&a, &c, 16); + printf("a >> 16 = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + mpl_lsh(&a, &c, 1); + printf("a << 1 = "); + mp_print(&c, stdout); + fputc('\n', stdout); + mpl_lsh(&a, &c, 5); + printf("a << 5 = "); + mp_print(&c, stdout); + fputc('\n', stdout); + mpl_lsh(&a, &c, 16); + printf("a << 16 = "); + mp_print(&c, stdout); + fputc('\n', stdout); + + mpl_num_set(&a, &pco); + printf("population(a) = %d\n", pco); + mpl_num_set(&b, &pco); + printf("population(b) = %d\n", pco); + + res = mpl_parity(&a); + if (res == MP_EVEN) + printf("a has even parity\n"); + else + printf("a has odd parity\n"); + + mp_clear(&c); + mp_clear(&b); + mp_clear(&a); + + return 0; } - diff --git a/nss/lib/freebl/mpi/tests/mptest-b.c b/nss/lib/freebl/mpi/tests/mptest-b.c index 51ffc20..07f30ea 100644 --- a/nss/lib/freebl/mpi/tests/mptest-b.c +++ b/nss/lib/freebl/mpi/tests/mptest-b.c @@ -15,14 +15,15 @@ #include "mp_gf2m.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix; - mp_int pp, a, b, x, y, order; - mp_int c, d, e; + int ix; + mp_int pp, a, b, x, y, order; + mp_int c, d, e; mp_digit r; - mp_err res; - unsigned int p[] = {163,7,6,3,0}; + mp_err res; + unsigned int p[] = { 163, 7, 6, 3, 0 }; unsigned int ptemp[10]; printf("Test b: Binary Polynomial Arithmetic\n\n"); @@ -40,12 +41,24 @@ int main(int argc, char *argv[]) mp_read_radix(&x, "03F0EBA16286A2D57EA0991168D4994637E8343E36", 16); mp_read_radix(&y, "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", 16); mp_read_radix(&order, "040000000000000000000292FE77E70C12A4234C33", 16); - printf("pp = "); mp_print(&pp, stdout); fputc('\n', stdout); - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - printf("x = "); mp_print(&x, stdout); fputc('\n', stdout); - printf("y = "); mp_print(&y, stdout); fputc('\n', stdout); - printf("order = "); mp_print(&order, stdout); fputc('\n', stdout); + printf("pp = "); + mp_print(&pp, stdout); + fputc('\n', stdout); + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + printf("x = "); + mp_print(&x, stdout); + fputc('\n', stdout); + printf("y = "); + mp_print(&y, stdout); + fputc('\n', stdout); + printf("order = "); + mp_print(&order, stdout); + fputc('\n', stdout); mp_init(&c); mp_init(&d); @@ -54,121 +67,152 @@ int main(int argc, char *argv[]) /* Test polynomial conversion */ ix = mp_bpoly2arr(&pp, ptemp, 10); if ( - (ix != 5) || - (ptemp[0] != p[0]) || - (ptemp[1] != p[1]) || - (ptemp[2] != p[2]) || - (ptemp[3] != p[3]) || - (ptemp[4] != p[4]) - ) { - printf("Polynomial to array conversion not correct\n"); - return -1; + (ix != 5) || + (ptemp[0] != p[0]) || + (ptemp[1] != p[1]) || + (ptemp[2] != p[2]) || + (ptemp[3] != p[3]) || + (ptemp[4] != p[4])) { + printf("Polynomial to array conversion not correct\n"); + return -1; } printf("Polynomial conversion test #1 successful.\n"); - MP_CHECKOK( mp_barr2poly(p, &c) ); + MP_CHECKOK(mp_barr2poly(p, &c)); if (mp_cmp(&pp, &c) != 0) { - printf("Array to polynomial conversion not correct\n"); + printf("Array to polynomial conversion not correct\n"); return -1; } printf("Polynomial conversion test #2 successful.\n"); /* Test addition */ - MP_CHECKOK( mp_badd(&a, &a, &c) ); + MP_CHECKOK(mp_badd(&a, &a, &c)); if (mp_cmp_z(&c) != 0) { - printf("a+a should equal zero\n"); + printf("a+a should equal zero\n"); return -1; } printf("Addition test #1 successful.\n"); - MP_CHECKOK( mp_badd(&a, &b, &c) ); - MP_CHECKOK( mp_badd(&b, &c, &c) ); + MP_CHECKOK(mp_badd(&a, &b, &c)); + MP_CHECKOK(mp_badd(&b, &c, &c)); if (mp_cmp(&c, &a) != 0) { - printf("c = (a + b) + b should equal a\n"); - printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("c = (a + b) + b should equal a\n"); + printf("a = "); + mp_print(&a, stdout); + fputc('\n', stdout); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); return -1; } printf("Addition test #2 successful.\n"); - + /* Test multiplication */ mp_set(&c, 2); - MP_CHECKOK( mp_bmul(&b, &c, &c) ); - MP_CHECKOK( mp_badd(&b, &c, &c) ); + MP_CHECKOK(mp_bmul(&b, &c, &c)); + MP_CHECKOK(mp_badd(&b, &c, &c)); mp_set(&d, 3); - MP_CHECKOK( mp_bmul(&b, &d, &d) ); + MP_CHECKOK(mp_bmul(&b, &d, &d)); if (mp_cmp(&c, &d) != 0) { - printf("c = (2 * b) + b should equal c = 3 * b\n"); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - printf("d = "); mp_print(&d, stdout); fputc('\n', stdout); + printf("c = (2 * b) + b should equal c = 3 * b\n"); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + printf("d = "); + mp_print(&d, stdout); + fputc('\n', stdout); return -1; } printf("Multiplication test #1 successful.\n"); /* Test modular reduction */ - MP_CHECKOK( mp_bmod(&b, p, &c) ); + MP_CHECKOK(mp_bmod(&b, p, &c)); if (mp_cmp(&b, &c) != 0) { - printf("c = b mod p should equal b\n"); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("c = b mod p should equal b\n"); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); return -1; } printf("Modular reduction test #1 successful.\n"); - MP_CHECKOK( mp_badd(&b, &pp, &c) ); - MP_CHECKOK( mp_bmod(&c, p, &c) ); + MP_CHECKOK(mp_badd(&b, &pp, &c)); + MP_CHECKOK(mp_bmod(&c, p, &c)); if (mp_cmp(&b, &c) != 0) { - printf("c = (b + p) mod p should equal b\n"); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("c = (b + p) mod p should equal b\n"); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); return -1; } printf("Modular reduction test #2 successful.\n"); - MP_CHECKOK( mp_bmul(&b, &pp, &c) ); - MP_CHECKOK( mp_bmod(&c, p, &c) ); + MP_CHECKOK(mp_bmul(&b, &pp, &c)); + MP_CHECKOK(mp_bmod(&c, p, &c)); if (mp_cmp_z(&c) != 0) { - printf("c = (b * p) mod p should equal 0\n"); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("c = (b * p) mod p should equal 0\n"); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); return -1; } printf("Modular reduction test #3 successful.\n"); /* Test modular multiplication */ - MP_CHECKOK( mp_bmulmod(&b, &pp, p, &c) ); + MP_CHECKOK(mp_bmulmod(&b, &pp, p, &c)); if (mp_cmp_z(&c) != 0) { - printf("c = (b * p) mod p should equal 0\n"); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("c = (b * p) mod p should equal 0\n"); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); return -1; } printf("Modular multiplication test #1 successful.\n"); mp_set(&c, 1); - MP_CHECKOK( mp_badd(&pp, &c, &c) ); - MP_CHECKOK( mp_bmulmod(&b, &c, p, &c) ); + MP_CHECKOK(mp_badd(&pp, &c, &c)); + MP_CHECKOK(mp_bmulmod(&b, &c, p, &c)); if (mp_cmp(&b, &c) != 0) { - printf("c = (b * (p + 1)) mod p should equal b\n"); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("c = (b * (p + 1)) mod p should equal b\n"); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); return -1; } printf("Modular multiplication test #2 successful.\n"); /* Test modular squaring */ - MP_CHECKOK( mp_copy(&b, &c) ); - MP_CHECKOK( mp_bmulmod(&b, &c, p, &c) ); - MP_CHECKOK( mp_bsqrmod(&b, p, &d) ); + MP_CHECKOK(mp_copy(&b, &c)); + MP_CHECKOK(mp_bmulmod(&b, &c, p, &c)); + MP_CHECKOK(mp_bsqrmod(&b, p, &d)); if (mp_cmp(&c, &d) != 0) { - printf("c = (b * b) mod p should equal d = b^2 mod p\n"); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); - printf("d = "); mp_print(&d, stdout); fputc('\n', stdout); + printf("c = (b * b) mod p should equal d = b^2 mod p\n"); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); + printf("d = "); + mp_print(&d, stdout); + fputc('\n', stdout); return -1; } printf("Modular squaring test #1 successful.\n"); - + /* Test modular division */ - MP_CHECKOK( mp_bdivmod(&b, &x, &pp, p, &c) ); - MP_CHECKOK( mp_bmulmod(&c, &x, p, &c) ); + MP_CHECKOK(mp_bdivmod(&b, &x, &pp, p, &c)); + MP_CHECKOK(mp_bmulmod(&c, &x, p, &c)); if (mp_cmp(&b, &c) != 0) { - printf("c = (b / x) * x mod p should equal b\n"); - printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); - printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); + printf("c = (b / x) * x mod p should equal b\n"); + printf("b = "); + mp_print(&b, stdout); + fputc('\n', stdout); + printf("c = "); + mp_print(&c, stdout); + fputc('\n', stdout); return -1; } printf("Modular division test #1 successful.\n"); diff --git a/nss/lib/freebl/mpi/utils/basecvt.c b/nss/lib/freebl/mpi/utils/basecvt.c index 6cfda55..0e99154 100644 --- a/nss/lib/freebl/mpi/utils/basecvt.c +++ b/nss/lib/freebl/mpi/utils/basecvt.c @@ -15,53 +15,54 @@ #include "mpi.h" -#define IBASE 10 -#define OBASE 16 -#define USAGE "Usage: %s ibase obase [value]\n" -#define MAXBASE 64 -#define MINBASE 2 +#define IBASE 10 +#define OBASE 16 +#define USAGE "Usage: %s ibase obase [value]\n" +#define MAXBASE 64 +#define MINBASE 2 -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix, ibase = IBASE, obase = OBASE; - mp_int val; + int ix, ibase = IBASE, obase = OBASE; + mp_int val; - ix = 1; - if(ix < argc) { - ibase = atoi(argv[ix++]); - - if(ibase < MINBASE || ibase > MAXBASE) { - fprintf(stderr, "%s: input radix must be between %d and %d inclusive\n", - argv[0], MINBASE, MAXBASE); - return 1; + ix = 1; + if (ix < argc) { + ibase = atoi(argv[ix++]); + + if (ibase < MINBASE || ibase > MAXBASE) { + fprintf(stderr, "%s: input radix must be between %d and %d inclusive\n", + argv[0], MINBASE, MAXBASE); + return 1; + } } - } - if(ix < argc) { - obase = atoi(argv[ix++]); + if (ix < argc) { + obase = atoi(argv[ix++]); - if(obase < MINBASE || obase > MAXBASE) { - fprintf(stderr, "%s: output radix must be between %d and %d inclusive\n", - argv[0], MINBASE, MAXBASE); - return 1; + if (obase < MINBASE || obase > MAXBASE) { + fprintf(stderr, "%s: output radix must be between %d and %d inclusive\n", + argv[0], MINBASE, MAXBASE); + return 1; + } } - } - mp_init(&val); - while(ix < argc) { - char *out; - int outlen; + mp_init(&val); + while (ix < argc) { + char *out; + int outlen; - mp_read_radix(&val, argv[ix++], ibase); + mp_read_radix(&val, argv[ix++], ibase); - outlen = mp_radix_size(&val, obase); - out = calloc(outlen, sizeof(char)); - mp_toradix(&val, out, obase); + outlen = mp_radix_size(&val, obase); + out = calloc(outlen, sizeof(char)); + mp_toradix(&val, out, obase); - printf("%s\n", out); - free(out); - } + printf("%s\n", out); + free(out); + } - mp_clear(&val); + mp_clear(&val); - return 0; + return 0; } diff --git a/nss/lib/freebl/mpi/utils/bbs_rand.c b/nss/lib/freebl/mpi/utils/bbs_rand.c index c905b0f..fed2fe2 100644 --- a/nss/lib/freebl/mpi/utils/bbs_rand.c +++ b/nss/lib/freebl/mpi/utils/bbs_rand.c @@ -7,55 +7,57 @@ #include "bbs_rand.h" -#define SEED 1 -#define MODULUS 2 +#define SEED 1 +#define MODULUS 2 /* This modulus is the product of two randomly generated 512-bit prime integers, each of which is congruent to 3 (mod 4). */ -static char *bbs_modulus = -"75A2A6E1D27393B86562B9CE7279A8403CB4258A637DAB5233465373E37837383EDC" -"332282B8575927BC4172CE8C147B4894050EE9D2BDEED355C121037270CA2570D127" -"7D2390CD1002263326635CC6B259148DE3A1A03201980A925E395E646A5E9164B0EC" -"28559EBA58C87447245ADD0651EDA507056A1129E3A3E16E903D64B437"; +static char *bbs_modulus = + "75A2A6E1D27393B86562B9CE7279A8403CB4258A637DAB5233465373E37837383EDC" + "332282B8575927BC4172CE8C147B4894050EE9D2BDEED355C121037270CA2570D127" + "7D2390CD1002263326635CC6B259148DE3A1A03201980A925E395E646A5E9164B0EC" + "28559EBA58C87447245ADD0651EDA507056A1129E3A3E16E903D64B437"; -static int bbs_init = 0; /* flag set when library is initialized */ -static mp_int bbs_state; /* the current state of the generator */ +static int bbs_init = 0; /* flag set when library is initialized */ +static mp_int bbs_state; /* the current state of the generator */ /* Suggested size of random seed data */ -int bbs_seed_size = (sizeof(bbs_modulus) / 2); +int bbs_seed_size = (sizeof(bbs_modulus) / 2); -void bbs_srand(unsigned char *data, int len) +void +bbs_srand(unsigned char *data, int len) { - if((bbs_init & SEED) == 0) { - mp_init(&bbs_state); - bbs_init |= SEED; - } + if ((bbs_init & SEED) == 0) { + mp_init(&bbs_state); + bbs_init |= SEED; + } - mp_read_raw(&bbs_state, (char *)data, len); + mp_read_raw(&bbs_state, (char *)data, len); } /* end bbs_srand() */ -unsigned int bbs_rand(void) +unsigned int +bbs_rand(void) { - static mp_int modulus; - unsigned int result = 0, ix; + static mp_int modulus; + unsigned int result = 0, ix; - if((bbs_init & MODULUS) == 0) { - mp_init(&modulus); - mp_read_radix(&modulus, bbs_modulus, 16); - bbs_init |= MODULUS; - } + if ((bbs_init & MODULUS) == 0) { + mp_init(&modulus); + mp_read_radix(&modulus, bbs_modulus, 16); + bbs_init |= MODULUS; + } - for(ix = 0; ix < sizeof(unsigned int); ix++) { - mp_digit d; + for (ix = 0; ix < sizeof(unsigned int); ix++) { + mp_digit d; - mp_sqrmod(&bbs_state, &modulus, &bbs_state); - d = DIGIT(&bbs_state, 0); + mp_sqrmod(&bbs_state, &modulus, &bbs_state); + d = DIGIT(&bbs_state, 0); - result = (result << CHAR_BIT) | (d & UCHAR_MAX); - } + result = (result << CHAR_BIT) | (d & UCHAR_MAX); + } - return result; + return result; } /* end bbs_rand() */ diff --git a/nss/lib/freebl/mpi/utils/bbs_rand.h b/nss/lib/freebl/mpi/utils/bbs_rand.h index faf0f3d..d12269b 100644 --- a/nss/lib/freebl/mpi/utils/bbs_rand.h +++ b/nss/lib/freebl/mpi/utils/bbs_rand.h @@ -13,12 +13,12 @@ #include <limits.h> #include "mpi.h" -#define BBS_RAND_MAX UINT_MAX +#define BBS_RAND_MAX UINT_MAX /* Suggested length of seed data */ extern int bbs_seed_size; -void bbs_srand(unsigned char *data, int len); +void bbs_srand(unsigned char *data, int len); unsigned int bbs_rand(void); #endif /* end _H_BBSRAND_ */ diff --git a/nss/lib/freebl/mpi/utils/bbsrand.c b/nss/lib/freebl/mpi/utils/bbsrand.c index 6ef20bb..d9151e0 100644 --- a/nss/lib/freebl/mpi/utils/bbsrand.c +++ b/nss/lib/freebl/mpi/utils/bbsrand.c @@ -15,20 +15,21 @@ #include "bbs_rand.h" -#define NUM_TESTS 100 +#define NUM_TESTS 100 -int main(void) +int +main(void) { - unsigned int seed, result, ix; + unsigned int seed, result, ix; - seed = time(NULL); - bbs_srand((unsigned char *)&seed, sizeof(seed)); + seed = time(NULL); + bbs_srand((unsigned char *)&seed, sizeof(seed)); - for(ix = 0; ix < NUM_TESTS; ix++) { - result = bbs_rand(); - - printf("Test %3u: %08X\n", ix + 1, result); - } + for (ix = 0; ix < NUM_TESTS; ix++) { + result = bbs_rand(); - return 0; + printf("Test %3u: %08X\n", ix + 1, result); + } + + return 0; } diff --git a/nss/lib/freebl/mpi/utils/dec2hex.c b/nss/lib/freebl/mpi/utils/dec2hex.c index 13550e4..ef3a520 100644 --- a/nss/lib/freebl/mpi/utils/dec2hex.c +++ b/nss/lib/freebl/mpi/utils/dec2hex.c @@ -13,26 +13,28 @@ #include "mpi.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a; - char *buf; - int len; + mp_int a; + char *buf; + int len; - if(argc < 2) { - fprintf(stderr, "Usage: %s <a>\n", argv[0]); - return 1; - } + if (argc < 2) { + fprintf(stderr, "Usage: %s <a>\n", argv[0]); + return 1; + } - mp_init(&a); mp_read_radix(&a, argv[1], 10); - len = mp_radix_size(&a, 16); - buf = malloc(len); - mp_toradix(&a, buf, 16); + mp_init(&a); + mp_read_radix(&a, argv[1], 10); + len = mp_radix_size(&a, 16); + buf = malloc(len); + mp_toradix(&a, buf, 16); - printf("%s\n", buf); + printf("%s\n", buf); - free(buf); - mp_clear(&a); + free(buf); + mp_clear(&a); - return 0; + return 0; } diff --git a/nss/lib/freebl/mpi/utils/exptmod.c b/nss/lib/freebl/mpi/utils/exptmod.c index 4aa5b23..3ac9078 100644 --- a/nss/lib/freebl/mpi/utils/exptmod.c +++ b/nss/lib/freebl/mpi/utils/exptmod.c @@ -14,37 +14,42 @@ #include "mpi.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a, b, m; - mp_err res; - char *str; - int len, rval = 0; - - if(argc < 3) { - fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]); - return 1; - } - - mp_init(&a); mp_init(&b); mp_init(&m); - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); - mp_read_radix(&m, argv[3], 10); - - if((res = mp_exptmod(&a, &b, &m, &a)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); - rval = 1; - } else { - len = mp_radix_size(&a, 10); - str = calloc(len, sizeof(char)); - mp_toradix(&a, str, 10); - - printf("%s\n", str); - - free(str); - } - - mp_clear(&a); mp_clear(&b); mp_clear(&m); - - return rval; + mp_int a, b, m; + mp_err res; + char *str; + int len, rval = 0; + + if (argc < 3) { + fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]); + return 1; + } + + mp_init(&a); + mp_init(&b); + mp_init(&m); + mp_read_radix(&a, argv[1], 10); + mp_read_radix(&b, argv[2], 10); + mp_read_radix(&m, argv[3], 10); + + if ((res = mp_exptmod(&a, &b, &m, &a)) != MP_OKAY) { + fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); + rval = 1; + } else { + len = mp_radix_size(&a, 10); + str = calloc(len, sizeof(char)); + mp_toradix(&a, str, 10); + + printf("%s\n", str); + + free(str); + } + + mp_clear(&a); + mp_clear(&b); + mp_clear(&m); + + return rval; } diff --git a/nss/lib/freebl/mpi/utils/fact.c b/nss/lib/freebl/mpi/utils/fact.c index a8735ad..da8e61a 100644 --- a/nss/lib/freebl/mpi/utils/fact.c +++ b/nss/lib/freebl/mpi/utils/fact.c @@ -15,68 +15,70 @@ mp_err mp_fact(mp_int *a, mp_int *b); -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a; - mp_err res; + mp_int a; + mp_err res; - if(argc < 2) { - fprintf(stderr, "Usage: %s <number>\n", argv[0]); - return 1; - } + if (argc < 2) { + fprintf(stderr, "Usage: %s <number>\n", argv[0]); + return 1; + } - mp_init(&a); - mp_read_radix(&a, argv[1], 10); + mp_init(&a); + mp_read_radix(&a, argv[1], 10); - if((res = mp_fact(&a, &a)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", argv[0], - mp_strerror(res)); - mp_clear(&a); - return 1; - } + if ((res = mp_fact(&a, &a)) != MP_OKAY) { + fprintf(stderr, "%s: error: %s\n", argv[0], + mp_strerror(res)); + mp_clear(&a); + return 1; + } - { - char *buf; - int len; + { + char *buf; + int len; - len = mp_radix_size(&a, 10); - buf = malloc(len); - mp_todecimal(&a, buf); + len = mp_radix_size(&a, 10); + buf = malloc(len); + mp_todecimal(&a, buf); - puts(buf); + puts(buf); - free(buf); - } + free(buf); + } - mp_clear(&a); - return 0; + mp_clear(&a); + return 0; } -mp_err mp_fact(mp_int *a, mp_int *b) +mp_err +mp_fact(mp_int *a, mp_int *b) { - mp_int ix, s; - mp_err res = MP_OKAY; + mp_int ix, s; + mp_err res = MP_OKAY; - if(mp_cmp_z(a) < 0) - return MP_UNDEF; + if (mp_cmp_z(a) < 0) + return MP_UNDEF; - mp_init(&s); - mp_add_d(&s, 1, &s); /* s = 1 */ - mp_init(&ix); - mp_add_d(&ix, 1, &ix); /* ix = 1 */ + mp_init(&s); + mp_add_d(&s, 1, &s); /* s = 1 */ + mp_init(&ix); + mp_add_d(&ix, 1, &ix); /* ix = 1 */ - for(/* */; mp_cmp(&ix, a) <= 0; mp_add_d(&ix, 1, &ix)) { - if((res = mp_mul(&s, &ix, &s)) != MP_OKAY) - break; - } + for (/* */; mp_cmp(&ix, a) <= 0; mp_add_d(&ix, 1, &ix)) { + if ((res = mp_mul(&s, &ix, &s)) != MP_OKAY) + break; + } - mp_clear(&ix); + mp_clear(&ix); - /* Copy out results if we got them */ - if(res == MP_OKAY) - mp_copy(&s, b); + /* Copy out results if we got them */ + if (res == MP_OKAY) + mp_copy(&s, b); - mp_clear(&s); + mp_clear(&s); - return res; + return res; } diff --git a/nss/lib/freebl/mpi/utils/gcd.c b/nss/lib/freebl/mpi/utils/gcd.c index d5f3a4e..9f11a25 100644 --- a/nss/lib/freebl/mpi/utils/gcd.c +++ b/nss/lib/freebl/mpi/utils/gcd.c @@ -13,74 +13,83 @@ #include "mpi.h" -char *g_prog = NULL; +char *g_prog = NULL; void print_mp_int(mp_int *mp, FILE *ofp); -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a, b, x, y; - mp_err res; - int ext = 0; - - g_prog = argv[0]; - - if(argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", g_prog); - return 1; - } - - mp_init(&a); mp_read_radix(&a, argv[1], 10); - mp_init(&b); mp_read_radix(&b, argv[2], 10); - - /* If we were called 'xgcd', compute x, y so that g = ax + by */ - if(strcmp(g_prog, "xgcd") == 0) { - ext = 1; - mp_init(&x); mp_init(&y); - } - - if(ext) { - if((res = mp_xgcd(&a, &b, &a, &x, &y)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", g_prog, mp_strerror(res)); - mp_clear(&a); mp_clear(&b); - mp_clear(&x); mp_clear(&y); - return 1; + mp_int a, b, x, y; + mp_err res; + int ext = 0; + + g_prog = argv[0]; + + if (argc < 3) { + fprintf(stderr, "Usage: %s <a> <b>\n", g_prog); + return 1; } - } else { - if((res = mp_gcd(&a, &b, &a)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", g_prog, - mp_strerror(res)); - mp_clear(&a); mp_clear(&b); - return 1; + + mp_init(&a); + mp_read_radix(&a, argv[1], 10); + mp_init(&b); + mp_read_radix(&b, argv[2], 10); + + /* If we were called 'xgcd', compute x, y so that g = ax + by */ + if (strcmp(g_prog, "xgcd") == 0) { + ext = 1; + mp_init(&x); + mp_init(&y); } - } - print_mp_int(&a, stdout); - if(ext) { - fputs("x = ", stdout); print_mp_int(&x, stdout); - fputs("y = ", stdout); print_mp_int(&y, stdout); - } + if (ext) { + if ((res = mp_xgcd(&a, &b, &a, &x, &y)) != MP_OKAY) { + fprintf(stderr, "%s: error: %s\n", g_prog, mp_strerror(res)); + mp_clear(&a); + mp_clear(&b); + mp_clear(&x); + mp_clear(&y); + return 1; + } + } else { + if ((res = mp_gcd(&a, &b, &a)) != MP_OKAY) { + fprintf(stderr, "%s: error: %s\n", g_prog, + mp_strerror(res)); + mp_clear(&a); + mp_clear(&b); + return 1; + } + } - mp_clear(&a); mp_clear(&b); + print_mp_int(&a, stdout); + if (ext) { + fputs("x = ", stdout); + print_mp_int(&x, stdout); + fputs("y = ", stdout); + print_mp_int(&y, stdout); + } - if(ext) { - mp_clear(&x); - mp_clear(&y); - } + mp_clear(&a); + mp_clear(&b); - return 0; + if (ext) { + mp_clear(&x); + mp_clear(&y); + } + return 0; } -void print_mp_int(mp_int *mp, FILE *ofp) +void +print_mp_int(mp_int *mp, FILE *ofp) { - char *buf; - int len; - - len = mp_radix_size(mp, 10); - buf = calloc(len, sizeof(char)); - mp_todecimal(mp, buf); - fprintf(ofp, "%s\n", buf); - free(buf); - + char *buf; + int len; + + len = mp_radix_size(mp, 10); + buf = calloc(len, sizeof(char)); + mp_todecimal(mp, buf); + fprintf(ofp, "%s\n", buf); + free(buf); } diff --git a/nss/lib/freebl/mpi/utils/hex2dec.c b/nss/lib/freebl/mpi/utils/hex2dec.c index 5bcb0f3..9b21d22 100644 --- a/nss/lib/freebl/mpi/utils/hex2dec.c +++ b/nss/lib/freebl/mpi/utils/hex2dec.c @@ -13,26 +13,28 @@ #include "mpi.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a; - char *buf; - int len; + mp_int a; + char *buf; + int len; - if(argc < 2) { - fprintf(stderr, "Usage: %s <a>\n", argv[0]); - return 1; - } + if (argc < 2) { + fprintf(stderr, "Usage: %s <a>\n", argv[0]); + return 1; + } - mp_init(&a); mp_read_radix(&a, argv[1], 16); - len = mp_radix_size(&a, 10); - buf = malloc(len); - mp_toradix(&a, buf, 10); + mp_init(&a); + mp_read_radix(&a, argv[1], 16); + len = mp_radix_size(&a, 10); + buf = malloc(len); + mp_toradix(&a, buf, 10); - printf("%s\n", buf); + printf("%s\n", buf); - free(buf); - mp_clear(&a); + free(buf); + mp_clear(&a); - return 0; + return 0; } diff --git a/nss/lib/freebl/mpi/utils/identest.c b/nss/lib/freebl/mpi/utils/identest.c index 8172d77..321d2c2 100644 --- a/nss/lib/freebl/mpi/utils/identest.c +++ b/nss/lib/freebl/mpi/utils/identest.c @@ -11,73 +11,74 @@ #define MAX_PREC (4096 / MP_DIGIT_BIT) -mp_err identity_test(void) +mp_err +identity_test(void) { - mp_size preca, precb; - mp_err res; - mp_int a, b; - mp_int t1, t2, t3, t4, t5; + mp_size preca, precb; + mp_err res; + mp_int a, b; + mp_int t1, t2, t3, t4, t5; - preca = (rand() % MAX_PREC) + 1; - precb = (rand() % MAX_PREC) + 1; + preca = (rand() % MAX_PREC) + 1; + precb = (rand() % MAX_PREC) + 1; - MP_DIGITS(&a) = 0; - MP_DIGITS(&b) = 0; - MP_DIGITS(&t1) = 0; - MP_DIGITS(&t2) = 0; - MP_DIGITS(&t3) = 0; - MP_DIGITS(&t4) = 0; - MP_DIGITS(&t5) = 0; + MP_DIGITS(&a) = 0; + MP_DIGITS(&b) = 0; + MP_DIGITS(&t1) = 0; + MP_DIGITS(&t2) = 0; + MP_DIGITS(&t3) = 0; + MP_DIGITS(&t4) = 0; + MP_DIGITS(&t5) = 0; - MP_CHECKOK( mp_init(&a) ); - MP_CHECKOK( mp_init(&b) ); - MP_CHECKOK( mp_init(&t1) ); - MP_CHECKOK( mp_init(&t2) ); - MP_CHECKOK( mp_init(&t3) ); - MP_CHECKOK( mp_init(&t4) ); - MP_CHECKOK( mp_init(&t5) ); + MP_CHECKOK(mp_init(&a)); + MP_CHECKOK(mp_init(&b)); + MP_CHECKOK(mp_init(&t1)); + MP_CHECKOK(mp_init(&t2)); + MP_CHECKOK(mp_init(&t3)); + MP_CHECKOK(mp_init(&t4)); + MP_CHECKOK(mp_init(&t5)); - MP_CHECKOK( mpp_random_size(&a, preca) ); - MP_CHECKOK( mpp_random_size(&b, precb) ); + MP_CHECKOK(mpp_random_size(&a, preca)); + MP_CHECKOK(mpp_random_size(&b, precb)); - if (mp_cmp(&a, &b) < 0) - mp_exch(&a, &b); + if (mp_cmp(&a, &b) < 0) + mp_exch(&a, &b); - MP_CHECKOK( mp_mod(&a, &b, &t1) ); /* t1 = a%b */ - MP_CHECKOK( mp_div(&a, &b, &t2, NULL) ); /* t2 = a/b */ - MP_CHECKOK( mp_mul(&b, &t2, &t3) ); /* t3 = (a/b)*b */ - MP_CHECKOK( mp_add(&t1, &t3, &t4) ); /* t4 = a%b + (a/b)*b */ - MP_CHECKOK( mp_sub(&t4, &a, &t5) ); /* t5 = a%b + (a/b)*b - a */ - if (mp_cmp_z(&t5) != 0) { - res = MP_UNDEF; - goto CLEANUP; - } + MP_CHECKOK(mp_mod(&a, &b, &t1)); /* t1 = a%b */ + MP_CHECKOK(mp_div(&a, &b, &t2, NULL)); /* t2 = a/b */ + MP_CHECKOK(mp_mul(&b, &t2, &t3)); /* t3 = (a/b)*b */ + MP_CHECKOK(mp_add(&t1, &t3, &t4)); /* t4 = a%b + (a/b)*b */ + MP_CHECKOK(mp_sub(&t4, &a, &t5)); /* t5 = a%b + (a/b)*b - a */ + if (mp_cmp_z(&t5) != 0) { + res = MP_UNDEF; + goto CLEANUP; + } CLEANUP: - mp_clear(&t5); - mp_clear(&t4); - mp_clear(&t3); - mp_clear(&t2); - mp_clear(&t1); - mp_clear(&b); - mp_clear(&a); - return res; + mp_clear(&t5); + mp_clear(&t4); + mp_clear(&t3); + mp_clear(&t2); + mp_clear(&t1); + mp_clear(&b); + mp_clear(&a); + return res; } int main(void) { - unsigned int seed = (unsigned int)time(NULL); - unsigned long count = 0; - mp_err res; + unsigned int seed = (unsigned int)time(NULL); + unsigned long count = 0; + mp_err res; - srand(seed); + srand(seed); - while (MP_OKAY == (res = identity_test())) { - if ((++count % 100) == 0) - fputc('.', stderr); - } + while (MP_OKAY == (res = identity_test())) { + if ((++count % 100) == 0) + fputc('.', stderr); + } - fprintf(stderr, "\ntest failed, err %d\n", res); - return res; + fprintf(stderr, "\ntest failed, err %d\n", res); + return res; } diff --git a/nss/lib/freebl/mpi/utils/invmod.c b/nss/lib/freebl/mpi/utils/invmod.c index c71cc02..9b4b04d 100644 --- a/nss/lib/freebl/mpi/utils/invmod.c +++ b/nss/lib/freebl/mpi/utils/invmod.c @@ -12,48 +12,50 @@ #include "mpi.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a, m; - mp_err res; - char *buf; - int len, out = 0; - - if(argc < 3) { - fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]); - return 1; - } - - mp_init(&a); mp_init(&m); - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&m, argv[2], 10); - - if(mp_cmp(&a, &m) > 0) - mp_mod(&a, &m, &a); - - switch((res = mp_invmod(&a, &m, &a))) { - case MP_OKAY: - len = mp_radix_size(&a, 10); - buf = malloc(len); - - mp_toradix(&a, buf, 10); - printf("%s\n", buf); - free(buf); - break; - - case MP_UNDEF: - printf("No inverse\n"); - out = 1; - break; - - default: - printf("error: %s (%d)\n", mp_strerror(res), res); - out = 2; - break; - } - - mp_clear(&a); - mp_clear(&m); - - return out; + mp_int a, m; + mp_err res; + char *buf; + int len, out = 0; + + if (argc < 3) { + fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]); + return 1; + } + + mp_init(&a); + mp_init(&m); + mp_read_radix(&a, argv[1], 10); + mp_read_radix(&m, argv[2], 10); + + if (mp_cmp(&a, &m) > 0) + mp_mod(&a, &m, &a); + + switch ((res = mp_invmod(&a, &m, &a))) { + case MP_OKAY: + len = mp_radix_size(&a, 10); + buf = malloc(len); + + mp_toradix(&a, buf, 10); + printf("%s\n", buf); + free(buf); + break; + + case MP_UNDEF: + printf("No inverse\n"); + out = 1; + break; + + default: + printf("error: %s (%d)\n", mp_strerror(res), res); + out = 2; + break; + } + + mp_clear(&a); + mp_clear(&m); + + return out; } diff --git a/nss/lib/freebl/mpi/utils/isprime.c b/nss/lib/freebl/mpi/utils/isprime.c index 6548899..d2d8695 100644 --- a/nss/lib/freebl/mpi/utils/isprime.c +++ b/nss/lib/freebl/mpi/utils/isprime.c @@ -14,75 +14,76 @@ #include "mpi.h" #include "mpprime.h" -#define RM_TESTS 15 /* how many iterations of Rabin-Miller? */ -#define MINIMUM 1024 /* don't bother us with a < this */ +#define RM_TESTS 15 /* how many iterations of Rabin-Miller? */ +#define MINIMUM 1024 /* don't bother us with a < this */ -int g_tests = RM_TESTS; -char *g_prog = NULL; +int g_tests = RM_TESTS; +char *g_prog = NULL; -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a; - mp_digit np = prime_tab_size; /* from mpprime.h */ - int res = 0; + mp_int a; + mp_digit np = prime_tab_size; /* from mpprime.h */ + int res = 0; - g_prog = argv[0]; + g_prog = argv[0]; - if(argc < 2) { - fprintf(stderr, "Usage: %s <a>, where <a> is a decimal integer\n" - "Use '0x' prefix for a hexadecimal value\n", g_prog); - return 1; - } + if (argc < 2) { + fprintf(stderr, "Usage: %s <a>, where <a> is a decimal integer\n" + "Use '0x' prefix for a hexadecimal value\n", + g_prog); + return 1; + } - /* Read number of tests from environment, if present */ - { - char *tmp; + /* Read number of tests from environment, if present */ + { + char *tmp; - if((tmp = getenv("RM_TESTS")) != NULL) { - if((g_tests = atoi(tmp)) <= 0) - g_tests = RM_TESTS; + if ((tmp = PR_GetEnvSecure("RM_TESTS")) != NULL) { + if ((g_tests = atoi(tmp)) <= 0) + g_tests = RM_TESTS; + } } - } - mp_init(&a); - if(argv[1][0] == '0' && argv[1][1] == 'x') - mp_read_radix(&a, argv[1] + 2, 16); - else - mp_read_radix(&a, argv[1], 10); + mp_init(&a); + if (argv[1][0] == '0' && argv[1][1] == 'x') + mp_read_radix(&a, argv[1] + 2, 16); + else + mp_read_radix(&a, argv[1], 10); + + if (mp_cmp_d(&a, MINIMUM) <= 0) { + fprintf(stderr, "%s: please use a value greater than %d\n", + g_prog, MINIMUM); + mp_clear(&a); + return 1; + } - if(mp_cmp_d(&a, MINIMUM) <= 0) { - fprintf(stderr, "%s: please use a value greater than %d\n", - g_prog, MINIMUM); - mp_clear(&a); - return 1; - } - - /* Test for divisibility by small primes */ - if(mpp_divis_primes(&a, &np) != MP_NO) { - printf("Not prime (divisible by small prime %d)\n", np); - res = 2; - goto CLEANUP; - } - - /* Test with Fermat's test, using 2 as a witness */ - if(mpp_fermat(&a, 2) != MP_YES) { - printf("Not prime (failed Fermat test)\n"); - res = 2; - goto CLEANUP; - } - - /* Test with Rabin-Miller probabilistic test */ - if(mpp_pprime(&a, g_tests) == MP_NO) { - printf("Not prime (failed pseudoprime test)\n"); - res = 2; - goto CLEANUP; - } - - printf("Probably prime, 1 in 4^%d chance of false positive\n", g_tests); + /* Test for divisibility by small primes */ + if (mpp_divis_primes(&a, &np) != MP_NO) { + printf("Not prime (divisible by small prime %d)\n", np); + res = 2; + goto CLEANUP; + } + + /* Test with Fermat's test, using 2 as a witness */ + if (mpp_fermat(&a, 2) != MP_YES) { + printf("Not prime (failed Fermat test)\n"); + res = 2; + goto CLEANUP; + } + + /* Test with Rabin-Miller probabilistic test */ + if (mpp_pprime(&a, g_tests) == MP_NO) { + printf("Not prime (failed pseudoprime test)\n"); + res = 2; + goto CLEANUP; + } + + printf("Probably prime, 1 in 4^%d chance of false positive\n", g_tests); CLEANUP: - mp_clear(&a); - - return res; + mp_clear(&a); + return res; } diff --git a/nss/lib/freebl/mpi/utils/lap.c b/nss/lib/freebl/mpi/utils/lap.c index b6ab884..501e453 100644 --- a/nss/lib/freebl/mpi/utils/lap.c +++ b/nss/lib/freebl/mpi/utils/lap.c @@ -17,72 +17,74 @@ void sig_catch(int ign); int g_quit = 0; -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int a, m, p, k; + mp_int a, m, p, k; - if(argc < 3) { - fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]); - return 1; - } + if (argc < 3) { + fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]); + return 1; + } - mp_init(&a); - mp_init(&m); - mp_init(&p); - mp_add_d(&p, 1, &p); + mp_init(&a); + mp_init(&m); + mp_init(&p); + mp_add_d(&p, 1, &p); - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&m, argv[2], 10); + mp_read_radix(&a, argv[1], 10); + mp_read_radix(&m, argv[2], 10); - mp_init_copy(&k, &a); + mp_init_copy(&k, &a); - signal(SIGINT, sig_catch); + signal(SIGINT, sig_catch); #ifndef __OS2__ - signal(SIGHUP, sig_catch); + signal(SIGHUP, sig_catch); #endif - signal(SIGTERM, sig_catch); - - while(mp_cmp(&p, &m) < 0) { - if(g_quit) { - int len; - char *buf; - - len = mp_radix_size(&p, 10); - buf = malloc(len); - mp_toradix(&p, buf, 10); - - fprintf(stderr, "Terminated at: %s\n", buf); - free(buf); - return 1; - } - if(mp_cmp_d(&k, 1) == 0) { - int len; - char *buf; + signal(SIGTERM, sig_catch); - len = mp_radix_size(&p, 10); - buf = malloc(len); - mp_toradix(&p, buf, 10); + while (mp_cmp(&p, &m) < 0) { + if (g_quit) { + int len; + char *buf; - printf("%s\n", buf); + len = mp_radix_size(&p, 10); + buf = malloc(len); + mp_toradix(&p, buf, 10); - free(buf); - break; - } + fprintf(stderr, "Terminated at: %s\n", buf); + free(buf); + return 1; + } + if (mp_cmp_d(&k, 1) == 0) { + int len; + char *buf; - mp_mulmod(&k, &a, &m, &k); - mp_add_d(&p, 1, &p); - } + len = mp_radix_size(&p, 10); + buf = malloc(len); + mp_toradix(&p, buf, 10); + + printf("%s\n", buf); + + free(buf); + break; + } + + mp_mulmod(&k, &a, &m, &k); + mp_add_d(&p, 1, &p); + } - if(mp_cmp(&p, &m) >= 0) - printf("No annihilating power.\n"); + if (mp_cmp(&p, &m) >= 0) + printf("No annihilating power.\n"); - mp_clear(&p); - mp_clear(&m); - mp_clear(&a); - return 0; + mp_clear(&p); + mp_clear(&m); + mp_clear(&a); + return 0; } -void sig_catch(int ign) +void +sig_catch(int ign) { - g_quit = 1; + g_quit = 1; } diff --git a/nss/lib/freebl/mpi/utils/makeprime.c b/nss/lib/freebl/mpi/utils/makeprime.c index 22808c6..401b753 100644 --- a/nss/lib/freebl/mpi/utils/makeprime.c +++ b/nss/lib/freebl/mpi/utils/makeprime.c @@ -29,84 +29,86 @@ Returns MP_OKAY if a prime has been generated, otherwise the error code indicates some other problem. The value of p is clobbered; the - caller should keep a copy if the value is needed. + caller should keep a copy if the value is needed. */ -mp_err make_prime(mp_int *p, int nr); +mp_err make_prime(mp_int *p, int nr); /* The main() is not required -- it's just a test driver */ -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_int start; - mp_err res; - - if(argc < 2) { - fprintf(stderr, "Usage: %s <start-value>\n", argv[0]); - return 1; - } - - mp_init(&start); - if(argv[1][0] == '0' && tolower(argv[1][1]) == 'x') { - mp_read_radix(&start, argv[1] + 2, 16); - } else { - mp_read_radix(&start, argv[1], 10); - } - mp_abs(&start, &start); - - if((res = make_prime(&start, 5)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); - mp_clear(&start); - - return 1; - - } else { - char *buf = malloc(mp_radix_size(&start, 10)); - - mp_todecimal(&start, buf); - printf("%s\n", buf); - free(buf); - - mp_clear(&start); - - return 0; - } - + mp_int start; + mp_err res; + + if (argc < 2) { + fprintf(stderr, "Usage: %s <start-value>\n", argv[0]); + return 1; + } + + mp_init(&start); + if (argv[1][0] == '0' && tolower(argv[1][1]) == 'x') { + mp_read_radix(&start, argv[1] + 2, 16); + } else { + mp_read_radix(&start, argv[1], 10); + } + mp_abs(&start, &start); + + if ((res = make_prime(&start, 5)) != MP_OKAY) { + fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); + mp_clear(&start); + + return 1; + + } else { + char *buf = malloc(mp_radix_size(&start, 10)); + + mp_todecimal(&start, buf); + printf("%s\n", buf); + free(buf); + + mp_clear(&start); + + return 0; + } + } /* end main() */ /*------------------------------------------------------------------------*/ -mp_err make_prime(mp_int *p, int nr) +mp_err +make_prime(mp_int *p, int nr) { - mp_err res; - - if(mp_iseven(p)) { - mp_add_d(p, 1, p); - } - - do { - mp_digit which = prime_tab_size; - - /* First test for divisibility by a few small primes */ - if((res = mpp_divis_primes(p, &which)) == MP_YES) - continue; - else if(res != MP_NO) - goto CLEANUP; - - /* If that passes, try one iteration of Fermat's test */ - if((res = mpp_fermat(p, 2)) == MP_NO) - continue; - else if(res != MP_YES) - goto CLEANUP; - - /* If that passes, run Rabin-Miller as often as requested */ - if((res = mpp_pprime(p, nr)) == MP_YES) - break; - else if(res != MP_NO) - goto CLEANUP; - - } while((res = mp_add_d(p, 2, p)) == MP_OKAY); - - CLEANUP: - return res; + mp_err res; + + if (mp_iseven(p)) { + mp_add_d(p, 1, p); + } + + do { + mp_digit which = prime_tab_size; + + /* First test for divisibility by a few small primes */ + if ((res = mpp_divis_primes(p, &which)) == MP_YES) + continue; + else if (res != MP_NO) + goto CLEANUP; + + /* If that passes, try one iteration of Fermat's test */ + if ((res = mpp_fermat(p, 2)) == MP_NO) + continue; + else if (res != MP_YES) + goto CLEANUP; + + /* If that passes, run Rabin-Miller as often as requested */ + if ((res = mpp_pprime(p, nr)) == MP_YES) + break; + else if (res != MP_NO) + goto CLEANUP; + + } while ((res = mp_add_d(p, 2, p)) == MP_OKAY); + +CLEANUP: + return res; } /* end make_prime() */ diff --git a/nss/lib/freebl/mpi/utils/metime.c b/nss/lib/freebl/mpi/utils/metime.c index de51043..122875e 100644 --- a/nss/lib/freebl/mpi/utils/metime.c +++ b/nss/lib/freebl/mpi/utils/metime.c @@ -1,4 +1,4 @@ -/* +/* * metime.c * * Modular exponentiation timing test @@ -18,82 +18,84 @@ double clk_to_sec(clock_t start, clock_t stop); -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - int ix, num, prec = 8; - unsigned int seed; - clock_t start, stop; - double sec; - - mp_int a, m, c; - - if(getenv("SEED") != NULL) - seed = abs(atoi(getenv("SEED"))); - else - seed = (unsigned int)time(NULL); - - if(argc < 2) { - fprintf(stderr, "Usage: %s <num-tests> [<nbits>]\n", argv[0]); - return 1; - } - - if((num = atoi(argv[1])) < 0) - num = -num; - - if(!num) { - fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]); - return 1; - } - - if(argc > 2) { - if((prec = atoi(argv[2])) <= 0) - prec = 8; - else - prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT; - - } - - printf("Modular exponentiation timing test\n" - "Precision: %d digits (%d bits)\n" - "# of tests: %d\n\n", prec, prec * DIGIT_BIT, num); - - mp_init_size(&a, prec); - mp_init_size(&m, prec); - mp_init_size(&c, prec); - - srand(seed); - - start = clock(); - for(ix = 0; ix < num; ix++) { - - mpp_random_size(&a, prec); - mpp_random_size(&c, prec); - mpp_random_size(&m, prec); - /* set msb and lsb of m */ - DIGIT(&m,0) |= 1; - DIGIT(&m, USED(&m)-1) |= (mp_digit)1 << (DIGIT_BIT - 1); - if (mp_cmp(&a, &m) > 0) - mp_sub(&a, &m, &a); - - mp_exptmod(&a, &c, &m, &c); - } - stop = clock(); - - sec = clk_to_sec(start, stop); - - printf("Total: %.3f seconds\n", sec); - printf("Individual: %.3f seconds\n", sec / num); - - mp_clear(&c); - mp_clear(&a); - mp_clear(&m); - - return 0; + int ix, num, prec = 8; + unsigned int seed; + clock_t start, stop; + double sec; + + mp_int a, m, c; + + if (PR_GetEnvSecure("SEED") != NULL) + seed = abs(atoi(PR_GetEnvSecure("SEED"))); + else + seed = (unsigned int)time(NULL); + + if (argc < 2) { + fprintf(stderr, "Usage: %s <num-tests> [<nbits>]\n", argv[0]); + return 1; + } + + if ((num = atoi(argv[1])) < 0) + num = -num; + + if (!num) { + fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]); + return 1; + } + + if (argc > 2) { + if ((prec = atoi(argv[2])) <= 0) + prec = 8; + else + prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT; + } + + printf("Modular exponentiation timing test\n" + "Precision: %d digits (%d bits)\n" + "# of tests: %d\n\n", + prec, prec * DIGIT_BIT, num); + + mp_init_size(&a, prec); + mp_init_size(&m, prec); + mp_init_size(&c, prec); + + srand(seed); + + start = clock(); + for (ix = 0; ix < num; ix++) { + + mpp_random_size(&a, prec); + mpp_random_size(&c, prec); + mpp_random_size(&m, prec); + /* set msb and lsb of m */ + DIGIT(&m, 0) |= 1; + DIGIT(&m, USED(&m) - 1) |= (mp_digit)1 << (DIGIT_BIT - 1); + if (mp_cmp(&a, &m) > 0) + mp_sub(&a, &m, &a); + + mp_exptmod(&a, &c, &m, &c); + } + stop = clock(); + + sec = clk_to_sec(start, stop); + + printf("Total: %.3f seconds\n", sec); + printf("Individual: %.3f seconds\n", sec / num); + + mp_clear(&c); + mp_clear(&a); + mp_clear(&m); + + return 0; } -double clk_to_sec(clock_t start, clock_t stop) +double +clk_to_sec(clock_t start, clock_t stop) { - return (double)(stop - start) / CLOCKS_PER_SEC; + return (double)(stop - start) / CLOCKS_PER_SEC; } /*------------------------------------------------------------------------*/ diff --git a/nss/lib/freebl/mpi/utils/pi.c b/nss/lib/freebl/mpi/utils/pi.c index 78f5736..7e31097 100644 --- a/nss/lib/freebl/mpi/utils/pi.c +++ b/nss/lib/freebl/mpi/utils/pi.c @@ -3,7 +3,7 @@ * * Compute pi to an arbitrary number of digits. Uses Machin's formula, * like everyone else on the planet: - * + * * pi = 16 * arctan(1/5) - 4 * arctan(1/239) * * This is pretty effective for up to a few thousand digits, but it @@ -23,89 +23,96 @@ mp_err arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum); -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - mp_err res; - mp_digit ndigits; - mp_int sum1, sum2; - clock_t start, stop; - int out = 0; - - /* Make the user specify precision on the command line */ - if(argc < 2) { - fprintf(stderr, "Usage: %s <num-digits>\n", argv[0]); - return 1; - } - - if((ndigits = abs(atoi(argv[1]))) == 0) { - fprintf(stderr, "%s: you must request at least 1 digit\n", argv[0]); - return 1; - } - - start = clock(); - mp_init(&sum1); mp_init(&sum2); - - /* sum1 = 16 * arctan(1/5) */ - if((res = arctan(16, 5, ndigits, &sum1)) != MP_OKAY) { - fprintf(stderr, "%s: arctan: %s\n", argv[0], mp_strerror(res)); - out = 1; goto CLEANUP; - } - - /* sum2 = 4 * arctan(1/239) */ - if((res = arctan(4, 239, ndigits, &sum2)) != MP_OKAY) { - fprintf(stderr, "%s: arctan: %s\n", argv[0], mp_strerror(res)); - out = 1; goto CLEANUP; - } - - /* pi = sum1 - sum2 */ - if((res = mp_sub(&sum1, &sum2, &sum1)) != MP_OKAY) { - fprintf(stderr, "%s: mp_sub: %s\n", argv[0], mp_strerror(res)); - out = 1; goto CLEANUP; - } - stop = clock(); - - /* Write the output in decimal */ - { - char *buf = malloc(mp_radix_size(&sum1, 10)); - - if(buf == NULL) { - fprintf(stderr, "%s: out of memory\n", argv[0]); - out = 1; goto CLEANUP; + mp_err res; + mp_digit ndigits; + mp_int sum1, sum2; + clock_t start, stop; + int out = 0; + + /* Make the user specify precision on the command line */ + if (argc < 2) { + fprintf(stderr, "Usage: %s <num-digits>\n", argv[0]); + return 1; } - mp_todecimal(&sum1, buf); - printf("%s\n", buf); - free(buf); - } - fprintf(stderr, "Computation took %.2f sec.\n", - (double)(stop - start) / CLOCKS_PER_SEC); + if ((ndigits = abs(atoi(argv[1]))) == 0) { + fprintf(stderr, "%s: you must request at least 1 digit\n", argv[0]); + return 1; + } - CLEANUP: - mp_clear(&sum1); - mp_clear(&sum2); + start = clock(); + mp_init(&sum1); + mp_init(&sum2); - return out; + /* sum1 = 16 * arctan(1/5) */ + if ((res = arctan(16, 5, ndigits, &sum1)) != MP_OKAY) { + fprintf(stderr, "%s: arctan: %s\n", argv[0], mp_strerror(res)); + out = 1; + goto CLEANUP; + } -} + /* sum2 = 4 * arctan(1/239) */ + if ((res = arctan(4, 239, ndigits, &sum2)) != MP_OKAY) { + fprintf(stderr, "%s: arctan: %s\n", argv[0], mp_strerror(res)); + out = 1; + goto CLEANUP; + } -/* Compute sum := mul * arctan(1/x), to 'prec' digits of precision */ -mp_err arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum) -{ - mp_int t, v; - mp_digit q = 1, rd; - mp_err res; - int sign = 1; + /* pi = sum1 - sum2 */ + if ((res = mp_sub(&sum1, &sum2, &sum1)) != MP_OKAY) { + fprintf(stderr, "%s: mp_sub: %s\n", argv[0], mp_strerror(res)); + out = 1; + goto CLEANUP; + } + stop = clock(); + + /* Write the output in decimal */ + { + char *buf = malloc(mp_radix_size(&sum1, 10)); + + if (buf == NULL) { + fprintf(stderr, "%s: out of memory\n", argv[0]); + out = 1; + goto CLEANUP; + } + mp_todecimal(&sum1, buf); + printf("%s\n", buf); + free(buf); + } + + fprintf(stderr, "Computation took %.2f sec.\n", + (double)(stop - start) / CLOCKS_PER_SEC); - prec += 3; /* push inaccuracies off the end */ +CLEANUP: + mp_clear(&sum1); + mp_clear(&sum2); - mp_init(&t); mp_set(&t, 10); - mp_init(&v); - if((res = mp_expt_d(&t, prec, &t)) != MP_OKAY || /* get 10^prec */ - (res = mp_mul_d(&t, mul, &t)) != MP_OKAY || /* ... times mul */ - (res = mp_mul_d(&t, x, &t)) != MP_OKAY) /* ... times x */ - goto CLEANUP; + return out; +} - /* +/* Compute sum := mul * arctan(1/x), to 'prec' digits of precision */ +mp_err +arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum) +{ + mp_int t, v; + mp_digit q = 1, rd; + mp_err res; + int sign = 1; + + prec += 3; /* push inaccuracies off the end */ + + mp_init(&t); + mp_set(&t, 10); + mp_init(&v); + if ((res = mp_expt_d(&t, prec, &t)) != MP_OKAY || /* get 10^prec */ + (res = mp_mul_d(&t, mul, &t)) != MP_OKAY || /* ... times mul */ + (res = mp_mul_d(&t, x, &t)) != MP_OKAY) /* ... times x */ + goto CLEANUP; + + /* The extra multiplication by x in the above takes care of what would otherwise have to be a special case for 1 / x^1 during the first loop iteration. A little sneaky, but effective. @@ -113,51 +120,51 @@ mp_err arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum) We compute arctan(1/x) by the formula: 1 1 1 1 - - - ----- + ----- - ----- + ... - x 3 x^3 5 x^5 7 x^7 + - - ----- + ----- - ----- + ... + x 3 x^3 5 x^5 7 x^7 We multiply through by 'mul' beforehand, which gives us a couple more iterations and more precision */ - x *= x; /* works as long as x < sqrt(RADIX), which it is here */ + x *= x; /* works as long as x < sqrt(RADIX), which it is here */ - mp_zero(sum); + mp_zero(sum); - do { - if((res = mp_div_d(&t, x, &t, &rd)) != MP_OKAY) - goto CLEANUP; + do { + if ((res = mp_div_d(&t, x, &t, &rd)) != MP_OKAY) + goto CLEANUP; - if(sign < 0 && rd != 0) - mp_add_d(&t, 1, &t); + if (sign < 0 && rd != 0) + mp_add_d(&t, 1, &t); - if((res = mp_div_d(&t, q, &v, &rd)) != MP_OKAY) - goto CLEANUP; + if ((res = mp_div_d(&t, q, &v, &rd)) != MP_OKAY) + goto CLEANUP; - if(sign < 0 && rd != 0) - mp_add_d(&v, 1, &v); + if (sign < 0 && rd != 0) + mp_add_d(&v, 1, &v); - if(sign > 0) - res = mp_add(sum, &v, sum); - else - res = mp_sub(sum, &v, sum); + if (sign > 0) + res = mp_add(sum, &v, sum); + else + res = mp_sub(sum, &v, sum); - if(res != MP_OKAY) - goto CLEANUP; + if (res != MP_OKAY) + goto CLEANUP; - sign *= -1; - q += 2; + sign *= -1; + q += 2; - } while(mp_cmp_z(&t) != 0); + } while (mp_cmp_z(&t) != 0); - /* Chop off inaccurate low-order digits */ - mp_div_d(sum, 1000, sum, NULL); + /* Chop off inaccurate low-order digits */ + mp_div_d(sum, 1000, sum, NULL); - CLEANUP: - mp_clear(&v); - mp_clear(&t); +CLEANUP: + mp_clear(&v); + mp_clear(&t); - return res; + return res; } /*------------------------------------------------------------------------*/ diff --git a/nss/lib/freebl/mpi/utils/primegen.c b/nss/lib/freebl/mpi/utils/primegen.c index aac7aba..f62a56a 100644 --- a/nss/lib/freebl/mpi/utils/primegen.c +++ b/nss/lib/freebl/mpi/utils/primegen.c @@ -25,134 +25,135 @@ #include "mplogic.h" #include "mpprime.h" -#define NUM_TESTS 5 /* Number of Rabin-Miller iterations to test with */ +#define NUM_TESTS 5 /* Number of Rabin-Miller iterations to test with */ #ifdef DEBUG -#define FPUTC(x,y) fputc(x,y) +#define FPUTC(x, y) fputc(x, y) #else -#define FPUTC(x,y) +#define FPUTC(x, y) #endif -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - unsigned char *raw; - char *out; - unsigned long nTries; - int rawlen, bits, outlen, ngen, ix, jx; - int g_strong = 0; - mp_int testval; - mp_err res; - clock_t start, end; - - /* We'll just use the C library's rand() for now, although this + unsigned char *raw; + char *out; + unsigned long nTries; + int rawlen, bits, outlen, ngen, ix, jx; + int g_strong = 0; + mp_int testval; + mp_err res; + clock_t start, end; + + /* We'll just use the C library's rand() for now, although this won't be good enough for cryptographic purposes */ - if((out = getenv("SEED")) == NULL) { - srand((unsigned int)time(NULL)); - } else { - srand((unsigned int)atoi(out)); - } - - if(argc < 2) { - fprintf(stderr, "Usage: %s <bits> [<count> [strong]]\n", argv[0]); - return 1; - } - - if((bits = abs(atoi(argv[1]))) < CHAR_BIT) { - fprintf(stderr, "%s: please request at least %d bits.\n", - argv[0], CHAR_BIT); - return 1; - } - - /* If optional third argument is given, use that as the number of + if ((out = PR_GetEnvSecure("SEED")) == NULL) { + srand((unsigned int)time(NULL)); + } else { + srand((unsigned int)atoi(out)); + } + + if (argc < 2) { + fprintf(stderr, "Usage: %s <bits> [<count> [strong]]\n", argv[0]); + return 1; + } + + if ((bits = abs(atoi(argv[1]))) < CHAR_BIT) { + fprintf(stderr, "%s: please request at least %d bits.\n", + argv[0], CHAR_BIT); + return 1; + } + + /* If optional third argument is given, use that as the number of primes to generate; otherwise generate one prime only. */ - if(argc < 3) { - ngen = 1; - } else { - ngen = abs(atoi(argv[2])); - } + if (argc < 3) { + ngen = 1; + } else { + ngen = abs(atoi(argv[2])); + } - /* If fourth argument is given, and is the word "strong", we'll + /* If fourth argument is given, and is the word "strong", we'll generate strong (Sophie Germain) primes. */ - if(argc > 3 && strcmp(argv[3], "strong") == 0) - g_strong = 1; - - /* testval - candidate being tested; nTries - number tried so far */ - if ((res = mp_init(&testval)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); - return 1; - } - - if(g_strong) { - printf("Requested %d strong prime value(s) of %d bits.\n", - ngen, bits); - } else { - printf("Requested %d prime value(s) of %d bits.\n", ngen, bits); - } - - rawlen = (bits / CHAR_BIT) + ((bits % CHAR_BIT) ? 1 : 0) + 1; - - if((raw = calloc(rawlen, sizeof(unsigned char))) == NULL) { - fprintf(stderr, "%s: out of memory, sorry.\n", argv[0]); - return 1; - } - - /* This loop is one for each prime we need to generate */ - for(jx = 0; jx < ngen; jx++) { - - raw[0] = 0; /* sign is positive */ - - /* Pack the initializer with random bytes */ - for(ix = 1; ix < rawlen; ix++) - raw[ix] = (rand() * rand()) & UCHAR_MAX; - - raw[1] |= 0x80; /* set high-order bit of test value */ - raw[rawlen - 1] |= 1; /* set low-order bit of test value */ - - /* Make an mp_int out of the initializer */ - mp_read_raw(&testval, (char *)raw, rawlen); - - /* Initialize candidate counter */ - nTries = 0; - - start = clock(); /* time generation for this prime */ - do { - res = mpp_make_prime(&testval, bits, g_strong, &nTries); - if (res != MP_NO) - break; - /* This code works whether digits are 16 or 32 bits */ - res = mp_add_d(&testval, 32 * 1024, &testval); - res = mp_add_d(&testval, 32 * 1024, &testval); - FPUTC(',', stderr); - } while (1); - end = clock(); - - if (res != MP_YES) { - break; + if (argc > 3 && strcmp(argv[3], "strong") == 0) + g_strong = 1; + + /* testval - candidate being tested; nTries - number tried so far */ + if ((res = mp_init(&testval)) != MP_OKAY) { + fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); + return 1; + } + + if (g_strong) { + printf("Requested %d strong prime value(s) of %d bits.\n", + ngen, bits); + } else { + printf("Requested %d prime value(s) of %d bits.\n", ngen, bits); } - FPUTC('\n', stderr); - puts("The following value is probably prime:"); - outlen = mp_radix_size(&testval, 10); - out = calloc(outlen, sizeof(unsigned char)); - mp_toradix(&testval, (char *)out, 10); - printf("10: %s\n", out); - mp_toradix(&testval, (char *)out, 16); - printf("16: %s\n\n", out); - free(out); - - printf("Number of candidates tried: %lu\n", nTries); - printf("This computation took %ld clock ticks (%.2f seconds)\n", - (end - start), ((double)(end - start) / CLOCKS_PER_SEC)); - - FPUTC('\n', stderr); - } /* end of loop to generate all requested primes */ - - if(res != MP_OKAY) - fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); - - free(raw); - mp_clear(&testval); - - return 0; + + rawlen = (bits / CHAR_BIT) + ((bits % CHAR_BIT) ? 1 : 0) + 1; + + if ((raw = calloc(rawlen, sizeof(unsigned char))) == NULL) { + fprintf(stderr, "%s: out of memory, sorry.\n", argv[0]); + return 1; + } + + /* This loop is one for each prime we need to generate */ + for (jx = 0; jx < ngen; jx++) { + + raw[0] = 0; /* sign is positive */ + + /* Pack the initializer with random bytes */ + for (ix = 1; ix < rawlen; ix++) + raw[ix] = (rand() * rand()) & UCHAR_MAX; + + raw[1] |= 0x80; /* set high-order bit of test value */ + raw[rawlen - 1] |= 1; /* set low-order bit of test value */ + + /* Make an mp_int out of the initializer */ + mp_read_raw(&testval, (char *)raw, rawlen); + + /* Initialize candidate counter */ + nTries = 0; + + start = clock(); /* time generation for this prime */ + do { + res = mpp_make_prime(&testval, bits, g_strong, &nTries); + if (res != MP_NO) + break; + /* This code works whether digits are 16 or 32 bits */ + res = mp_add_d(&testval, 32 * 1024, &testval); + res = mp_add_d(&testval, 32 * 1024, &testval); + FPUTC(',', stderr); + } while (1); + end = clock(); + + if (res != MP_YES) { + break; + } + FPUTC('\n', stderr); + puts("The following value is probably prime:"); + outlen = mp_radix_size(&testval, 10); + out = calloc(outlen, sizeof(unsigned char)); + mp_toradix(&testval, (char *)out, 10); + printf("10: %s\n", out); + mp_toradix(&testval, (char *)out, 16); + printf("16: %s\n\n", out); + free(out); + + printf("Number of candidates tried: %lu\n", nTries); + printf("This computation took %ld clock ticks (%.2f seconds)\n", + (end - start), ((double)(end - start) / CLOCKS_PER_SEC)); + + FPUTC('\n', stderr); + } /* end of loop to generate all requested primes */ + + if (res != MP_OKAY) + fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); + + free(raw); + mp_clear(&testval); + + return 0; } diff --git a/nss/lib/freebl/mpi/utils/prng.c b/nss/lib/freebl/mpi/utils/prng.c index 59ccae0..38748d1 100644 --- a/nss/lib/freebl/mpi/utils/prng.c +++ b/nss/lib/freebl/mpi/utils/prng.c @@ -21,37 +21,37 @@ #include "bbs_rand.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - unsigned char *seed; - unsigned int ix, num = 1; - pid_t pid; - - if(argc > 1) { - num = atoi(argv[1]); - if(num <= 0) - num = 1; - } + unsigned char *seed; + unsigned int ix, num = 1; + pid_t pid; - pid = getpid(); - srand(time(NULL) * (unsigned int)pid); + if (argc > 1) { + num = atoi(argv[1]); + if (num <= 0) + num = 1; + } - /* Not a perfect seed, but not bad */ - seed = malloc(bbs_seed_size); - for(ix = 0; ix < bbs_seed_size; ix++) { - seed[ix] = rand() % UCHAR_MAX; - } + pid = getpid(); + srand(time(NULL) * (unsigned int)pid); - bbs_srand(seed, bbs_seed_size); - memset(seed, 0, bbs_seed_size); - free(seed); + /* Not a perfect seed, but not bad */ + seed = malloc(bbs_seed_size); + for (ix = 0; ix < bbs_seed_size; ix++) { + seed[ix] = rand() % UCHAR_MAX; + } - while(num-- > 0) { - ix = bbs_rand(); + bbs_srand(seed, bbs_seed_size); + memset(seed, 0, bbs_seed_size); + free(seed); - printf("%u\n", ix); - } + while (num-- > 0) { + ix = bbs_rand(); - return 0; + printf("%u\n", ix); + } + return 0; } diff --git a/nss/lib/freebl/mpi/utils/sieve.c b/nss/lib/freebl/mpi/utils/sieve.c index 71a17c8..57768af 100644 --- a/nss/lib/freebl/mpi/utils/sieve.c +++ b/nss/lib/freebl/mpi/utils/sieve.c @@ -28,14 +28,14 @@ #include <stdlib.h> #include <limits.h> -typedef unsigned char byte; +typedef unsigned char byte; typedef struct { - int size; - byte *bits; - long base; - int next; - int nbits; + int size; + byte *bits; + long base; + int next; + int nbits; } sieve; void sieve_init(sieve *sp, long base, int nbits); @@ -45,191 +45,199 @@ void sieve_reset(sieve *sp, long base); void sieve_cross(sieve *sp, long val); void sieve_clear(sieve *sp); -#define S_ISSET(S, B) (((S)->bits[(B)/CHAR_BIT]>>((B)%CHAR_BIT))&1) -#define S_SET(S, B) ((S)->bits[(B)/CHAR_BIT]|=(1<<((B)%CHAR_BIT))) -#define S_CLR(S, B) ((S)->bits[(B)/CHAR_BIT]&=~(1<<((B)%CHAR_BIT))) -#define S_VAL(S, B) ((S)->base+(2*(B))) -#define S_BIT(S, V) (((V)-((S)->base))/2) +#define S_ISSET(S, B) (((S)->bits[(B) / CHAR_BIT] >> ((B) % CHAR_BIT)) & 1) +#define S_SET(S, B) ((S)->bits[(B) / CHAR_BIT] |= (1 << ((B) % CHAR_BIT))) +#define S_CLR(S, B) ((S)->bits[(B) / CHAR_BIT] &= ~(1 << ((B) % CHAR_BIT))) +#define S_VAL(S, B) ((S)->base + (2 * (B))) +#define S_BIT(S, V) (((V) - ((S)->base)) / 2) -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - sieve s; - long pr, *p; - int c, ix, cur = 0; + sieve s; + long pr, *p; + int c, ix, cur = 0; - if(argc < 2) { - fprintf(stderr, "Usage: %s <width>\n", argv[0]); - return 1; - } + if (argc < 2) { + fprintf(stderr, "Usage: %s <width>\n", argv[0]); + return 1; + } - c = atoi(argv[1]); - if(c < 0) c = -c; + c = atoi(argv[1]); + if (c < 0) + c = -c; - fprintf(stderr, "%s: sieving to %d positions\n", argv[0], c); + fprintf(stderr, "%s: sieving to %d positions\n", argv[0], c); - sieve_init(&s, 3, c); + sieve_init(&s, 3, c); - c = 0; - while((pr = sieve_next(&s)) > 0) { - ++c; - } + c = 0; + while ((pr = sieve_next(&s)) > 0) { + ++c; + } - p = calloc(c, sizeof(long)); - if(!p) { - fprintf(stderr, "%s: out of memory after first half\n", argv[0]); - sieve_clear(&s); - exit(1); - } + p = calloc(c, sizeof(long)); + if (!p) { + fprintf(stderr, "%s: out of memory after first half\n", argv[0]); + sieve_clear(&s); + exit(1); + } + + fprintf(stderr, "%s: half done ... \n", argv[0]); - fprintf(stderr, "%s: half done ... \n", argv[0]); + for (ix = 0; ix < s.nbits; ix++) { + if (S_ISSET(&s, ix)) { + p[cur] = S_VAL(&s, ix); + printf("%ld\n", p[cur]); + ++cur; + } + } - for(ix = 0; ix < s.nbits; ix++) { - if(S_ISSET(&s, ix)) { - p[cur] = S_VAL(&s, ix); - printf("%ld\n", p[cur]); - ++cur; + sieve_reset(&s, p[cur - 1]); + fprintf(stderr, "%s: crossing off %d found primes ... \n", argv[0], cur); + for (ix = 0; ix < cur; ix++) { + sieve_cross(&s, p[ix]); + if (!(ix % 1000)) + fputc('.', stderr); } - } - - sieve_reset(&s, p[cur - 1]); - fprintf(stderr, "%s: crossing off %d found primes ... \n", argv[0], cur); - for(ix = 0; ix < cur; ix++) { - sieve_cross(&s, p[ix]); - if(!(ix % 1000)) - fputc('.', stderr); - } - fputc('\n', stderr); - - free(p); - - fprintf(stderr, "%s: sieving again from %ld ... \n", argv[0], p[cur - 1]); - c = 0; - while((pr = sieve_next(&s)) > 0) { - ++c; - } - - fprintf(stderr, "%s: done!\n", argv[0]); - for(ix = 0; ix < s.nbits; ix++) { - if(S_ISSET(&s, ix)) { - printf("%ld\n", S_VAL(&s, ix)); + fputc('\n', stderr); + + free(p); + + fprintf(stderr, "%s: sieving again from %ld ... \n", argv[0], p[cur - 1]); + c = 0; + while ((pr = sieve_next(&s)) > 0) { + ++c; + } + + fprintf(stderr, "%s: done!\n", argv[0]); + for (ix = 0; ix < s.nbits; ix++) { + if (S_ISSET(&s, ix)) { + printf("%ld\n", S_VAL(&s, ix)); + } } - } - sieve_clear(&s); + sieve_clear(&s); - return 0; + return 0; } -void sieve_init(sieve *sp, long base, int nbits) +void +sieve_init(sieve *sp, long base, int nbits) { - sp->size = (nbits / CHAR_BIT); - - if(nbits % CHAR_BIT) - ++sp->size; - - sp->bits = calloc(sp->size, sizeof(byte)); - memset(sp->bits, UCHAR_MAX, sp->size); - if(!(base & 1)) - ++base; - sp->base = base; - - sp->next = 0; - sp->nbits = sp->size * CHAR_BIT; + sp->size = (nbits / CHAR_BIT); + + if (nbits % CHAR_BIT) + ++sp->size; + + sp->bits = calloc(sp->size, sizeof(byte)); + memset(sp->bits, UCHAR_MAX, sp->size); + if (!(base & 1)) + ++base; + sp->base = base; + + sp->next = 0; + sp->nbits = sp->size * CHAR_BIT; } -void sieve_grow(sieve *sp, int nbits) +void +sieve_grow(sieve *sp, int nbits) { - int ns = (nbits / CHAR_BIT); + int ns = (nbits / CHAR_BIT); - if(nbits % CHAR_BIT) - ++ns; + if (nbits % CHAR_BIT) + ++ns; - if(ns > sp->size) { - byte *tmp; - int ix; + if (ns > sp->size) { + byte *tmp; + int ix; - tmp = calloc(ns, sizeof(byte)); - if(tmp == NULL) { - fprintf(stderr, "Error: out of memory in sieve_grow\n"); - return; - } + tmp = calloc(ns, sizeof(byte)); + if (tmp == NULL) { + fprintf(stderr, "Error: out of memory in sieve_grow\n"); + return; + } - memcpy(tmp, sp->bits, sp->size); - for(ix = sp->size; ix < ns; ix++) { - tmp[ix] = UCHAR_MAX; - } + memcpy(tmp, sp->bits, sp->size); + for (ix = sp->size; ix < ns; ix++) { + tmp[ix] = UCHAR_MAX; + } - free(sp->bits); - sp->bits = tmp; - sp->size = ns; + free(sp->bits); + sp->bits = tmp; + sp->size = ns; - sp->nbits = sp->size * CHAR_BIT; - } + sp->nbits = sp->size * CHAR_BIT; + } } -long sieve_next(sieve *sp) +long +sieve_next(sieve *sp) { - long out; - int ix = 0; - long val; + long out; + int ix = 0; + long val; - if(sp->next > sp->nbits) - return -1; + if (sp->next > sp->nbits) + return -1; - out = S_VAL(sp, sp->next); + out = S_VAL(sp, sp->next); #ifdef DEBUG - fprintf(stderr, "Sieving %ld\n", out); + fprintf(stderr, "Sieving %ld\n", out); #endif - /* Sieve out all multiples of the current prime */ - val = out; - while(ix < sp->nbits) { - val += out; - ix = S_BIT(sp, val); - if((val & 1) && ix < sp->nbits) { /* && S_ISSET(sp, ix)) { */ - S_CLR(sp, ix); + /* Sieve out all multiples of the current prime */ + val = out; + while (ix < sp->nbits) { + val += out; + ix = S_BIT(sp, val); + if ((val & 1) && ix < sp->nbits) { /* && S_ISSET(sp, ix)) { */ + S_CLR(sp, ix); #ifdef DEBUG - fprintf(stderr, "Crossing out %ld (bit %d)\n", val, ix); + fprintf(stderr, "Crossing out %ld (bit %d)\n", val, ix); #endif + } } - } - /* Scan ahead to the next prime */ - ++sp->next; - while(sp->next < sp->nbits && !S_ISSET(sp, sp->next)) + /* Scan ahead to the next prime */ ++sp->next; + while (sp->next < sp->nbits && !S_ISSET(sp, sp->next)) + ++sp->next; - return out; + return out; } -void sieve_cross(sieve *sp, long val) +void +sieve_cross(sieve *sp, long val) { - int ix = 0; - long cur = val; + int ix = 0; + long cur = val; - while(cur < sp->base) - cur += val; + while (cur < sp->base) + cur += val; - ix = S_BIT(sp, cur); - while(ix < sp->nbits) { - if(cur & 1) - S_CLR(sp, ix); - cur += val; ix = S_BIT(sp, cur); - } + while (ix < sp->nbits) { + if (cur & 1) + S_CLR(sp, ix); + cur += val; + ix = S_BIT(sp, cur); + } } -void sieve_reset(sieve *sp, long base) +void +sieve_reset(sieve *sp, long base) { - memset(sp->bits, UCHAR_MAX, sp->size); - sp->base = base; - sp->next = 0; + memset(sp->bits, UCHAR_MAX, sp->size); + sp->base = base; + sp->next = 0; } -void sieve_clear(sieve *sp) +void +sieve_clear(sieve *sp) { - if(sp->bits) - free(sp->bits); + if (sp->bits) + free(sp->bits); - sp->bits = NULL; + sp->bits = NULL; } diff --git a/nss/lib/freebl/mpi/vis_proto.h b/nss/lib/freebl/mpi/vis_proto.h index 7e8ed29..275de59 100644 --- a/nss/lib/freebl/mpi/vis_proto.h +++ b/nss/lib/freebl/mpi/vis_proto.h @@ -9,7 +9,7 @@ #ifndef VIS_PROTO_H #define VIS_PROTO_H -#pragma ident "@(#)vis_proto.h 1.3 97/03/30 SMI" +#pragma ident "@(#)vis_proto.h 1.3 97/03/30 SMI" #ifdef __cplusplus extern "C" { @@ -186,46 +186,46 @@ void vis_error(char * /*fmt*/, int /*a0*/); void vis_sim_init(void); /* For better performance */ -#define vis_fmul8x16(farg,darg) vis_fmul8x16_dummy((farg),0,(darg)) +#define vis_fmul8x16(farg, darg) vis_fmul8x16_dummy((farg), 0, (darg)) /* Nicknames for explicit ASI loads and stores. */ -#define vis_st_u8 vis_stdfa_ASI_FL8P -#define vis_st_u8_i vis_stdfa_ASI_FL8P_index -#define vis_st_u8_le vis_stdfa_ASI_FL8PL -#define vis_st_u16 vis_stdfa_ASI_FL16P -#define vis_st_u16_i vis_stdfa_ASI_FL16P_index -#define vis_st_u16_le vis_stdfa_ASI_FL16PL - -#define vis_ld_u8 vis_lddfa_ASI_FL8P -#define vis_ld_u8_i vis_lddfa_ASI_FL8P_index -#define vis_ld_u8_le vis_lddfa_ASI_FL8PL -#define vis_ld_u16 vis_lddfa_ASI_FL16P -#define vis_ld_u16_i vis_lddfa_ASI_FL16P_index -#define vis_ld_u16_le vis_lddfa_ASI_FL16PL - -#define vis_pst_8 vis_stdfa_ASI_PST8P -#define vis_pst_16 vis_stdfa_ASI_PST16P -#define vis_pst_32 vis_stdfa_ASI_PST32P - -#define vis_st_u8s vis_stdfa_ASI_FL8S -#define vis_st_u8s_le vis_stdfa_ASI_FL8SL -#define vis_st_u16s vis_stdfa_ASI_FL16S +#define vis_st_u8 vis_stdfa_ASI_FL8P +#define vis_st_u8_i vis_stdfa_ASI_FL8P_index +#define vis_st_u8_le vis_stdfa_ASI_FL8PL +#define vis_st_u16 vis_stdfa_ASI_FL16P +#define vis_st_u16_i vis_stdfa_ASI_FL16P_index +#define vis_st_u16_le vis_stdfa_ASI_FL16PL + +#define vis_ld_u8 vis_lddfa_ASI_FL8P +#define vis_ld_u8_i vis_lddfa_ASI_FL8P_index +#define vis_ld_u8_le vis_lddfa_ASI_FL8PL +#define vis_ld_u16 vis_lddfa_ASI_FL16P +#define vis_ld_u16_i vis_lddfa_ASI_FL16P_index +#define vis_ld_u16_le vis_lddfa_ASI_FL16PL + +#define vis_pst_8 vis_stdfa_ASI_PST8P +#define vis_pst_16 vis_stdfa_ASI_PST16P +#define vis_pst_32 vis_stdfa_ASI_PST32P + +#define vis_st_u8s vis_stdfa_ASI_FL8S +#define vis_st_u8s_le vis_stdfa_ASI_FL8SL +#define vis_st_u16s vis_stdfa_ASI_FL16S #define vis_st_u16s_le vis_stdfa_ASI_FL16SL -#define vis_ld_u8s vis_lddfa_ASI_FL8S -#define vis_ld_u8s_le vis_lddfa_ASI_FL8SL -#define vis_ld_u16s vis_lddfa_ASI_FL16S +#define vis_ld_u8s vis_lddfa_ASI_FL8S +#define vis_ld_u8s_le vis_lddfa_ASI_FL8SL +#define vis_ld_u16s vis_lddfa_ASI_FL16S #define vis_ld_u16s_le vis_lddfa_ASI_FL16SL -#define vis_pst_8s vis_stdfa_ASI_PST8S -#define vis_pst_16s vis_stdfa_ASI_PST16S -#define vis_pst_32s vis_stdfa_ASI_PST32S +#define vis_pst_8s vis_stdfa_ASI_PST8S +#define vis_pst_16s vis_stdfa_ASI_PST16S +#define vis_pst_32s vis_stdfa_ASI_PST32S /* "<" and ">=" may be implemented in terms of ">" and "<=". */ -#define vis_fcmplt16(a,b) vis_fcmpgt16((b),(a)) -#define vis_fcmplt32(a,b) vis_fcmpgt32((b),(a)) -#define vis_fcmpge16(a,b) vis_fcmple16((b),(a)) -#define vis_fcmpge32(a,b) vis_fcmple32((b),(a)) +#define vis_fcmplt16(a, b) vis_fcmpgt16((b), (a)) +#define vis_fcmplt32(a, b) vis_fcmpgt32((b), (a)) +#define vis_fcmpge16(a, b) vis_fcmple16((b), (a)) +#define vis_fcmpge32(a, b) vis_fcmple32((b), (a)) #ifdef __cplusplus } // End of extern "C" |