2 * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
5 * Licensed under the OpenSSL license (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
11 #include "internal/nelem.h"
15 # include <openssl/ec.h>
16 # ifndef OPENSSL_NO_ENGINE
17 # include <openssl/engine.h>
19 # include <openssl/err.h>
20 # include <openssl/obj_mac.h>
21 # include <openssl/objects.h>
22 # include <openssl/rand.h>
23 # include <openssl/bn.h>
24 # include <openssl/opensslconf.h>
26 static size_t crv_len = 0;
27 static EC_builtin_curve *curves = NULL;
29 /* test multiplication with group order, long and negative scalars */
30 static int group_order_tests(EC_GROUP *group)
32 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
33 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
37 if (!TEST_ptr(n1 = BN_new())
38 || !TEST_ptr(n2 = BN_new())
39 || !TEST_ptr(order = BN_new())
40 || !TEST_ptr(ctx = BN_CTX_new())
41 || !TEST_ptr(P = EC_POINT_new(group))
42 || !TEST_ptr(Q = EC_POINT_new(group))
43 || !TEST_ptr(R = EC_POINT_new(group))
44 || !TEST_ptr(S = EC_POINT_new(group)))
47 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
48 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
49 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
50 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
51 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
52 || !TEST_true(EC_POINT_is_at_infinity(group, Q)))
55 for (i = 1; i <= 2; i++) {
56 const BIGNUM *scalars[6];
57 const EC_POINT *points[6];
59 if (!TEST_true(BN_set_word(n1, i))
61 * If i == 1, P will be the predefined generator for which
62 * EC_GROUP_precompute_mult has set up precomputation.
64 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
65 || !TEST_true(BN_one(n1))
67 || !TEST_true(BN_sub(n1, n1, order))
68 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
69 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
72 || !TEST_true(BN_add(n2, order, BN_value_one()))
73 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
74 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
76 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
77 || !TEST_true(BN_mul(n2, n1, n2, ctx))
78 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
79 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
82 /* n2 = order^2 - 1 */
83 BN_set_negative(n2, 0);
84 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
85 /* Add P to verify the result. */
86 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
87 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
89 /* Exercise EC_POINTs_mul, including corner cases. */
90 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
93 scalars[0] = scalars[1] = BN_value_one();
94 points[0] = points[1] = P;
96 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
97 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
98 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
102 points[0] = Q; /* => infinity */
104 points[1] = P; /* => -P */
106 points[2] = Q; /* => infinity */
108 points[3] = Q; /* => infinity */
110 points[4] = P; /* => P */
112 points[5] = Q; /* => infinity */
113 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
114 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
120 if (r == 0 && i != 0)
121 TEST_info(i == 1 ? "allowing precomputation" :
122 "without precomputation");
134 static int prime_field_tests(void)
137 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
138 EC_GROUP *group = NULL, *tmp = NULL;
139 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
140 *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
141 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
142 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
143 const EC_POINT *points[4];
144 const BIGNUM *scalars[4];
145 unsigned char buf[100];
149 if (!TEST_ptr(ctx = BN_CTX_new())
150 || !TEST_ptr(p = BN_new())
151 || !TEST_ptr(a = BN_new())
152 || !TEST_ptr(b = BN_new())
153 || !TEST_true(BN_hex2bn(&p, "17"))
154 || !TEST_true(BN_hex2bn(&a, "1"))
155 || !TEST_true(BN_hex2bn(&b, "1"))
157 * applications should use EC_GROUP_new_curve_GFp so
158 * that the library gets to choose the EC_METHOD
160 || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
161 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
162 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
163 || !TEST_true(EC_GROUP_copy(tmp, group)))
165 EC_GROUP_free(group);
169 if (!TEST_true(EC_GROUP_get_curve_GFp(group, p, a, b, ctx)))
172 TEST_info("Curve defined by Weierstrass equation");
173 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
174 test_output_bignum("a", a);
175 test_output_bignum("b", b);
176 test_output_bignum("p", p);
179 if (!TEST_ptr(P = EC_POINT_new(group))
180 || !TEST_ptr(Q = EC_POINT_new(group))
181 || !TEST_ptr(R = EC_POINT_new(group))
182 || !TEST_true(EC_POINT_set_to_infinity(group, P))
183 || !TEST_true(EC_POINT_is_at_infinity(group, P))
184 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
185 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
186 || !TEST_true(EC_POINT_is_at_infinity(group, P))
187 || !TEST_ptr(x = BN_new())
188 || !TEST_ptr(y = BN_new())
189 || !TEST_ptr(z = BN_new())
190 || !TEST_ptr(yplusone = BN_new())
191 || !TEST_true(BN_hex2bn(&x, "D"))
192 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1,
196 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
197 if (!TEST_true(EC_POINT_get_affine_coordinates_GFp(group, Q, x, y,
200 TEST_info("Point is not on curve");
201 test_output_bignum("x", x);
202 test_output_bignum("y", y);
206 TEST_note("A cyclic subgroup:");
209 if (!TEST_int_ne(k--, 0))
212 if (EC_POINT_is_at_infinity(group, P)) {
213 TEST_note(" point at infinity");
215 if (!TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y,
219 test_output_bignum("x", x);
220 test_output_bignum("y", y);
223 if (!TEST_true(EC_POINT_copy(R, P))
224 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
227 } while (!EC_POINT_is_at_infinity(group, P));
229 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
230 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
234 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
236 if (!TEST_size_t_ne(len, 0)
237 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
238 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
240 test_output_memory("Generator as octet string, compressed form:",
243 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
244 buf, sizeof(buf), ctx);
245 if (!TEST_size_t_ne(len, 0)
246 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
247 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
249 test_output_memory("Generator as octet string, uncompressed form:",
252 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
253 buf, sizeof(buf), ctx);
254 if (!TEST_size_t_ne(len, 0)
255 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
256 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
258 test_output_memory("Generator as octet string, hybrid form:",
261 if (!TEST_true(EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z,
264 TEST_info("A representation of the inverse of that generator in");
265 TEST_note("Jacobian projective coordinates");
266 test_output_bignum("x", x);
267 test_output_bignum("y", y);
268 test_output_bignum("z", z);
270 if (!TEST_true(EC_POINT_invert(group, P, ctx))
271 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
274 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
275 * 2000) -- not a NIST curve, but commonly used
278 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
279 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
280 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
281 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
282 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
283 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
284 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
285 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
286 || !TEST_true(BN_hex2bn(&x, "4A96B568"
287 "8EF573284664698968C38BB913CBFC82"))
288 || !TEST_true(BN_hex2bn(&y, "23a62855"
289 "3168947d59dcc912042351377ac5fb32"))
290 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
292 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
293 * and therefore setting the coordinates should fail.
295 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
297 || !TEST_true(EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
298 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
299 || !TEST_true(BN_hex2bn(&z, "0100000000"
300 "000000000001F4C8F927AED3CA752257"))
301 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
302 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
304 TEST_info("SEC2 curve secp160r1 -- Generator");
305 test_output_bignum("x", x);
306 test_output_bignum("y", y);
307 /* G_y value taken from the standard: */
308 if (!TEST_true(BN_hex2bn(&z, "23a62855"
309 "3168947d59dcc912042351377ac5fb32"))
311 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
312 || !group_order_tests(group)
313 || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))
314 || !TEST_true(EC_GROUP_copy(P_160, group))
316 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
318 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
319 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
320 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
321 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
322 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
323 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
324 "0FA7E9AB72243049FEB8DEECC146B9B1"))
325 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
326 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
327 "7CBF20EB43A18800F4FF0AFD82FF1012"))
328 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1,
330 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
331 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
332 "FFFFFFFF99DEF836146BC9B1B4D22831"))
333 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
334 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
337 TEST_info("NIST curve P-192 -- Generator");
338 test_output_bignum("x", x);
339 test_output_bignum("y", y);
340 /* G_y value taken from the standard: */
341 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
342 "631011ED6B24CDD573F977A11E794811"))
344 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
346 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
347 * and therefore setting the coordinates should fail.
349 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
351 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
352 || !group_order_tests(group)
353 || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))
354 || !TEST_true(EC_GROUP_copy(P_192, group))
356 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
358 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
359 "FFFFFFFF000000000000000000000001"))
360 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
361 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
362 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
363 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
364 "5044B0B7D7BFD8BA270B39432355FFB4"))
365 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
366 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
367 "4A03C1D356C21122343280D6115C1D21"))
368 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0,
370 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
371 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
372 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
373 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
374 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
377 TEST_info("NIST curve P-224 -- Generator");
378 test_output_bignum("x", x);
379 test_output_bignum("y", y);
380 /* G_y value taken from the standard: */
381 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
382 "CD4375A05A07476444D5819985007E34"))
384 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
386 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
387 * and therefore setting the coordinates should fail.
389 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
391 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
392 || !group_order_tests(group)
393 || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
394 || !TEST_true(EC_GROUP_copy(P_224, group))
396 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
398 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
399 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
400 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
401 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
402 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
403 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
404 "651D06B0CC53B0F63BCE3C3E27D2604B"))
405 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
407 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
408 "77037D812DEB33A0F4A13945D898C296"))
409 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1,
411 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
412 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
413 "BCE6FAADA7179E84F3B9CAC2FC632551"))
414 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
415 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
418 TEST_info("NIST curve P-256 -- Generator");
419 test_output_bignum("x", x);
420 test_output_bignum("y", y);
421 /* G_y value taken from the standard: */
422 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
423 "2BCE33576B315ECECBB6406837BF51F5"))
425 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
427 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
428 * and therefore setting the coordinates should fail.
430 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
432 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
433 || !group_order_tests(group)
434 || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
435 || !TEST_true(EC_GROUP_copy(P_256, group))
437 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
439 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
440 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
441 "FFFFFFFF0000000000000000FFFFFFFF"))
442 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
443 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
444 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
445 "FFFFFFFF0000000000000000FFFFFFFC"))
446 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
447 "181D9C6EFE8141120314088F5013875A"
448 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
449 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
451 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
452 "6E1D3B628BA79B9859F741E082542A38"
453 "5502F25DBF55296C3A545E3872760AB7"))
454 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1,
456 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
457 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
458 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
459 "581A0DB248B0A77AECEC196ACCC52973"))
460 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
461 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
464 TEST_info("NIST curve P-384 -- Generator");
465 test_output_bignum("x", x);
466 test_output_bignum("y", y);
467 /* G_y value taken from the standard: */
468 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
469 "F8F41DBD289A147CE9DA3113B5F0B8C0"
470 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
472 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
474 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
475 * and therefore setting the coordinates should fail.
477 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
479 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
480 || !group_order_tests(group)
481 || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
482 || !TEST_true(EC_GROUP_copy(P_384, group))
484 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
485 || !TEST_true(BN_hex2bn(&p, "1FF"
486 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
487 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
488 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
489 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
490 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
491 || !TEST_true(BN_hex2bn(&a, "1FF"
492 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
493 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
494 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
495 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
496 || !TEST_true(BN_hex2bn(&b, "051"
497 "953EB9618E1C9A1F929A21A0B68540EE"
498 "A2DA725B99B315F3B8B489918EF109E1"
499 "56193951EC7E937B1652C0BD3BB1BF07"
500 "3573DF883D2C34F1EF451FD46B503F00"))
501 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
502 || !TEST_true(BN_hex2bn(&x, "C6"
503 "858E06B70404E9CD9E3ECB662395B442"
504 "9C648139053FB521F828AF606B4D3DBA"
505 "A14B5E77EFE75928FE1DC127A2FFA8DE"
506 "3348B3C1856A429BF97E7E31C2E5BD66"))
507 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0,
509 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
510 || !TEST_true(BN_hex2bn(&z, "1FF"
511 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
512 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
513 "51868783BF2F966B7FCC0148F709A5D0"
514 "3BB5C9B8899C47AEBB6FB71E91386409"))
515 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
516 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
519 TEST_info("NIST curve P-521 -- Generator");
520 test_output_bignum("x", x);
521 test_output_bignum("y", y);
522 /* G_y value taken from the standard: */
523 if (!TEST_true(BN_hex2bn(&z, "118"
524 "39296A789A3BC0045C8A5FB42C7D1BD9"
525 "98F54449579B446817AFBD17273E662C"
526 "97EE72995EF42640C550B9013FAD0761"
527 "353C7086A272C24088BE94769FD16650"))
529 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
531 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
532 * and therefore setting the coordinates should fail.
534 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
536 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
537 || !group_order_tests(group)
538 || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
539 || !TEST_true(EC_GROUP_copy(P_521, group))
541 /* more tests using the last curve */
543 /* Restore the point that got mangled in the (x, y + 1) test. */
544 || !TEST_true(EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
545 || !TEST_true(EC_POINT_copy(Q, P))
546 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
547 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
548 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
549 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
550 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
551 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
552 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
553 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
560 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
561 || !TEST_true(BN_add(y, z, BN_value_one()))
563 || !TEST_true(BN_rshift1(y, y)))
565 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
568 TEST_note("combined multiplication ...");
570 /* z is still the group order */
571 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
572 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
573 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
574 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
575 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
576 || !TEST_true(BN_add(z, z, y)))
578 BN_set_negative(z, 1);
580 scalars[1] = z; /* z = -(order + y) */
582 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
583 || !TEST_true(EC_POINT_is_at_infinity(group, P))
584 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
585 || !TEST_true(BN_add(z, x, y)))
587 BN_set_negative(z, 1);
590 scalars[2] = z; /* z = -(x+y) */
592 if (!TEST_ptr(scalar3 = BN_new()))
595 scalars[3] = scalar3;
597 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
598 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
610 EC_GROUP_free(group);
621 EC_GROUP_free(P_160);
622 EC_GROUP_free(P_192);
623 EC_GROUP_free(P_224);
624 EC_GROUP_free(P_256);
625 EC_GROUP_free(P_384);
626 EC_GROUP_free(P_521);
630 # ifndef OPENSSL_NO_EC2M
632 static struct c2_curve_test {
643 } char2_curve_tests[] = {
644 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
647 "0800000000000000000000000000000000000000C9",
650 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
651 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
652 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
654 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
657 "0800000000000000000000000000000000000000C9",
659 "020A601907B8C953CA1481EB10512F78744A3205FD",
660 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
661 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
662 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
664 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
667 "020000000000000000000000000000000000000004000000000000000001",
670 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
671 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
673 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
676 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
679 "020000000000000000000000000000000000000004000000000000000001",
680 "000000000000000000000000000000000000000000000000000000000001",
681 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
682 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
683 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
685 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
688 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
692 "00000000000000000000000000000000000000000000000000000000000010A1",
696 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
698 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
701 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
704 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
708 "00000000000000000000000000000000000000000000000000000000000010A1",
710 "0000000000000000000000000000000000000000000000000000000000000001",
712 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
714 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
716 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
719 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
722 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
725 "0200000000000000000000000000000000000000"
726 "0000000000000000000000000000000000000000008000000000000000000001",
729 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
730 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
731 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
732 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
734 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
735 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
738 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
741 "0200000000000000000000000000000000000000"
742 "0000000000000000000000000000000000000000008000000000000000000001",
743 "0000000000000000000000000000000000000000"
744 "0000000000000000000000000000000000000000000000000000000000000001",
745 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
746 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
747 "015D4860D088DDB3496B0C6064756260441CDE4A"
748 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
749 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
750 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
752 "0100000000000000000000000000000000000000"
753 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
756 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
760 "0000000000000000000000000000000000000000000000000000000000000000"
761 "0000000000000000000000000000000000000000000000000000000000000425",
765 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
766 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
768 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
769 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
772 "00000000000000000000000000000000000000000000000000000000131850E1"
773 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
776 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
780 "0000000000000000000000000000000000000000000000000000000000000000"
781 "0000000000000000000000000000000000000000000000000000000000000425",
783 "0000000000000000000000000000000000000000000000000000000000000000"
784 "0000000000000000000000000000000000000000000000000000000000000001",
786 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
787 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
789 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
790 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
792 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
793 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
796 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
797 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
802 static int char2_curve_test(int n)
806 BIGNUM *p = NULL, *a = NULL, *b = NULL;
807 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
808 EC_GROUP *group = NULL, *variable = NULL;
809 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
810 const EC_POINT *points[3];
811 const BIGNUM *scalars[3];
812 struct c2_curve_test *const test = char2_curve_tests + n;
814 if (!TEST_ptr(ctx = BN_CTX_new())
815 || !TEST_ptr(p = BN_new())
816 || !TEST_ptr(a = BN_new())
817 || !TEST_ptr(b = BN_new())
818 || !TEST_ptr(x = BN_new())
819 || !TEST_ptr(y = BN_new())
820 || !TEST_ptr(z = BN_new())
821 || !TEST_ptr(yplusone = BN_new())
822 || !TEST_true(BN_hex2bn(&p, test->p))
823 || !TEST_true(BN_hex2bn(&a, test->a))
824 || !TEST_true(BN_hex2bn(&b, test->b))
825 || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method()))
826 || !TEST_true(EC_GROUP_set_curve_GF2m(group, p, a, b, ctx))
827 || !TEST_ptr(P = EC_POINT_new(group))
828 || !TEST_ptr(Q = EC_POINT_new(group))
829 || !TEST_ptr(R = EC_POINT_new(group))
830 || !TEST_true(BN_hex2bn(&x, test->x))
831 || !TEST_true(BN_hex2bn(&y, test->y))
832 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
835 /* Change test based on whether binary point compression is enabled or not. */
836 # ifdef OPENSSL_EC_BIN_PT_COMP
838 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
839 * and therefore setting the coordinates should fail.
841 if (!TEST_false(EC_POINT_set_affine_coordinates_GF2m(group, P, x, yplusone,
843 || !TEST_true(EC_POINT_set_compressed_coordinates_GF2m(group, P, x,
846 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
847 || !TEST_true(BN_hex2bn(&z, test->order))
848 || !TEST_true(BN_hex2bn(&cof, test->cof))
849 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
850 || !TEST_true(EC_POINT_get_affine_coordinates_GF2m(group, P, x, y,
853 TEST_info("%s -- Generator", test->name);
854 test_output_bignum("x", x);
855 test_output_bignum("y", y);
856 /* G_y value taken from the standard: */
857 if (!TEST_true(BN_hex2bn(&z, test->y))
858 || !TEST_BN_eq(y, z))
862 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
863 * and therefore setting the coordinates should fail.
865 if (!TEST_false(EC_POINT_set_affine_coordinates_GF2m(group, P, x, yplusone,
867 || !TEST_true(EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx))
868 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
869 || !TEST_true(BN_hex2bn(&z, test->order))
870 || !TEST_true(BN_hex2bn(&cof, test->cof))
871 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
873 TEST_info("%s -- Generator:", test->name);
874 test_output_bignum("x", x);
875 test_output_bignum("y", y);
878 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
879 || !group_order_tests(group)
880 || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group)))
881 || !TEST_true(EC_GROUP_copy(variable, group)))
884 /* more tests using the last curve */
885 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
886 if (!TEST_true(EC_POINT_set_affine_coordinates_GF2m(group, P, x, y,
888 || !TEST_true(EC_POINT_copy(Q, P))
889 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
890 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
891 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
892 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
893 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
894 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
895 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
896 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
903 if (!TEST_true(BN_add(y, z, BN_value_one()))
905 || !TEST_true(BN_rshift1(y, y)))
907 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
910 TEST_note("combined multiplication ...");
912 /* z is still the group order */
913 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
914 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
915 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
916 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
919 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
920 || !TEST_true(BN_add(z, z, y)))
922 BN_set_negative(z, 1);
924 scalars[1] = z; /* z = -(order + y) */
926 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
927 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
930 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
931 || !TEST_true(BN_add(z, x, y)))
933 BN_set_negative(z, 1);
936 scalars[2] = z; /* z = -(x+y) */
938 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
939 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
957 EC_GROUP_free(group);
958 EC_GROUP_free(variable);
962 static int char2_field_tests(void)
965 BIGNUM *p = NULL, *a = NULL, *b = NULL;
966 EC_GROUP *group = NULL, *tmp = NULL;
967 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
968 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
969 unsigned char buf[100];
973 if (!TEST_ptr(ctx = BN_CTX_new())
974 || !TEST_ptr(p = BN_new())
975 || !TEST_ptr(a = BN_new())
976 || !TEST_ptr(b = BN_new())
977 || !TEST_true(BN_hex2bn(&p, "13"))
978 || !TEST_true(BN_hex2bn(&a, "3"))
979 || !TEST_true(BN_hex2bn(&b, "1")))
982 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
983 * EC_GROUP_new_curve_GF2m
984 * so that the library gets
985 * to choose the EC_METHOD */
987 || !TEST_true(EC_GROUP_set_curve_GF2m(group, p, a, b, ctx))
988 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
989 || !TEST_true(EC_GROUP_copy(tmp, group)))
991 EC_GROUP_free(group);
995 if (!TEST_true(EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)))
998 TEST_info("Curve defined by Weierstrass equation");
999 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
1000 test_output_bignum("a", a);
1001 test_output_bignum("b", b);
1002 test_output_bignum("p", p);
1004 if (!TEST_ptr(P = EC_POINT_new(group))
1005 || !TEST_ptr(Q = EC_POINT_new(group))
1006 || !TEST_ptr(R = EC_POINT_new(group))
1007 || !TEST_true(EC_POINT_set_to_infinity(group, P))
1008 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1012 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
1013 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
1014 || !TEST_true(EC_POINT_is_at_infinity(group, P))
1015 || !TEST_ptr(x = BN_new())
1016 || !TEST_ptr(y = BN_new())
1017 || !TEST_ptr(z = BN_new())
1018 || !TEST_ptr(cof = BN_new())
1019 || !TEST_ptr(yplusone = BN_new())
1020 || !TEST_true(BN_hex2bn(&x, "6"))
1021 /* Change test based on whether binary point compression is enabled or not. */
1022 # ifdef OPENSSL_EC_BIN_PT_COMP
1023 || !TEST_true(EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1,
1026 || !TEST_true(BN_hex2bn(&y, "8"))
1027 || !TEST_true(EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx))
1031 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
1032 /* Change test based on whether binary point compression is enabled or not. */
1033 # ifdef OPENSSL_EC_BIN_PT_COMP
1034 if (!TEST_true(EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y,
1038 TEST_info("Point is not on curve");
1039 test_output_bignum("x", x);
1040 test_output_bignum("y", y);
1044 TEST_note("A cyclic subgroup:");
1047 if (!TEST_int_ne(k--, 0))
1050 if (EC_POINT_is_at_infinity(group, P))
1051 TEST_note(" point at infinity");
1053 if (!TEST_true(EC_POINT_get_affine_coordinates_GF2m(group, P, x, y,
1057 test_output_bignum("x", x);
1058 test_output_bignum("y", y);
1061 if (!TEST_true(EC_POINT_copy(R, P))
1062 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1065 while (!EC_POINT_is_at_infinity(group, P));
1067 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1068 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1071 /* Change test based on whether binary point compression is enabled or not. */
1072 # ifdef OPENSSL_EC_BIN_PT_COMP
1073 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1074 buf, sizeof(buf), ctx);
1075 if (!TEST_size_t_ne(len, 0)
1076 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1077 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1079 test_output_memory("Generator as octet string, compressed form:",
1083 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1084 buf, sizeof(buf), ctx);
1085 if (!TEST_size_t_ne(len, 0)
1086 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1087 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1089 test_output_memory("Generator as octet string, uncompressed form:",
1092 /* Change test based on whether binary point compression is enabled or not. */
1093 # ifdef OPENSSL_EC_BIN_PT_COMP
1095 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1097 if (!TEST_size_t_ne(len, 0)
1098 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1099 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1101 test_output_memory("Generator as octet string, hybrid form:",
1105 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1106 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1117 EC_GROUP_free(group);
1131 static int internal_curve_test(int n)
1133 EC_GROUP *group = NULL;
1134 int nid = curves[n].nid;
1136 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1137 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1141 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1142 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1143 EC_GROUP_free(group);
1146 EC_GROUP_free(group);
1150 static int internal_curve_test_method(int n)
1152 int r, nid = curves[n].nid;
1155 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1156 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1159 r = group_order_tests(group);
1160 EC_GROUP_free(group);
1164 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1166 * nistp_test_params contains magic numbers for testing our optimized
1167 * implementations of several NIST curves with characteristic > 3.
1169 struct nistp_test_params {
1170 const EC_METHOD *(*meth) ();
1173 * Qx, Qy and D are taken from
1174 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1175 * Otherwise, values are standard curve parameters from FIPS 180-3
1177 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1180 static const struct nistp_test_params nistp_tests_params[] = {
1183 EC_GFp_nistp224_method,
1186 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1188 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1190 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1192 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1194 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1196 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1198 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1200 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1202 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1206 EC_GFp_nistp256_method,
1209 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1211 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1213 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1215 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1217 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1219 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1221 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1223 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1225 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1229 EC_GFp_nistp521_method,
1233 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1234 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1237 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1238 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1241 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1242 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1245 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1246 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1249 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1250 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1253 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1254 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1257 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1258 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1261 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1262 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1265 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1266 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1270 static int nistp_single_test(int idx)
1272 const struct nistp_test_params *test = nistp_tests_params + idx;
1274 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1275 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1276 EC_GROUP *NISTP = NULL;
1277 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1280 TEST_note("NIST curve P-%d (optimised implementation):",
1282 if (!TEST_ptr(ctx = BN_CTX_new())
1283 || !TEST_ptr(p = BN_new())
1284 || !TEST_ptr(a = BN_new())
1285 || !TEST_ptr(b = BN_new())
1286 || !TEST_ptr(x = BN_new())
1287 || !TEST_ptr(y = BN_new())
1288 || !TEST_ptr(m = BN_new())
1289 || !TEST_ptr(n = BN_new())
1290 || !TEST_ptr(order = BN_new())
1291 || !TEST_ptr(yplusone = BN_new())
1293 || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1294 || !TEST_true(BN_hex2bn(&p, test->p))
1295 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
1296 || !TEST_true(BN_hex2bn(&a, test->a))
1297 || !TEST_true(BN_hex2bn(&b, test->b))
1298 || !TEST_true(EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx))
1299 || !TEST_ptr(G = EC_POINT_new(NISTP))
1300 || !TEST_ptr(P = EC_POINT_new(NISTP))
1301 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1302 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1303 || !TEST_true(BN_hex2bn(&x, test->Qx))
1304 || !TEST_true(BN_hex2bn(&y, test->Qy))
1305 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1307 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1308 * and therefore setting the coordinates should fail.
1310 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x,
1312 || !TEST_true(EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y,
1314 || !TEST_true(BN_hex2bn(&x, test->Gx))
1315 || !TEST_true(BN_hex2bn(&y, test->Gy))
1316 || !TEST_true(EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx))
1317 || !TEST_true(BN_hex2bn(&order, test->order))
1318 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1319 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1322 TEST_note("NIST test vectors ... ");
1323 if (!TEST_true(BN_hex2bn(&n, test->d)))
1325 /* fixed point multiplication */
1326 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1327 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1329 /* random point multiplication */
1330 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1331 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1333 /* set generator to P = 2*G, where G is the standard generator */
1334 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1335 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1336 /* set the scalar to m=n/2, where n is the NIST test scalar */
1337 || !TEST_true(BN_rshift(m, n, 1)))
1340 /* test the non-standard generator */
1341 /* fixed point multiplication */
1342 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1343 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1345 /* random point multiplication */
1346 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1347 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1350 * We have not performed precomputation so have_precompute mult should be
1353 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1355 /* now repeat all tests with precomputation */
1356 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1357 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
1360 /* fixed point multiplication */
1361 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1362 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1364 /* random point multiplication */
1365 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1366 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1368 /* reset generator */
1369 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1371 /* fixed point multiplication */
1372 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1373 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1375 /* random point multiplication */
1376 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1377 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1380 /* regression test for felem_neg bug */
1381 if (!TEST_true(BN_set_word(m, 32))
1382 || !TEST_true(BN_set_word(n, 31))
1383 || !TEST_true(EC_POINT_copy(P, G))
1384 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1385 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1386 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1389 r = group_order_tests(NISTP);
1391 EC_GROUP_free(NISTP);
1395 EC_POINT_free(Q_CHECK);
1410 static const unsigned char p521_named[] = {
1411 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1414 static const unsigned char p521_explicit[] = {
1415 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1416 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1417 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1418 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1419 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1420 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1421 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1422 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1423 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1424 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1425 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1426 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1427 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1428 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1429 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1430 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1431 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1432 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1433 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1434 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1435 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1436 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1437 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1438 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1439 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1440 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1441 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1442 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1443 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1444 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1445 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1446 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1447 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1448 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1449 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1450 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1451 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1452 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1455 static int parameter_test(void)
1457 EC_GROUP *group = NULL, *group2 = NULL;
1458 ECPARAMETERS *ecparameters = NULL;
1459 unsigned char *buf = NULL;
1462 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp112r1))
1463 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1464 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1465 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1468 EC_GROUP_free(group);
1471 /* Test the named curve encoding, which should be default. */
1472 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1473 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1474 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1481 * Test the explicit encoding. P-521 requires correctly zero-padding the
1482 * curve coefficients.
1484 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1485 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1486 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
1491 EC_GROUP_free(group);
1492 EC_GROUP_free(group2);
1493 ECPARAMETERS_free(ecparameters);
1499 int setup_tests(void)
1501 #ifndef OPENSSL_NO_EC
1502 crv_len = EC_get_builtin_curves(NULL, 0);
1503 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
1504 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
1507 ADD_TEST(parameter_test);
1508 ADD_TEST(prime_field_tests);
1509 # ifndef OPENSSL_NO_EC2M
1510 ADD_TEST(char2_field_tests);
1511 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
1513 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1514 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
1516 ADD_ALL_TESTS(internal_curve_test, crv_len);
1517 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
1522 void cleanup_tests(void)
1524 #ifndef OPENSSL_NO_EC
1525 OPENSSL_free(curves);