X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fec%2Fectest.c;h=67dfdaa191299c1f28ae11d2b33d5b31e99fee6c;hp=9b32f55be80856b96d4dc5ae1ea0278a4bc6737b;hb=8c7096835b48d773463cee4fe97fbc334e911cc9;hpb=652ae06badda3a8964f650ce1713e335257548d9 diff --git a/crypto/ec/ectest.c b/crypto/ec/ectest.c index 9b32f55be8..67dfdaa191 100644 --- a/crypto/ec/ectest.c +++ b/crypto/ec/ectest.c @@ -92,6 +92,13 @@ int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); retur #include #include #include +#include +#include + +#if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12) +/* suppress "too big too optimize" warning */ +#pragma warning(disable:4959) +#endif #define ABORT do { \ fflush(stdout); \ @@ -100,10 +107,6 @@ int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); retur EXIT(1); \ } while (0) -void prime_field_tests(void); -void char2_field_tests(void); -void internal_curve_test(void); - #define TIMING_BASE_PT 0 #define TIMING_RAND_PT 1 #define TIMING_SIMUL 2 @@ -188,7 +191,50 @@ static void timings(EC_GROUP *group, int type, BN_CTX *ctx) } #endif -void prime_field_tests() +/* test multiplication with group order, long and negative scalars */ +static void group_order_tests(EC_GROUP *group) + { + BIGNUM *n1, *n2, *order; + EC_POINT *P = EC_POINT_new(group); + EC_POINT *Q = EC_POINT_new(group); + BN_CTX *ctx = BN_CTX_new(); + + n1 = BN_new(); n2 = BN_new(); order = BN_new(); + fprintf(stdout, "verify group order ..."); + fflush(stdout); + if (!EC_GROUP_get_order(group, order, ctx)) ABORT; + if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) ABORT; + fprintf(stdout, "."); + fflush(stdout); + if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; + if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) ABORT; + fprintf(stdout, " ok\n"); + fprintf(stdout, "long/negative scalar tests ... "); + if (!BN_one(n1)) ABORT; + /* n1 = 1 - order */ + if (!BN_sub(n1, n1, order)) ABORT; + if(!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT; + /* n2 = 1 + order */ + if (!BN_add(n2, order, BN_value_one())) ABORT; + if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT; + /* n2 = (1 - order) * (1 + order) */ + if (!BN_mul(n2, n1, n2, ctx)) ABORT; + if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT; + fprintf(stdout, "ok\n"); + EC_POINT_free(P); + EC_POINT_free(Q); + BN_free(n1); + BN_free(n2); + BN_free(order); + BN_CTX_free(ctx); + } + +static void prime_field_tests(void) { BN_CTX *ctx = NULL; BIGNUM *p, *a, *b; @@ -224,7 +270,7 @@ void prime_field_tests() EC_GROUP *tmp; tmp = EC_GROUP_new(EC_GROUP_method_of(group)); if (!tmp) ABORT; - if (!EC_GROUP_copy(tmp, group)); + if (!EC_GROUP_copy(tmp, group)) ABORT; EC_GROUP_free(group); group = tmp; } @@ -314,21 +360,21 @@ void prime_field_tests() if (len == 0) ABORT; if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT; if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT; - fprintf(stdout, "Generator as octect string, compressed form:\n "); + fprintf(stdout, "Generator as octet string, compressed form:\n "); for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx); if (len == 0) ABORT; if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT; if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT; - fprintf(stdout, "\nGenerator as octect string, uncompressed form:\n "); + fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx); if (len == 0) ABORT; if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT; if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT; - fprintf(stdout, "\nGenerator as octect string, hybrid form:\n "); + fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT; @@ -374,17 +420,7 @@ void prime_field_tests() if (EC_GROUP_get_degree(group) != 160) ABORT; fprintf(stdout, " ok\n"); - fprintf(stdout, "verify group order ..."); - fflush(stdout); - if (!EC_GROUP_get_order(group, z, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, "."); - fflush(stdout); - if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, " ok\n"); + group_order_tests(group); if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; if (!EC_GROUP_copy(P_160, group)) ABORT; @@ -418,17 +454,7 @@ void prime_field_tests() if (EC_GROUP_get_degree(group) != 192) ABORT; fprintf(stdout, " ok\n"); - fprintf(stdout, "verify group order ..."); - fflush(stdout); - if (!EC_GROUP_get_order(group, z, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, "."); - fflush(stdout); - if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, " ok\n"); + group_order_tests(group); if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; if (!EC_GROUP_copy(P_192, group)) ABORT; @@ -462,17 +488,7 @@ void prime_field_tests() if (EC_GROUP_get_degree(group) != 224) ABORT; fprintf(stdout, " ok\n"); - fprintf(stdout, "verify group order ..."); - fflush(stdout); - if (!EC_GROUP_get_order(group, z, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, "."); - fflush(stdout); - if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, " ok\n"); + group_order_tests(group); if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; if (!EC_GROUP_copy(P_224, group)) ABORT; @@ -507,17 +523,7 @@ void prime_field_tests() if (EC_GROUP_get_degree(group) != 256) ABORT; fprintf(stdout, " ok\n"); - fprintf(stdout, "verify group order ..."); - fflush(stdout); - if (!EC_GROUP_get_order(group, z, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, "."); - fflush(stdout); - if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, " ok\n"); + group_order_tests(group); if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; if (!EC_GROUP_copy(P_256, group)) ABORT; @@ -556,18 +562,8 @@ void prime_field_tests() fprintf(stdout, "verify degree ..."); if (EC_GROUP_get_degree(group) != 384) ABORT; fprintf(stdout, " ok\n"); - - fprintf(stdout, "verify group order ..."); - fflush(stdout); - if (!EC_GROUP_get_order(group, z, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, "."); - fflush(stdout); - if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, " ok\n"); + + group_order_tests(group); if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; if (!EC_GROUP_copy(P_384, group)) ABORT; @@ -612,18 +608,8 @@ void prime_field_tests() fprintf(stdout, "verify degree ..."); if (EC_GROUP_get_degree(group) != 521) ABORT; fprintf(stdout, " ok\n"); - - fprintf(stdout, "verify group order ..."); - fflush(stdout); - if (!EC_GROUP_get_order(group, z, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, "."); - fflush(stdout); - if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; - fprintf(stdout, " ok\n"); + + group_order_tests(group); if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; if (!EC_GROUP_copy(P_521, group)) ABORT; @@ -642,14 +628,17 @@ void prime_field_tests() if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */ { - const EC_POINT *points[3]; - const BIGNUM *scalars[3]; + const EC_POINT *points[4]; + const BIGNUM *scalars[4]; + BIGNUM scalar3; if (EC_POINT_is_at_infinity(group, Q)) ABORT; points[0] = Q; points[1] = Q; points[2] = Q; + points[3] = Q; + if (!EC_GROUP_get_order(group, z, ctx)) ABORT; if (!BN_add(y, z, BN_value_one())) ABORT; if (BN_is_odd(y)) ABORT; if (!BN_rshift1(y, y)) ABORT; @@ -670,7 +659,7 @@ void prime_field_tests() if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT; if (!BN_add(z, z, y)) ABORT; - BN_set_sign(z, 1); + BN_set_negative(z, 1); scalars[0] = y; scalars[1] = z; /* z = -(order + y) */ @@ -682,15 +671,21 @@ void prime_field_tests() if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT; if (!BN_add(z, x, y)) ABORT; - BN_set_sign(z, 1); + BN_set_negative(z, 1); scalars[0] = x; scalars[1] = y; scalars[2] = z; /* z = -(x+y) */ - if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT; + BN_init(&scalar3); + BN_zero(&scalar3); + scalars[3] = &scalar3; + + if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) ABORT; if (!EC_POINT_is_at_infinity(group, P)) ABORT; fprintf(stdout, " ok\n\n"); + + BN_free(&scalar3); } @@ -777,22 +772,14 @@ void prime_field_tests() fprintf(stdout, "verify degree ..."); \ if (EC_GROUP_get_degree(group) != _degree) ABORT; \ fprintf(stdout, " ok\n"); \ - fprintf(stdout, "verify group order ..."); \ - fflush(stdout); \ - if (!EC_GROUP_get_order(group, z, ctx)) ABORT; \ - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \ - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \ - fprintf(stdout, "."); \ - fflush(stdout); \ - if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; \ - if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \ - if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \ - fprintf(stdout, " ok\n"); \ + group_order_tests(group); \ if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \ - if (!EC_GROUP_copy(_variable, group)) ABORT; + if (!EC_GROUP_copy(_variable, group)) ABORT; \ -void char2_field_tests() - { +#ifndef OPENSSL_NO_EC2M + +static void char2_field_tests(void) + { BN_CTX *ctx = NULL; BIGNUM *p, *a, *b; EC_GROUP *group; @@ -827,7 +814,7 @@ void char2_field_tests() EC_GROUP *tmp; tmp = EC_GROUP_new(EC_GROUP_method_of(group)); if (!tmp) ABORT; - if (!EC_GROUP_copy(tmp, group)); + if (!EC_GROUP_copy(tmp, group)) ABORT; EC_GROUP_free(group); group = tmp; } @@ -1145,7 +1132,7 @@ void char2_field_tests() if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT; if (!BN_add(z, z, y)) ABORT; - BN_set_sign(z, 1); + BN_set_negative(z, 1); scalars[0] = y; scalars[1] = z; /* z = -(order + y) */ @@ -1157,7 +1144,7 @@ void char2_field_tests() if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT; if (!BN_add(z, x, y)) ABORT; - BN_set_sign(z, 1); + BN_set_negative(z, 1); scalars[0] = x; scalars[1] = y; scalars[2] = z; /* z = -(x+y) */ @@ -1224,8 +1211,9 @@ void char2_field_tests() if (C2_B571) EC_GROUP_free(C2_B571); } +#endif -void internal_curve_test(void) +static void internal_curve_test(void) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; @@ -1250,10 +1238,10 @@ void internal_curve_test(void) { EC_GROUP *group = NULL; int nid = curves[n].nid; - if ((group = EC_GROUP_new_by_nid(nid)) == NULL) + if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) { ok = 0; - fprintf(stdout, "\nEC_GROUP_new_by_nid() failed with" + fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with" " curve %s\n", OBJ_nid2sn(nid)); /* try next curve */ continue; @@ -1272,13 +1260,116 @@ void internal_curve_test(void) EC_GROUP_free(group); } if (ok) - fprintf(stdout, " ok\n"); + fprintf(stdout, " ok\n\n"); else - fprintf(stdout, " failed\n"); + fprintf(stdout, " failed\n\n"); OPENSSL_free(curves); return; } +#ifdef EC_NISTP224_64_GCC_128 +void nistp224_test() + { + fprintf(stdout, "\nNIST curve P-224 (optimised implementation):\n"); + BIGNUM *p, *a, *b, *x, *y, *n, *m, *order; + p = BN_new(); + a = BN_new(); + b = BN_new(); + x = BN_new(); y = BN_new(); + m = BN_new(); n = BN_new(); order = BN_new(); + BN_CTX *ctx = BN_CTX_new(); + EC_GROUP *NISTP224; + EC_POINT *G, *P, *Q, *Q_CHECK; + + NISTP224 = EC_GROUP_new(EC_GFp_nistp224_method()); + if(!NISTP224) ABORT; + if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT; + if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT; + if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT; + if (!EC_GROUP_set_curve_GFp(NISTP224, p, a, b, ctx)) ABORT; + G = EC_POINT_new(NISTP224); + P = EC_POINT_new(NISTP224); + Q = EC_POINT_new(NISTP224); + Q_CHECK = EC_POINT_new(NISTP224); + if(!BN_hex2bn(&x, "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E")) ABORT; + if(!BN_hex2bn(&y, "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555")) ABORT; + if(!EC_POINT_set_affine_coordinates_GFp(NISTP224, Q_CHECK, x, y, ctx)) ABORT; + if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT; + if (!BN_hex2bn(&y, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT; + if (!EC_POINT_set_affine_coordinates_GFp(NISTP224, G, x, y, ctx)) ABORT; + if (!BN_hex2bn(&order, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT; + if (!EC_GROUP_set_generator(NISTP224, G, order, BN_value_one())) ABORT; + + fprintf(stdout, "verify degree ... "); + if (EC_GROUP_get_degree(NISTP224) != 224) ABORT; + fprintf(stdout, "ok\n"); + + fprintf(stdout, "NIST test vectors ... "); + if (!BN_hex2bn(&n, "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8")) ABORT; + /* fixed point multiplication */ + EC_POINT_mul(NISTP224, Q, n, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP224, Q, NULL, G, n, ctx); + if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; + + /* set generator to P = 2*G, where G is the standard generator */ + if (!EC_POINT_dbl(NISTP224, P, G, ctx)) ABORT; + if (!EC_GROUP_set_generator(NISTP224, P, order, BN_value_one())) ABORT; + /* set the scalar to m=n/2, where n is the NIST test scalar */ + if (!BN_rshift(m, n, 1)) ABORT; + + /* test the non-standard generator */ + /* fixed point multiplication */ + EC_POINT_mul(NISTP224, Q, m, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP224, Q, NULL, P, m, ctx); + if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; + + /* now repeat all tests with precomputation */ + if (!EC_GROUP_precompute_mult(NISTP224, ctx)) ABORT; + + /* fixed point multiplication */ + EC_POINT_mul(NISTP224, Q, m, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP224, Q, NULL, P, m, ctx); + if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; + + /* reset generator */ + if (!EC_GROUP_set_generator(NISTP224, G, order, BN_value_one())) ABORT; + /* fixed point multiplication */ + EC_POINT_mul(NISTP224, Q, n, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP224, Q, NULL, G, n, ctx); + if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; + + fprintf(stdout, "ok\n"); + group_order_tests(NISTP224); +#if 0 + timings(NISTP224, TIMING_BASE_PT, ctx); + timings(NISTP224, TIMING_RAND_PT, ctx); +#endif + EC_GROUP_free(NISTP224); + EC_POINT_free(G); + EC_POINT_free(P); + EC_POINT_free(Q); + EC_POINT_free(Q_CHECK); + BN_free(n); + BN_free(m); + BN_free(p); + BN_free(a); + BN_free(b); + BN_free(x); + BN_free(y); + BN_free(order); + BN_CTX_free(ctx); + } +#endif + static const char rnd_seed[] = "string to make the random number generator think it has entropy"; int main(int argc, char *argv[]) @@ -1302,7 +1393,12 @@ int main(int argc, char *argv[]) prime_field_tests(); puts(""); +#ifndef OPENSSL_NO_EC2M char2_field_tests(); +#endif +#ifdef EC_NISTP224_64_GCC_128 + nistp224_test(); +#endif /* test the internal curves */ internal_curve_test(); @@ -1311,7 +1407,7 @@ int main(int argc, char *argv[]) #endif CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); - ERR_remove_state(0); + ERR_remove_thread_state(NULL); CRYPTO_mem_leaks_fp(stderr); return 0;