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 for testing purposes
13 * when the deprecated calls are not hidden
15 #ifndef OPENSSL_NO_DEPRECATED_3_0
16 # define OPENSSL_SUPPRESS_DEPRECATED
20 #include "internal/nelem.h"
24 # include <openssl/ec.h>
25 # ifndef OPENSSL_NO_ENGINE
26 # include <openssl/engine.h>
28 # include <openssl/err.h>
29 # include <openssl/obj_mac.h>
30 # include <openssl/objects.h>
31 # include <openssl/rand.h>
32 # include <openssl/bn.h>
33 # include <openssl/opensslconf.h>
35 static size_t crv_len = 0;
36 static EC_builtin_curve *curves = NULL;
38 /* test multiplication with group order, long and negative scalars */
39 static int group_order_tests(EC_GROUP *group)
41 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
42 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
43 const EC_POINT *G = NULL;
47 if (!TEST_ptr(n1 = BN_new())
48 || !TEST_ptr(n2 = BN_new())
49 || !TEST_ptr(order = BN_new())
50 || !TEST_ptr(ctx = BN_CTX_new())
51 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
52 || !TEST_ptr(P = EC_POINT_new(group))
53 || !TEST_ptr(Q = EC_POINT_new(group))
54 || !TEST_ptr(R = EC_POINT_new(group))
55 || !TEST_ptr(S = EC_POINT_new(group)))
58 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
59 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
60 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
61 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
62 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
63 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
64 || !TEST_true(EC_POINT_copy(P, G))
65 || !TEST_true(BN_one(n1))
66 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
67 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
68 || !TEST_true(BN_sub(n1, order, n1))
69 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
70 || !TEST_true(EC_POINT_invert(group, Q, ctx))
71 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
74 for (i = 1; i <= 2; i++) {
75 # ifndef OPENSSL_NO_DEPRECATED_3_0
76 const BIGNUM *scalars[6];
77 const EC_POINT *points[6];
80 if (!TEST_true(BN_set_word(n1, i))
82 * If i == 1, P will be the predefined generator for which
83 * EC_GROUP_precompute_mult has set up precomputation.
85 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
86 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
87 || !TEST_true(BN_one(n1))
89 || !TEST_true(BN_sub(n1, n1, order))
90 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
91 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
94 || !TEST_true(BN_add(n2, order, BN_value_one()))
95 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
96 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
98 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
99 || !TEST_true(BN_mul(n2, n1, n2, ctx))
100 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
101 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
104 /* n2 = order^2 - 1 */
105 BN_set_negative(n2, 0);
106 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
107 /* Add P to verify the result. */
108 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
109 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
110 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
113 # ifndef OPENSSL_NO_DEPRECATED_3_0
114 /* Exercise EC_POINTs_mul, including corner cases. */
115 scalars[0] = scalars[1] = BN_value_one();
116 points[0] = points[1] = P;
118 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
119 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
120 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
124 points[0] = Q; /* => infinity */
126 points[1] = P; /* => -P */
128 points[2] = Q; /* => infinity */
130 points[3] = Q; /* => infinity */
132 points[4] = P; /* => P */
134 points[5] = Q; /* => infinity */
135 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
136 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
143 if (r == 0 && i != 0)
144 TEST_info(i == 1 ? "allowing precomputation" :
145 "without precomputation");
157 static int prime_field_tests(void)
160 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
161 EC_GROUP *group = NULL, *tmp = NULL;
162 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
163 *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
164 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
165 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
166 # ifndef OPENSSL_NO_DEPRECATED_3_0
167 const EC_POINT *points[4];
168 const BIGNUM *scalars[4];
170 unsigned char buf[100];
174 if (!TEST_ptr(ctx = BN_CTX_new())
175 || !TEST_ptr(p = BN_new())
176 || !TEST_ptr(a = BN_new())
177 || !TEST_ptr(b = BN_new())
178 || !TEST_true(BN_hex2bn(&p, "17"))
179 || !TEST_true(BN_hex2bn(&a, "1"))
180 || !TEST_true(BN_hex2bn(&b, "1"))
182 * applications should use EC_GROUP_new_curve_GFp so
183 * that the library gets to choose the EC_METHOD
185 || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
186 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
187 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
188 || !TEST_true(EC_GROUP_copy(tmp, group)))
190 EC_GROUP_free(group);
194 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
197 TEST_info("Curve defined by Weierstrass equation");
198 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
199 test_output_bignum("a", a);
200 test_output_bignum("b", b);
201 test_output_bignum("p", p);
204 if (!TEST_ptr(P = EC_POINT_new(group))
205 || !TEST_ptr(Q = EC_POINT_new(group))
206 || !TEST_ptr(R = EC_POINT_new(group))
207 || !TEST_true(EC_POINT_set_to_infinity(group, P))
208 || !TEST_true(EC_POINT_is_at_infinity(group, P))
209 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
210 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
211 || !TEST_true(EC_POINT_is_at_infinity(group, P))
212 || !TEST_ptr(x = BN_new())
213 || !TEST_ptr(y = BN_new())
214 || !TEST_ptr(z = BN_new())
215 || !TEST_ptr(yplusone = BN_new())
216 || !TEST_true(BN_hex2bn(&x, "D"))
217 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
220 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
221 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
223 TEST_info("Point is not on curve");
224 test_output_bignum("x", x);
225 test_output_bignum("y", y);
229 TEST_note("A cyclic subgroup:");
232 if (!TEST_int_ne(k--, 0))
235 if (EC_POINT_is_at_infinity(group, P)) {
236 TEST_note(" point at infinity");
238 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
242 test_output_bignum("x", x);
243 test_output_bignum("y", y);
246 if (!TEST_true(EC_POINT_copy(R, P))
247 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
250 } while (!EC_POINT_is_at_infinity(group, P));
252 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
253 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
257 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
259 if (!TEST_size_t_ne(len, 0)
260 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
261 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
263 test_output_memory("Generator as octet string, compressed form:",
266 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
267 buf, sizeof(buf), ctx);
268 if (!TEST_size_t_ne(len, 0)
269 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
270 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
272 test_output_memory("Generator as octet string, uncompressed form:",
275 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
276 buf, sizeof(buf), ctx);
277 if (!TEST_size_t_ne(len, 0)
278 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
279 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
281 test_output_memory("Generator as octet string, hybrid form:",
284 if (!TEST_true(EC_POINT_invert(group, P, ctx))
285 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
288 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
289 * 2000) -- not a NIST curve, but commonly used
292 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
293 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
294 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
295 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
296 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
297 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
298 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
299 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
300 || !TEST_true(BN_hex2bn(&x, "4A96B568"
301 "8EF573284664698968C38BB913CBFC82"))
302 || !TEST_true(BN_hex2bn(&y, "23a62855"
303 "3168947d59dcc912042351377ac5fb32"))
304 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
306 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
307 * and therefore setting the coordinates should fail.
309 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
311 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
312 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
313 || !TEST_true(BN_hex2bn(&z, "0100000000"
314 "000000000001F4C8F927AED3CA752257"))
315 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
316 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
318 TEST_info("SEC2 curve secp160r1 -- Generator");
319 test_output_bignum("x", x);
320 test_output_bignum("y", y);
321 /* G_y value taken from the standard: */
322 if (!TEST_true(BN_hex2bn(&z, "23a62855"
323 "3168947d59dcc912042351377ac5fb32"))
325 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
326 || !group_order_tests(group)
327 || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))
328 || !TEST_true(EC_GROUP_copy(P_160, group))
330 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
332 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
333 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
334 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
335 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
336 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
337 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
338 "0FA7E9AB72243049FEB8DEECC146B9B1"))
339 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
340 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
341 "7CBF20EB43A18800F4FF0AFD82FF1012"))
342 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
343 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
344 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
345 "FFFFFFFF99DEF836146BC9B1B4D22831"))
346 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
347 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
350 TEST_info("NIST curve P-192 -- Generator");
351 test_output_bignum("x", x);
352 test_output_bignum("y", y);
353 /* G_y value taken from the standard: */
354 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
355 "631011ED6B24CDD573F977A11E794811"))
357 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
359 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
360 * and therefore setting the coordinates should fail.
362 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
364 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
365 || !group_order_tests(group)
366 || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))
367 || !TEST_true(EC_GROUP_copy(P_192, group))
369 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
371 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
372 "FFFFFFFF000000000000000000000001"))
373 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
374 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
375 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
376 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
377 "5044B0B7D7BFD8BA270B39432355FFB4"))
378 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
379 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
380 "4A03C1D356C21122343280D6115C1D21"))
381 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
382 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
383 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
384 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
385 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
386 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
389 TEST_info("NIST curve P-224 -- Generator");
390 test_output_bignum("x", x);
391 test_output_bignum("y", y);
392 /* G_y value taken from the standard: */
393 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
394 "CD4375A05A07476444D5819985007E34"))
396 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
398 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
399 * and therefore setting the coordinates should fail.
401 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
403 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
404 || !group_order_tests(group)
405 || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
406 || !TEST_true(EC_GROUP_copy(P_224, group))
408 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
410 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
411 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
412 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
413 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
414 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
415 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
416 "651D06B0CC53B0F63BCE3C3E27D2604B"))
417 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
419 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
420 "77037D812DEB33A0F4A13945D898C296"))
421 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
422 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
423 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
424 "BCE6FAADA7179E84F3B9CAC2FC632551"))
425 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
426 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
429 TEST_info("NIST curve P-256 -- Generator");
430 test_output_bignum("x", x);
431 test_output_bignum("y", y);
432 /* G_y value taken from the standard: */
433 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
434 "2BCE33576B315ECECBB6406837BF51F5"))
436 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
438 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
439 * and therefore setting the coordinates should fail.
441 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
443 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
444 || !group_order_tests(group)
445 || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
446 || !TEST_true(EC_GROUP_copy(P_256, group))
448 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
450 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
451 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
452 "FFFFFFFF0000000000000000FFFFFFFF"))
453 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
454 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
455 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
456 "FFFFFFFF0000000000000000FFFFFFFC"))
457 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
458 "181D9C6EFE8141120314088F5013875A"
459 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
460 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
462 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
463 "6E1D3B628BA79B9859F741E082542A38"
464 "5502F25DBF55296C3A545E3872760AB7"))
465 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
466 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
467 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
468 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
469 "581A0DB248B0A77AECEC196ACCC52973"))
470 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
471 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
474 TEST_info("NIST curve P-384 -- Generator");
475 test_output_bignum("x", x);
476 test_output_bignum("y", y);
477 /* G_y value taken from the standard: */
478 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
479 "F8F41DBD289A147CE9DA3113B5F0B8C0"
480 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
482 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
484 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
485 * and therefore setting the coordinates should fail.
487 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
489 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
490 || !group_order_tests(group)
491 || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
492 || !TEST_true(EC_GROUP_copy(P_384, group))
494 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
495 || !TEST_true(BN_hex2bn(&p, "1FF"
496 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
497 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
500 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
501 || !TEST_true(BN_hex2bn(&a, "1FF"
502 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
503 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
504 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
505 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
506 || !TEST_true(BN_hex2bn(&b, "051"
507 "953EB9618E1C9A1F929A21A0B68540EE"
508 "A2DA725B99B315F3B8B489918EF109E1"
509 "56193951EC7E937B1652C0BD3BB1BF07"
510 "3573DF883D2C34F1EF451FD46B503F00"))
511 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
512 || !TEST_true(BN_hex2bn(&x, "C6"
513 "858E06B70404E9CD9E3ECB662395B442"
514 "9C648139053FB521F828AF606B4D3DBA"
515 "A14B5E77EFE75928FE1DC127A2FFA8DE"
516 "3348B3C1856A429BF97E7E31C2E5BD66"))
517 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
518 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
519 || !TEST_true(BN_hex2bn(&z, "1FF"
520 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
521 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
522 "51868783BF2F966B7FCC0148F709A5D0"
523 "3BB5C9B8899C47AEBB6FB71E91386409"))
524 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
525 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
528 TEST_info("NIST curve P-521 -- Generator");
529 test_output_bignum("x", x);
530 test_output_bignum("y", y);
531 /* G_y value taken from the standard: */
532 if (!TEST_true(BN_hex2bn(&z, "118"
533 "39296A789A3BC0045C8A5FB42C7D1BD9"
534 "98F54449579B446817AFBD17273E662C"
535 "97EE72995EF42640C550B9013FAD0761"
536 "353C7086A272C24088BE94769FD16650"))
538 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
540 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
541 * and therefore setting the coordinates should fail.
543 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
545 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
546 || !group_order_tests(group)
547 || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
548 || !TEST_true(EC_GROUP_copy(P_521, group))
550 /* more tests using the last curve */
552 /* Restore the point that got mangled in the (x, y + 1) test. */
553 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
554 || !TEST_true(EC_POINT_copy(Q, P))
555 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
556 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
557 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
558 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
559 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
560 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
561 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
562 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
565 # ifndef OPENSSL_NO_DEPRECATED_3_0
566 TEST_note("combined multiplication ...");
572 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
573 || !TEST_true(BN_add(y, z, BN_value_one()))
575 || !TEST_true(BN_rshift1(y, y)))
578 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
581 /* z is still the group order */
582 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
583 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
584 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
585 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
586 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
587 || !TEST_true(BN_add(z, z, y)))
589 BN_set_negative(z, 1);
591 scalars[1] = z; /* z = -(order + y) */
593 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
594 || !TEST_true(EC_POINT_is_at_infinity(group, P))
595 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
596 || !TEST_true(BN_add(z, x, y)))
598 BN_set_negative(z, 1);
601 scalars[2] = z; /* z = -(x+y) */
603 if (!TEST_ptr(scalar3 = BN_new()))
606 scalars[3] = scalar3;
608 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
609 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
619 EC_GROUP_free(group);
630 EC_GROUP_free(P_160);
631 EC_GROUP_free(P_192);
632 EC_GROUP_free(P_224);
633 EC_GROUP_free(P_256);
634 EC_GROUP_free(P_384);
635 EC_GROUP_free(P_521);
639 # ifndef OPENSSL_NO_EC2M
641 static struct c2_curve_test {
652 } char2_curve_tests[] = {
653 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
656 "0800000000000000000000000000000000000000C9",
659 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
660 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
661 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
663 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
666 "0800000000000000000000000000000000000000C9",
668 "020A601907B8C953CA1481EB10512F78744A3205FD",
669 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
670 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
671 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
673 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
676 "020000000000000000000000000000000000000004000000000000000001",
679 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
680 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
682 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
685 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
688 "020000000000000000000000000000000000000004000000000000000001",
689 "000000000000000000000000000000000000000000000000000000000001",
690 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
691 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
692 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
694 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
697 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
701 "00000000000000000000000000000000000000000000000000000000000010A1",
705 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
707 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
710 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
713 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
717 "00000000000000000000000000000000000000000000000000000000000010A1",
719 "0000000000000000000000000000000000000000000000000000000000000001",
721 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
723 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
725 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
728 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
731 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
734 "0200000000000000000000000000000000000000"
735 "0000000000000000000000000000000000000000008000000000000000000001",
738 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
739 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
740 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
741 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
743 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
744 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
747 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
750 "0200000000000000000000000000000000000000"
751 "0000000000000000000000000000000000000000008000000000000000000001",
752 "0000000000000000000000000000000000000000"
753 "0000000000000000000000000000000000000000000000000000000000000001",
754 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
755 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
756 "015D4860D088DDB3496B0C6064756260441CDE4A"
757 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
758 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
759 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
761 "0100000000000000000000000000000000000000"
762 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
765 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
769 "0000000000000000000000000000000000000000000000000000000000000000"
770 "0000000000000000000000000000000000000000000000000000000000000425",
774 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
775 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
777 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
778 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
781 "00000000000000000000000000000000000000000000000000000000131850E1"
782 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
785 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
789 "0000000000000000000000000000000000000000000000000000000000000000"
790 "0000000000000000000000000000000000000000000000000000000000000425",
792 "0000000000000000000000000000000000000000000000000000000000000000"
793 "0000000000000000000000000000000000000000000000000000000000000001",
795 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
796 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
798 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
799 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
801 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
802 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
805 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
806 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
811 static int char2_curve_test(int n)
815 BIGNUM *p = NULL, *a = NULL, *b = NULL;
816 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
817 EC_GROUP *group = NULL, *variable = NULL;
818 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
819 # ifndef OPENSSL_NO_DEPRECATED_3_0
820 const EC_POINT *points[3];
821 const BIGNUM *scalars[3];
823 struct c2_curve_test *const test = char2_curve_tests + n;
825 if (!TEST_ptr(ctx = BN_CTX_new())
826 || !TEST_ptr(p = BN_new())
827 || !TEST_ptr(a = BN_new())
828 || !TEST_ptr(b = BN_new())
829 || !TEST_ptr(x = BN_new())
830 || !TEST_ptr(y = BN_new())
831 || !TEST_ptr(z = BN_new())
832 || !TEST_ptr(yplusone = BN_new())
833 || !TEST_true(BN_hex2bn(&p, test->p))
834 || !TEST_true(BN_hex2bn(&a, test->a))
835 || !TEST_true(BN_hex2bn(&b, test->b))
836 || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method()))
837 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
838 || !TEST_ptr(P = EC_POINT_new(group))
839 || !TEST_ptr(Q = EC_POINT_new(group))
840 || !TEST_ptr(R = EC_POINT_new(group))
841 || !TEST_true(BN_hex2bn(&x, test->x))
842 || !TEST_true(BN_hex2bn(&y, test->y))
843 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
846 /* Change test based on whether binary point compression is enabled or not. */
847 # ifdef OPENSSL_EC_BIN_PT_COMP
849 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
850 * and therefore setting the coordinates should fail.
852 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
853 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
856 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
857 || !TEST_true(BN_hex2bn(&z, test->order))
858 || !TEST_true(BN_hex2bn(&cof, test->cof))
859 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
860 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
862 TEST_info("%s -- Generator", test->name);
863 test_output_bignum("x", x);
864 test_output_bignum("y", y);
865 /* G_y value taken from the standard: */
866 if (!TEST_true(BN_hex2bn(&z, test->y))
867 || !TEST_BN_eq(y, z))
871 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
872 * and therefore setting the coordinates should fail.
874 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
875 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
876 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
877 || !TEST_true(BN_hex2bn(&z, test->order))
878 || !TEST_true(BN_hex2bn(&cof, test->cof))
879 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
881 TEST_info("%s -- Generator:", test->name);
882 test_output_bignum("x", x);
883 test_output_bignum("y", y);
886 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
887 || !group_order_tests(group)
888 || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group)))
889 || !TEST_true(EC_GROUP_copy(variable, group)))
892 /* more tests using the last curve */
893 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
894 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
895 || !TEST_true(EC_POINT_copy(Q, P))
896 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
897 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
898 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
899 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
900 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
901 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
902 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
903 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
906 # ifndef OPENSSL_NO_DEPRECATED_3_0
907 TEST_note("combined multiplication ...");
912 if (!TEST_true(BN_add(y, z, BN_value_one()))
914 || !TEST_true(BN_rshift1(y, y)))
916 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
919 /* z is still the group order */
920 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
921 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
922 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
923 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
926 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
927 || !TEST_true(BN_add(z, z, y)))
929 BN_set_negative(z, 1);
931 scalars[1] = z; /* z = -(order + y) */
933 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
934 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
937 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
938 || !TEST_true(BN_add(z, x, y)))
940 BN_set_negative(z, 1);
943 scalars[2] = z; /* z = -(x+y) */
945 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
946 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
965 EC_GROUP_free(group);
966 EC_GROUP_free(variable);
970 static int char2_field_tests(void)
973 BIGNUM *p = NULL, *a = NULL, *b = NULL;
974 EC_GROUP *group = NULL, *tmp = NULL;
975 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
976 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
977 unsigned char buf[100];
981 if (!TEST_ptr(ctx = BN_CTX_new())
982 || !TEST_ptr(p = BN_new())
983 || !TEST_ptr(a = BN_new())
984 || !TEST_ptr(b = BN_new())
985 || !TEST_true(BN_hex2bn(&p, "13"))
986 || !TEST_true(BN_hex2bn(&a, "3"))
987 || !TEST_true(BN_hex2bn(&b, "1")))
990 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
991 * EC_GROUP_new_curve_GF2m
992 * so that the library gets
993 * to choose the EC_METHOD */
995 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
996 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
997 || !TEST_true(EC_GROUP_copy(tmp, group)))
999 EC_GROUP_free(group);
1003 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
1006 TEST_info("Curve defined by Weierstrass equation");
1007 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
1008 test_output_bignum("a", a);
1009 test_output_bignum("b", b);
1010 test_output_bignum("p", p);
1012 if (!TEST_ptr(P = EC_POINT_new(group))
1013 || !TEST_ptr(Q = EC_POINT_new(group))
1014 || !TEST_ptr(R = EC_POINT_new(group))
1015 || !TEST_true(EC_POINT_set_to_infinity(group, P))
1016 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1020 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
1021 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
1022 || !TEST_true(EC_POINT_is_at_infinity(group, P))
1023 || !TEST_ptr(x = BN_new())
1024 || !TEST_ptr(y = BN_new())
1025 || !TEST_ptr(z = BN_new())
1026 || !TEST_ptr(cof = BN_new())
1027 || !TEST_ptr(yplusone = BN_new())
1028 || !TEST_true(BN_hex2bn(&x, "6"))
1029 /* Change test based on whether binary point compression is enabled or not. */
1030 # ifdef OPENSSL_EC_BIN_PT_COMP
1031 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
1033 || !TEST_true(BN_hex2bn(&y, "8"))
1034 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
1038 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
1039 /* Change test based on whether binary point compression is enabled or not. */
1040 # ifdef OPENSSL_EC_BIN_PT_COMP
1041 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
1044 TEST_info("Point is not on curve");
1045 test_output_bignum("x", x);
1046 test_output_bignum("y", y);
1050 TEST_note("A cyclic subgroup:");
1053 if (!TEST_int_ne(k--, 0))
1056 if (EC_POINT_is_at_infinity(group, P))
1057 TEST_note(" point at infinity");
1059 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1063 test_output_bignum("x", x);
1064 test_output_bignum("y", y);
1067 if (!TEST_true(EC_POINT_copy(R, P))
1068 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1071 while (!EC_POINT_is_at_infinity(group, P));
1073 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1074 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1077 /* Change test based on whether binary point compression is enabled or not. */
1078 # ifdef OPENSSL_EC_BIN_PT_COMP
1079 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1080 buf, sizeof(buf), ctx);
1081 if (!TEST_size_t_ne(len, 0)
1082 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1083 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1085 test_output_memory("Generator as octet string, compressed form:",
1089 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1090 buf, sizeof(buf), ctx);
1091 if (!TEST_size_t_ne(len, 0)
1092 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1093 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1095 test_output_memory("Generator as octet string, uncompressed form:",
1098 /* Change test based on whether binary point compression is enabled or not. */
1099 # ifdef OPENSSL_EC_BIN_PT_COMP
1101 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1103 if (!TEST_size_t_ne(len, 0)
1104 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1105 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1107 test_output_memory("Generator as octet string, hybrid form:",
1111 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1112 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1123 EC_GROUP_free(group);
1137 static int internal_curve_test(int n)
1139 EC_GROUP *group = NULL;
1140 int nid = curves[n].nid;
1142 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1143 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1147 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1148 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1149 EC_GROUP_free(group);
1152 EC_GROUP_free(group);
1156 static int internal_curve_test_method(int n)
1158 int r, nid = curves[n].nid;
1161 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1162 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1165 r = group_order_tests(group);
1166 EC_GROUP_free(group);
1170 static int group_field_test(void)
1173 BIGNUM *secp521r1_field = NULL;
1174 BIGNUM *sect163r2_field = NULL;
1175 EC_GROUP *secp521r1_group = NULL;
1176 EC_GROUP *sect163r2_group = NULL;
1178 BN_hex2bn(&secp521r1_field,
1179 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1180 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1181 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1182 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1186 BN_hex2bn(§163r2_field,
1187 "08000000000000000000000000000000"
1190 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1191 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1194 # ifndef OPENSSL_NO_EC2M
1195 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1196 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1200 EC_GROUP_free(secp521r1_group);
1201 EC_GROUP_free(sect163r2_group);
1202 BN_free(secp521r1_field);
1203 BN_free(sect163r2_field);
1207 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1209 * nistp_test_params contains magic numbers for testing our optimized
1210 * implementations of several NIST curves with characteristic > 3.
1212 struct nistp_test_params {
1213 const EC_METHOD *(*meth) (void);
1216 * Qx, Qy and D are taken from
1217 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1218 * Otherwise, values are standard curve parameters from FIPS 180-3
1220 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1223 static const struct nistp_test_params nistp_tests_params[] = {
1226 EC_GFp_nistp224_method,
1229 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1231 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1233 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1235 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1237 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1239 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1241 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1243 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1245 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1249 EC_GFp_nistp256_method,
1252 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1254 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1256 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1258 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1260 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1262 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1264 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1266 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1268 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1272 EC_GFp_nistp521_method,
1276 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1277 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1280 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1281 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1284 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1285 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1288 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1289 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1292 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1293 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1296 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1297 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1300 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1301 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1304 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1305 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1308 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1309 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1313 static int nistp_single_test(int idx)
1315 const struct nistp_test_params *test = nistp_tests_params + idx;
1317 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1318 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1319 EC_GROUP *NISTP = NULL;
1320 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1323 TEST_note("NIST curve P-%d (optimised implementation):",
1325 if (!TEST_ptr(ctx = BN_CTX_new())
1326 || !TEST_ptr(p = BN_new())
1327 || !TEST_ptr(a = BN_new())
1328 || !TEST_ptr(b = BN_new())
1329 || !TEST_ptr(x = BN_new())
1330 || !TEST_ptr(y = BN_new())
1331 || !TEST_ptr(m = BN_new())
1332 || !TEST_ptr(n = BN_new())
1333 || !TEST_ptr(order = BN_new())
1334 || !TEST_ptr(yplusone = BN_new())
1336 || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1337 || !TEST_true(BN_hex2bn(&p, test->p))
1338 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
1339 || !TEST_true(BN_hex2bn(&a, test->a))
1340 || !TEST_true(BN_hex2bn(&b, test->b))
1341 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1342 || !TEST_ptr(G = EC_POINT_new(NISTP))
1343 || !TEST_ptr(P = EC_POINT_new(NISTP))
1344 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1345 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1346 || !TEST_true(BN_hex2bn(&x, test->Qx))
1347 || !TEST_true(BN_hex2bn(&y, test->Qy))
1348 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1350 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1351 * and therefore setting the coordinates should fail.
1353 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1355 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1357 || !TEST_true(BN_hex2bn(&x, test->Gx))
1358 || !TEST_true(BN_hex2bn(&y, test->Gy))
1359 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1360 || !TEST_true(BN_hex2bn(&order, test->order))
1361 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1362 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1365 TEST_note("NIST test vectors ... ");
1366 if (!TEST_true(BN_hex2bn(&n, test->d)))
1368 /* fixed point multiplication */
1369 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1370 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1372 /* random point multiplication */
1373 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1374 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1376 /* set generator to P = 2*G, where G is the standard generator */
1377 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1378 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1379 /* set the scalar to m=n/2, where n is the NIST test scalar */
1380 || !TEST_true(BN_rshift(m, n, 1)))
1383 /* test the non-standard generator */
1384 /* fixed point multiplication */
1385 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1386 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1388 /* random point multiplication */
1389 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1390 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1393 * We have not performed precomputation so have_precompute mult should be
1396 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1398 /* now repeat all tests with precomputation */
1399 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1400 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
1403 /* fixed point multiplication */
1404 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1405 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1407 /* random point multiplication */
1408 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1409 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1411 /* reset generator */
1412 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1414 /* fixed point multiplication */
1415 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1416 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1418 /* random point multiplication */
1419 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1420 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1423 /* regression test for felem_neg bug */
1424 if (!TEST_true(BN_set_word(m, 32))
1425 || !TEST_true(BN_set_word(n, 31))
1426 || !TEST_true(EC_POINT_copy(P, G))
1427 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1428 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1429 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1432 r = group_order_tests(NISTP);
1434 EC_GROUP_free(NISTP);
1438 EC_POINT_free(Q_CHECK);
1453 static const unsigned char p521_named[] = {
1454 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1457 static const unsigned char p521_explicit[] = {
1458 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1459 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1460 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1466 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1472 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1473 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1474 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1475 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1476 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1477 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1478 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1479 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1480 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1481 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1482 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1483 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1484 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1485 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1486 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1487 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1488 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1489 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1490 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1491 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1492 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1493 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1494 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1495 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1499 * This test validates a named curve's group parameters using
1500 * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1501 * group parameters results in the curve not being valid.
1503 static int check_named_curve_test(int id)
1505 int ret = 0, nid, field_nid, has_seed;
1506 EC_GROUP *group = NULL, *gtest = NULL;
1507 const EC_POINT *group_gen = NULL;
1508 EC_POINT *other_gen = NULL;
1509 BIGNUM *group_p = NULL, *group_a = NULL, *group_b = NULL;
1510 BIGNUM *other_p = NULL, *other_a = NULL, *other_b = NULL;
1511 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1512 BIGNUM *other_order = NULL;
1513 const BIGNUM *group_order = NULL;
1514 BN_CTX *bn_ctx = NULL;
1515 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1516 static size_t invalid_seed_len = sizeof(invalid_seed);
1519 nid = curves[id].nid;
1520 if (!TEST_ptr(bn_ctx = BN_CTX_new())
1521 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1522 || !TEST_ptr(gtest = EC_GROUP_dup(group))
1523 || !TEST_ptr(group_p = BN_new())
1524 || !TEST_ptr(group_a = BN_new())
1525 || !TEST_ptr(group_b = BN_new())
1526 || !TEST_ptr(group_cofactor = BN_new())
1527 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1528 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1529 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1530 || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL))
1531 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1532 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1533 || !TEST_ptr(other_order = BN_dup(group_order))
1534 || !TEST_true(BN_add_word(other_order, 1))
1535 || !TEST_ptr(other_a = BN_dup(group_a))
1536 || !TEST_true(BN_add_word(other_a, 1))
1537 || !TEST_ptr(other_b = BN_dup(group_b))
1538 || !TEST_true(BN_add_word(other_b, 1))
1539 || !TEST_ptr(other_cofactor = BN_dup(group_cofactor))
1540 || !TEST_true(BN_add_word(other_cofactor, 1)))
1543 /* Determine if the built-in curve has a seed field set */
1544 has_seed = (EC_GROUP_get_seed_len(group) > 0);
1545 field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
1546 if (field_nid == NID_X9_62_characteristic_two_field) {
1547 if (!TEST_ptr(other_p = BN_dup(group_p))
1548 || !TEST_true(BN_lshift1(other_p, other_p)))
1551 if (!TEST_ptr(other_p = BN_dup(group_p)))
1554 * Just choosing any arbitrary prime does not work..
1555 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1556 * nist prime. So only select one of these as an alternate prime.
1558 if (!TEST_ptr(BN_copy(other_p,
1559 BN_ucmp(BN_get0_nist_prime_192(), other_p) == 0 ?
1560 BN_get0_nist_prime_256() :
1561 BN_get0_nist_prime_192())))
1565 /* Passes because this is a valid curve */
1566 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)
1567 /* Only NIST curves pass */
1568 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 1, NULL),
1569 EC_curve_nid2nist(nid) != NULL ? nid : NID_undef))
1572 /* Fail if the curve name doesn't match the parameters */
1573 EC_GROUP_set_curve_name(group, nid + 1);
1575 if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1579 /* Restore curve name and ensure it's passing */
1580 EC_GROUP_set_curve_name(group, nid);
1581 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1584 if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len),
1590 * If the built-in curve has a seed and we set the seed to another value
1591 * then it will fail the check.
1593 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1597 * If the built-in curve does not have a seed then setting the seed will
1598 * pass the check (as the seed is optional).
1600 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1603 /* Pass if the seed is unknown (as it is optional) */
1604 if (!TEST_int_eq(EC_GROUP_set_seed(group, NULL, 0), 1)
1605 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1608 /* Check that a duped group passes */
1609 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1612 /* check that changing any generator parameter fails */
1613 if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order,
1615 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1616 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order,
1618 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1619 /* The order is not an optional field, so this should fail */
1620 || !TEST_false(EC_GROUP_set_generator(gtest, group_gen, NULL,
1622 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1624 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1625 /* Check that if the cofactor is not set then it still passes */
1626 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1628 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)
1629 /* check that restoring the generator passes */
1630 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1632 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1636 * check that changing any curve parameter fails
1638 * Setting arbitrary p, a or b might fail for some EC_GROUPs
1639 * depending on the internal EC_METHOD implementation, hence run
1640 * these tests conditionally to the success of EC_GROUP_set_curve().
1643 if (EC_GROUP_set_curve(gtest, other_p, group_a, group_b, NULL)) {
1644 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1647 /* clear the error stack if EC_GROUP_set_curve() failed */
1651 if (EC_GROUP_set_curve(gtest, group_p, other_a, group_b, NULL)) {
1652 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1655 /* clear the error stack if EC_GROUP_set_curve() failed */
1659 if (EC_GROUP_set_curve(gtest, group_p, group_a, other_b, NULL)) {
1660 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1663 /* clear the error stack if EC_GROUP_set_curve() failed */
1669 /* Check that restoring the curve parameters passes */
1670 if (!TEST_true(EC_GROUP_set_curve(gtest, group_p, group_a, group_b, NULL))
1671 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1682 BN_free(group_cofactor);
1683 BN_free(other_cofactor);
1684 BN_free(other_order);
1685 EC_POINT_free(other_gen);
1686 EC_GROUP_free(gtest);
1687 EC_GROUP_free(group);
1688 BN_CTX_free(bn_ctx);
1693 * This checks the lookup capability of EC_GROUP_check_named_curve()
1694 * when the given group was created with explicit parameters.
1696 * It is possible to retrieve an alternative alias that does not match
1697 * the original nid in this case.
1699 static int check_named_curve_lookup_test(int id)
1701 int ret = 0, nid, rv = 0;
1702 EC_GROUP *g = NULL , *ga = NULL;
1703 ECPARAMETERS *p = NULL, *pa = NULL;
1707 nid = curves[id].nid;
1708 if (!TEST_ptr(ctx = BN_CTX_new())
1709 || !TEST_ptr(g = EC_GROUP_new_by_curve_name(nid))
1710 || !TEST_ptr(p = EC_GROUP_get_ecparameters(g, NULL)))
1713 /* replace with group from explicit parameters */
1715 if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p)))
1718 if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0, NULL), 0))
1723 * fail if the returned nid is not an alias of the original group.
1725 * The comparison here is done by comparing two explicit
1726 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1727 * comparison happens with unnamed EC_GROUPs using the same
1730 if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv))
1731 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL)))
1734 /* replace with group from explicit parameters, then compare */
1736 if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa))
1737 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0))
1746 ECPARAMETERS_free(p);
1747 ECPARAMETERS_free(pa);
1754 * Sometime we cannot compare nids for equality, as the built-in curve table
1755 * includes aliases with different names for the same curve.
1757 * This function returns TRUE (1) if the checked nids are identical, or if they
1758 * alias to the same curve. FALSE (0) otherwise.
1761 int are_ec_nids_compatible(int n1d, int n2d)
1765 # ifndef OPENSSL_NO_EC2M
1767 case NID_wap_wsg_idm_ecid_wtls4:
1768 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1771 case NID_wap_wsg_idm_ecid_wtls3:
1772 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1775 case NID_wap_wsg_idm_ecid_wtls10:
1776 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1779 case NID_wap_wsg_idm_ecid_wtls11:
1780 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1782 case NID_X9_62_c2pnb163v1:
1783 case NID_wap_wsg_idm_ecid_wtls5:
1784 ret = (n2d == NID_X9_62_c2pnb163v1
1785 || n2d == NID_wap_wsg_idm_ecid_wtls5);
1787 # endif /* OPENSSL_NO_EC2M */
1789 case NID_wap_wsg_idm_ecid_wtls6:
1790 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1793 case NID_wap_wsg_idm_ecid_wtls7:
1794 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1796 # ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1798 case NID_wap_wsg_idm_ecid_wtls12:
1799 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1803 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1804 * that is associated with a specialized method.
1806 case NID_wap_wsg_idm_ecid_wtls12:
1807 ret = (n2d == NID_secp224r1);
1809 # endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1818 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1819 * EC_GROUP for built-in curves.
1821 * Note that it is possible to retrieve an alternative alias that does not match
1824 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1826 static int check_named_curve_from_ecparameters(int id)
1828 int ret = 0, nid, tnid;
1829 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1830 const EC_POINT *group_gen = NULL;
1831 EC_POINT *other_gen = NULL;
1832 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1833 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1834 const BIGNUM *group_order = NULL;
1835 BIGNUM *other_order = NULL;
1836 BN_CTX *bn_ctx = NULL;
1837 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1838 static size_t invalid_seed_len = sizeof(invalid_seed);
1839 ECPARAMETERS *params = NULL, *other_params = NULL;
1840 EC_GROUP *g_ary[8] = {NULL};
1841 EC_GROUP **g_next = &g_ary[0];
1842 ECPARAMETERS *p_ary[8] = {NULL};
1843 ECPARAMETERS **p_next = &p_ary[0];
1846 nid = curves[id].nid;
1847 TEST_note("Curve %s", OBJ_nid2sn(nid));
1848 if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1850 BN_CTX_start(bn_ctx);
1852 if (/* Allocations */
1853 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1854 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1855 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1856 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1857 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1858 /* Generate reference group and params */
1859 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1860 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1861 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1862 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1863 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1864 /* compute `other_*` values */
1865 || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1866 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1867 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1868 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1869 other_gen_x, other_gen_y, bn_ctx))
1870 || !TEST_true(BN_copy(other_order, group_order))
1871 || !TEST_true(BN_add_word(other_order, 1))
1872 || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1873 || !TEST_true(BN_add_word(other_cofactor, 1)))
1876 EC_POINT_free(other_gen);
1879 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1880 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1881 other_gen_x, other_gen_y,
1886 * ###########################
1887 * # Actual tests start here #
1888 * ###########################
1892 * Creating a group from built-in explicit parameters returns a
1895 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1896 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1899 * We cannot always guarantee the names match, as the built-in table
1900 * contains aliases for the same curve with different names.
1902 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1903 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1906 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1907 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1911 * An invalid seed in the parameters should be ignored: expect a "named"
1914 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1916 || !TEST_ptr(other_params = *p_next++ =
1917 EC_GROUP_get_ecparameters(tmpg, NULL))
1918 || !TEST_ptr(tgroup = *g_next++ =
1919 EC_GROUP_new_from_ecparameters(other_params))
1920 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1921 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1922 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1923 OPENSSL_EC_EXPLICIT_CURVE)) {
1924 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1929 * A null seed in the parameters should be ignored, as it is optional:
1930 * expect a "named" group.
1932 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1933 || !TEST_ptr(other_params = *p_next++ =
1934 EC_GROUP_get_ecparameters(tmpg, NULL))
1935 || !TEST_ptr(tgroup = *g_next++ =
1936 EC_GROUP_new_from_ecparameters(other_params))
1937 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1938 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1939 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1940 OPENSSL_EC_EXPLICIT_CURVE)) {
1941 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1946 * Check that changing any of the generator parameters does not yield a
1947 * match with the built-in curves
1949 if (/* Other gen, same group order & cofactor */
1950 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1952 || !TEST_ptr(other_params = *p_next++ =
1953 EC_GROUP_get_ecparameters(tmpg, NULL))
1954 || !TEST_ptr(tgroup = *g_next++ =
1955 EC_GROUP_new_from_ecparameters(other_params))
1956 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1957 /* Same gen & cofactor, different order */
1958 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1960 || !TEST_ptr(other_params = *p_next++ =
1961 EC_GROUP_get_ecparameters(tmpg, NULL))
1962 || !TEST_ptr(tgroup = *g_next++ =
1963 EC_GROUP_new_from_ecparameters(other_params))
1964 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1965 /* The order is not an optional field, so this should fail */
1966 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1968 /* Check that a wrong cofactor is ignored, and we still match */
1969 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1971 || !TEST_ptr(other_params = *p_next++ =
1972 EC_GROUP_get_ecparameters(tmpg, NULL))
1973 || !TEST_ptr(tgroup = *g_next++ =
1974 EC_GROUP_new_from_ecparameters(other_params))
1975 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1976 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1977 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1978 OPENSSL_EC_EXPLICIT_CURVE)
1979 /* Check that if the cofactor is not set then it still matches */
1980 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1982 || !TEST_ptr(other_params = *p_next++ =
1983 EC_GROUP_get_ecparameters(tmpg, NULL))
1984 || !TEST_ptr(tgroup = *g_next++ =
1985 EC_GROUP_new_from_ecparameters(other_params))
1986 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1987 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1988 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1989 OPENSSL_EC_EXPLICIT_CURVE)
1990 /* check that restoring the generator passes */
1991 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1993 || !TEST_ptr(other_params = *p_next++ =
1994 EC_GROUP_get_ecparameters(tmpg, NULL))
1995 || !TEST_ptr(tgroup = *g_next++ =
1996 EC_GROUP_new_from_ecparameters(other_params))
1997 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1998 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1999 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
2000 OPENSSL_EC_EXPLICIT_CURVE))
2005 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
2006 EC_GROUP_free(*g_next);
2007 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
2008 ECPARAMETERS_free(*p_next);
2009 ECPARAMETERS_free(params);
2010 EC_POINT_free(other_gen);
2011 EC_GROUP_free(tmpg);
2012 EC_GROUP_free(group);
2014 BN_CTX_free(bn_ctx);
2019 static int parameter_test(void)
2021 EC_GROUP *group = NULL, *group2 = NULL;
2022 ECPARAMETERS *ecparameters = NULL;
2023 unsigned char *buf = NULL;
2026 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1))
2027 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
2028 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
2029 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
2032 EC_GROUP_free(group);
2035 /* Test the named curve encoding, which should be default. */
2036 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
2037 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
2038 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
2045 * Test the explicit encoding. P-521 requires correctly zero-padding the
2046 * curve coefficients.
2048 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
2049 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
2050 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
2055 EC_GROUP_free(group);
2056 EC_GROUP_free(group2);
2057 ECPARAMETERS_free(ecparameters);
2063 * random 256-bit explicit parameters curve, cofactor absent
2064 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
2065 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
2067 static const unsigned char params_cf_pass[] = {
2068 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2069 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
2070 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2071 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2072 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
2073 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2074 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2075 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
2076 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
2077 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
2078 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
2079 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
2080 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
2081 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
2082 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
2083 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
2084 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
2085 0x14, 0xa8, 0x2f, 0x4f
2089 * random 256-bit explicit parameters curve, cofactor absent
2090 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
2091 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
2093 static const unsigned char params_cf_fail[] = {
2094 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2095 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
2096 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2097 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2098 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
2099 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2100 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2101 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
2102 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
2103 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
2104 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
2105 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
2106 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
2107 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
2108 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
2109 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
2110 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
2111 0x34, 0xa2, 0x21, 0x01
2115 * Test two random 256-bit explicit parameters curves with absent cofactor.
2116 * The two curves are chosen to roughly straddle the bounds at which the lib
2117 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
2119 * - params_cf_pass: order is sufficiently close to p to compute cofactor
2120 * - params_cf_fail: order is too far away from p to compute cofactor
2122 * For standards-compliant curves, cofactor is chosen as small as possible.
2123 * So you can see neither of these curves are fit for cryptographic use.
2125 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
2126 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
2127 * will always succeed in computing the cofactor. Neither of these curves
2128 * conform to that -- this is just robustness testing.
2130 static int cofactor_range_test(void)
2132 EC_GROUP *group = NULL;
2135 const unsigned char *b1 = (const unsigned char *)params_cf_fail;
2136 const unsigned char *b2 = (const unsigned char *)params_cf_pass;
2138 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
2139 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
2140 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
2141 sizeof(params_cf_pass)))
2142 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
2143 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
2148 EC_GROUP_free(group);
2153 * For named curves, test that:
2154 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
2155 * - a nonsensical cofactor throws an error (negative test)
2156 * - nonsensical orders throw errors (negative tests)
2158 static int cardinality_test(int n)
2161 int nid = curves[n].nid;
2163 EC_GROUP *g1 = NULL, *g2 = NULL;
2164 EC_POINT *g2_gen = NULL;
2165 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
2166 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
2168 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
2170 if (!TEST_ptr(ctx = BN_CTX_new())
2171 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))
2172 || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) {
2180 g1_p = BN_CTX_get(ctx);
2181 g1_a = BN_CTX_get(ctx);
2182 g1_b = BN_CTX_get(ctx);
2183 g1_x = BN_CTX_get(ctx);
2184 g1_y = BN_CTX_get(ctx);
2185 g1_order = BN_CTX_get(ctx);
2186 g1_cf = BN_CTX_get(ctx);
2188 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
2189 /* pull out the explicit curve parameters */
2190 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
2191 || !TEST_true(EC_POINT_get_affine_coordinates(g1,
2192 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
2193 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
2194 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
2195 /* construct g2 manually with g1 parameters */
2196 || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx))
2197 || !TEST_ptr(g2_gen = EC_POINT_new(g2))
2198 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
2199 /* pass NULL cofactor: lib should compute it */
2200 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2201 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2202 || !TEST_BN_eq(g1_cf, g2_cf)
2203 /* pass zero cofactor: lib should compute it */
2204 || !TEST_true(BN_set_word(g2_cf, 0))
2205 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2206 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2207 || !TEST_BN_eq(g1_cf, g2_cf)
2208 /* negative test for invalid cofactor */
2209 || !TEST_true(BN_set_word(g2_cf, 0))
2210 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2211 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2212 /* negative test for NULL order */
2213 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
2214 /* negative test for zero order */
2215 || !TEST_true(BN_set_word(g1_order, 0))
2216 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2217 /* negative test for negative order */
2218 || !TEST_true(BN_set_word(g2_cf, 0))
2219 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2220 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2221 /* negative test for too large order */
2222 || !TEST_true(BN_lshift(g1_order, g1_p, 2))
2223 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
2227 EC_POINT_free(g2_gen);
2235 static int check_ec_key_field_public_range_test(int id)
2237 int ret = 0, type = 0;
2238 const EC_POINT *pub = NULL;
2239 const EC_GROUP *group = NULL;
2240 const EC_METHOD *meth = NULL;
2241 const BIGNUM *field = NULL;
2242 BIGNUM *x = NULL, *y = NULL;
2245 if (!TEST_ptr(x = BN_new())
2246 || !TEST_ptr(y = BN_new())
2247 || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid))
2248 || !TEST_ptr(group = EC_KEY_get0_group(key))
2249 || !TEST_ptr(meth = EC_GROUP_method_of(group))
2250 || !TEST_ptr(field = EC_GROUP_get0_field(group))
2251 || !TEST_int_gt(EC_KEY_generate_key(key), 0)
2252 || !TEST_int_gt(EC_KEY_check_key(key), 0)
2253 || !TEST_ptr(pub = EC_KEY_get0_public_key(key))
2254 || !TEST_int_gt(EC_POINT_get_affine_coordinates(group, pub, x, y,
2259 * Make the public point out of range by adding the field (which will still
2260 * be the same point on the curve). The add is different for char2 fields.
2262 type = EC_METHOD_get_field_type(meth);
2263 #ifndef OPENSSL_NO_EC2M
2264 if (type == NID_X9_62_characteristic_two_field) {
2265 /* test for binary curves */
2266 if (!TEST_true(BN_GF2m_add(x, x, field)))
2270 if (type == NID_X9_62_prime_field) {
2271 /* test for prime curves */
2272 if (!TEST_true(BN_add(x, x, field)))
2275 /* this should never happen */
2276 TEST_error("Unsupported EC_METHOD field_type");
2279 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key, x, y), 0))
2291 * Helper for ec_point_hex2point_test
2293 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2296 * If P is NULL use point at infinity.
2299 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2300 point_conversion_form_t form,
2304 EC_POINT *Q = NULL, *Pinf = NULL;
2308 /* If P is NULL use point at infinity. */
2309 if (!TEST_ptr(Pinf = EC_POINT_new(group))
2310 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2315 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2316 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2317 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2321 * The next check is most likely superfluous, as EC_POINT_cmp should already
2323 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2324 * so we include it anyway!
2327 && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2333 EC_POINT_free(Pinf);
2341 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2343 static int ec_point_hex2point_test(int id)
2346 EC_GROUP *group = NULL;
2347 const EC_POINT *G = NULL;
2349 BN_CTX * bnctx = NULL;
2352 nid = curves[id].nid;
2353 if (!TEST_ptr(bnctx = BN_CTX_new())
2354 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2355 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2356 || !TEST_ptr(P = EC_POINT_dup(G, group)))
2359 if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2360 POINT_CONVERSION_COMPRESSED,
2362 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2363 POINT_CONVERSION_COMPRESSED,
2365 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2366 POINT_CONVERSION_UNCOMPRESSED,
2368 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2369 POINT_CONVERSION_UNCOMPRESSED,
2371 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2372 POINT_CONVERSION_HYBRID,
2374 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2375 POINT_CONVERSION_HYBRID,
2383 EC_GROUP_free(group);
2389 #endif /* OPENSSL_NO_EC */
2391 int setup_tests(void)
2393 #ifndef OPENSSL_NO_EC
2394 crv_len = EC_get_builtin_curves(NULL, 0);
2395 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2396 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2399 ADD_TEST(parameter_test);
2400 ADD_TEST(cofactor_range_test);
2401 ADD_ALL_TESTS(cardinality_test, crv_len);
2402 ADD_TEST(prime_field_tests);
2403 # ifndef OPENSSL_NO_EC2M
2404 ADD_TEST(char2_field_tests);
2405 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2407 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
2408 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2410 ADD_ALL_TESTS(internal_curve_test, crv_len);
2411 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2412 ADD_TEST(group_field_test);
2413 ADD_ALL_TESTS(check_named_curve_test, crv_len);
2414 ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
2415 ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len);
2416 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2417 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2418 #endif /* OPENSSL_NO_EC */
2422 void cleanup_tests(void)
2424 #ifndef OPENSSL_NO_EC
2425 OPENSSL_free(curves);