int main(int argc, char *argv[]) { int ntests, prec, ix; unsigned int seed; char *senv; clock_t start, stop; double multime; mp_int a, b, c; if((senv = getenv("SEED")) != NULL) seed = atoi(senv); else 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(&b, prec); mp_init_size(&c, 2 * prec); srand(seed); start = clock(); for(ix = 0; ix < ntests; ix++) { mpp_random_size(&a, prec); mpp_random_size(&b, prec); mp_mul(&a, &a, &c); } stop = clock(); multime = (double)(stop - start) / CLOCKS_PER_SEC; printf("Total: %.4f\n", multime); printf("Individual: %.4f\n", multime / ntests); mp_clear(&a); mp_clear(&b); mp_clear(&c); return 0; }
/* Tests the time required for a point multiplication */ mp_err testPointMulTime(ECGroup *ecgroup) { mp_err res = MP_OKAY; mp_int rx, ry, n; int size; MP_DIGITS(&rx) = 0; MP_DIGITS(&ry) = 0; MP_DIGITS(&n) = 0; MP_CHECKOK(mp_init(&rx)); MP_CHECKOK(mp_init(&ry)); MP_CHECKOK(mp_init(&n)); /* compute random scalar */ size = mpl_significant_bits(&ecgroup->meth->irr); if (size < MP_OKAY) { res = MP_NO; goto CLEANUP; } MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS)); MP_CHECKOK(ecgroup->meth->field_mod(&n, &n, ecgroup->meth)); M_TimeOperation(ec_GFp_pt_mul_jac_fp (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup), 1000); M_TimeOperation(ec_GFp_point_mul_jac_4w_fp (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup), 1000); M_TimeOperation(ec_GFp_point_mul_wNAF_fp (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup), 1000); M_TimeOperation(ec_GFp_pt_mul_jac (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup), 100); CLEANUP: if (res == MP_OKAY) printf(" Test Passed - Point Multiplication Timing\n"); else printf("TEST FAILED - Point Multiplication Timing\n"); mp_clear(&rx); mp_clear(&ry); mp_clear(&n); return res; }
/* Tests point multiplication with a random scalar repeatedly, comparing * for consistency within different algorithms. */ mp_err testPointMulRandom(ECGroup *ecgroup) { mp_err res; mp_int rx, ry, rx2, ry2, n; int i, size; EC_group_fp *group = (EC_group_fp *) ecgroup->extra1; MP_DIGITS(&rx) = 0; MP_DIGITS(&ry) = 0; MP_DIGITS(&rx2) = 0; MP_DIGITS(&ry2) = 0; MP_DIGITS(&n) = 0; MP_CHECKOK(mp_init(&rx)); MP_CHECKOK(mp_init(&ry)); MP_CHECKOK(mp_init(&rx2)); MP_CHECKOK(mp_init(&ry2)); MP_CHECKOK(mp_init(&n)); for (i = 0; i < 100; i++) { /* compute random scalar */ size = mpl_significant_bits(&ecgroup->meth->irr); if (size < MP_OKAY) { res = MP_NO; goto CLEANUP; } MP_CHECKOK(mpp_random_size(&n, group->orderBitSize)); MP_CHECKOK(mp_mod(&n, &ecgroup->order, &n)); ec_GFp_pt_mul_jac(&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup); ec_GFp_pt_mul_jac_fp(&n, &ecgroup->genx, &ecgroup->geny, &rx2, &ry2, ecgroup); if ((mp_cmp(&rx, &rx2) != 0) || (mp_cmp(&ry, &ry2) != 0)) { printf (" Error: different results for Point Multiplication - Double & Add.\n"); res = MP_NO; goto CLEANUP; } ec_GFp_point_mul_wNAF_fp(&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup); if ((mp_cmp(&rx, &rx2) != 0) || (mp_cmp(&ry, &ry2) != 0)) { printf (" Error: different results for Point Multiplication - wNAF.\n"); res = MP_NO; goto CLEANUP; } ec_GFp_point_mul_jac_4w_fp(&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry, ecgroup); if ((mp_cmp(&rx, &rx2) != 0) || (mp_cmp(&ry, &ry2) != 0)) { printf (" Error: different results for Point Multiplication - 4 bit window.\n"); res = MP_NO; goto CLEANUP; } } CLEANUP: if (res == MP_OKAY) printf(" Test Passed - Point Random Multiplication\n"); else printf("TEST FAILED - Point Random Multiplication\n"); mp_clear(&rx); mp_clear(&ry); mp_clear(&rx2); mp_clear(&ry2); mp_clear(&n); return res; }
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; } } 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; }
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; }
/* 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; }
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; }