static void ndraw(mp_int *a, const char *name) { char buf[16000]; printf("%s: ", name); mp_toradix(a, buf, 10); printf("%s\n", buf); mp_toradix(a, buf, 16); printf("0x%s\n", buf); }
DLL_EXPORT int ECDHEMakeKey(char *x, char *y, char *z, char *k) { ecc_key ecc_dhe; init_dependencies(); int res = ecc_make_key_ex(NULL, find_prng("sprng"), &ecc_dhe, &ecc256); if (!res) { mp_toradix(ecc_dhe.pubkey.x, x, 16); mp_toradix(ecc_dhe.pubkey.y, y, 16); mp_toradix(ecc_dhe.pubkey.z, z, 16); mp_toradix(ecc_dhe.k, k, 16); ecc_free(&ecc_dhe); } }
void BigInteger::getText(string& str, unsigned int radix) const { int size; CHECK_MP(mp_radix_size(const_cast<mp_int*>(&t), radix, &size)); str.resize(size - 1, ' '); CHECK_MP(mp_toradix(const_cast<mp_int*>(&t), str.begin(), radix)); }
int mp_fwrite(mp_int *a, int radix, FILE *stream) { char *buf; int err, len, x; if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { return err; } buf = OPT_CAST(char) XMALLOC (len); if (buf == NULL) { return MP_MEM; } if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { XFREE (buf); return err; } for (x = 0; x < len; x++) { if (fputc(buf[x], stream) == EOF) { XFREE (buf); return MP_VAL; } } XFREE (buf); return MP_OKAY; }
static void _write_data(mp_int *mp, FILE *fp) { char buf[256]; /* write ppp identifer */ fwrite(" PPP ", 1, 5, fp); /* write key version */ fprintf(fp, "%04d ", keyVersion()); /* Current data format is versioned file, * mpi radix 62. */ int current_data_format = 2; /* write data format */ fprintf(fp, "%04d ", current_data_format); /* write flags */ fprintf(fp, "%04x ", pppCheckFlags(0xffff)); /* IMPORTANT NOTE: * * If you change current_data_format above, * make sure you: * * 1. Update the code below that writes the data to * reflect the data format you specified in * current_data_format above. * 2. Add compatible read code to the switch statement * in _read_data() above. */ /* mpi radix 62 is the data format du jour */ mp_toradix(mp, (unsigned char *)buf, 62); fwrite(buf, 1, strlen(buf)+1, fp); }
int main(void) { char input[128]; mp_int val; mp_err res; fprintf(stderr, "Please enter a number (base 10): "); fgets(input, sizeof(input), stdin); mp_init(&val); if((res = mp_read_radix(&val, (unsigned char *)input, 10)) != MP_OKAY) { fprintf(stderr, "Error converting input value: %s\n", mp_strerror(res)); return 1; } { int out_len = mp_radix_size(&val, 10); unsigned char *buf = malloc(out_len); mp_toradix(&val, buf, 10); printf("You entered: %s\n", buf); free(buf); } mp_clear(&val); return 0; }
char *operator<<(char *s,Mpi &a) { // Same here. Because there is no way to specify a radix, // we use 10 by default a.err=mp_toradix(&(a.mpi_n),s,10); return s; }
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; }
void ndraw(mp_int * a, char *name) { char buf[4096]; printf("%s: ", name); mp_toradix(a, buf, 64); printf("%s\n", buf); }
void bn_int2string (char *string, size_t size, mp_int *a) { (void) size; int ret; ret = mp_toradix (a, string, 10); if (ret != MP_OKAY) Fatal (1, error, "Error converting number to string"); }
/* Tests a point p in Jacobian coordinates, comparing against the * expected affine result (x, y). */ mp_err testJacPoint(ecfp_jac_pt * p, mp_int *x, mp_int *y, ECGroup *ecgroup) { char s[1000]; mp_int rx, ry, rz; mp_err res = MP_OKAY; MP_DIGITS(&rx) = 0; MP_DIGITS(&ry) = 0; MP_DIGITS(&rz) = 0; MP_CHECKOK(mp_init(&rx)); MP_CHECKOK(mp_init(&ry)); MP_CHECKOK(mp_init(&rz)); ecfp_fp2i(&rx, p->x, ecgroup); ecfp_fp2i(&ry, p->y, ecgroup); ecfp_fp2i(&rz, p->z, ecgroup); /* convert result R to affine coordinates */ ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup); /* Compare to expected result */ if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) { printf(" Error: Jacobian Floating Point Incorrect.\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf("floating point result\nrx %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf("ry %s\n", s); MP_CHECKOK(mp_toradix(x, s, 16)); printf("integer result\nx %s\n", s); MP_CHECKOK(mp_toradix(y, s, 16)); printf("y %s\n", s); res = MP_NO; goto CLEANUP; } CLEANUP: mp_clear(&rx); mp_clear(&ry); mp_clear(&rz); return res; }
int main(void) { int res, x, y; char buf[4096]; FILE *out; mp_int a, b; mp_init(&a); mp_init(&b); out = fopen("drprimes.txt", "w"); for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) { top: printf("Seeking a %d-bit safe prime\n", sizes[x] * DIGIT_BIT); mp_grow(&a, sizes[x]); mp_zero(&a); for (y = 1; y < sizes[x]; y++) { a.dp[y] = MP_MASK; } /* make a DR modulus */ a.dp[0] = -1; a.used = sizes[x]; /* now loop */ res = 0; for (;;) { a.dp[0] += 4; if (a.dp[0] >= MP_MASK) break; mp_prime_is_prime(&a, 1, &res); if (res == 0) continue; printf("."); fflush(stdout); mp_sub_d(&a, 1, &b); mp_div_2(&b, &b); mp_prime_is_prime(&b, 3, &res); if (res == 0) continue; mp_prime_is_prime(&a, 3, &res); if (res == 1) break; } if (res != 1) { printf("Error not DR modulus\n"); sizes[x] += 1; goto top; } else { mp_toradix(&a, buf, 10); printf("\n\np == %s\n\n", buf); fprintf(out, "%d-bit prime:\np == %s\n\n", mp_count_bits(&a), buf); fflush(out); } } fclose(out); mp_clear(&a); mp_clear(&b); return 0; }
/** * Create a string representation of a given multi-precision integer * * @param s destination pointer * @param mp the number to represent * @param base Output the string representation in this base */ void static fhe_mp_to_string(char **s, mp_int *mp, int base) { int size; // is int, not size_t; this is how libtommath wants it // libtommath documentation says that the maximum base is 64; base < 2 does // not make sense. (Actually, base 1 makes sense, but nobody seems to // agree with me on that one.) assert(base > 1 && base <= 64); /* Allocate space and generate ASCII representation of private key */ (void)mp_radix_size(mp, 0x10, &size); *s = (char *)checkMalloc(size); (void)mp_toradix(mp, *s, 0x10); }
int main (void) { mp_int p, q; char buf[4096]; int k, li; clock_t t1; srand (time (NULL)); load_tab(); printf ("Enter # of bits: \n"); fgets (buf, sizeof (buf), stdin); sscanf (buf, "%d", &k); printf ("Enter number of bases to try (1 to 8):\n"); fgets (buf, sizeof (buf), stdin); sscanf (buf, "%d", &li); mp_init (&p); mp_init (&q); t1 = clock (); pprime (k, li, &p, &q); t1 = clock () - t1; printf ("\n\nTook %ld ticks, %d bits\n", t1, mp_count_bits (&p)); mp_toradix (&p, buf, 10); printf ("P == %s\n", buf); mp_toradix (&q, buf, 10); printf ("Q == %s\n", buf); return 0; }
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; }
int mp_put_str(mp_int * a, char **str, int radix) { size_t buflen, multiplicator; mp_int tmp; mp_init(&tmp); multiplicator = (size_t) ((double) (a->used) / (double) (MPI_LOG2)) + 1; buflen = (multiplicator < (size_t) 4096) ? (size_t) 4096 : multiplicator + 100; *str = malloc(buflen); if (*str == NULL) { mp_clear(&tmp); return 0; } mp_copy(a, &tmp); mp_toradix(&tmp, *str, radix); mp_clear(&tmp); return MP_OKAY; }
int main(int argc, char *argv[]) { 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; } } 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; } } mp_init(&val); while(ix < argc) { char *out; int outlen; mp_read_radix(&val, argv[ix++], ibase); outlen = mp_radix_size(&val, obase); out = calloc(outlen, sizeof(char)); mp_toradix(&val, out, obase); printf("%s\n", out); free(out); } mp_clear(&val); return 0; }
ostream &operator<<(ostream &s, Mpi &a) { long flags; mp_word base; flags=s.flags(); // curently, only bases 8,10,16 are supported. If we had a // global variable with a default radix for the conversions, // we could support all of them. if (flags & ios::hex) base=16; else { if (flags & ios::oct) base=8; else base=10; } a.err=mp_toradix(&(a.mpi_n),(char *)iobuf,base); s << (char *)iobuf; return s; }
int main(int argc, char *argv[]) { mp_int a; char *buf; int len; 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); printf("%s\n", buf); free(buf); mp_clear(&a); return 0; }
/* makes a prime of at least k bits */ int pprime (int k, int li, mp_int * p, mp_int * q) { mp_int a, b, c, n, x, y, z, v; int res, ii; static const mp_digit bases[] = { 2, 3, 5, 7, 11, 13, 17, 19 }; /* single digit ? */ if (k <= (int) DIGIT_BIT) { mp_set (p, prime_digit ()); return MP_OKAY; } if ((res = mp_init (&c)) != MP_OKAY) { return res; } if ((res = mp_init (&v)) != MP_OKAY) { goto LBL_C; } /* product of first 50 primes */ if ((res = mp_read_radix (&v, "19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190", 10)) != MP_OKAY) { goto LBL_V; } if ((res = mp_init (&a)) != MP_OKAY) { goto LBL_V; } /* set the prime */ mp_set (&a, prime_digit ()); if ((res = mp_init (&b)) != MP_OKAY) { goto LBL_A; } if ((res = mp_init (&n)) != MP_OKAY) { goto LBL_B; } if ((res = mp_init (&x)) != MP_OKAY) { goto LBL_N; } if ((res = mp_init (&y)) != MP_OKAY) { goto LBL_X; } if ((res = mp_init (&z)) != MP_OKAY) { goto LBL_Y; } /* now loop making the single digit */ while (mp_count_bits (&a) < k) { fprintf (stderr, "prime has %4d bits left\r", k - mp_count_bits (&a)); fflush (stderr); top: mp_set (&b, prime_digit ()); /* now compute z = a * b * 2 */ if ((res = mp_mul (&a, &b, &z)) != MP_OKAY) { /* z = a * b */ goto LBL_Z; } if ((res = mp_copy (&z, &c)) != MP_OKAY) { /* c = a * b */ goto LBL_Z; } if ((res = mp_mul_2 (&z, &z)) != MP_OKAY) { /* z = 2 * a * b */ goto LBL_Z; } /* n = z + 1 */ if ((res = mp_add_d (&z, 1, &n)) != MP_OKAY) { /* n = z + 1 */ goto LBL_Z; } /* check (n, v) == 1 */ if ((res = mp_gcd (&n, &v, &y)) != MP_OKAY) { /* y = (n, v) */ goto LBL_Z; } if (mp_cmp_d (&y, 1) != MP_EQ) goto top; /* now try base x=bases[ii] */ for (ii = 0; ii < li; ii++) { mp_set (&x, bases[ii]); /* compute x^a mod n */ if ((res = mp_exptmod (&x, &a, &n, &y)) != MP_OKAY) { /* y = x^a mod n */ goto LBL_Z; } /* if y == 1 loop */ if (mp_cmp_d (&y, 1) == MP_EQ) continue; /* now x^2a mod n */ if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2a mod n */ goto LBL_Z; } if (mp_cmp_d (&y, 1) == MP_EQ) continue; /* compute x^b mod n */ if ((res = mp_exptmod (&x, &b, &n, &y)) != MP_OKAY) { /* y = x^b mod n */ goto LBL_Z; } /* if y == 1 loop */ if (mp_cmp_d (&y, 1) == MP_EQ) continue; /* now x^2b mod n */ if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2b mod n */ goto LBL_Z; } if (mp_cmp_d (&y, 1) == MP_EQ) continue; /* compute x^c mod n == x^ab mod n */ if ((res = mp_exptmod (&x, &c, &n, &y)) != MP_OKAY) { /* y = x^ab mod n */ goto LBL_Z; } /* if y == 1 loop */ if (mp_cmp_d (&y, 1) == MP_EQ) continue; /* now compute (x^c mod n)^2 */ if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2ab mod n */ goto LBL_Z; } /* y should be 1 */ if (mp_cmp_d (&y, 1) != MP_EQ) continue; break; } /* no bases worked? */ if (ii == li) goto top; { char buf[4096]; mp_toradix(&n, buf, 10); printf("Certificate of primality for:\n%s\n\n", buf); mp_toradix(&a, buf, 10); printf("A == \n%s\n\n", buf); mp_toradix(&b, buf, 10); printf("B == \n%s\n\nG == %d\n", buf, bases[ii]); printf("----------------------------------------------------------------\n"); } /* a = n */ mp_copy (&n, &a); } /* get q to be the order of the large prime subgroup */ mp_sub_d (&n, 1, q); mp_div_2 (q, q); mp_div (q, &b, q, NULL); mp_exch (&n, p); res = MP_OKAY; LBL_Z:mp_clear (&z); LBL_Y:mp_clear (&y); LBL_X:mp_clear (&x); LBL_N:mp_clear (&n); LBL_B:mp_clear (&b); LBL_A:mp_clear (&a); LBL_V:mp_clear (&v); LBL_C:mp_clear (&c); return res; }
/* Tests a point multiplication (various algorithms) */ mp_err testPointMul(ECGroup *ecgroup) { mp_err res; char s[1000]; mp_int rx, ry, order_1; /* Init */ MP_DIGITS(&rx) = 0; MP_DIGITS(&ry) = 0; MP_DIGITS(&order_1) = 0; MP_CHECKOK(mp_init(&rx)); MP_CHECKOK(mp_init(&ry)); MP_CHECKOK(mp_init(&order_1)); MP_CHECKOK(mp_set_int(&order_1, 1)); MP_CHECKOK(mp_sub(&ecgroup->order, &order_1, &order_1)); /* Test Algorithm 1: Jacobian-Affine Double & Add */ ec_GFp_pt_mul_jac_fp(&order_1, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup); MP_CHECKOK(ecgroup->meth->field_neg(&ry, &ry, ecgroup->meth)); if ((mp_cmp(&rx, &ecgroup->genx) != 0) || (mp_cmp(&ry, &ecgroup->geny) != 0)) { printf (" Error: ec_GFp_pt_mul_jac_fp invalid result (expected (- base point)).\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf("rx %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf("ry %s\n", s); res = MP_NO; goto CLEANUP; } ec_GFp_pt_mul_jac_fp(&ecgroup->order, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup); if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { printf (" Error: ec_GFp_pt_mul_jac_fp invalid result (expected point at infinity.\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf("rx %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf("ry %s\n", s); res = MP_NO; goto CLEANUP; } /* Test Algorithm 2: 4-bit Window in Jacobian */ ec_GFp_point_mul_jac_4w_fp(&order_1, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup); MP_CHECKOK(ecgroup->meth->field_neg(&ry, &ry, ecgroup->meth)); if ((mp_cmp(&rx, &ecgroup->genx) != 0) || (mp_cmp(&ry, &ecgroup->geny) != 0)) { printf (" Error: ec_GFp_point_mul_jac_4w_fp invalid result (expected (- base point)).\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf("rx %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf("ry %s\n", s); res = MP_NO; goto CLEANUP; } ec_GFp_point_mul_jac_4w_fp(&ecgroup->order, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup); if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { printf (" Error: ec_GFp_point_mul_jac_4w_fp invalid result (expected point at infinity.\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf("rx %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf("ry %s\n", s); res = MP_NO; goto CLEANUP; } /* Test Algorithm 3: wNAF with modified Jacobian coordinates */ ec_GFp_point_mul_wNAF_fp(&order_1, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup); MP_CHECKOK(ecgroup->meth->field_neg(&ry, &ry, ecgroup->meth)); if ((mp_cmp(&rx, &ecgroup->genx) != 0) || (mp_cmp(&ry, &ecgroup->geny) != 0)) { printf (" Error: ec_GFp_pt_mul_wNAF_fp invalid result (expected (- base point)).\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf("rx %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf("ry %s\n", s); res = MP_NO; goto CLEANUP; } ec_GFp_point_mul_wNAF_fp(&ecgroup->order, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup); if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { printf (" Error: ec_GFp_pt_mul_wNAF_fp invalid result (expected point at infinity.\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf("rx %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf("ry %s\n", s); res = MP_NO; goto CLEANUP; } CLEANUP: if (res == MP_OKAY) printf(" Test Passed - Point Multiplication\n"); else printf("TEST FAILED - Point Multiplication\n"); mp_clear(&rx); mp_clear(&ry); mp_clear(&order_1); return res; }
/* Tests a point p in Modified Jacobian coordinates, comparing against the * expected affine result (x, y). */ mp_err testJmPoint(ecfp_jm_pt * r, mp_int *x, mp_int *y, ECGroup *ecgroup) { char s[1000]; mp_int rx, ry, rz, raz4, test; mp_err res = MP_OKAY; /* Initialization */ MP_DIGITS(&rx) = 0; MP_DIGITS(&ry) = 0; MP_DIGITS(&rz) = 0; MP_DIGITS(&raz4) = 0; MP_DIGITS(&test) = 0; MP_CHECKOK(mp_init(&rx)); MP_CHECKOK(mp_init(&ry)); MP_CHECKOK(mp_init(&rz)); MP_CHECKOK(mp_init(&raz4)); MP_CHECKOK(mp_init(&test)); /* Convert to integer */ ecfp_fp2i(&rx, r->x, ecgroup); ecfp_fp2i(&ry, r->y, ecgroup); ecfp_fp2i(&rz, r->z, ecgroup); ecfp_fp2i(&raz4, r->az4, ecgroup); /* Verify raz4 = rz^4 * a */ mp_sqrmod(&rz, &ecgroup->meth->irr, &test); mp_sqrmod(&test, &ecgroup->meth->irr, &test); mp_mulmod(&test, &ecgroup->curvea, &ecgroup->meth->irr, &test); if (mp_cmp(&test, &raz4) != 0) { printf(" Error: a*z^4 not valid\n"); MP_CHECKOK(mp_toradix(&ecgroup->curvea, s, 16)); printf("a %s\n", s); MP_CHECKOK(mp_toradix(&rz, s, 16)); printf("rz %s\n", s); MP_CHECKOK(mp_toradix(&raz4, s, 16)); printf("raz4 %s\n", s); res = MP_NO; goto CLEANUP; } /* convert result R to affine coordinates */ ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup); /* Compare against expected result */ if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) { printf(" Error: Modified Jacobian Floating Point Incorrect.\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf("floating point result\nrx %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf("ry %s\n", s); MP_CHECKOK(mp_toradix(x, s, 16)); printf("integer result\nx %s\n", s); MP_CHECKOK(mp_toradix(y, s, 16)); printf("y %s\n", s); res = MP_NO; goto CLEANUP; } CLEANUP: mp_clear(&rx); mp_clear(&ry); mp_clear(&rz); mp_clear(&raz4); mp_clear(&test); return res; }
/* Tests a point p in Chudnovsky Jacobian coordinates, comparing against * the expected affine result (x, y). */ mp_err testChudPoint(ecfp_chud_pt * p, mp_int *x, mp_int *y, ECGroup *ecgroup) { char s[1000]; mp_int rx, ry, rz, rz2, rz3, test; mp_err res = MP_OKAY; /* Initialization */ MP_DIGITS(&rx) = 0; MP_DIGITS(&ry) = 0; MP_DIGITS(&rz) = 0; MP_DIGITS(&rz2) = 0; MP_DIGITS(&rz3) = 0; MP_DIGITS(&test) = 0; MP_CHECKOK(mp_init(&rx)); MP_CHECKOK(mp_init(&ry)); MP_CHECKOK(mp_init(&rz)); MP_CHECKOK(mp_init(&rz2)); MP_CHECKOK(mp_init(&rz3)); MP_CHECKOK(mp_init(&test)); /* Convert to integers */ ecfp_fp2i(&rx, p->x, ecgroup); ecfp_fp2i(&ry, p->y, ecgroup); ecfp_fp2i(&rz, p->z, ecgroup); ecfp_fp2i(&rz2, p->z2, ecgroup); ecfp_fp2i(&rz3, p->z3, ecgroup); /* Verify z2, z3 are valid */ mp_sqrmod(&rz, &ecgroup->meth->irr, &test); if (mp_cmp(&test, &rz2) != 0) { printf(" Error: rzp2 not valid\n"); res = MP_NO; goto CLEANUP; } mp_mulmod(&test, &rz, &ecgroup->meth->irr, &test); if (mp_cmp(&test, &rz3) != 0) { printf(" Error: rzp2 not valid\n"); res = MP_NO; goto CLEANUP; } /* convert result R to affine coordinates */ ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup); /* Compare against expected result */ if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) { printf(" Error: Chudnovsky Floating Point Incorrect.\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf("floating point result\nrx %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf("ry %s\n", s); MP_CHECKOK(mp_toradix(x, s, 16)); printf("integer result\nx %s\n", s); MP_CHECKOK(mp_toradix(y, s, 16)); printf("y %s\n", s); res = MP_NO; goto CLEANUP; } CLEANUP: mp_clear(&rx); mp_clear(&ry); mp_clear(&rz); mp_clear(&rz2); mp_clear(&rz3); mp_clear(&test); return res; }
/* write one */ static int write_radix(void *a, char *b, int radix) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_toradix(a, b, radix)); }
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 won't be good enough for cryptographic purposes */ 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 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; } 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; }
int main(int argc, char *argv[]) { unsigned char *raw, *out; int rawlen, bits, outlen, ngen, ix, jx; mp_int testval, q, ntries; mp_err res; mp_digit np; clock_t start, end; #ifdef MACOS argc = ccommand(&argv); #endif /* We'll just use the C library's rand() for now, although this won't be good enough for cryptographic purposes */ if((out = (unsigned char *)getenv("SEED")) == NULL) { srand((unsigned int)time(NULL)); } else { srand((unsigned int)atoi((char *)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 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 q - used in finding strong primes */ if((res = mp_init(&testval)) != MP_OKAY || (res = mp_init(&ntries)) != MP_OKAY || (res = mp_init(&q)) != MP_OKAY) { fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); return 1; } if(g_strong) { printf("Requested %d strong prime values of at least %d bits.\n", ngen, bits); } else { printf("Requested %d prime values of at least %d bits.\n", ngen, bits); } rawlen = (bits / CHAR_BIT) + ((bits % CHAR_BIT) ? 1 : 0); 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++) { /* Pack the initializer with random bytes */ for(ix = 0; ix < rawlen; ix++) raw[ix] = (rand() * rand()) & UCHAR_MAX; raw[0] |= 0x80; /* set high-order bit of test value */ if(g_strong) raw[rawlen - 1] |= 7; /* set low-order 3 bits of test value */ else raw[rawlen - 1] |= 1; /* set low-order bit of test value */ /* Make an mp_int out of the initializer */ mp_read_unsigned_bin(&testval, raw, rawlen); /* If we asked for a strong prime, shift down one bit so that when we double, we're still within the right range of bits ... this is why we OR'd with 7 instead of 1 above (leaves two bits set so that the value remains congruent to 3 (mod 4)). */ if(g_strong) { mp_copy(&testval, &q); mp_div_2(&testval, &testval); } /* Initialize candidate counter */ mp_zero(&ntries); mp_add_d(&ntries, 1, &ntries); start = clock(); /* time generation for this prime */ for(;;) { /* Test for divisibility by small primes (of which there is a table conveniently stored in mpprime.c) */ np = prime_tab_size; if(mpp_divis_primes(&testval, &np) == MP_NO) { /* If we're trying for a strong prime, test 2p+1 before running other primality tests */ if(g_strong) { np = prime_tab_size; if(mpp_divis_primes(&q, &np) == MP_YES) goto NEXT_CANDIDATE; } /* If that passed, run a Fermat test */ res = mpp_fermat(&testval, 2); switch(res) { case MP_NO: /* composite */ goto NEXT_CANDIDATE; case MP_YES: /* may be prime */ break; default: goto CLEANUP; /* some other error */ } /* If that passed, run some Miller-Rabin tests */ res = mpp_pprime(&testval, NUM_TESTS); switch(res) { case MP_NO: /* composite */ goto NEXT_CANDIDATE; case MP_YES: /* may be prime */ break; default: goto CLEANUP; /* some other error */ } /* 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... */ if(g_strong) { if(res == MP_YES) { fputc('.', stderr); /* If we get here, we've already tested q against small prime divisors, so we can just do the regular primality testing */ /* Fermat, as with its parent ... */ res = mpp_fermat(&q, 2); switch(res) { case MP_NO: /* composite */ goto NEXT_CANDIDATE; case MP_YES: /* may be prime */ break; default: goto CLEANUP; /* some other error */ } /* And, with Miller-Rabin, as with its parent ... */ res = mpp_pprime(&q, NUM_TESTS); switch(res) { case MP_NO: /* composite */ goto NEXT_CANDIDATE; case MP_YES: /* may be prime */ break; default: goto CLEANUP; /* some other error */ } /* If it passed, we've got a winner */ if(res == MP_YES) { fputc('\n', stderr); mp_copy(&q, &testval); break; } } /* end if(res == MP_YES) */ } else { /* We get here if g_strong is false */ if(res == MP_YES) break; } } /* end if(not divisible by small primes) */ /* If we're testing strong primes, skip to the next odd value congruent to 3 (mod 4). Otherwise, just skip to the next odd value */ NEXT_CANDIDATE: if(g_strong) { mp_add_d(&q, 4, &q); mp_div_2(&q, &testval); } else mp_add_d(&testval, 2, &testval); mp_add_d(&ntries, 1, &ntries); } /* end of loop to generate a single prime */ end = clock(); printf("After %d tests, the following value is still probably prime:\n", NUM_TESTS); outlen = mp_radix_size(&testval, 10); out = calloc(outlen, sizeof(unsigned char)); mp_toradix(&testval, out, 10); printf("10: %s\n", (char *)out); mp_toradix(&testval, out, 16); printf("16: %s\n\n", (char *)out); free(out); printf("Number of candidates tried: "); outlen = mp_radix_size(&ntries, 10); out = calloc(outlen, sizeof(unsigned char)); mp_toradix(&ntries, out, 10); printf("%s\n", (char *)out); free(out); printf("This computation took %ld clock ticks (%.2f seconds)\n", (end - start), ((double)(end - start) / CLOCKS_PER_SEC)); fputc('\n', stdout); } /* end of loop to generate all requested primes */ CLEANUP: if(res != MP_OKAY) fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); free(raw); mp_clear(&testval); mp_clear(&q); mp_clear(&ntries); return 0; }
void draw(mp_float *a) { char buf[8192]; mp_toradix(&(a->mantissa), buf, 10); printf("%s * 2^%ld\n", buf, a->exp); }
int main(void) { mp_int a, b, c, d, e, f; unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n, t; unsigned rr; int i, n, err, cnt, ix, old_kara_m, old_kara_s; mp_digit mp; mp_init(&a); mp_init(&b); mp_init(&c); mp_init(&d); mp_init(&e); mp_init(&f); srand(time(NULL)); #if 0 // test montgomery printf("Testing montgomery...\n"); for (i = 1; i < 10; i++) { printf("Testing digit size: %d\n", i); for (n = 0; n < 1000; n++) { mp_rand(&a, i); a.dp[0] |= 1; // let's see if R is right mp_montgomery_calc_normalization(&b, &a); mp_montgomery_setup(&a, &mp); // now test a random reduction for (ix = 0; ix < 100; ix++) { mp_rand(&c, 1 + abs(rand()) % (2*i)); mp_copy(&c, &d); mp_copy(&c, &e); mp_mod(&d, &a, &d); mp_montgomery_reduce(&c, &a, mp); mp_mulmod(&c, &b, &a, &c); if (mp_cmp(&c, &d) != MP_EQ) { printf("d = e mod a, c = e MOD a\n"); mp_todecimal(&a, buf); printf("a = %s\n", buf); mp_todecimal(&e, buf); printf("e = %s\n", buf); mp_todecimal(&d, buf); printf("d = %s\n", buf); mp_todecimal(&c, buf); printf("c = %s\n", buf); printf("compare no compare!\n"); exit(EXIT_FAILURE); } } } } printf("done\n"); // test mp_get_int printf("Testing: mp_get_int\n"); for (i = 0; i < 1000; ++i) { t = ((unsigned long) rand() * rand() + 1) & 0xFFFFFFFF; mp_set_int(&a, t); if (t != mp_get_int(&a)) { printf("mp_get_int() bad result!\n"); return 1; } } mp_set_int(&a, 0); if (mp_get_int(&a) != 0) { printf("mp_get_int() bad result!\n"); return 1; } mp_set_int(&a, 0xffffffff); if (mp_get_int(&a) != 0xffffffff) { printf("mp_get_int() bad result!\n"); return 1; } // test mp_sqrt printf("Testing: mp_sqrt\n"); for (i = 0; i < 1000; ++i) { printf("%6d\r", i); fflush(stdout); n = (rand() & 15) + 1; mp_rand(&a, n); if (mp_sqrt(&a, &b) != MP_OKAY) { printf("mp_sqrt() error!\n"); return 1; } mp_n_root(&a, 2, &a); if (mp_cmp_mag(&b, &a) != MP_EQ) { printf("mp_sqrt() bad result!\n"); return 1; } } printf("\nTesting: mp_is_square\n"); for (i = 0; i < 1000; ++i) { printf("%6d\r", i); fflush(stdout); /* test mp_is_square false negatives */ n = (rand() & 7) + 1; mp_rand(&a, n); mp_sqr(&a, &a); if (mp_is_square(&a, &n) != MP_OKAY) { printf("fn:mp_is_square() error!\n"); return 1; } if (n == 0) { printf("fn:mp_is_square() bad result!\n"); return 1; } /* test for false positives */ mp_add_d(&a, 1, &a); if (mp_is_square(&a, &n) != MP_OKAY) { printf("fp:mp_is_square() error!\n"); return 1; } if (n == 1) { printf("fp:mp_is_square() bad result!\n"); return 1; } } printf("\n\n"); /* test for size */ for (ix = 10; ix < 128; ix++) { printf("Testing (not safe-prime): %9d bits \r", ix); fflush(stdout); err = mp_prime_random_ex(&a, 8, ix, (rand() & 1) ? LTM_PRIME_2MSB_OFF : LTM_PRIME_2MSB_ON, myrng, NULL); if (err != MP_OKAY) { printf("failed with err code %d\n", err); return EXIT_FAILURE; } if (mp_count_bits(&a) != ix) { printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); return EXIT_FAILURE; } } for (ix = 16; ix < 128; ix++) { printf("Testing ( safe-prime): %9d bits \r", ix); fflush(stdout); err = mp_prime_random_ex(&a, 8, ix, ((rand() & 1) ? LTM_PRIME_2MSB_OFF : LTM_PRIME_2MSB_ON) | LTM_PRIME_SAFE, myrng, NULL); if (err != MP_OKAY) { printf("failed with err code %d\n", err); return EXIT_FAILURE; } if (mp_count_bits(&a) != ix) { printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); return EXIT_FAILURE; } /* let's see if it's really a safe prime */ mp_sub_d(&a, 1, &a); mp_div_2(&a, &a); mp_prime_is_prime(&a, 8, &cnt); if (cnt != MP_YES) { printf("sub is not prime!\n"); return EXIT_FAILURE; } } printf("\n\n"); mp_read_radix(&a, "123456", 10); mp_toradix_n(&a, buf, 10, 3); printf("a == %s\n", buf); mp_toradix_n(&a, buf, 10, 4); printf("a == %s\n", buf); mp_toradix_n(&a, buf, 10, 30); printf("a == %s\n", buf); #if 0 for (;;) { fgets(buf, sizeof(buf), stdin); mp_read_radix(&a, buf, 10); mp_prime_next_prime(&a, 5, 1); mp_toradix(&a, buf, 10); printf("%s, %lu\n", buf, a.dp[0] & 3); } #endif /* test mp_cnt_lsb */ printf("testing mp_cnt_lsb...\n"); mp_set(&a, 1); for (ix = 0; ix < 1024; ix++) { if (mp_cnt_lsb(&a) != ix) { printf("Failed at %d, %d\n", ix, mp_cnt_lsb(&a)); return 0; } mp_mul_2(&a, &a); } /* test mp_reduce_2k */ printf("Testing mp_reduce_2k...\n"); for (cnt = 3; cnt <= 128; ++cnt) { mp_digit tmp; mp_2expt(&a, cnt); mp_sub_d(&a, 2, &a); /* a = 2**cnt - 2 */ printf("\nTesting %4d bits", cnt); printf("(%d)", mp_reduce_is_2k(&a)); mp_reduce_2k_setup(&a, &tmp); printf("(%d)", tmp); for (ix = 0; ix < 1000; ix++) { if (!(ix & 127)) { printf("."); fflush(stdout); } mp_rand(&b, (cnt / DIGIT_BIT + 1) * 2); mp_copy(&c, &b); mp_mod(&c, &a, &c); mp_reduce_2k(&b, &a, 2); if (mp_cmp(&c, &b)) { printf("FAILED\n"); exit(0); } } } /* test mp_div_3 */ printf("Testing mp_div_3...\n"); mp_set(&d, 3); for (cnt = 0; cnt < 10000;) { mp_digit r1, r2; if (!(++cnt & 127)) printf("%9d\r", cnt); mp_rand(&a, abs(rand()) % 128 + 1); mp_div(&a, &d, &b, &e); mp_div_3(&a, &c, &r2); if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) { printf("\n\nmp_div_3 => Failure\n"); } } printf("\n\nPassed div_3 testing\n"); /* test the DR reduction */ printf("testing mp_dr_reduce...\n"); for (cnt = 2; cnt < 32; cnt++) { printf("%d digit modulus\n", cnt); mp_grow(&a, cnt); mp_zero(&a); for (ix = 1; ix < cnt; ix++) { a.dp[ix] = MP_MASK; } a.used = cnt; a.dp[0] = 3; mp_rand(&b, cnt - 1); mp_copy(&b, &c); rr = 0; do { if (!(rr & 127)) { printf("%9lu\r", rr); fflush(stdout); } mp_sqr(&b, &b); mp_add_d(&b, 1, &b); mp_copy(&b, &c); mp_mod(&b, &a, &b); mp_dr_reduce(&c, &a, (((mp_digit) 1) << DIGIT_BIT) - a.dp[0]); if (mp_cmp(&b, &c) != MP_EQ) { printf("Failed on trial %lu\n", rr); exit(-1); } } while (++rr < 500); printf("Passed DR test for %d digits\n", cnt); } #endif /* test the mp_reduce_2k_l code */ #if 0 #if 0 /* first load P with 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF */ mp_2expt(&a, 1024); mp_read_radix(&b, "2A434B9FDEC95D8F9D550FFFFFFFFFFFFFFFF", 16); mp_sub(&a, &b, &a); #elif 1 /* p = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F */ mp_2expt(&a, 2048); mp_read_radix(&b, "1000000000000000000000000000000004945DDBF8EA2A91D5776399BB83E188F", 16); mp_sub(&a, &b, &a); #endif mp_todecimal(&a, buf); printf("p==%s\n", buf); /* now mp_reduce_is_2k_l() should return */ if (mp_reduce_is_2k_l(&a) != 1) { printf("mp_reduce_is_2k_l() return 0, should be 1\n"); return EXIT_FAILURE; } mp_reduce_2k_setup_l(&a, &d); /* now do a million square+1 to see if it varies */ mp_rand(&b, 64); mp_mod(&b, &a, &b); mp_copy(&b, &c); printf("testing mp_reduce_2k_l..."); fflush(stdout); for (cnt = 0; cnt < (1UL << 20); cnt++) { mp_sqr(&b, &b); mp_add_d(&b, 1, &b); mp_reduce_2k_l(&b, &a, &d); mp_sqr(&c, &c); mp_add_d(&c, 1, &c); mp_mod(&c, &a, &c); if (mp_cmp(&b, &c) != MP_EQ) { printf("mp_reduce_2k_l() failed at step %lu\n", cnt); mp_tohex(&b, buf); printf("b == %s\n", buf); mp_tohex(&c, buf); printf("c == %s\n", buf); return EXIT_FAILURE; } } printf("...Passed\n"); #endif div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n = sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n = sub_d_n = 0; /* force KARA and TOOM to enable despite cutoffs */ KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 8; TOOM_SQR_CUTOFF = TOOM_MUL_CUTOFF = 16; for (;;) { /* randomly clear and re-init one variable, this has the affect of triming the alloc space */ switch (abs(rand()) % 7) { case 0: mp_clear(&a); mp_init(&a); break; case 1: mp_clear(&b); mp_init(&b); break; case 2: mp_clear(&c); mp_init(&c); break; case 3: mp_clear(&d); mp_init(&d); break; case 4: mp_clear(&e); mp_init(&e); break; case 5: mp_clear(&f); mp_init(&f); break; case 6: break; /* don't clear any */ } printf ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ", add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n); fgets(cmd, 4095, stdin); cmd[strlen(cmd) - 1] = 0; printf("%s ]\r", cmd); fflush(stdout); if (!strcmp(cmd, "mul2d")) { ++mul2d_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); sscanf(buf, "%d", &rr); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); mp_mul_2d(&a, rr, &a); a.sign = b.sign; if (mp_cmp(&a, &b) != MP_EQ) { printf("mul2d failed, rr == %d\n", rr); draw(&a); draw(&b); return 0; } } else if (!strcmp(cmd, "div2d")) { ++div2d_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); sscanf(buf, "%d", &rr); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); mp_div_2d(&a, rr, &a, &e); a.sign = b.sign; if (a.used == b.used && a.used == 0) { a.sign = b.sign = MP_ZPOS; } if (mp_cmp(&a, &b) != MP_EQ) { printf("div2d failed, rr == %d\n", rr); draw(&a); draw(&b); return 0; } } else if (!strcmp(cmd, "add")) { ++add_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&c, buf, 64); mp_copy(&a, &d); mp_add(&d, &b, &d); if (mp_cmp(&c, &d) != MP_EQ) { printf("add %lu failure!\n", add_n); draw(&a); draw(&b); draw(&c); draw(&d); return 0; } /* test the sign/unsigned storage functions */ rr = mp_signed_bin_size(&c); mp_to_signed_bin(&c, (unsigned char *) cmd); memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); mp_read_signed_bin(&d, (unsigned char *) cmd, rr); if (mp_cmp(&c, &d) != MP_EQ) { printf("mp_signed_bin failure!\n"); draw(&c); draw(&d); return 0; } rr = mp_unsigned_bin_size(&c); mp_to_unsigned_bin(&c, (unsigned char *) cmd); memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); mp_read_unsigned_bin(&d, (unsigned char *) cmd, rr); if (mp_cmp_mag(&c, &d) != MP_EQ) { printf("mp_unsigned_bin failure!\n"); draw(&c); draw(&d); return 0; } } else if (!strcmp(cmd, "sub")) { ++sub_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&c, buf, 64); mp_copy(&a, &d); mp_sub(&d, &b, &d); if (mp_cmp(&c, &d) != MP_EQ) { printf("sub %lu failure!\n", sub_n); draw(&a); draw(&b); draw(&c); draw(&d); return 0; } } else if (!strcmp(cmd, "mul")) { ++mul_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&c, buf, 64); mp_copy(&a, &d); mp_mul(&d, &b, &d); if (mp_cmp(&c, &d) != MP_EQ) { printf("mul %lu failure!\n", mul_n); draw(&a); draw(&b); draw(&c); draw(&d); return 0; } } else if (!strcmp(cmd, "div")) { ++div_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&c, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&d, buf, 64); mp_div(&a, &b, &e, &f); if (mp_cmp(&c, &e) != MP_EQ || mp_cmp(&d, &f) != MP_EQ) { printf("div %lu %d, %d, failure!\n", div_n, mp_cmp(&c, &e), mp_cmp(&d, &f)); draw(&a); draw(&b); draw(&c); draw(&d); draw(&e); draw(&f); return 0; } } else if (!strcmp(cmd, "sqr")) { ++sqr_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); mp_copy(&a, &c); mp_sqr(&c, &c); if (mp_cmp(&b, &c) != MP_EQ) { printf("sqr %lu failure!\n", sqr_n); draw(&a); draw(&b); draw(&c); return 0; } } else if (!strcmp(cmd, "gcd")) { ++gcd_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&c, buf, 64); mp_copy(&a, &d); mp_gcd(&d, &b, &d); d.sign = c.sign; if (mp_cmp(&c, &d) != MP_EQ) { printf("gcd %lu failure!\n", gcd_n); draw(&a); draw(&b); draw(&c); draw(&d); return 0; } } else if (!strcmp(cmd, "lcm")) { ++lcm_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&c, buf, 64); mp_copy(&a, &d); mp_lcm(&d, &b, &d); d.sign = c.sign; if (mp_cmp(&c, &d) != MP_EQ) { printf("lcm %lu failure!\n", lcm_n); draw(&a); draw(&b); draw(&c); draw(&d); return 0; } } else if (!strcmp(cmd, "expt")) { ++expt_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&c, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&d, buf, 64); mp_copy(&a, &e); mp_exptmod(&e, &b, &c, &e); if (mp_cmp(&d, &e) != MP_EQ) { printf("expt %lu failure!\n", expt_n); draw(&a); draw(&b); draw(&c); draw(&d); draw(&e); return 0; } } else if (!strcmp(cmd, "invmod")) { ++inv_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&c, buf, 64); mp_invmod(&a, &b, &d); mp_mulmod(&d, &a, &b, &e); if (mp_cmp_d(&e, 1) != MP_EQ) { printf("inv [wrong value from MPI?!] failure\n"); draw(&a); draw(&b); draw(&c); draw(&d); mp_gcd(&a, &b, &e); draw(&e); return 0; } } else if (!strcmp(cmd, "div2")) { ++div2_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); mp_div_2(&a, &c); if (mp_cmp(&c, &b) != MP_EQ) { printf("div_2 %lu failure\n", div2_n); draw(&a); draw(&b); draw(&c); return 0; } } else if (!strcmp(cmd, "mul2")) { ++mul2_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); mp_mul_2(&a, &c); if (mp_cmp(&c, &b) != MP_EQ) { printf("mul_2 %lu failure\n", mul2_n); draw(&a); draw(&b); draw(&c); return 0; } } else if (!strcmp(cmd, "add_d")) { ++add_d_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); sscanf(buf, "%d", &ix); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); mp_add_d(&a, ix, &c); if (mp_cmp(&b, &c) != MP_EQ) { printf("add_d %lu failure\n", add_d_n); draw(&a); draw(&b); draw(&c); printf("d == %d\n", ix); return 0; } } else if (!strcmp(cmd, "sub_d")) { ++sub_d_n; fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64); fgets(buf, 4095, stdin); sscanf(buf, "%d", &ix); fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64); mp_sub_d(&a, ix, &c); if (mp_cmp(&b, &c) != MP_EQ) { printf("sub_d %lu failure\n", sub_d_n); draw(&a); draw(&b); draw(&c); printf("d == %d\n", ix); return 0; } } } return 0; }
int main(void) { char buf[2000]; int x, y; mp_int q, p; FILE *out; clock_t t1; mp_digit z; mp_init_multi(&q, &p, NULL); out = fopen("2kprime.1", "w"); for (x = 0; x < (int)(sizeof(sizes) / sizeof(sizes[0])); x++) { top: mp_2expt(&q, sizes[x]); mp_add_d(&q, 3, &q); z = -3; t1 = clock(); for(;;) { mp_sub_d(&q, 4, &q); z += 4; if (z > MP_MASK) { printf("No primes of size %d found\n", sizes[x]); break; } if (clock() - t1 > CLOCKS_PER_SEC) { printf("."); fflush(stdout); // sleep((clock() - t1 + CLOCKS_PER_SEC/2)/CLOCKS_PER_SEC); t1 = clock(); } /* quick test on q */ mp_prime_is_prime(&q, 1, &y); if (y == 0) { continue; } /* find (q-1)/2 */ mp_sub_d(&q, 1, &p); mp_div_2(&p, &p); mp_prime_is_prime(&p, 3, &y); if (y == 0) { continue; } /* test on q */ mp_prime_is_prime(&q, 3, &y); if (y == 0) { continue; } break; } if (y == 0) { ++sizes[x]; goto top; } mp_toradix(&q, buf, 10); printf("\n\n%d-bits (k = %lu) = %s\n", sizes[x], z, buf); fprintf(out, "%d-bits (k = %lu) = %s\n", sizes[x], z, buf); fflush(out); } return 0; }
/* Performs basic tests of elliptic curve cryptography over prime fields. * If tests fail, then it prints an error message, aborts, and returns an * error code. Otherwise, returns 0. */ int ectest_curve_GFp(ECGroup *group, int ectestPrint, int ectestTime, int generic) { mp_int one, order_1, gx, gy, rx, ry, n; int size; mp_err res; char s[1000]; /* initialize values */ MP_CHECKOK(mp_init(&one)); MP_CHECKOK(mp_init(&order_1)); MP_CHECKOK(mp_init(&gx)); MP_CHECKOK(mp_init(&gy)); MP_CHECKOK(mp_init(&rx)); MP_CHECKOK(mp_init(&ry)); MP_CHECKOK(mp_init(&n)); MP_CHECKOK(mp_set_int(&one, 1)); MP_CHECKOK(mp_sub(&group->order, &one, &order_1)); /* encode base point */ if (group->meth->field_dec) { MP_CHECKOK(group->meth->field_dec(&group->genx, &gx, group->meth)); MP_CHECKOK(group->meth->field_dec(&group->geny, &gy, group->meth)); } else { MP_CHECKOK(mp_copy(&group->genx, &gx)); MP_CHECKOK(mp_copy(&group->geny, &gy)); } if (ectestPrint) { /* output base point */ printf(" base point P:\n"); MP_CHECKOK(mp_toradix(&gx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&gy, s, 16)); printf(" %s\n", s); if (group->meth->field_enc) { printf(" base point P (encoded):\n"); MP_CHECKOK(mp_toradix(&group->genx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&group->geny, s, 16)); printf(" %s\n", s); } } #ifdef ECL_ENABLE_GFP_PT_MUL_AFF /* multiply base point by order - 1 and check for negative of base * point */ MP_CHECKOK(ec_GFp_pt_mul_aff(&order_1, &group->genx, &group->geny, &rx, &ry, group)); if (ectestPrint) { printf(" (order-1)*P (affine):\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf(" %s\n", s); } MP_CHECKOK(group->meth->field_neg(&ry, &ry, group->meth)); if ((mp_cmp(&rx, &group->genx) != 0) || (mp_cmp(&ry, &group->geny) != 0)) { printf(" Error: invalid result (expected (- base point)).\n"); res = MP_NO; goto CLEANUP; } #endif #ifdef ECL_ENABLE_GFP_PT_MUL_AFF /* multiply base point by order - 1 and check for negative of base * point */ MP_CHECKOK(ec_GFp_pt_mul_jac(&order_1, &group->genx, &group->geny, &rx, &ry, group)); if (ectestPrint) { printf(" (order-1)*P (jacobian):\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf(" %s\n", s); } MP_CHECKOK(group->meth->field_neg(&ry, &ry, group->meth)); if ((mp_cmp(&rx, &group->genx) != 0) || (mp_cmp(&ry, &group->geny) != 0)) { printf(" Error: invalid result (expected (- base point)).\n"); res = MP_NO; goto CLEANUP; } #endif /* multiply base point by order - 1 and check for negative of base * point */ MP_CHECKOK(ECPoint_mul(group, &order_1, NULL, NULL, &rx, &ry)); if (ectestPrint) { printf(" (order-1)*P (ECPoint_mul):\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf(" %s\n", s); } MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry)); if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { printf(" Error: invalid result (expected (- base point)).\n"); res = MP_NO; goto CLEANUP; } /* multiply base point by order - 1 and check for negative of base * point */ MP_CHECKOK(ECPoint_mul(group, &order_1, &gx, &gy, &rx, &ry)); if (ectestPrint) { printf(" (order-1)*P (ECPoint_mul):\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf(" %s\n", s); } MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry)); if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { printf(" Error: invalid result (expected (- base point)).\n"); res = MP_NO; goto CLEANUP; } #ifdef ECL_ENABLE_GFP_PT_MUL_AFF /* multiply base point by order and check for point at infinity */ MP_CHECKOK(ec_GFp_pt_mul_aff(&group->order, &group->genx, &group->geny, &rx, &ry, group)); if (ectestPrint) { printf(" (order)*P (affine):\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf(" %s\n", s); } if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { printf(" Error: invalid result (expected point at infinity).\n"); res = MP_NO; goto CLEANUP; } #endif #ifdef ECL_ENABLE_GFP_PT_MUL_JAC /* multiply base point by order and check for point at infinity */ MP_CHECKOK(ec_GFp_pt_mul_jac(&group->order, &group->genx, &group->geny, &rx, &ry, group)); if (ectestPrint) { printf(" (order)*P (jacobian):\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf(" %s\n", s); } if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { printf(" Error: invalid result (expected point at infinity).\n"); res = MP_NO; goto CLEANUP; } #endif /* multiply base point by order and check for point at infinity */ MP_CHECKOK(ECPoint_mul(group, &group->order, NULL, NULL, &rx, &ry)); if (ectestPrint) { printf(" (order)*P (ECPoint_mul):\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf(" %s\n", s); } if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { printf(" Error: invalid result (expected point at infinity).\n"); res = MP_NO; goto CLEANUP; } /* multiply base point by order and check for point at infinity */ MP_CHECKOK(ECPoint_mul(group, &group->order, &gx, &gy, &rx, &ry)); if (ectestPrint) { printf(" (order)*P (ECPoint_mul):\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf(" %s\n", s); } if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { printf(" Error: invalid result (expected point at infinity).\n"); res = MP_NO; goto CLEANUP; } /* check that (order-1)P + (order-1)P + P == (order-1)P */ MP_CHECKOK(ECPoints_mul(group, &order_1, &order_1, &gx, &gy, &rx, &ry)); MP_CHECKOK(ECPoints_mul(group, &one, &one, &rx, &ry, &rx, &ry)); if (ectestPrint) { printf(" (order-1)*P + (order-1)*P + P == (order-1)*P (ECPoints_mul):\n"); MP_CHECKOK(mp_toradix(&rx, s, 16)); printf(" %s\n", s); MP_CHECKOK(mp_toradix(&ry, s, 16)); printf(" %s\n", s); } MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry)); if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { printf(" Error: invalid result (expected (- base point)).\n"); res = MP_NO; goto CLEANUP; } /* test validate_point function */ if (ECPoint_validate(group, &gx, &gy) != MP_YES) { printf(" Error: validate point on base point failed.\n"); res = MP_NO; goto CLEANUP; } MP_CHECKOK(mp_add_d(&gy, 1, &ry)); if (ECPoint_validate(group, &gx, &ry) != MP_NO) { printf(" Error: validate point on invalid point passed.\n"); res = MP_NO; goto CLEANUP; } if (ectestTime) { /* compute random scalar */ size = mpl_significant_bits(&group->meth->irr); if (size < MP_OKAY) { goto CLEANUP; } MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS)); MP_CHECKOK(group->meth->field_mod(&n, &n, group->meth)); /* timed test */ if (generic) { #ifdef ECL_ENABLE_GFP_PT_MUL_AFF M_TimeOperation(MP_CHECKOK(ec_GFp_pt_mul_aff(&n, &group->genx, &group->geny, &rx, &ry, group)), 100); #endif M_TimeOperation(MP_CHECKOK(ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)), 100); M_TimeOperation(MP_CHECKOK(ECPoints_mul(group, &n, &n, &gx, &gy, &rx, &ry)), 100); } else { M_TimeOperation(MP_CHECKOK(ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)), 100); M_TimeOperation(MP_CHECKOK(ECPoint_mul(group, &n, &gx, &gy, &rx, &ry)), 100); M_TimeOperation(MP_CHECKOK(ECPoints_mul(group, &n, &n, &gx, &gy, &rx, &ry)), 100); } } CLEANUP: mp_clear(&one); mp_clear(&order_1); mp_clear(&gx); mp_clear(&gy); mp_clear(&rx); mp_clear(&ry); mp_clear(&n); if (res != MP_OKAY) { printf(" Error: exiting with error value %i\n", res); } return res; }