2 * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
5 * Licensed under the Apache License 2.0 (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
12 * We need access to the deprecated EC_POINTs_mul, EC_GROUP_precompute_mult,
13 * and EC_GROUP_have_precompute_mult for testing purposes
14 * when the deprecated calls are not hidden
16 #ifndef OPENSSL_NO_DEPRECATED_3_0
17 # define OPENSSL_SUPPRESS_DEPRECATED
21 #include "internal/nelem.h"
25 # include <openssl/ec.h>
26 # ifndef OPENSSL_NO_ENGINE
27 # include <openssl/engine.h>
29 # include <openssl/err.h>
30 # include <openssl/obj_mac.h>
31 # include <openssl/objects.h>
32 # include <openssl/rand.h>
33 # include <openssl/bn.h>
34 # include <openssl/opensslconf.h>
36 static size_t crv_len = 0;
37 static EC_builtin_curve *curves = NULL;
39 /* test multiplication with group order, long and negative scalars */
40 static int group_order_tests(EC_GROUP *group)
42 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
43 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
44 const EC_POINT *G = NULL;
48 if (!TEST_ptr(n1 = BN_new())
49 || !TEST_ptr(n2 = BN_new())
50 || !TEST_ptr(order = BN_new())
51 || !TEST_ptr(ctx = BN_CTX_new())
52 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
53 || !TEST_ptr(P = EC_POINT_new(group))
54 || !TEST_ptr(Q = EC_POINT_new(group))
55 || !TEST_ptr(R = EC_POINT_new(group))
56 || !TEST_ptr(S = EC_POINT_new(group)))
59 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
60 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
61 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
62 # ifndef OPENSSL_NO_DEPRECATED_3_0
63 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
65 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
66 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
67 || !TEST_true(EC_POINT_copy(P, G))
68 || !TEST_true(BN_one(n1))
69 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
70 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
71 || !TEST_true(BN_sub(n1, order, n1))
72 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
73 || !TEST_true(EC_POINT_invert(group, Q, ctx))
74 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
77 for (i = 1; i <= 2; i++) {
78 # ifndef OPENSSL_NO_DEPRECATED_3_0
79 const BIGNUM *scalars[6];
80 const EC_POINT *points[6];
83 if (!TEST_true(BN_set_word(n1, i))
85 * If i == 1, P will be the predefined generator for which
86 * EC_GROUP_precompute_mult has set up precomputation.
88 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
89 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
90 || !TEST_true(BN_one(n1))
92 || !TEST_true(BN_sub(n1, n1, order))
93 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
94 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
97 || !TEST_true(BN_add(n2, order, BN_value_one()))
98 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
99 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
101 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
102 || !TEST_true(BN_mul(n2, n1, n2, ctx))
103 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
104 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
107 /* n2 = order^2 - 1 */
108 BN_set_negative(n2, 0);
109 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
110 /* Add P to verify the result. */
111 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
112 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
113 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
116 # ifndef OPENSSL_NO_DEPRECATED_3_0
117 /* Exercise EC_POINTs_mul, including corner cases. */
118 scalars[0] = scalars[1] = BN_value_one();
119 points[0] = points[1] = P;
121 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
122 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
123 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
127 points[0] = Q; /* => infinity */
129 points[1] = P; /* => -P */
131 points[2] = Q; /* => infinity */
133 points[3] = Q; /* => infinity */
135 points[4] = P; /* => P */
137 points[5] = Q; /* => infinity */
138 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
139 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
146 if (r == 0 && i != 0)
147 TEST_info(i == 1 ? "allowing precomputation" :
148 "without precomputation");
160 static int prime_field_tests(void)
163 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
164 EC_GROUP *group = NULL, *tmp = NULL;
165 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
166 *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
167 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
168 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
169 # ifndef OPENSSL_NO_DEPRECATED_3_0
170 const EC_POINT *points[4];
171 const BIGNUM *scalars[4];
173 unsigned char buf[100];
177 if (!TEST_ptr(ctx = BN_CTX_new())
178 || !TEST_ptr(p = BN_new())
179 || !TEST_ptr(a = BN_new())
180 || !TEST_ptr(b = BN_new())
181 || !TEST_true(BN_hex2bn(&p, "17"))
182 || !TEST_true(BN_hex2bn(&a, "1"))
183 || !TEST_true(BN_hex2bn(&b, "1"))
185 * applications should use EC_GROUP_new_curve_GFp so
186 * that the library gets to choose the EC_METHOD
188 || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
189 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
190 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
191 || !TEST_true(EC_GROUP_copy(tmp, group)))
193 EC_GROUP_free(group);
197 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
200 TEST_info("Curve defined by Weierstrass equation");
201 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
202 test_output_bignum("a", a);
203 test_output_bignum("b", b);
204 test_output_bignum("p", p);
207 if (!TEST_ptr(P = EC_POINT_new(group))
208 || !TEST_ptr(Q = EC_POINT_new(group))
209 || !TEST_ptr(R = EC_POINT_new(group))
210 || !TEST_true(EC_POINT_set_to_infinity(group, P))
211 || !TEST_true(EC_POINT_is_at_infinity(group, P))
212 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
213 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
214 || !TEST_true(EC_POINT_is_at_infinity(group, P))
215 || !TEST_ptr(x = BN_new())
216 || !TEST_ptr(y = BN_new())
217 || !TEST_ptr(z = BN_new())
218 || !TEST_ptr(yplusone = BN_new())
219 || !TEST_true(BN_hex2bn(&x, "D"))
220 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
223 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
224 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
226 TEST_info("Point is not on curve");
227 test_output_bignum("x", x);
228 test_output_bignum("y", y);
232 TEST_note("A cyclic subgroup:");
235 if (!TEST_int_ne(k--, 0))
238 if (EC_POINT_is_at_infinity(group, P)) {
239 TEST_note(" point at infinity");
241 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
245 test_output_bignum("x", x);
246 test_output_bignum("y", y);
249 if (!TEST_true(EC_POINT_copy(R, P))
250 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
253 } while (!EC_POINT_is_at_infinity(group, P));
255 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
256 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
260 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
262 if (!TEST_size_t_ne(len, 0)
263 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
264 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
266 test_output_memory("Generator as octet string, compressed form:",
269 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
270 buf, sizeof(buf), ctx);
271 if (!TEST_size_t_ne(len, 0)
272 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
273 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
275 test_output_memory("Generator as octet string, uncompressed form:",
278 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
279 buf, sizeof(buf), ctx);
280 if (!TEST_size_t_ne(len, 0)
281 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
282 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
284 test_output_memory("Generator as octet string, hybrid form:",
287 if (!TEST_true(EC_POINT_invert(group, P, ctx))
288 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
291 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
292 * 2000) -- not a NIST curve, but commonly used
295 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
296 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
297 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
298 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
299 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
300 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
301 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
302 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
303 || !TEST_true(BN_hex2bn(&x, "4A96B568"
304 "8EF573284664698968C38BB913CBFC82"))
305 || !TEST_true(BN_hex2bn(&y, "23a62855"
306 "3168947d59dcc912042351377ac5fb32"))
307 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
309 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
310 * and therefore setting the coordinates should fail.
312 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
314 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
315 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
316 || !TEST_true(BN_hex2bn(&z, "0100000000"
317 "000000000001F4C8F927AED3CA752257"))
318 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
319 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
321 TEST_info("SEC2 curve secp160r1 -- Generator");
322 test_output_bignum("x", x);
323 test_output_bignum("y", y);
324 /* G_y value taken from the standard: */
325 if (!TEST_true(BN_hex2bn(&z, "23a62855"
326 "3168947d59dcc912042351377ac5fb32"))
328 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
329 || !group_order_tests(group)
330 || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))
331 || !TEST_true(EC_GROUP_copy(P_160, group))
333 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
335 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
336 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
337 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
338 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
339 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
340 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
341 "0FA7E9AB72243049FEB8DEECC146B9B1"))
342 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
343 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
344 "7CBF20EB43A18800F4FF0AFD82FF1012"))
345 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
346 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
347 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
348 "FFFFFFFF99DEF836146BC9B1B4D22831"))
349 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
350 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
353 TEST_info("NIST curve P-192 -- Generator");
354 test_output_bignum("x", x);
355 test_output_bignum("y", y);
356 /* G_y value taken from the standard: */
357 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
358 "631011ED6B24CDD573F977A11E794811"))
360 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
362 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
363 * and therefore setting the coordinates should fail.
365 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
367 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
368 || !group_order_tests(group)
369 || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))
370 || !TEST_true(EC_GROUP_copy(P_192, group))
372 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
374 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
375 "FFFFFFFF000000000000000000000001"))
376 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
377 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
378 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
379 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
380 "5044B0B7D7BFD8BA270B39432355FFB4"))
381 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
382 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
383 "4A03C1D356C21122343280D6115C1D21"))
384 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
385 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
386 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
387 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
388 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
389 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
392 TEST_info("NIST curve P-224 -- Generator");
393 test_output_bignum("x", x);
394 test_output_bignum("y", y);
395 /* G_y value taken from the standard: */
396 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
397 "CD4375A05A07476444D5819985007E34"))
399 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
401 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
402 * and therefore setting the coordinates should fail.
404 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
406 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
407 || !group_order_tests(group)
408 || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
409 || !TEST_true(EC_GROUP_copy(P_224, group))
411 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
413 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
414 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
415 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
416 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
417 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
418 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
419 "651D06B0CC53B0F63BCE3C3E27D2604B"))
420 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
422 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
423 "77037D812DEB33A0F4A13945D898C296"))
424 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
425 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
426 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
427 "BCE6FAADA7179E84F3B9CAC2FC632551"))
428 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
429 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
432 TEST_info("NIST curve P-256 -- Generator");
433 test_output_bignum("x", x);
434 test_output_bignum("y", y);
435 /* G_y value taken from the standard: */
436 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
437 "2BCE33576B315ECECBB6406837BF51F5"))
439 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
441 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
442 * and therefore setting the coordinates should fail.
444 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
446 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
447 || !group_order_tests(group)
448 || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
449 || !TEST_true(EC_GROUP_copy(P_256, group))
451 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
453 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
454 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
455 "FFFFFFFF0000000000000000FFFFFFFF"))
456 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
457 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
458 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
459 "FFFFFFFF0000000000000000FFFFFFFC"))
460 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
461 "181D9C6EFE8141120314088F5013875A"
462 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
463 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
465 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
466 "6E1D3B628BA79B9859F741E082542A38"
467 "5502F25DBF55296C3A545E3872760AB7"))
468 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
469 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
470 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
471 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
472 "581A0DB248B0A77AECEC196ACCC52973"))
473 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
474 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
477 TEST_info("NIST curve P-384 -- Generator");
478 test_output_bignum("x", x);
479 test_output_bignum("y", y);
480 /* G_y value taken from the standard: */
481 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
482 "F8F41DBD289A147CE9DA3113B5F0B8C0"
483 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
485 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
487 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
488 * and therefore setting the coordinates should fail.
490 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
492 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
493 || !group_order_tests(group)
494 || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
495 || !TEST_true(EC_GROUP_copy(P_384, group))
497 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
498 || !TEST_true(BN_hex2bn(&p, "1FF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
500 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
501 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
502 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
503 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
504 || !TEST_true(BN_hex2bn(&a, "1FF"
505 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
506 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
507 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
508 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
509 || !TEST_true(BN_hex2bn(&b, "051"
510 "953EB9618E1C9A1F929A21A0B68540EE"
511 "A2DA725B99B315F3B8B489918EF109E1"
512 "56193951EC7E937B1652C0BD3BB1BF07"
513 "3573DF883D2C34F1EF451FD46B503F00"))
514 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
515 || !TEST_true(BN_hex2bn(&x, "C6"
516 "858E06B70404E9CD9E3ECB662395B442"
517 "9C648139053FB521F828AF606B4D3DBA"
518 "A14B5E77EFE75928FE1DC127A2FFA8DE"
519 "3348B3C1856A429BF97E7E31C2E5BD66"))
520 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
521 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
522 || !TEST_true(BN_hex2bn(&z, "1FF"
523 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
524 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
525 "51868783BF2F966B7FCC0148F709A5D0"
526 "3BB5C9B8899C47AEBB6FB71E91386409"))
527 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
528 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
531 TEST_info("NIST curve P-521 -- Generator");
532 test_output_bignum("x", x);
533 test_output_bignum("y", y);
534 /* G_y value taken from the standard: */
535 if (!TEST_true(BN_hex2bn(&z, "118"
536 "39296A789A3BC0045C8A5FB42C7D1BD9"
537 "98F54449579B446817AFBD17273E662C"
538 "97EE72995EF42640C550B9013FAD0761"
539 "353C7086A272C24088BE94769FD16650"))
541 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
543 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
544 * and therefore setting the coordinates should fail.
546 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
548 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
549 || !group_order_tests(group)
550 || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
551 || !TEST_true(EC_GROUP_copy(P_521, group))
553 /* more tests using the last curve */
555 /* Restore the point that got mangled in the (x, y + 1) test. */
556 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
557 || !TEST_true(EC_POINT_copy(Q, P))
558 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
559 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
560 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
561 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
562 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
563 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
564 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
565 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
568 # ifndef OPENSSL_NO_DEPRECATED_3_0
569 TEST_note("combined multiplication ...");
575 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
576 || !TEST_true(BN_add(y, z, BN_value_one()))
578 || !TEST_true(BN_rshift1(y, y)))
581 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
584 /* z is still the group order */
585 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
586 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
587 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
588 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
589 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
590 || !TEST_true(BN_add(z, z, y)))
592 BN_set_negative(z, 1);
594 scalars[1] = z; /* z = -(order + y) */
596 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
597 || !TEST_true(EC_POINT_is_at_infinity(group, P))
598 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
599 || !TEST_true(BN_add(z, x, y)))
601 BN_set_negative(z, 1);
604 scalars[2] = z; /* z = -(x+y) */
606 if (!TEST_ptr(scalar3 = BN_new()))
609 scalars[3] = scalar3;
611 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
612 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
622 EC_GROUP_free(group);
633 EC_GROUP_free(P_160);
634 EC_GROUP_free(P_192);
635 EC_GROUP_free(P_224);
636 EC_GROUP_free(P_256);
637 EC_GROUP_free(P_384);
638 EC_GROUP_free(P_521);
642 # ifndef OPENSSL_NO_EC2M
644 static struct c2_curve_test {
655 } char2_curve_tests[] = {
656 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
659 "0800000000000000000000000000000000000000C9",
662 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
663 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
664 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
666 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
669 "0800000000000000000000000000000000000000C9",
671 "020A601907B8C953CA1481EB10512F78744A3205FD",
672 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
673 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
674 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
676 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
679 "020000000000000000000000000000000000000004000000000000000001",
682 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
683 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
685 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
688 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
691 "020000000000000000000000000000000000000004000000000000000001",
692 "000000000000000000000000000000000000000000000000000000000001",
693 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
694 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
695 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
697 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
700 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
704 "00000000000000000000000000000000000000000000000000000000000010A1",
708 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
710 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
713 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
716 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
720 "00000000000000000000000000000000000000000000000000000000000010A1",
722 "0000000000000000000000000000000000000000000000000000000000000001",
724 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
726 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
728 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
731 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
734 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
737 "0200000000000000000000000000000000000000"
738 "0000000000000000000000000000000000000000008000000000000000000001",
741 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
742 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
743 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
744 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
746 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
747 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
750 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
753 "0200000000000000000000000000000000000000"
754 "0000000000000000000000000000000000000000008000000000000000000001",
755 "0000000000000000000000000000000000000000"
756 "0000000000000000000000000000000000000000000000000000000000000001",
757 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
758 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
759 "015D4860D088DDB3496B0C6064756260441CDE4A"
760 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
761 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
762 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
764 "0100000000000000000000000000000000000000"
765 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
768 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
772 "0000000000000000000000000000000000000000000000000000000000000000"
773 "0000000000000000000000000000000000000000000000000000000000000425",
777 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
778 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
780 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
781 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
784 "00000000000000000000000000000000000000000000000000000000131850E1"
785 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
788 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
792 "0000000000000000000000000000000000000000000000000000000000000000"
793 "0000000000000000000000000000000000000000000000000000000000000425",
795 "0000000000000000000000000000000000000000000000000000000000000000"
796 "0000000000000000000000000000000000000000000000000000000000000001",
798 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
799 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
801 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
802 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
804 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
805 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
808 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
809 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
814 static int char2_curve_test(int n)
818 BIGNUM *p = NULL, *a = NULL, *b = NULL;
819 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
820 EC_GROUP *group = NULL, *variable = NULL;
821 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
822 # ifndef OPENSSL_NO_DEPRECATED_3_0
823 const EC_POINT *points[3];
824 const BIGNUM *scalars[3];
826 struct c2_curve_test *const test = char2_curve_tests + n;
828 if (!TEST_ptr(ctx = BN_CTX_new())
829 || !TEST_ptr(p = BN_new())
830 || !TEST_ptr(a = BN_new())
831 || !TEST_ptr(b = BN_new())
832 || !TEST_ptr(x = BN_new())
833 || !TEST_ptr(y = BN_new())
834 || !TEST_ptr(z = BN_new())
835 || !TEST_ptr(yplusone = BN_new())
836 || !TEST_true(BN_hex2bn(&p, test->p))
837 || !TEST_true(BN_hex2bn(&a, test->a))
838 || !TEST_true(BN_hex2bn(&b, test->b))
839 || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method()))
840 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
841 || !TEST_ptr(P = EC_POINT_new(group))
842 || !TEST_ptr(Q = EC_POINT_new(group))
843 || !TEST_ptr(R = EC_POINT_new(group))
844 || !TEST_true(BN_hex2bn(&x, test->x))
845 || !TEST_true(BN_hex2bn(&y, test->y))
846 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
849 /* Change test based on whether binary point compression is enabled or not. */
850 # ifdef OPENSSL_EC_BIN_PT_COMP
852 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
853 * and therefore setting the coordinates should fail.
855 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
856 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
859 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
860 || !TEST_true(BN_hex2bn(&z, test->order))
861 || !TEST_true(BN_hex2bn(&cof, test->cof))
862 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
863 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
865 TEST_info("%s -- Generator", test->name);
866 test_output_bignum("x", x);
867 test_output_bignum("y", y);
868 /* G_y value taken from the standard: */
869 if (!TEST_true(BN_hex2bn(&z, test->y))
870 || !TEST_BN_eq(y, z))
874 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
875 * and therefore setting the coordinates should fail.
877 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
878 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
879 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
880 || !TEST_true(BN_hex2bn(&z, test->order))
881 || !TEST_true(BN_hex2bn(&cof, test->cof))
882 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
884 TEST_info("%s -- Generator:", test->name);
885 test_output_bignum("x", x);
886 test_output_bignum("y", y);
889 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
890 || !group_order_tests(group)
891 || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group)))
892 || !TEST_true(EC_GROUP_copy(variable, group)))
895 /* more tests using the last curve */
896 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
897 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
898 || !TEST_true(EC_POINT_copy(Q, P))
899 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
900 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
901 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
902 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
903 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
904 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
905 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
906 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
909 # ifndef OPENSSL_NO_DEPRECATED_3_0
910 TEST_note("combined multiplication ...");
915 if (!TEST_true(BN_add(y, z, BN_value_one()))
917 || !TEST_true(BN_rshift1(y, y)))
919 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
922 /* z is still the group order */
923 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
924 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
925 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
926 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
929 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
930 || !TEST_true(BN_add(z, z, y)))
932 BN_set_negative(z, 1);
934 scalars[1] = z; /* z = -(order + y) */
936 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
937 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
940 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
941 || !TEST_true(BN_add(z, x, y)))
943 BN_set_negative(z, 1);
946 scalars[2] = z; /* z = -(x+y) */
948 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
949 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
968 EC_GROUP_free(group);
969 EC_GROUP_free(variable);
973 static int char2_field_tests(void)
976 BIGNUM *p = NULL, *a = NULL, *b = NULL;
977 EC_GROUP *group = NULL, *tmp = NULL;
978 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
979 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
980 unsigned char buf[100];
984 if (!TEST_ptr(ctx = BN_CTX_new())
985 || !TEST_ptr(p = BN_new())
986 || !TEST_ptr(a = BN_new())
987 || !TEST_ptr(b = BN_new())
988 || !TEST_true(BN_hex2bn(&p, "13"))
989 || !TEST_true(BN_hex2bn(&a, "3"))
990 || !TEST_true(BN_hex2bn(&b, "1")))
993 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
994 * EC_GROUP_new_curve_GF2m
995 * so that the library gets
996 * to choose the EC_METHOD */
998 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
999 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
1000 || !TEST_true(EC_GROUP_copy(tmp, group)))
1002 EC_GROUP_free(group);
1006 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
1009 TEST_info("Curve defined by Weierstrass equation");
1010 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
1011 test_output_bignum("a", a);
1012 test_output_bignum("b", b);
1013 test_output_bignum("p", p);
1015 if (!TEST_ptr(P = EC_POINT_new(group))
1016 || !TEST_ptr(Q = EC_POINT_new(group))
1017 || !TEST_ptr(R = EC_POINT_new(group))
1018 || !TEST_true(EC_POINT_set_to_infinity(group, P))
1019 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1023 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
1024 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
1025 || !TEST_true(EC_POINT_is_at_infinity(group, P))
1026 || !TEST_ptr(x = BN_new())
1027 || !TEST_ptr(y = BN_new())
1028 || !TEST_ptr(z = BN_new())
1029 || !TEST_ptr(cof = BN_new())
1030 || !TEST_ptr(yplusone = BN_new())
1031 || !TEST_true(BN_hex2bn(&x, "6"))
1032 /* Change test based on whether binary point compression is enabled or not. */
1033 # ifdef OPENSSL_EC_BIN_PT_COMP
1034 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
1036 || !TEST_true(BN_hex2bn(&y, "8"))
1037 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
1041 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
1042 /* Change test based on whether binary point compression is enabled or not. */
1043 # ifdef OPENSSL_EC_BIN_PT_COMP
1044 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
1047 TEST_info("Point is not on curve");
1048 test_output_bignum("x", x);
1049 test_output_bignum("y", y);
1053 TEST_note("A cyclic subgroup:");
1056 if (!TEST_int_ne(k--, 0))
1059 if (EC_POINT_is_at_infinity(group, P))
1060 TEST_note(" point at infinity");
1062 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1066 test_output_bignum("x", x);
1067 test_output_bignum("y", y);
1070 if (!TEST_true(EC_POINT_copy(R, P))
1071 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1074 while (!EC_POINT_is_at_infinity(group, P));
1076 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1077 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1080 /* Change test based on whether binary point compression is enabled or not. */
1081 # ifdef OPENSSL_EC_BIN_PT_COMP
1082 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1083 buf, sizeof(buf), ctx);
1084 if (!TEST_size_t_ne(len, 0)
1085 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1086 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1088 test_output_memory("Generator as octet string, compressed form:",
1092 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1093 buf, sizeof(buf), ctx);
1094 if (!TEST_size_t_ne(len, 0)
1095 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1096 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1098 test_output_memory("Generator as octet string, uncompressed form:",
1101 /* Change test based on whether binary point compression is enabled or not. */
1102 # ifdef OPENSSL_EC_BIN_PT_COMP
1104 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1106 if (!TEST_size_t_ne(len, 0)
1107 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1108 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1110 test_output_memory("Generator as octet string, hybrid form:",
1114 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1115 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1126 EC_GROUP_free(group);
1140 static int internal_curve_test(int n)
1142 EC_GROUP *group = NULL;
1143 int nid = curves[n].nid;
1145 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1146 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1150 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1151 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1152 EC_GROUP_free(group);
1155 EC_GROUP_free(group);
1159 static int internal_curve_test_method(int n)
1161 int r, nid = curves[n].nid;
1164 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1165 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1168 r = group_order_tests(group);
1169 EC_GROUP_free(group);
1173 static int group_field_test(void)
1176 BIGNUM *secp521r1_field = NULL;
1177 BIGNUM *sect163r2_field = NULL;
1178 EC_GROUP *secp521r1_group = NULL;
1179 EC_GROUP *sect163r2_group = NULL;
1181 BN_hex2bn(&secp521r1_field,
1182 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1183 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1184 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1185 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1189 BN_hex2bn(§163r2_field,
1190 "08000000000000000000000000000000"
1193 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1194 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1197 # ifndef OPENSSL_NO_EC2M
1198 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1199 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1203 EC_GROUP_free(secp521r1_group);
1204 EC_GROUP_free(sect163r2_group);
1205 BN_free(secp521r1_field);
1206 BN_free(sect163r2_field);
1210 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1212 * nistp_test_params contains magic numbers for testing our optimized
1213 * implementations of several NIST curves with characteristic > 3.
1215 struct nistp_test_params {
1216 const EC_METHOD *(*meth) (void);
1219 * Qx, Qy and D are taken from
1220 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1221 * Otherwise, values are standard curve parameters from FIPS 180-3
1223 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1226 static const struct nistp_test_params nistp_tests_params[] = {
1229 EC_GFp_nistp224_method,
1232 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1234 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1236 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1238 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1240 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1242 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1244 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1246 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1248 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1252 EC_GFp_nistp256_method,
1255 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1257 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1259 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1261 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1263 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1265 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1267 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1269 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1271 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1275 EC_GFp_nistp521_method,
1279 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1280 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1283 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1284 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1287 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1288 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1291 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1292 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1295 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1296 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1299 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1300 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1303 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1304 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1307 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1308 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1311 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1312 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1316 static int nistp_single_test(int idx)
1318 const struct nistp_test_params *test = nistp_tests_params + idx;
1320 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1321 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1322 EC_GROUP *NISTP = NULL;
1323 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1326 TEST_note("NIST curve P-%d (optimised implementation):",
1328 if (!TEST_ptr(ctx = BN_CTX_new())
1329 || !TEST_ptr(p = BN_new())
1330 || !TEST_ptr(a = BN_new())
1331 || !TEST_ptr(b = BN_new())
1332 || !TEST_ptr(x = BN_new())
1333 || !TEST_ptr(y = BN_new())
1334 || !TEST_ptr(m = BN_new())
1335 || !TEST_ptr(n = BN_new())
1336 || !TEST_ptr(order = BN_new())
1337 || !TEST_ptr(yplusone = BN_new())
1339 || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1340 || !TEST_true(BN_hex2bn(&p, test->p))
1341 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
1342 || !TEST_true(BN_hex2bn(&a, test->a))
1343 || !TEST_true(BN_hex2bn(&b, test->b))
1344 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1345 || !TEST_ptr(G = EC_POINT_new(NISTP))
1346 || !TEST_ptr(P = EC_POINT_new(NISTP))
1347 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1348 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1349 || !TEST_true(BN_hex2bn(&x, test->Qx))
1350 || !TEST_true(BN_hex2bn(&y, test->Qy))
1351 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1353 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1354 * and therefore setting the coordinates should fail.
1356 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1358 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1360 || !TEST_true(BN_hex2bn(&x, test->Gx))
1361 || !TEST_true(BN_hex2bn(&y, test->Gy))
1362 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1363 || !TEST_true(BN_hex2bn(&order, test->order))
1364 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1365 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1368 TEST_note("NIST test vectors ... ");
1369 if (!TEST_true(BN_hex2bn(&n, test->d)))
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))
1379 /* set generator to P = 2*G, where G is the standard generator */
1380 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1381 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1382 /* set the scalar to m=n/2, where n is the NIST test scalar */
1383 || !TEST_true(BN_rshift(m, n, 1)))
1386 /* test the non-standard generator */
1387 /* fixed point multiplication */
1388 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1389 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1391 /* random point multiplication */
1392 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1393 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1394 # ifndef OPENSSL_NO_DEPRECATED_3_0
1395 /* We have not performed precomp so this should be false */
1396 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1397 /* now repeat all tests with precomputation */
1398 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1399 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP))
1404 /* fixed point multiplication */
1405 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1406 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1408 /* random point multiplication */
1409 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1410 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1412 /* reset generator */
1413 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1415 /* fixed point multiplication */
1416 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1417 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1419 /* random point multiplication */
1420 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1421 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1424 /* regression test for felem_neg bug */
1425 if (!TEST_true(BN_set_word(m, 32))
1426 || !TEST_true(BN_set_word(n, 31))
1427 || !TEST_true(EC_POINT_copy(P, G))
1428 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1429 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1430 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1433 r = group_order_tests(NISTP);
1435 EC_GROUP_free(NISTP);
1439 EC_POINT_free(Q_CHECK);
1454 static const unsigned char p521_named[] = {
1455 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1458 static const unsigned char p521_explicit[] = {
1459 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1460 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1461 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1462 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1463 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1464 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1465 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1466 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1467 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1468 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1469 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1470 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1471 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1472 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1473 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1474 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1475 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1476 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1477 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1478 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1479 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1480 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1481 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1482 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1483 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1484 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1485 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1486 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1487 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1488 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1489 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1490 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1491 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1492 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1493 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1494 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1495 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1496 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1500 * This test validates a named curve's group parameters using
1501 * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1502 * group parameters results in the curve not being valid.
1504 static int check_named_curve_test(int id)
1506 int ret = 0, nid, field_nid, has_seed;
1507 EC_GROUP *group = NULL, *gtest = NULL;
1508 const EC_POINT *group_gen = NULL;
1509 EC_POINT *other_gen = NULL;
1510 BIGNUM *group_p = NULL, *group_a = NULL, *group_b = NULL;
1511 BIGNUM *other_p = NULL, *other_a = NULL, *other_b = NULL;
1512 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1513 BIGNUM *other_order = NULL;
1514 const BIGNUM *group_order = NULL;
1515 BN_CTX *bn_ctx = NULL;
1516 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1517 static size_t invalid_seed_len = sizeof(invalid_seed);
1520 nid = curves[id].nid;
1521 if (!TEST_ptr(bn_ctx = BN_CTX_new())
1522 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1523 || !TEST_ptr(gtest = EC_GROUP_dup(group))
1524 || !TEST_ptr(group_p = BN_new())
1525 || !TEST_ptr(group_a = BN_new())
1526 || !TEST_ptr(group_b = BN_new())
1527 || !TEST_ptr(group_cofactor = BN_new())
1528 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1529 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1530 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1531 || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL))
1532 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1533 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1534 || !TEST_ptr(other_order = BN_dup(group_order))
1535 || !TEST_true(BN_add_word(other_order, 1))
1536 || !TEST_ptr(other_a = BN_dup(group_a))
1537 || !TEST_true(BN_add_word(other_a, 1))
1538 || !TEST_ptr(other_b = BN_dup(group_b))
1539 || !TEST_true(BN_add_word(other_b, 1))
1540 || !TEST_ptr(other_cofactor = BN_dup(group_cofactor))
1541 || !TEST_true(BN_add_word(other_cofactor, 1)))
1544 /* Determine if the built-in curve has a seed field set */
1545 has_seed = (EC_GROUP_get_seed_len(group) > 0);
1546 field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
1547 if (field_nid == NID_X9_62_characteristic_two_field) {
1548 if (!TEST_ptr(other_p = BN_dup(group_p))
1549 || !TEST_true(BN_lshift1(other_p, other_p)))
1552 if (!TEST_ptr(other_p = BN_dup(group_p)))
1555 * Just choosing any arbitrary prime does not work..
1556 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1557 * nist prime. So only select one of these as an alternate prime.
1559 if (!TEST_ptr(BN_copy(other_p,
1560 BN_ucmp(BN_get0_nist_prime_192(), other_p) == 0 ?
1561 BN_get0_nist_prime_256() :
1562 BN_get0_nist_prime_192())))
1566 /* Passes because this is a valid curve */
1567 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)
1568 /* Only NIST curves pass */
1569 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 1, NULL),
1570 EC_curve_nid2nist(nid) != NULL ? nid : NID_undef))
1573 /* Fail if the curve name doesn't match the parameters */
1574 EC_GROUP_set_curve_name(group, nid + 1);
1576 if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1580 /* Restore curve name and ensure it's passing */
1581 EC_GROUP_set_curve_name(group, nid);
1582 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1585 if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len),
1591 * If the built-in curve has a seed and we set the seed to another value
1592 * then it will fail the check.
1594 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1598 * If the built-in curve does not have a seed then setting the seed will
1599 * pass the check (as the seed is optional).
1601 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1604 /* Pass if the seed is unknown (as it is optional) */
1605 if (!TEST_int_eq(EC_GROUP_set_seed(group, NULL, 0), 1)
1606 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1609 /* Check that a duped group passes */
1610 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1613 /* check that changing any generator parameter fails */
1614 if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order,
1616 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1617 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order,
1619 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1620 /* The order is not an optional field, so this should fail */
1621 || !TEST_false(EC_GROUP_set_generator(gtest, group_gen, NULL,
1623 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1625 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1626 /* Check that if the cofactor is not set then it still passes */
1627 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1629 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)
1630 /* check that restoring the generator passes */
1631 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1633 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1637 * check that changing any curve parameter fails
1639 * Setting arbitrary p, a or b might fail for some EC_GROUPs
1640 * depending on the internal EC_METHOD implementation, hence run
1641 * these tests conditionally to the success of EC_GROUP_set_curve().
1644 if (EC_GROUP_set_curve(gtest, other_p, group_a, group_b, NULL)) {
1645 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1648 /* clear the error stack if EC_GROUP_set_curve() failed */
1652 if (EC_GROUP_set_curve(gtest, group_p, other_a, group_b, NULL)) {
1653 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1656 /* clear the error stack if EC_GROUP_set_curve() failed */
1660 if (EC_GROUP_set_curve(gtest, group_p, group_a, other_b, NULL)) {
1661 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1664 /* clear the error stack if EC_GROUP_set_curve() failed */
1670 /* Check that restoring the curve parameters passes */
1671 if (!TEST_true(EC_GROUP_set_curve(gtest, group_p, group_a, group_b, NULL))
1672 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1683 BN_free(group_cofactor);
1684 BN_free(other_cofactor);
1685 BN_free(other_order);
1686 EC_POINT_free(other_gen);
1687 EC_GROUP_free(gtest);
1688 EC_GROUP_free(group);
1689 BN_CTX_free(bn_ctx);
1694 * This checks the lookup capability of EC_GROUP_check_named_curve()
1695 * when the given group was created with explicit parameters.
1697 * It is possible to retrieve an alternative alias that does not match
1698 * the original nid in this case.
1700 static int check_named_curve_lookup_test(int id)
1702 int ret = 0, nid, rv = 0;
1703 EC_GROUP *g = NULL , *ga = NULL;
1704 ECPARAMETERS *p = NULL, *pa = NULL;
1708 nid = curves[id].nid;
1709 if (!TEST_ptr(ctx = BN_CTX_new())
1710 || !TEST_ptr(g = EC_GROUP_new_by_curve_name(nid))
1711 || !TEST_ptr(p = EC_GROUP_get_ecparameters(g, NULL)))
1714 /* replace with group from explicit parameters */
1716 if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p)))
1719 if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0, NULL), 0))
1724 * fail if the returned nid is not an alias of the original group.
1726 * The comparison here is done by comparing two explicit
1727 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1728 * comparison happens with unnamed EC_GROUPs using the same
1731 if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv))
1732 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL)))
1735 /* replace with group from explicit parameters, then compare */
1737 if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa))
1738 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0))
1747 ECPARAMETERS_free(p);
1748 ECPARAMETERS_free(pa);
1755 * Sometime we cannot compare nids for equality, as the built-in curve table
1756 * includes aliases with different names for the same curve.
1758 * This function returns TRUE (1) if the checked nids are identical, or if they
1759 * alias to the same curve. FALSE (0) otherwise.
1762 int are_ec_nids_compatible(int n1d, int n2d)
1766 # ifndef OPENSSL_NO_EC2M
1768 case NID_wap_wsg_idm_ecid_wtls4:
1769 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1772 case NID_wap_wsg_idm_ecid_wtls3:
1773 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1776 case NID_wap_wsg_idm_ecid_wtls10:
1777 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1780 case NID_wap_wsg_idm_ecid_wtls11:
1781 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1783 case NID_X9_62_c2pnb163v1:
1784 case NID_wap_wsg_idm_ecid_wtls5:
1785 ret = (n2d == NID_X9_62_c2pnb163v1
1786 || n2d == NID_wap_wsg_idm_ecid_wtls5);
1788 # endif /* OPENSSL_NO_EC2M */
1790 case NID_wap_wsg_idm_ecid_wtls6:
1791 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1794 case NID_wap_wsg_idm_ecid_wtls7:
1795 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1797 # ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1799 case NID_wap_wsg_idm_ecid_wtls12:
1800 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1804 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1805 * that is associated with a specialized method.
1807 case NID_wap_wsg_idm_ecid_wtls12:
1808 ret = (n2d == NID_secp224r1);
1810 # endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1819 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1820 * EC_GROUP for built-in curves.
1822 * Note that it is possible to retrieve an alternative alias that does not match
1825 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1827 static int check_named_curve_from_ecparameters(int id)
1829 int ret = 0, nid, tnid;
1830 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1831 const EC_POINT *group_gen = NULL;
1832 EC_POINT *other_gen = NULL;
1833 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1834 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1835 const BIGNUM *group_order = NULL;
1836 BIGNUM *other_order = NULL;
1837 BN_CTX *bn_ctx = NULL;
1838 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1839 static size_t invalid_seed_len = sizeof(invalid_seed);
1840 ECPARAMETERS *params = NULL, *other_params = NULL;
1841 EC_GROUP *g_ary[8] = {NULL};
1842 EC_GROUP **g_next = &g_ary[0];
1843 ECPARAMETERS *p_ary[8] = {NULL};
1844 ECPARAMETERS **p_next = &p_ary[0];
1847 nid = curves[id].nid;
1848 TEST_note("Curve %s", OBJ_nid2sn(nid));
1849 if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1851 BN_CTX_start(bn_ctx);
1853 if (/* Allocations */
1854 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1855 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1856 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1857 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1858 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1859 /* Generate reference group and params */
1860 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1861 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1862 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1863 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1864 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1865 /* compute `other_*` values */
1866 || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1867 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1868 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1869 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1870 other_gen_x, other_gen_y, bn_ctx))
1871 || !TEST_true(BN_copy(other_order, group_order))
1872 || !TEST_true(BN_add_word(other_order, 1))
1873 || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1874 || !TEST_true(BN_add_word(other_cofactor, 1)))
1877 EC_POINT_free(other_gen);
1880 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1881 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1882 other_gen_x, other_gen_y,
1887 * ###########################
1888 * # Actual tests start here #
1889 * ###########################
1893 * Creating a group from built-in explicit parameters returns a
1896 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1897 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1900 * We cannot always guarantee the names match, as the built-in table
1901 * contains aliases for the same curve with different names.
1903 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1904 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1907 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1908 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1912 * An invalid seed in the parameters should be ignored: expect a "named"
1915 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1917 || !TEST_ptr(other_params = *p_next++ =
1918 EC_GROUP_get_ecparameters(tmpg, NULL))
1919 || !TEST_ptr(tgroup = *g_next++ =
1920 EC_GROUP_new_from_ecparameters(other_params))
1921 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1922 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1923 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1924 OPENSSL_EC_EXPLICIT_CURVE)) {
1925 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1930 * A null seed in the parameters should be ignored, as it is optional:
1931 * expect a "named" group.
1933 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1934 || !TEST_ptr(other_params = *p_next++ =
1935 EC_GROUP_get_ecparameters(tmpg, NULL))
1936 || !TEST_ptr(tgroup = *g_next++ =
1937 EC_GROUP_new_from_ecparameters(other_params))
1938 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1939 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1940 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1941 OPENSSL_EC_EXPLICIT_CURVE)) {
1942 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1947 * Check that changing any of the generator parameters does not yield a
1948 * match with the built-in curves
1950 if (/* Other gen, same group order & cofactor */
1951 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1953 || !TEST_ptr(other_params = *p_next++ =
1954 EC_GROUP_get_ecparameters(tmpg, NULL))
1955 || !TEST_ptr(tgroup = *g_next++ =
1956 EC_GROUP_new_from_ecparameters(other_params))
1957 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1958 /* Same gen & cofactor, different order */
1959 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1961 || !TEST_ptr(other_params = *p_next++ =
1962 EC_GROUP_get_ecparameters(tmpg, NULL))
1963 || !TEST_ptr(tgroup = *g_next++ =
1964 EC_GROUP_new_from_ecparameters(other_params))
1965 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1966 /* The order is not an optional field, so this should fail */
1967 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1969 /* Check that a wrong cofactor is ignored, and we still match */
1970 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1972 || !TEST_ptr(other_params = *p_next++ =
1973 EC_GROUP_get_ecparameters(tmpg, NULL))
1974 || !TEST_ptr(tgroup = *g_next++ =
1975 EC_GROUP_new_from_ecparameters(other_params))
1976 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1977 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1978 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1979 OPENSSL_EC_EXPLICIT_CURVE)
1980 /* Check that if the cofactor is not set then it still matches */
1981 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1983 || !TEST_ptr(other_params = *p_next++ =
1984 EC_GROUP_get_ecparameters(tmpg, NULL))
1985 || !TEST_ptr(tgroup = *g_next++ =
1986 EC_GROUP_new_from_ecparameters(other_params))
1987 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1988 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1989 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1990 OPENSSL_EC_EXPLICIT_CURVE)
1991 /* check that restoring the generator passes */
1992 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1994 || !TEST_ptr(other_params = *p_next++ =
1995 EC_GROUP_get_ecparameters(tmpg, NULL))
1996 || !TEST_ptr(tgroup = *g_next++ =
1997 EC_GROUP_new_from_ecparameters(other_params))
1998 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1999 || !TEST_true(are_ec_nids_compatible(nid, tnid))
2000 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
2001 OPENSSL_EC_EXPLICIT_CURVE))
2006 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
2007 EC_GROUP_free(*g_next);
2008 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
2009 ECPARAMETERS_free(*p_next);
2010 ECPARAMETERS_free(params);
2011 EC_POINT_free(other_gen);
2012 EC_GROUP_free(tmpg);
2013 EC_GROUP_free(group);
2015 BN_CTX_free(bn_ctx);
2020 static int parameter_test(void)
2022 EC_GROUP *group = NULL, *group2 = NULL;
2023 ECPARAMETERS *ecparameters = NULL;
2024 unsigned char *buf = NULL;
2027 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1))
2028 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
2029 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
2030 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
2033 EC_GROUP_free(group);
2036 /* Test the named curve encoding, which should be default. */
2037 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
2038 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
2039 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
2046 * Test the explicit encoding. P-521 requires correctly zero-padding the
2047 * curve coefficients.
2049 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
2050 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
2051 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
2056 EC_GROUP_free(group);
2057 EC_GROUP_free(group2);
2058 ECPARAMETERS_free(ecparameters);
2064 * random 256-bit explicit parameters curve, cofactor absent
2065 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
2066 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
2068 static const unsigned char params_cf_pass[] = {
2069 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2070 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
2071 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2072 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2073 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
2074 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2075 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2076 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
2077 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
2078 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
2079 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
2080 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
2081 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
2082 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
2083 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
2084 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
2085 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
2086 0x14, 0xa8, 0x2f, 0x4f
2090 * random 256-bit explicit parameters curve, cofactor absent
2091 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
2092 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
2094 static const unsigned char params_cf_fail[] = {
2095 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2096 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
2097 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2098 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2099 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
2100 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2101 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2102 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
2103 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
2104 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
2105 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
2106 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
2107 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
2108 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
2109 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
2110 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
2111 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
2112 0x34, 0xa2, 0x21, 0x01
2116 * Test two random 256-bit explicit parameters curves with absent cofactor.
2117 * The two curves are chosen to roughly straddle the bounds at which the lib
2118 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
2120 * - params_cf_pass: order is sufficiently close to p to compute cofactor
2121 * - params_cf_fail: order is too far away from p to compute cofactor
2123 * For standards-compliant curves, cofactor is chosen as small as possible.
2124 * So you can see neither of these curves are fit for cryptographic use.
2126 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
2127 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
2128 * will always succeed in computing the cofactor. Neither of these curves
2129 * conform to that -- this is just robustness testing.
2131 static int cofactor_range_test(void)
2133 EC_GROUP *group = NULL;
2136 const unsigned char *b1 = (const unsigned char *)params_cf_fail;
2137 const unsigned char *b2 = (const unsigned char *)params_cf_pass;
2139 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
2140 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
2141 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
2142 sizeof(params_cf_pass)))
2143 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
2144 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
2149 EC_GROUP_free(group);
2154 * For named curves, test that:
2155 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
2156 * - a nonsensical cofactor throws an error (negative test)
2157 * - nonsensical orders throw errors (negative tests)
2159 static int cardinality_test(int n)
2162 int nid = curves[n].nid;
2164 EC_GROUP *g1 = NULL, *g2 = NULL;
2165 EC_POINT *g2_gen = NULL;
2166 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
2167 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
2169 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
2171 if (!TEST_ptr(ctx = BN_CTX_new())
2172 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))
2173 || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) {
2181 g1_p = BN_CTX_get(ctx);
2182 g1_a = BN_CTX_get(ctx);
2183 g1_b = BN_CTX_get(ctx);
2184 g1_x = BN_CTX_get(ctx);
2185 g1_y = BN_CTX_get(ctx);
2186 g1_order = BN_CTX_get(ctx);
2187 g1_cf = BN_CTX_get(ctx);
2189 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
2190 /* pull out the explicit curve parameters */
2191 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
2192 || !TEST_true(EC_POINT_get_affine_coordinates(g1,
2193 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
2194 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
2195 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
2196 /* construct g2 manually with g1 parameters */
2197 || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx))
2198 || !TEST_ptr(g2_gen = EC_POINT_new(g2))
2199 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
2200 /* pass NULL cofactor: lib should compute it */
2201 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2202 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2203 || !TEST_BN_eq(g1_cf, g2_cf)
2204 /* pass zero cofactor: lib should compute it */
2205 || !TEST_true(BN_set_word(g2_cf, 0))
2206 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2207 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2208 || !TEST_BN_eq(g1_cf, g2_cf)
2209 /* negative test for invalid cofactor */
2210 || !TEST_true(BN_set_word(g2_cf, 0))
2211 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2212 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2213 /* negative test for NULL order */
2214 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
2215 /* negative test for zero order */
2216 || !TEST_true(BN_set_word(g1_order, 0))
2217 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2218 /* negative test for negative order */
2219 || !TEST_true(BN_set_word(g2_cf, 0))
2220 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2221 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2222 /* negative test for too large order */
2223 || !TEST_true(BN_lshift(g1_order, g1_p, 2))
2224 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
2228 EC_POINT_free(g2_gen);
2236 static int check_ec_key_field_public_range_test(int id)
2238 int ret = 0, type = 0;
2239 const EC_POINT *pub = NULL;
2240 const EC_GROUP *group = NULL;
2241 const EC_METHOD *meth = NULL;
2242 const BIGNUM *field = NULL;
2243 BIGNUM *x = NULL, *y = NULL;
2246 if (!TEST_ptr(x = BN_new())
2247 || !TEST_ptr(y = BN_new())
2248 || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid))
2249 || !TEST_ptr(group = EC_KEY_get0_group(key))
2250 || !TEST_ptr(meth = EC_GROUP_method_of(group))
2251 || !TEST_ptr(field = EC_GROUP_get0_field(group))
2252 || !TEST_int_gt(EC_KEY_generate_key(key), 0)
2253 || !TEST_int_gt(EC_KEY_check_key(key), 0)
2254 || !TEST_ptr(pub = EC_KEY_get0_public_key(key))
2255 || !TEST_int_gt(EC_POINT_get_affine_coordinates(group, pub, x, y,
2260 * Make the public point out of range by adding the field (which will still
2261 * be the same point on the curve). The add is different for char2 fields.
2263 type = EC_METHOD_get_field_type(meth);
2264 #ifndef OPENSSL_NO_EC2M
2265 if (type == NID_X9_62_characteristic_two_field) {
2266 /* test for binary curves */
2267 if (!TEST_true(BN_GF2m_add(x, x, field)))
2271 if (type == NID_X9_62_prime_field) {
2272 /* test for prime curves */
2273 if (!TEST_true(BN_add(x, x, field)))
2276 /* this should never happen */
2277 TEST_error("Unsupported EC_METHOD field_type");
2280 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key, x, y), 0))
2292 * Helper for ec_point_hex2point_test
2294 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2297 * If P is NULL use point at infinity.
2300 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2301 point_conversion_form_t form,
2305 EC_POINT *Q = NULL, *Pinf = NULL;
2309 /* If P is NULL use point at infinity. */
2310 if (!TEST_ptr(Pinf = EC_POINT_new(group))
2311 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2316 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2317 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2318 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2322 * The next check is most likely superfluous, as EC_POINT_cmp should already
2324 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2325 * so we include it anyway!
2328 && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2334 EC_POINT_free(Pinf);
2342 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2344 static int ec_point_hex2point_test(int id)
2347 EC_GROUP *group = NULL;
2348 const EC_POINT *G = NULL;
2350 BN_CTX * bnctx = NULL;
2353 nid = curves[id].nid;
2354 if (!TEST_ptr(bnctx = BN_CTX_new())
2355 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2356 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2357 || !TEST_ptr(P = EC_POINT_dup(G, group)))
2360 if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2361 POINT_CONVERSION_COMPRESSED,
2363 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2364 POINT_CONVERSION_COMPRESSED,
2366 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2367 POINT_CONVERSION_UNCOMPRESSED,
2369 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2370 POINT_CONVERSION_UNCOMPRESSED,
2372 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2373 POINT_CONVERSION_HYBRID,
2375 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2376 POINT_CONVERSION_HYBRID,
2384 EC_GROUP_free(group);
2390 #endif /* OPENSSL_NO_EC */
2392 int setup_tests(void)
2394 #ifndef OPENSSL_NO_EC
2395 crv_len = EC_get_builtin_curves(NULL, 0);
2396 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2397 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2400 ADD_TEST(parameter_test);
2401 ADD_TEST(cofactor_range_test);
2402 ADD_ALL_TESTS(cardinality_test, crv_len);
2403 ADD_TEST(prime_field_tests);
2404 # ifndef OPENSSL_NO_EC2M
2405 ADD_TEST(char2_field_tests);
2406 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2408 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
2409 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2411 ADD_ALL_TESTS(internal_curve_test, crv_len);
2412 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2413 ADD_TEST(group_field_test);
2414 ADD_ALL_TESTS(check_named_curve_test, crv_len);
2415 ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
2416 ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len);
2417 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2418 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2419 #endif /* OPENSSL_NO_EC */
2423 void cleanup_tests(void)
2425 #ifndef OPENSSL_NO_EC
2426 OPENSSL_free(curves);