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>
35 # include "openssl/core_names.h"
36 # include "openssl/param_build.h"
37 # include "openssl/evp.h"
39 static size_t crv_len = 0;
40 static EC_builtin_curve *curves = NULL;
42 /* test multiplication with group order, long and negative scalars */
43 static int group_order_tests(EC_GROUP *group)
45 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
46 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
47 const EC_POINT *G = NULL;
51 if (!TEST_ptr(n1 = BN_new())
52 || !TEST_ptr(n2 = BN_new())
53 || !TEST_ptr(order = BN_new())
54 || !TEST_ptr(ctx = BN_CTX_new())
55 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
56 || !TEST_ptr(P = EC_POINT_new(group))
57 || !TEST_ptr(Q = EC_POINT_new(group))
58 || !TEST_ptr(R = EC_POINT_new(group))
59 || !TEST_ptr(S = EC_POINT_new(group)))
62 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
63 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
64 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
65 # ifndef OPENSSL_NO_DEPRECATED_3_0
66 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
68 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
69 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
70 || !TEST_true(EC_POINT_copy(P, G))
71 || !TEST_true(BN_one(n1))
72 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
73 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
74 || !TEST_true(BN_sub(n1, order, n1))
75 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
76 || !TEST_true(EC_POINT_invert(group, Q, ctx))
77 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
80 for (i = 1; i <= 2; i++) {
81 # ifndef OPENSSL_NO_DEPRECATED_3_0
82 const BIGNUM *scalars[6];
83 const EC_POINT *points[6];
86 if (!TEST_true(BN_set_word(n1, i))
88 * If i == 1, P will be the predefined generator for which
89 * EC_GROUP_precompute_mult has set up precomputation.
91 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
92 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
93 || !TEST_true(BN_one(n1))
95 || !TEST_true(BN_sub(n1, n1, order))
96 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
97 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
100 || !TEST_true(BN_add(n2, order, BN_value_one()))
101 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
102 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
104 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
105 || !TEST_true(BN_mul(n2, n1, n2, ctx))
106 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
107 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
110 /* n2 = order^2 - 1 */
111 BN_set_negative(n2, 0);
112 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
113 /* Add P to verify the result. */
114 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
115 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
116 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
119 # ifndef OPENSSL_NO_DEPRECATED_3_0
120 /* Exercise EC_POINTs_mul, including corner cases. */
121 scalars[0] = scalars[1] = BN_value_one();
122 points[0] = points[1] = P;
124 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
125 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
126 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
130 points[0] = Q; /* => infinity */
132 points[1] = P; /* => -P */
134 points[2] = Q; /* => infinity */
136 points[3] = Q; /* => infinity */
138 points[4] = P; /* => P */
140 points[5] = Q; /* => infinity */
141 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
142 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
149 if (r == 0 && i != 0)
150 TEST_info(i == 1 ? "allowing precomputation" :
151 "without precomputation");
163 static int prime_field_tests(void)
166 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
167 EC_GROUP *group = NULL;
168 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
169 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
170 # ifndef OPENSSL_NO_DEPRECATED_3_0
171 const EC_POINT *points[4];
172 const BIGNUM *scalars[4];
174 unsigned char buf[100];
178 if (!TEST_ptr(ctx = BN_CTX_new())
179 || !TEST_ptr(p = BN_new())
180 || !TEST_ptr(a = BN_new())
181 || !TEST_ptr(b = BN_new())
182 || !TEST_true(BN_hex2bn(&p, "17"))
183 || !TEST_true(BN_hex2bn(&a, "1"))
184 || !TEST_true(BN_hex2bn(&b, "1"))
185 || !TEST_ptr(group = EC_GROUP_new_curve_GFp(p, a, b, ctx))
186 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
189 TEST_info("Curve defined by Weierstrass equation");
190 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
191 test_output_bignum("a", a);
192 test_output_bignum("b", b);
193 test_output_bignum("p", p);
196 if (!TEST_ptr(P = EC_POINT_new(group))
197 || !TEST_ptr(Q = EC_POINT_new(group))
198 || !TEST_ptr(R = EC_POINT_new(group))
199 || !TEST_true(EC_POINT_set_to_infinity(group, P))
200 || !TEST_true(EC_POINT_is_at_infinity(group, P))
201 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
202 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
203 || !TEST_true(EC_POINT_is_at_infinity(group, P))
204 || !TEST_ptr(x = BN_new())
205 || !TEST_ptr(y = BN_new())
206 || !TEST_ptr(z = BN_new())
207 || !TEST_ptr(yplusone = BN_new())
208 || !TEST_true(BN_hex2bn(&x, "D"))
209 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
212 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
213 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
215 TEST_info("Point is not on curve");
216 test_output_bignum("x", x);
217 test_output_bignum("y", y);
221 TEST_note("A cyclic subgroup:");
224 if (!TEST_int_ne(k--, 0))
227 if (EC_POINT_is_at_infinity(group, P)) {
228 TEST_note(" point at infinity");
230 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
234 test_output_bignum("x", x);
235 test_output_bignum("y", y);
238 if (!TEST_true(EC_POINT_copy(R, P))
239 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
242 } while (!EC_POINT_is_at_infinity(group, P));
244 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
245 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
249 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
251 if (!TEST_size_t_ne(len, 0)
252 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
253 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
255 test_output_memory("Generator as octet string, compressed form:",
258 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
259 buf, sizeof(buf), ctx);
260 if (!TEST_size_t_ne(len, 0)
261 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
262 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
264 test_output_memory("Generator as octet string, uncompressed form:",
267 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
268 buf, sizeof(buf), ctx);
269 if (!TEST_size_t_ne(len, 0)
270 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
271 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
273 test_output_memory("Generator as octet string, hybrid form:",
276 if (!TEST_true(EC_POINT_invert(group, P, ctx))
277 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
280 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
281 * 2000) -- not a NIST curve, but commonly used
284 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
285 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
286 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
287 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
288 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
289 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
290 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
291 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
292 || !TEST_true(BN_hex2bn(&x, "4A96B568"
293 "8EF573284664698968C38BB913CBFC82"))
294 || !TEST_true(BN_hex2bn(&y, "23a62855"
295 "3168947d59dcc912042351377ac5fb32"))
296 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
298 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
299 * and therefore setting the coordinates should fail.
301 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
303 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
304 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
305 || !TEST_true(BN_hex2bn(&z, "0100000000"
306 "000000000001F4C8F927AED3CA752257"))
307 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
308 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
310 TEST_info("SEC2 curve secp160r1 -- Generator");
311 test_output_bignum("x", x);
312 test_output_bignum("y", y);
313 /* G_y value taken from the standard: */
314 if (!TEST_true(BN_hex2bn(&z, "23a62855"
315 "3168947d59dcc912042351377ac5fb32"))
317 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
318 || !group_order_tests(group)
320 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
322 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
323 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
324 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
325 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
326 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
327 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
328 "0FA7E9AB72243049FEB8DEECC146B9B1"))
329 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
330 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
331 "7CBF20EB43A18800F4FF0AFD82FF1012"))
332 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
333 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
334 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
335 "FFFFFFFF99DEF836146BC9B1B4D22831"))
336 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
337 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
340 TEST_info("NIST curve P-192 -- Generator");
341 test_output_bignum("x", x);
342 test_output_bignum("y", y);
343 /* G_y value taken from the standard: */
344 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
345 "631011ED6B24CDD573F977A11E794811"))
347 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
349 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
350 * and therefore setting the coordinates should fail.
352 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
354 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
355 || !group_order_tests(group)
357 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
359 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
360 "FFFFFFFF000000000000000000000001"))
361 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
362 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
363 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
364 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
365 "5044B0B7D7BFD8BA270B39432355FFB4"))
366 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
367 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
368 "4A03C1D356C21122343280D6115C1D21"))
369 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
370 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
371 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
372 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
373 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
374 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
377 TEST_info("NIST curve P-224 -- Generator");
378 test_output_bignum("x", x);
379 test_output_bignum("y", y);
380 /* G_y value taken from the standard: */
381 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
382 "CD4375A05A07476444D5819985007E34"))
384 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
386 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
387 * and therefore setting the coordinates should fail.
389 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
391 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
392 || !group_order_tests(group)
394 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
396 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
397 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
398 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
399 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
400 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
401 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
402 "651D06B0CC53B0F63BCE3C3E27D2604B"))
403 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
405 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
406 "77037D812DEB33A0F4A13945D898C296"))
407 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
408 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
409 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
410 "BCE6FAADA7179E84F3B9CAC2FC632551"))
411 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
412 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
415 TEST_info("NIST curve P-256 -- Generator");
416 test_output_bignum("x", x);
417 test_output_bignum("y", y);
418 /* G_y value taken from the standard: */
419 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
420 "2BCE33576B315ECECBB6406837BF51F5"))
422 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
424 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
425 * and therefore setting the coordinates should fail.
427 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
429 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
430 || !group_order_tests(group)
432 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
434 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
435 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
436 "FFFFFFFF0000000000000000FFFFFFFF"))
437 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
438 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
439 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
440 "FFFFFFFF0000000000000000FFFFFFFC"))
441 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
442 "181D9C6EFE8141120314088F5013875A"
443 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
444 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
446 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
447 "6E1D3B628BA79B9859F741E082542A38"
448 "5502F25DBF55296C3A545E3872760AB7"))
449 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
450 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
451 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
452 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
453 "581A0DB248B0A77AECEC196ACCC52973"))
454 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
455 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
458 TEST_info("NIST curve P-384 -- Generator");
459 test_output_bignum("x", x);
460 test_output_bignum("y", y);
461 /* G_y value taken from the standard: */
462 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
463 "F8F41DBD289A147CE9DA3113B5F0B8C0"
464 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
466 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
468 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
469 * and therefore setting the coordinates should fail.
471 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
473 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
474 || !group_order_tests(group)
476 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
477 || !TEST_true(BN_hex2bn(&p, "1FF"
478 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
479 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
480 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
481 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
482 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
483 || !TEST_true(BN_hex2bn(&a, "1FF"
484 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
485 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
486 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
487 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
488 || !TEST_true(BN_hex2bn(&b, "051"
489 "953EB9618E1C9A1F929A21A0B68540EE"
490 "A2DA725B99B315F3B8B489918EF109E1"
491 "56193951EC7E937B1652C0BD3BB1BF07"
492 "3573DF883D2C34F1EF451FD46B503F00"))
493 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
494 || !TEST_true(BN_hex2bn(&x, "C6"
495 "858E06B70404E9CD9E3ECB662395B442"
496 "9C648139053FB521F828AF606B4D3DBA"
497 "A14B5E77EFE75928FE1DC127A2FFA8DE"
498 "3348B3C1856A429BF97E7E31C2E5BD66"))
499 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
500 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
501 || !TEST_true(BN_hex2bn(&z, "1FF"
502 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
503 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
504 "51868783BF2F966B7FCC0148F709A5D0"
505 "3BB5C9B8899C47AEBB6FB71E91386409"))
506 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
507 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
510 TEST_info("NIST curve P-521 -- Generator");
511 test_output_bignum("x", x);
512 test_output_bignum("y", y);
513 /* G_y value taken from the standard: */
514 if (!TEST_true(BN_hex2bn(&z, "118"
515 "39296A789A3BC0045C8A5FB42C7D1BD9"
516 "98F54449579B446817AFBD17273E662C"
517 "97EE72995EF42640C550B9013FAD0761"
518 "353C7086A272C24088BE94769FD16650"))
520 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
522 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
523 * and therefore setting the coordinates should fail.
525 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
527 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
528 || !group_order_tests(group)
530 /* more tests using the last curve */
532 /* Restore the point that got mangled in the (x, y + 1) test. */
533 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
534 || !TEST_true(EC_POINT_copy(Q, P))
535 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
536 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
537 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
538 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
539 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
540 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
541 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
542 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
545 # ifndef OPENSSL_NO_DEPRECATED_3_0
546 TEST_note("combined multiplication ...");
552 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
553 || !TEST_true(BN_add(y, z, BN_value_one()))
555 || !TEST_true(BN_rshift1(y, y)))
558 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
561 /* z is still the group order */
562 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
563 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
564 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
565 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
566 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
567 || !TEST_true(BN_add(z, z, y)))
569 BN_set_negative(z, 1);
571 scalars[1] = z; /* z = -(order + y) */
573 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
574 || !TEST_true(EC_POINT_is_at_infinity(group, P))
575 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
576 || !TEST_true(BN_add(z, x, y)))
578 BN_set_negative(z, 1);
581 scalars[2] = z; /* z = -(x+y) */
583 if (!TEST_ptr(scalar3 = BN_new()))
586 scalars[3] = scalar3;
588 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
589 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
599 EC_GROUP_free(group);
611 # ifndef OPENSSL_NO_EC2M
613 static struct c2_curve_test {
624 } char2_curve_tests[] = {
625 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
628 "0800000000000000000000000000000000000000C9",
631 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
632 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
633 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
635 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
638 "0800000000000000000000000000000000000000C9",
640 "020A601907B8C953CA1481EB10512F78744A3205FD",
641 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
642 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
643 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
645 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
648 "020000000000000000000000000000000000000004000000000000000001",
651 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
652 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
654 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
657 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
660 "020000000000000000000000000000000000000004000000000000000001",
661 "000000000000000000000000000000000000000000000000000000000001",
662 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
663 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
664 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
666 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
669 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
673 "00000000000000000000000000000000000000000000000000000000000010A1",
677 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
679 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
682 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
685 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
689 "00000000000000000000000000000000000000000000000000000000000010A1",
691 "0000000000000000000000000000000000000000000000000000000000000001",
693 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
695 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
697 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
700 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
703 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
706 "0200000000000000000000000000000000000000"
707 "0000000000000000000000000000000000000000008000000000000000000001",
710 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
711 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
712 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
713 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
715 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
716 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
719 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
722 "0200000000000000000000000000000000000000"
723 "0000000000000000000000000000000000000000008000000000000000000001",
724 "0000000000000000000000000000000000000000"
725 "0000000000000000000000000000000000000000000000000000000000000001",
726 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
727 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
728 "015D4860D088DDB3496B0C6064756260441CDE4A"
729 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
730 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
731 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
733 "0100000000000000000000000000000000000000"
734 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
737 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
741 "0000000000000000000000000000000000000000000000000000000000000000"
742 "0000000000000000000000000000000000000000000000000000000000000425",
746 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
747 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
749 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
750 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
753 "00000000000000000000000000000000000000000000000000000000131850E1"
754 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
757 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
761 "0000000000000000000000000000000000000000000000000000000000000000"
762 "0000000000000000000000000000000000000000000000000000000000000425",
764 "0000000000000000000000000000000000000000000000000000000000000000"
765 "0000000000000000000000000000000000000000000000000000000000000001",
767 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
768 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
770 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
771 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
773 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
774 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
777 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
778 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
783 static int char2_curve_test(int n)
787 BIGNUM *p = NULL, *a = NULL, *b = NULL;
788 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
789 EC_GROUP *group = NULL;
790 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
791 # ifndef OPENSSL_NO_DEPRECATED_3_0
792 const EC_POINT *points[3];
793 const BIGNUM *scalars[3];
795 struct c2_curve_test *const test = char2_curve_tests + n;
797 if (!TEST_ptr(ctx = BN_CTX_new())
798 || !TEST_ptr(p = BN_new())
799 || !TEST_ptr(a = BN_new())
800 || !TEST_ptr(b = BN_new())
801 || !TEST_ptr(x = BN_new())
802 || !TEST_ptr(y = BN_new())
803 || !TEST_ptr(z = BN_new())
804 || !TEST_ptr(yplusone = BN_new())
805 || !TEST_true(BN_hex2bn(&p, test->p))
806 || !TEST_true(BN_hex2bn(&a, test->a))
807 || !TEST_true(BN_hex2bn(&b, test->b))
808 || !TEST_true(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx))
809 || !TEST_ptr(P = EC_POINT_new(group))
810 || !TEST_ptr(Q = EC_POINT_new(group))
811 || !TEST_ptr(R = EC_POINT_new(group))
812 || !TEST_true(BN_hex2bn(&x, test->x))
813 || !TEST_true(BN_hex2bn(&y, test->y))
814 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
817 /* Change test based on whether binary point compression is enabled or not. */
818 # ifdef OPENSSL_EC_BIN_PT_COMP
820 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
821 * and therefore setting the coordinates should fail.
823 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
824 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
827 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
828 || !TEST_true(BN_hex2bn(&z, test->order))
829 || !TEST_true(BN_hex2bn(&cof, test->cof))
830 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
831 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
833 TEST_info("%s -- Generator", test->name);
834 test_output_bignum("x", x);
835 test_output_bignum("y", y);
836 /* G_y value taken from the standard: */
837 if (!TEST_true(BN_hex2bn(&z, test->y))
838 || !TEST_BN_eq(y, z))
842 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
843 * and therefore setting the coordinates should fail.
845 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
846 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
847 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
848 || !TEST_true(BN_hex2bn(&z, test->order))
849 || !TEST_true(BN_hex2bn(&cof, test->cof))
850 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
852 TEST_info("%s -- Generator:", test->name);
853 test_output_bignum("x", x);
854 test_output_bignum("y", y);
857 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
858 || !group_order_tests(group))
861 /* more tests using the last curve */
862 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
863 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
864 || !TEST_true(EC_POINT_copy(Q, P))
865 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
866 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
867 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
868 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
869 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
870 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
871 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
872 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
875 # ifndef OPENSSL_NO_DEPRECATED_3_0
876 TEST_note("combined multiplication ...");
881 if (!TEST_true(BN_add(y, z, BN_value_one()))
883 || !TEST_true(BN_rshift1(y, y)))
885 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
888 /* z is still the group order */
889 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
890 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
891 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
892 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
895 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
896 || !TEST_true(BN_add(z, z, y)))
898 BN_set_negative(z, 1);
900 scalars[1] = z; /* z = -(order + y) */
902 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
903 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
906 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
907 || !TEST_true(BN_add(z, x, y)))
909 BN_set_negative(z, 1);
912 scalars[2] = z; /* z = -(x+y) */
914 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
915 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
934 EC_GROUP_free(group);
938 static int char2_field_tests(void)
941 BIGNUM *p = NULL, *a = NULL, *b = NULL;
942 EC_GROUP *group = NULL;
943 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
944 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
945 unsigned char buf[100];
949 if (!TEST_ptr(ctx = BN_CTX_new())
950 || !TEST_ptr(p = BN_new())
951 || !TEST_ptr(a = BN_new())
952 || !TEST_ptr(b = BN_new())
953 || !TEST_true(BN_hex2bn(&p, "13"))
954 || !TEST_true(BN_hex2bn(&a, "3"))
955 || !TEST_true(BN_hex2bn(&b, "1")))
958 if (!TEST_ptr(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx))
959 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
962 TEST_info("Curve defined by Weierstrass equation");
963 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
964 test_output_bignum("a", a);
965 test_output_bignum("b", b);
966 test_output_bignum("p", p);
968 if (!TEST_ptr(P = EC_POINT_new(group))
969 || !TEST_ptr(Q = EC_POINT_new(group))
970 || !TEST_ptr(R = EC_POINT_new(group))
971 || !TEST_true(EC_POINT_set_to_infinity(group, P))
972 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
976 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
977 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
978 || !TEST_true(EC_POINT_is_at_infinity(group, P))
979 || !TEST_ptr(x = BN_new())
980 || !TEST_ptr(y = BN_new())
981 || !TEST_ptr(z = BN_new())
982 || !TEST_ptr(cof = BN_new())
983 || !TEST_ptr(yplusone = BN_new())
984 || !TEST_true(BN_hex2bn(&x, "6"))
985 /* Change test based on whether binary point compression is enabled or not. */
986 # ifdef OPENSSL_EC_BIN_PT_COMP
987 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
989 || !TEST_true(BN_hex2bn(&y, "8"))
990 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
994 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
995 /* Change test based on whether binary point compression is enabled or not. */
996 # ifdef OPENSSL_EC_BIN_PT_COMP
997 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
1000 TEST_info("Point is not on curve");
1001 test_output_bignum("x", x);
1002 test_output_bignum("y", y);
1006 TEST_note("A cyclic subgroup:");
1009 if (!TEST_int_ne(k--, 0))
1012 if (EC_POINT_is_at_infinity(group, P))
1013 TEST_note(" point at infinity");
1015 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1019 test_output_bignum("x", x);
1020 test_output_bignum("y", y);
1023 if (!TEST_true(EC_POINT_copy(R, P))
1024 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1027 while (!EC_POINT_is_at_infinity(group, P));
1029 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1030 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1033 /* Change test based on whether binary point compression is enabled or not. */
1034 # ifdef OPENSSL_EC_BIN_PT_COMP
1035 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1036 buf, sizeof(buf), ctx);
1037 if (!TEST_size_t_ne(len, 0)
1038 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1039 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1041 test_output_memory("Generator as octet string, compressed form:",
1045 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1046 buf, sizeof(buf), ctx);
1047 if (!TEST_size_t_ne(len, 0)
1048 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1049 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1051 test_output_memory("Generator as octet string, uncompressed form:",
1054 /* Change test based on whether binary point compression is enabled or not. */
1055 # ifdef OPENSSL_EC_BIN_PT_COMP
1057 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1059 if (!TEST_size_t_ne(len, 0)
1060 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1061 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1063 test_output_memory("Generator as octet string, hybrid form:",
1067 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1068 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1079 EC_GROUP_free(group);
1092 static int internal_curve_test(int n)
1094 EC_GROUP *group = NULL;
1095 int nid = curves[n].nid;
1097 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1098 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1102 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1103 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1104 EC_GROUP_free(group);
1107 EC_GROUP_free(group);
1111 static int internal_curve_test_method(int n)
1113 int r, nid = curves[n].nid;
1116 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1117 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1120 r = group_order_tests(group);
1121 EC_GROUP_free(group);
1125 static int group_field_test(void)
1128 BIGNUM *secp521r1_field = NULL;
1129 BIGNUM *sect163r2_field = NULL;
1130 EC_GROUP *secp521r1_group = NULL;
1131 EC_GROUP *sect163r2_group = NULL;
1133 BN_hex2bn(&secp521r1_field,
1134 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1135 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1136 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1137 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1141 BN_hex2bn(§163r2_field,
1142 "08000000000000000000000000000000"
1145 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1146 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1149 # ifndef OPENSSL_NO_EC2M
1150 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1151 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1155 EC_GROUP_free(secp521r1_group);
1156 EC_GROUP_free(sect163r2_group);
1157 BN_free(secp521r1_field);
1158 BN_free(sect163r2_field);
1163 * nistp_test_params contains magic numbers for testing
1164 * several NIST curves with characteristic > 3.
1166 struct nistp_test_params {
1170 * Qx, Qy and D are taken from
1171 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1172 * Otherwise, values are standard curve parameters from FIPS 180-3
1174 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1177 static const struct nistp_test_params nistp_tests_params[] = {
1183 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1185 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1187 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1189 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1191 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1193 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1195 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1197 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1199 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1203 NID_X9_62_prime256v1,
1206 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1208 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1210 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1212 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1214 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1216 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1218 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1220 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1222 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1230 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1231 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1234 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1235 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1238 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1239 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1242 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1243 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1246 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1247 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1250 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1251 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1254 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1255 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1258 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1259 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1262 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1263 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1267 static int nistp_single_test(int idx)
1269 const struct nistp_test_params *test = nistp_tests_params + idx;
1271 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1272 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1273 EC_GROUP *NISTP = NULL;
1274 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1277 TEST_note("NIST curve P-%d (optimised implementation):",
1279 if (!TEST_ptr(ctx = BN_CTX_new())
1280 || !TEST_ptr(p = BN_new())
1281 || !TEST_ptr(a = BN_new())
1282 || !TEST_ptr(b = BN_new())
1283 || !TEST_ptr(x = BN_new())
1284 || !TEST_ptr(y = BN_new())
1285 || !TEST_ptr(m = BN_new())
1286 || !TEST_ptr(n = BN_new())
1287 || !TEST_ptr(order = BN_new())
1288 || !TEST_ptr(yplusone = BN_new())
1290 || !TEST_ptr(NISTP = EC_GROUP_new_by_curve_name(test->nid))
1291 || !TEST_true(BN_hex2bn(&p, test->p))
1292 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
1293 || !TEST_true(BN_hex2bn(&a, test->a))
1294 || !TEST_true(BN_hex2bn(&b, test->b))
1295 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1296 || !TEST_ptr(G = EC_POINT_new(NISTP))
1297 || !TEST_ptr(P = EC_POINT_new(NISTP))
1298 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1299 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1300 || !TEST_true(BN_hex2bn(&x, test->Qx))
1301 || !TEST_true(BN_hex2bn(&y, test->Qy))
1302 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1304 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1305 * and therefore setting the coordinates should fail.
1307 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1309 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1311 || !TEST_true(BN_hex2bn(&x, test->Gx))
1312 || !TEST_true(BN_hex2bn(&y, test->Gy))
1313 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1314 || !TEST_true(BN_hex2bn(&order, test->order))
1315 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1316 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1319 TEST_note("NIST test vectors ... ");
1320 if (!TEST_true(BN_hex2bn(&n, test->d)))
1322 /* fixed point multiplication */
1323 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1324 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1326 /* random point multiplication */
1327 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1328 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1330 /* set generator to P = 2*G, where G is the standard generator */
1331 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1332 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1333 /* set the scalar to m=n/2, where n is the NIST test scalar */
1334 || !TEST_true(BN_rshift(m, n, 1)))
1337 /* test the non-standard generator */
1338 /* fixed point multiplication */
1339 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1340 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1342 /* random point multiplication */
1343 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1344 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1345 # ifndef OPENSSL_NO_DEPRECATED_3_0
1346 /* We have not performed precomp so this should be false */
1347 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1348 /* now repeat all tests with precomputation */
1349 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1354 /* fixed point multiplication */
1355 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1356 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1358 /* random point multiplication */
1359 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1360 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1362 /* reset generator */
1363 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1365 /* fixed point multiplication */
1366 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1367 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1369 /* random point multiplication */
1370 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1371 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1374 /* regression test for felem_neg bug */
1375 if (!TEST_true(BN_set_word(m, 32))
1376 || !TEST_true(BN_set_word(n, 31))
1377 || !TEST_true(EC_POINT_copy(P, G))
1378 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1379 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1380 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1385 EC_GROUP_free(NISTP);
1389 EC_POINT_free(Q_CHECK);
1403 static const unsigned char p521_named[] = {
1404 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1407 static const unsigned char p521_explicit[] = {
1408 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1409 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1410 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1411 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1412 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1413 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1414 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1415 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1416 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1417 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1418 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1419 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1420 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1421 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1422 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1423 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1424 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1425 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1426 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1427 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1428 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1429 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1430 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1431 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1432 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1433 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1434 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1435 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1436 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1437 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1438 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1439 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1440 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1441 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1442 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1443 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1444 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1445 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1449 * This test validates a named curve's group parameters using
1450 * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1451 * group parameters results in the curve not being valid.
1453 static int check_named_curve_test(int id)
1455 int ret = 0, nid, field_nid, has_seed;
1456 EC_GROUP *group = NULL, *gtest = NULL;
1457 const EC_POINT *group_gen = NULL;
1458 EC_POINT *other_gen = NULL;
1459 BIGNUM *group_p = NULL, *group_a = NULL, *group_b = NULL;
1460 BIGNUM *other_p = NULL, *other_a = NULL, *other_b = NULL;
1461 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1462 BIGNUM *other_order = NULL;
1463 const BIGNUM *group_order = NULL;
1464 BN_CTX *bn_ctx = NULL;
1465 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1466 static size_t invalid_seed_len = sizeof(invalid_seed);
1469 nid = curves[id].nid;
1470 if (!TEST_ptr(bn_ctx = BN_CTX_new())
1471 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1472 || !TEST_ptr(gtest = EC_GROUP_dup(group))
1473 || !TEST_ptr(group_p = BN_new())
1474 || !TEST_ptr(group_a = BN_new())
1475 || !TEST_ptr(group_b = BN_new())
1476 || !TEST_ptr(group_cofactor = BN_new())
1477 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1478 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1479 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1480 || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL))
1481 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1482 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1483 || !TEST_ptr(other_order = BN_dup(group_order))
1484 || !TEST_true(BN_add_word(other_order, 1))
1485 || !TEST_ptr(other_a = BN_dup(group_a))
1486 || !TEST_true(BN_add_word(other_a, 1))
1487 || !TEST_ptr(other_b = BN_dup(group_b))
1488 || !TEST_true(BN_add_word(other_b, 1))
1489 || !TEST_ptr(other_cofactor = BN_dup(group_cofactor))
1490 || !TEST_true(BN_add_word(other_cofactor, 1)))
1493 /* Determine if the built-in curve has a seed field set */
1494 has_seed = (EC_GROUP_get_seed_len(group) > 0);
1495 field_nid = EC_GROUP_get_field_type(group);
1496 if (field_nid == NID_X9_62_characteristic_two_field) {
1497 if (!TEST_ptr(other_p = BN_dup(group_p))
1498 || !TEST_true(BN_lshift1(other_p, other_p)))
1501 if (!TEST_ptr(other_p = BN_dup(group_p)))
1504 * Just choosing any arbitrary prime does not work..
1505 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1506 * nist prime. So only select one of these as an alternate prime.
1508 if (!TEST_ptr(BN_copy(other_p,
1509 BN_ucmp(BN_get0_nist_prime_192(), other_p) == 0 ?
1510 BN_get0_nist_prime_256() :
1511 BN_get0_nist_prime_192())))
1515 /* Passes because this is a valid curve */
1516 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)
1517 /* Only NIST curves pass */
1518 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 1, NULL),
1519 EC_curve_nid2nist(nid) != NULL ? nid : NID_undef))
1522 /* Fail if the curve name doesn't match the parameters */
1523 EC_GROUP_set_curve_name(group, nid + 1);
1525 if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1529 /* Restore curve name and ensure it's passing */
1530 EC_GROUP_set_curve_name(group, nid);
1531 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1534 if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len),
1540 * If the built-in curve has a seed and we set the seed to another value
1541 * then it will fail the check.
1543 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1547 * If the built-in curve does not have a seed then setting the seed will
1548 * pass the check (as the seed is optional).
1550 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1553 /* Pass if the seed is unknown (as it is optional) */
1554 if (!TEST_int_eq(EC_GROUP_set_seed(group, NULL, 0), 1)
1555 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1558 /* Check that a duped group passes */
1559 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1562 /* check that changing any generator parameter fails */
1563 if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order,
1565 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1566 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order,
1568 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1569 /* The order is not an optional field, so this should fail */
1570 || !TEST_false(EC_GROUP_set_generator(gtest, group_gen, NULL,
1572 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1574 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1575 /* Check that if the cofactor is not set then it still passes */
1576 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1578 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)
1579 /* check that restoring the generator passes */
1580 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1582 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1586 * check that changing any curve parameter fails
1588 * Setting arbitrary p, a or b might fail for some EC_GROUPs
1589 * depending on the internal EC_METHOD implementation, hence run
1590 * these tests conditionally to the success of EC_GROUP_set_curve().
1593 if (EC_GROUP_set_curve(gtest, other_p, group_a, group_b, NULL)) {
1594 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1597 /* clear the error stack if EC_GROUP_set_curve() failed */
1601 if (EC_GROUP_set_curve(gtest, group_p, other_a, group_b, NULL)) {
1602 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1605 /* clear the error stack if EC_GROUP_set_curve() failed */
1609 if (EC_GROUP_set_curve(gtest, group_p, group_a, other_b, NULL)) {
1610 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1613 /* clear the error stack if EC_GROUP_set_curve() failed */
1619 /* Check that restoring the curve parameters passes */
1620 if (!TEST_true(EC_GROUP_set_curve(gtest, group_p, group_a, group_b, NULL))
1621 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1632 BN_free(group_cofactor);
1633 BN_free(other_cofactor);
1634 BN_free(other_order);
1635 EC_POINT_free(other_gen);
1636 EC_GROUP_free(gtest);
1637 EC_GROUP_free(group);
1638 BN_CTX_free(bn_ctx);
1643 * This checks the lookup capability of EC_GROUP_check_named_curve()
1644 * when the given group was created with explicit parameters.
1646 * It is possible to retrieve an alternative alias that does not match
1647 * the original nid in this case.
1649 static int check_named_curve_lookup_test(int id)
1651 int ret = 0, nid, rv = 0;
1652 EC_GROUP *g = NULL , *ga = NULL;
1653 ECPARAMETERS *p = NULL, *pa = NULL;
1657 nid = curves[id].nid;
1658 if (!TEST_ptr(ctx = BN_CTX_new())
1659 || !TEST_ptr(g = EC_GROUP_new_by_curve_name(nid))
1660 || !TEST_ptr(p = EC_GROUP_get_ecparameters(g, NULL)))
1663 /* replace with group from explicit parameters */
1665 if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p)))
1668 if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0, NULL), 0))
1673 * fail if the returned nid is not an alias of the original group.
1675 * The comparison here is done by comparing two explicit
1676 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1677 * comparison happens with unnamed EC_GROUPs using the same
1680 if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv))
1681 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL)))
1684 /* replace with group from explicit parameters, then compare */
1686 if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa))
1687 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0))
1696 ECPARAMETERS_free(p);
1697 ECPARAMETERS_free(pa);
1704 * Sometime we cannot compare nids for equality, as the built-in curve table
1705 * includes aliases with different names for the same curve.
1707 * This function returns TRUE (1) if the checked nids are identical, or if they
1708 * alias to the same curve. FALSE (0) otherwise.
1711 int are_ec_nids_compatible(int n1d, int n2d)
1715 # ifndef OPENSSL_NO_EC2M
1717 case NID_wap_wsg_idm_ecid_wtls4:
1718 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1721 case NID_wap_wsg_idm_ecid_wtls3:
1722 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1725 case NID_wap_wsg_idm_ecid_wtls10:
1726 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1729 case NID_wap_wsg_idm_ecid_wtls11:
1730 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1732 case NID_X9_62_c2pnb163v1:
1733 case NID_wap_wsg_idm_ecid_wtls5:
1734 ret = (n2d == NID_X9_62_c2pnb163v1
1735 || n2d == NID_wap_wsg_idm_ecid_wtls5);
1737 # endif /* OPENSSL_NO_EC2M */
1739 case NID_wap_wsg_idm_ecid_wtls6:
1740 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1743 case NID_wap_wsg_idm_ecid_wtls7:
1744 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1746 # ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1748 case NID_wap_wsg_idm_ecid_wtls12:
1749 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1753 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1754 * that is associated with a specialized method.
1756 case NID_wap_wsg_idm_ecid_wtls12:
1757 ret = (n2d == NID_secp224r1);
1759 # endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1768 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1769 * EC_GROUP for built-in curves.
1771 * Note that it is possible to retrieve an alternative alias that does not match
1774 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1776 static int check_named_curve_from_ecparameters(int id)
1778 int ret = 0, nid, tnid;
1779 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1780 const EC_POINT *group_gen = NULL;
1781 EC_POINT *other_gen = NULL;
1782 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1783 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1784 const BIGNUM *group_order = NULL;
1785 BIGNUM *other_order = NULL;
1786 BN_CTX *bn_ctx = NULL;
1787 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1788 static size_t invalid_seed_len = sizeof(invalid_seed);
1789 ECPARAMETERS *params = NULL, *other_params = NULL;
1790 EC_GROUP *g_ary[8] = {NULL};
1791 EC_GROUP **g_next = &g_ary[0];
1792 ECPARAMETERS *p_ary[8] = {NULL};
1793 ECPARAMETERS **p_next = &p_ary[0];
1796 nid = curves[id].nid;
1797 TEST_note("Curve %s", OBJ_nid2sn(nid));
1798 if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1800 BN_CTX_start(bn_ctx);
1802 if (/* Allocations */
1803 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1804 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1805 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1806 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1807 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1808 /* Generate reference group and params */
1809 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1810 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1811 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1812 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1813 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1814 /* compute `other_*` values */
1815 || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1816 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1817 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1818 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1819 other_gen_x, other_gen_y, bn_ctx))
1820 || !TEST_true(BN_copy(other_order, group_order))
1821 || !TEST_true(BN_add_word(other_order, 1))
1822 || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1823 || !TEST_true(BN_add_word(other_cofactor, 1)))
1826 EC_POINT_free(other_gen);
1829 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1830 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1831 other_gen_x, other_gen_y,
1836 * ###########################
1837 * # Actual tests start here #
1838 * ###########################
1842 * Creating a group from built-in explicit parameters returns a
1845 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1846 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1849 * We cannot always guarantee the names match, as the built-in table
1850 * contains aliases for the same curve with different names.
1852 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1853 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1856 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1857 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1861 * An invalid seed in the parameters should be ignored: expect a "named"
1864 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1866 || !TEST_ptr(other_params = *p_next++ =
1867 EC_GROUP_get_ecparameters(tmpg, NULL))
1868 || !TEST_ptr(tgroup = *g_next++ =
1869 EC_GROUP_new_from_ecparameters(other_params))
1870 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1871 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1872 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1873 OPENSSL_EC_EXPLICIT_CURVE)) {
1874 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1879 * A null seed in the parameters should be ignored, as it is optional:
1880 * expect a "named" group.
1882 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1883 || !TEST_ptr(other_params = *p_next++ =
1884 EC_GROUP_get_ecparameters(tmpg, NULL))
1885 || !TEST_ptr(tgroup = *g_next++ =
1886 EC_GROUP_new_from_ecparameters(other_params))
1887 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1888 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1889 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1890 OPENSSL_EC_EXPLICIT_CURVE)) {
1891 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1896 * Check that changing any of the generator parameters does not yield a
1897 * match with the built-in curves
1899 if (/* Other gen, same group order & cofactor */
1900 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1902 || !TEST_ptr(other_params = *p_next++ =
1903 EC_GROUP_get_ecparameters(tmpg, NULL))
1904 || !TEST_ptr(tgroup = *g_next++ =
1905 EC_GROUP_new_from_ecparameters(other_params))
1906 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1907 /* Same gen & cofactor, different order */
1908 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1910 || !TEST_ptr(other_params = *p_next++ =
1911 EC_GROUP_get_ecparameters(tmpg, NULL))
1912 || !TEST_ptr(tgroup = *g_next++ =
1913 EC_GROUP_new_from_ecparameters(other_params))
1914 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1915 /* The order is not an optional field, so this should fail */
1916 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1918 /* Check that a wrong cofactor is ignored, and we still match */
1919 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1921 || !TEST_ptr(other_params = *p_next++ =
1922 EC_GROUP_get_ecparameters(tmpg, NULL))
1923 || !TEST_ptr(tgroup = *g_next++ =
1924 EC_GROUP_new_from_ecparameters(other_params))
1925 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1926 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1927 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1928 OPENSSL_EC_EXPLICIT_CURVE)
1929 /* Check that if the cofactor is not set then it still matches */
1930 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1932 || !TEST_ptr(other_params = *p_next++ =
1933 EC_GROUP_get_ecparameters(tmpg, NULL))
1934 || !TEST_ptr(tgroup = *g_next++ =
1935 EC_GROUP_new_from_ecparameters(other_params))
1936 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1937 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1938 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1939 OPENSSL_EC_EXPLICIT_CURVE)
1940 /* check that restoring the generator passes */
1941 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1943 || !TEST_ptr(other_params = *p_next++ =
1944 EC_GROUP_get_ecparameters(tmpg, NULL))
1945 || !TEST_ptr(tgroup = *g_next++ =
1946 EC_GROUP_new_from_ecparameters(other_params))
1947 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1948 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1949 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1950 OPENSSL_EC_EXPLICIT_CURVE))
1955 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
1956 EC_GROUP_free(*g_next);
1957 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
1958 ECPARAMETERS_free(*p_next);
1959 ECPARAMETERS_free(params);
1960 EC_POINT_free(other_gen);
1961 EC_GROUP_free(tmpg);
1962 EC_GROUP_free(group);
1964 BN_CTX_free(bn_ctx);
1969 static int parameter_test(void)
1971 EC_GROUP *group = NULL, *group2 = NULL;
1972 ECPARAMETERS *ecparameters = NULL;
1973 unsigned char *buf = NULL;
1976 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1))
1977 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1978 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1979 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1982 EC_GROUP_free(group);
1985 /* Test the named curve encoding, which should be default. */
1986 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1987 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1988 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1995 * Test the explicit encoding. P-521 requires correctly zero-padding the
1996 * curve coefficients.
1998 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1999 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
2000 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
2005 EC_GROUP_free(group);
2006 EC_GROUP_free(group2);
2007 ECPARAMETERS_free(ecparameters);
2013 * random 256-bit explicit parameters curve, cofactor absent
2014 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
2015 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
2017 static const unsigned char params_cf_pass[] = {
2018 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2019 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
2020 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2021 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2022 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
2023 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2024 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2025 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
2026 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
2027 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
2028 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
2029 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
2030 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
2031 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
2032 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
2033 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
2034 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
2035 0x14, 0xa8, 0x2f, 0x4f
2039 * random 256-bit explicit parameters curve, cofactor absent
2040 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
2041 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
2043 static const unsigned char params_cf_fail[] = {
2044 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2045 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
2046 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2047 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2048 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
2049 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2050 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2051 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
2052 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
2053 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
2054 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
2055 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
2056 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
2057 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
2058 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
2059 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
2060 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
2061 0x34, 0xa2, 0x21, 0x01
2065 * Test two random 256-bit explicit parameters curves with absent cofactor.
2066 * The two curves are chosen to roughly straddle the bounds at which the lib
2067 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
2069 * - params_cf_pass: order is sufficiently close to p to compute cofactor
2070 * - params_cf_fail: order is too far away from p to compute cofactor
2072 * For standards-compliant curves, cofactor is chosen as small as possible.
2073 * So you can see neither of these curves are fit for cryptographic use.
2075 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
2076 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
2077 * will always succeed in computing the cofactor. Neither of these curves
2078 * conform to that -- this is just robustness testing.
2080 static int cofactor_range_test(void)
2082 EC_GROUP *group = NULL;
2085 const unsigned char *b1 = (const unsigned char *)params_cf_fail;
2086 const unsigned char *b2 = (const unsigned char *)params_cf_pass;
2088 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
2089 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
2090 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
2091 sizeof(params_cf_pass)))
2092 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
2093 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
2098 EC_GROUP_free(group);
2103 * For named curves, test that:
2104 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
2105 * - a nonsensical cofactor throws an error (negative test)
2106 * - nonsensical orders throw errors (negative tests)
2108 static int cardinality_test(int n)
2110 int ret = 0, is_binary = 0;
2111 int nid = curves[n].nid;
2113 EC_GROUP *g1 = NULL, *g2 = NULL;
2114 EC_POINT *g2_gen = NULL;
2115 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
2116 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
2118 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
2120 if (!TEST_ptr(ctx = BN_CTX_new())
2121 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))) {
2126 is_binary = (EC_GROUP_get_field_type(g1) == NID_X9_62_characteristic_two_field);
2129 g1_p = BN_CTX_get(ctx);
2130 g1_a = BN_CTX_get(ctx);
2131 g1_b = BN_CTX_get(ctx);
2132 g1_x = BN_CTX_get(ctx);
2133 g1_y = BN_CTX_get(ctx);
2134 g1_order = BN_CTX_get(ctx);
2135 g1_cf = BN_CTX_get(ctx);
2137 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
2138 /* pull out the explicit curve parameters */
2139 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
2140 || !TEST_true(EC_POINT_get_affine_coordinates(g1,
2141 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
2142 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
2143 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
2144 /* construct g2 manually with g1 parameters */
2145 # ifndef OPENSSL_NO_EC2M
2146 || !TEST_ptr(g2 = (is_binary) ?
2147 EC_GROUP_new_curve_GF2m(g1_p, g1_a, g1_b, ctx) :
2148 EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx))
2150 || !TEST_int_eq(0, is_binary)
2151 || !TEST_ptr(g2 = EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx))
2153 || !TEST_ptr(g2_gen = EC_POINT_new(g2))
2154 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
2155 /* pass NULL cofactor: lib should compute it */
2156 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2157 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2158 || !TEST_BN_eq(g1_cf, g2_cf)
2159 /* pass zero cofactor: lib should compute it */
2160 || !TEST_true(BN_set_word(g2_cf, 0))
2161 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2162 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2163 || !TEST_BN_eq(g1_cf, g2_cf)
2164 /* negative test for invalid cofactor */
2165 || !TEST_true(BN_set_word(g2_cf, 0))
2166 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2167 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2168 /* negative test for NULL order */
2169 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
2170 /* negative test for zero order */
2171 || !TEST_true(BN_set_word(g1_order, 0))
2172 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2173 /* negative test for negative order */
2174 || !TEST_true(BN_set_word(g2_cf, 0))
2175 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2176 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2177 /* negative test for too large order */
2178 || !TEST_true(BN_lshift(g1_order, g1_p, 2))
2179 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
2183 EC_POINT_free(g2_gen);
2191 static int check_ec_key_field_public_range_test(int id)
2193 int ret = 0, type = 0;
2194 const EC_POINT *pub = NULL;
2195 const EC_GROUP *group = NULL;
2196 const BIGNUM *field = NULL;
2197 BIGNUM *x = NULL, *y = NULL;
2200 if (!TEST_ptr(x = BN_new())
2201 || !TEST_ptr(y = BN_new())
2202 || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid))
2203 || !TEST_ptr(group = EC_KEY_get0_group(key))
2204 || !TEST_ptr(field = EC_GROUP_get0_field(group))
2205 || !TEST_int_gt(EC_KEY_generate_key(key), 0)
2206 || !TEST_int_gt(EC_KEY_check_key(key), 0)
2207 || !TEST_ptr(pub = EC_KEY_get0_public_key(key))
2208 || !TEST_int_gt(EC_POINT_get_affine_coordinates(group, pub, x, y,
2213 * Make the public point out of range by adding the field (which will still
2214 * be the same point on the curve). The add is different for char2 fields.
2216 type = EC_GROUP_get_field_type(group);
2217 #ifndef OPENSSL_NO_EC2M
2218 if (type == NID_X9_62_characteristic_two_field) {
2219 /* test for binary curves */
2220 if (!TEST_true(BN_GF2m_add(x, x, field)))
2224 if (type == NID_X9_62_prime_field) {
2225 /* test for prime curves */
2226 if (!TEST_true(BN_add(x, x, field)))
2229 /* this should never happen */
2230 TEST_error("Unsupported EC_METHOD field_type");
2233 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key, x, y), 0))
2245 * Helper for ec_point_hex2point_test
2247 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2250 * If P is NULL use point at infinity.
2253 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2254 point_conversion_form_t form,
2258 EC_POINT *Q = NULL, *Pinf = NULL;
2262 /* If P is NULL use point at infinity. */
2263 if (!TEST_ptr(Pinf = EC_POINT_new(group))
2264 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2269 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2270 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2271 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2275 * The next check is most likely superfluous, as EC_POINT_cmp should already
2277 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2278 * so we include it anyway!
2281 && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2287 EC_POINT_free(Pinf);
2295 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2297 static int ec_point_hex2point_test(int id)
2300 EC_GROUP *group = NULL;
2301 const EC_POINT *G = NULL;
2303 BN_CTX * bnctx = NULL;
2306 nid = curves[id].nid;
2307 if (!TEST_ptr(bnctx = BN_CTX_new())
2308 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2309 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2310 || !TEST_ptr(P = EC_POINT_dup(G, group)))
2313 if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2314 POINT_CONVERSION_COMPRESSED,
2316 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2317 POINT_CONVERSION_COMPRESSED,
2319 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2320 POINT_CONVERSION_UNCOMPRESSED,
2322 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2323 POINT_CONVERSION_UNCOMPRESSED,
2325 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2326 POINT_CONVERSION_HYBRID,
2328 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2329 POINT_CONVERSION_HYBRID,
2337 EC_GROUP_free(group);
2343 static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx,
2344 unsigned char *gen, int gen_size)
2347 EVP_PKEY_CTX *pctx = NULL;
2348 EVP_PKEY *pkeyparam = NULL;
2349 OSSL_PARAM_BLD *bld = NULL;
2350 const char *field_name;
2351 OSSL_PARAM *params = NULL;
2352 const OSSL_PARAM *gettable;
2354 BIGNUM *p_out = NULL, *a_out = NULL, *b_out = NULL;
2355 BIGNUM *order_out = NULL, *cofactor_out = NULL;
2357 unsigned char buf[1024];
2358 size_t buf_len, name_len;
2359 #ifndef OPENSSL_NO_EC2M
2360 unsigned int k1 = 0, k2 = 0, k3 = 0;
2361 const char *basis_name = NULL;
2364 p = BN_CTX_get(ctx);
2365 a = BN_CTX_get(ctx);
2366 b = BN_CTX_get(ctx);
2369 || !TEST_ptr(bld = OSSL_PARAM_BLD_new()))
2372 if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) {
2373 field_name = SN_X9_62_prime_field;
2375 field_name = SN_X9_62_characteristic_two_field;
2376 #ifndef OPENSSL_NO_EC2M
2377 if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) {
2378 basis_name = SN_X9_62_tpBasis;
2379 if (!TEST_true(EC_GROUP_get_trinomial_basis(group, &k1)))
2382 basis_name = SN_X9_62_ppBasis;
2383 if (!TEST_true(EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)))
2386 #endif /* OPENSSL_NO_EC2M */
2388 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))
2389 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
2390 OSSL_PKEY_PARAM_EC_FIELD_TYPE, field_name, 0))
2391 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, p))
2392 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
2393 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b)))
2396 if (EC_GROUP_get0_seed(group) != NULL) {
2397 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
2398 OSSL_PKEY_PARAM_EC_SEED, EC_GROUP_get0_seed(group),
2399 EC_GROUP_get_seed_len(group))))
2402 if (EC_GROUP_get0_cofactor(group) != NULL) {
2403 if (!TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
2404 EC_GROUP_get0_cofactor(group))))
2408 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
2409 OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_size))
2410 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER,
2411 EC_GROUP_get0_order(group))))
2414 if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))
2415 || !TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL))
2416 || !TEST_int_gt(EVP_PKEY_param_fromdata_init(pctx), 0)
2417 || !TEST_int_gt(EVP_PKEY_fromdata(pctx, &pkeyparam, params), 0))
2420 /*- Check that all the set values are retrievable -*/
2422 /* There should be no match to a group name since the generator changed */
2423 if (!TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam,
2424 OSSL_PKEY_PARAM_GROUP_NAME, name, sizeof(name),
2428 /* The encoding should be explicit as it has no group */
2429 if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
2430 OSSL_PKEY_PARAM_EC_ENCODING,
2431 name, sizeof(name), &name_len))
2432 || !TEST_str_eq(name, OSSL_PKEY_EC_ENCODING_EXPLICIT))
2435 if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
2436 OSSL_PKEY_PARAM_EC_FIELD_TYPE, name, sizeof(name),
2438 || !TEST_str_eq(name, field_name))
2441 if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam,
2442 OSSL_PKEY_PARAM_EC_GENERATOR, buf, sizeof(buf), &buf_len))
2443 || !TEST_mem_eq(buf, (int)buf_len, gen, gen_size))
2446 if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_P, &p_out))
2447 || !TEST_BN_eq(p_out, p)
2448 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_A,
2450 || !TEST_BN_eq(a_out, a)
2451 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_B,
2453 || !TEST_BN_eq(b_out, b)
2454 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_ORDER,
2456 || !TEST_BN_eq(order_out, EC_GROUP_get0_order(group)))
2459 if (EC_GROUP_get0_cofactor(group) != NULL) {
2460 if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam,
2461 OSSL_PKEY_PARAM_EC_COFACTOR, &cofactor_out))
2462 || !TEST_BN_eq(cofactor_out, EC_GROUP_get0_cofactor(group)))
2465 if (EC_GROUP_get0_seed(group) != NULL) {
2466 if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam,
2467 OSSL_PKEY_PARAM_EC_SEED, buf, sizeof(buf), &buf_len))
2468 || !TEST_mem_eq(buf, buf_len, EC_GROUP_get0_seed(group),
2469 EC_GROUP_get_seed_len(group)))
2473 if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) {
2474 /* No extra fields should be set for a prime field */
2475 if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2476 OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out))
2477 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2478 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
2479 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2480 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
2481 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2482 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
2483 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2484 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out))
2485 || !TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam,
2486 OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name),
2490 #ifndef OPENSSL_NO_EC2M
2491 if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2492 OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out))
2493 || !TEST_int_eq(EC_GROUP_get_degree(group), i_out)
2494 || !TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
2495 OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name),
2497 || !TEST_str_eq(name, basis_name))
2500 if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) {
2501 if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2502 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
2503 || !TEST_int_eq(k1, i_out)
2504 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2505 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
2506 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2507 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
2508 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2509 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out)))
2512 if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2513 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
2514 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2515 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
2516 || !TEST_int_eq(k1, i_out)
2517 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2518 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
2519 || !TEST_int_eq(k2, i_out)
2520 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2521 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out))
2522 || !TEST_int_eq(k3, i_out))
2525 #endif /* OPENSSL_NO_EC2M */
2527 if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pkeyparam))
2528 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_GROUP_NAME))
2529 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ENCODING))
2530 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_FIELD_TYPE))
2531 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_P))
2532 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_A))
2533 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_B))
2534 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_GENERATOR))
2535 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ORDER))
2536 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_COFACTOR))
2537 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_SEED))
2538 #ifndef OPENSSL_NO_EC2M
2539 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_M))
2540 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TYPE))
2541 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS))
2542 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K1))
2543 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K2))
2544 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K3))
2551 BN_free(cofactor_out);
2555 OSSL_PARAM_BLD_free_params(params);
2556 OSSL_PARAM_BLD_free(bld);
2557 EVP_PKEY_free(pkeyparam);
2558 EVP_PKEY_CTX_free(pctx);
2563 * check the EC_METHOD respects the supplied EC_GROUP_set_generator G
2565 static int custom_generator_test(int id)
2567 int ret = 0, nid, bsize;
2568 EC_GROUP *group = NULL;
2569 EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL;
2572 unsigned char *b1 = NULL, *b2 = NULL;
2575 nid = curves[id].nid;
2576 TEST_note("Curve %s", OBJ_nid2sn(nid));
2577 if (!TEST_ptr(ctx = BN_CTX_new()))
2582 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)))
2585 /* expected byte length of encoded points */
2586 bsize = (EC_GROUP_get_degree(group) + 7) / 8;
2587 bsize = 1 + 2 * bsize; /* UNCOMPRESSED_POINT format */
2589 if (!TEST_ptr(k = BN_CTX_get(ctx))
2590 /* fetch a testing scalar k != 0,1 */
2591 || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1,
2592 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
2594 || !TEST_true(BN_clear_bit(k, 0))
2595 || !TEST_ptr(G2 = EC_POINT_new(group))
2596 || !TEST_ptr(Q1 = EC_POINT_new(group))
2598 || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx))
2599 /* pull out the bytes of that */
2600 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2601 POINT_CONVERSION_UNCOMPRESSED, NULL,
2603 || !TEST_ptr(b1 = OPENSSL_malloc(bsize))
2604 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2605 POINT_CONVERSION_UNCOMPRESSED, b1,
2607 /* new generator is G2 := 2G */
2608 || !TEST_true(EC_POINT_dbl(group, G2, EC_GROUP_get0_generator(group),
2610 || !TEST_true(EC_GROUP_set_generator(group, G2,
2611 EC_GROUP_get0_order(group),
2612 EC_GROUP_get0_cofactor(group)))
2613 || !TEST_ptr(Q2 = EC_POINT_new(group))
2614 || !TEST_true(BN_rshift1(k, k))
2616 || !TEST_true(EC_POINT_mul(group, Q2, k, NULL, NULL, ctx))
2617 || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
2618 POINT_CONVERSION_UNCOMPRESSED, NULL,
2620 || !TEST_ptr(b2 = OPENSSL_malloc(bsize))
2621 || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
2622 POINT_CONVERSION_UNCOMPRESSED, b2,
2624 /* Q1 = kG = k/2 G2 = Q2 should hold */
2625 || !TEST_mem_eq(b1, bsize, b2, bsize))
2628 if (!do_test_custom_explicit_fromdata(group, ctx, b1, bsize))
2637 EC_GROUP_free(group);
2647 * check creation of curves from explicit params through the public API
2649 static int custom_params_test(int id)
2651 int ret = 0, nid, bsize;
2652 const char *curve_name = NULL;
2653 EC_GROUP *group = NULL, *altgroup = NULL;
2654 EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL;
2655 const EC_POINT *Q = NULL;
2658 unsigned char *buf1 = NULL, *buf2 = NULL;
2659 const BIGNUM *z = NULL, *cof = NULL, *priv1 = NULL;
2660 BIGNUM *p = NULL, *a = NULL, *b = NULL;
2662 EC_KEY *eckey1 = NULL, *eckey2 = NULL;
2663 EVP_PKEY *pkey1 = NULL, *pkey2 = NULL;
2664 EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL;
2666 unsigned char *pub1 = NULL , *pub2 = NULL;
2667 OSSL_PARAM_BLD *param_bld = NULL;
2668 OSSL_PARAM *params1 = NULL, *params2 = NULL;
2671 nid = curves[id].nid;
2672 curve_name = OBJ_nid2sn(nid);
2673 TEST_note("Curve %s", curve_name);
2676 return TEST_skip("custom params not supported with SM2");
2678 if (!TEST_ptr(ctx = BN_CTX_new()))
2681 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)))
2684 is_prime = EC_GROUP_get_field_type(group) == NID_X9_62_prime_field;
2685 # ifdef OPENSSL_NO_EC2M
2687 ret = TEST_skip("binary curves not supported in this build");
2693 if (!TEST_ptr(p = BN_CTX_get(ctx))
2694 || !TEST_ptr(a = BN_CTX_get(ctx))
2695 || !TEST_ptr(b = BN_CTX_get(ctx))
2696 || !TEST_ptr(k = BN_CTX_get(ctx)))
2699 /* expected byte length of encoded points */
2700 bsize = (EC_GROUP_get_degree(group) + 7) / 8;
2701 bsize = 1 + 2 * bsize; /* UNCOMPRESSED_POINT format */
2703 /* extract parameters from built-in curve */
2704 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))
2705 || !TEST_ptr(G2 = EC_POINT_new(group))
2706 /* new generator is G2 := 2G */
2707 || !TEST_true(EC_POINT_dbl(group, G2,
2708 EC_GROUP_get0_generator(group), ctx))
2709 /* pull out the bytes of that */
2710 || !TEST_int_eq(EC_POINT_point2oct(group, G2,
2711 POINT_CONVERSION_UNCOMPRESSED,
2712 NULL, 0, ctx), bsize)
2713 || !TEST_ptr(buf1 = OPENSSL_malloc(bsize))
2714 || !TEST_int_eq(EC_POINT_point2oct(group, G2,
2715 POINT_CONVERSION_UNCOMPRESSED,
2716 buf1, bsize, ctx), bsize)
2717 || !TEST_ptr(z = EC_GROUP_get0_order(group))
2718 || !TEST_ptr(cof = EC_GROUP_get0_cofactor(group))
2722 /* create a new group using same params (but different generator) */
2724 if (!TEST_ptr(altgroup = EC_GROUP_new_curve_GFp(p, a, b, ctx)))
2727 # ifndef OPENSSL_NO_EC2M
2729 if (!TEST_ptr(altgroup = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
2734 /* set 2*G as the generator of altgroup */
2735 EC_POINT_free(G2); /* discard G2 as it refers to the original group */
2736 if (!TEST_ptr(G2 = EC_POINT_new(altgroup))
2737 || !TEST_true(EC_POINT_oct2point(altgroup, G2, buf1, bsize, ctx))
2738 || !TEST_int_eq(EC_POINT_is_on_curve(altgroup, G2, ctx), 1)
2739 || !TEST_true(EC_GROUP_set_generator(altgroup, G2, z, cof))
2743 /* verify math checks out */
2744 if (/* allocate temporary points on group and altgroup */
2745 !TEST_ptr(Q1 = EC_POINT_new(group))
2746 || !TEST_ptr(Q2 = EC_POINT_new(altgroup))
2747 /* fetch a testing scalar k != 0,1 */
2748 || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1,
2749 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
2751 || !TEST_true(BN_clear_bit(k, 0))
2752 /* Q1 := kG on group */
2753 || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx))
2754 /* pull out the bytes of that */
2755 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2756 POINT_CONVERSION_UNCOMPRESSED,
2757 NULL, 0, ctx), bsize)
2758 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2759 POINT_CONVERSION_UNCOMPRESSED,
2760 buf1, bsize, ctx), bsize)
2762 || !TEST_true(BN_rshift1(k, k))
2763 /* Q2 := k/2 G2 on altgroup */
2764 || !TEST_true(EC_POINT_mul(altgroup, Q2, k, NULL, NULL, ctx))
2765 /* pull out the bytes of that */
2766 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q2,
2767 POINT_CONVERSION_UNCOMPRESSED,
2768 NULL, 0, ctx), bsize)
2769 || !TEST_ptr(buf2 = OPENSSL_malloc(bsize))
2770 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q2,
2771 POINT_CONVERSION_UNCOMPRESSED,
2772 buf2, bsize, ctx), bsize)
2773 /* Q1 = kG = k/2 G2 = Q2 should hold */
2774 || !TEST_mem_eq(buf1, bsize, buf2, bsize))
2777 /* create two `EC_KEY`s on altgroup */
2778 if (!TEST_ptr(eckey1 = EC_KEY_new())
2779 || !TEST_true(EC_KEY_set_group(eckey1, altgroup))
2780 || !TEST_true(EC_KEY_generate_key(eckey1))
2781 || !TEST_ptr(eckey2 = EC_KEY_new())
2782 || !TEST_true(EC_KEY_set_group(eckey2, altgroup))
2783 || !TEST_true(EC_KEY_generate_key(eckey2)))
2786 /* retrieve priv1 for later */
2787 if (!TEST_ptr(priv1 = EC_KEY_get0_private_key(eckey1)))
2791 * retrieve bytes for pub1 for later
2793 * We compute the pub key in the original group as we will later use it to
2794 * define a provider key in the built-in group.
2796 if (!TEST_true(EC_POINT_mul(group, Q1, priv1, NULL, NULL, ctx))
2797 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2798 POINT_CONVERSION_UNCOMPRESSED,
2799 NULL, 0, ctx), bsize)
2800 || !TEST_ptr(pub1 = OPENSSL_malloc(bsize))
2801 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2802 POINT_CONVERSION_UNCOMPRESSED,
2803 pub1, bsize, ctx), bsize))
2806 /* retrieve bytes for pub2 for later */
2807 if (!TEST_ptr(Q = EC_KEY_get0_public_key(eckey2))
2808 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q,
2809 POINT_CONVERSION_UNCOMPRESSED,
2810 NULL, 0, ctx), bsize)
2811 || !TEST_ptr(pub2 = OPENSSL_malloc(bsize))
2812 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q,
2813 POINT_CONVERSION_UNCOMPRESSED,
2814 pub2, bsize, ctx), bsize))
2817 /* create two `EVP_PKEY`s from the `EC_KEY`s */
2818 if(!TEST_ptr(pkey1 = EVP_PKEY_new())
2819 || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey1, eckey1), 1))
2821 eckey1 = NULL; /* ownership passed to pkey1 */
2822 if(!TEST_ptr(pkey2 = EVP_PKEY_new())
2823 || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey2, eckey2), 1))
2825 eckey2 = NULL; /* ownership passed to pkey2 */
2827 /* Compute keyexchange in both directions */
2828 if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))
2829 || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1)
2830 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1)
2831 || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &sslen), 1)
2832 || !TEST_int_gt(bsize, sslen)
2833 || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &sslen), 1))
2835 if (!TEST_ptr(pctx2 = EVP_PKEY_CTX_new(pkey2, NULL))
2836 || !TEST_int_eq(EVP_PKEY_derive_init(pctx2), 1)
2837 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx2, pkey1), 1)
2838 || !TEST_int_eq(EVP_PKEY_derive(pctx2, NULL, &t), 1)
2839 || !TEST_int_gt(bsize, t)
2840 || !TEST_int_le(sslen, t)
2841 || !TEST_int_eq(EVP_PKEY_derive(pctx2, buf2, &t), 1))
2844 /* Both sides should expect the same shared secret */
2845 if (!TEST_mem_eq(buf1, sslen, buf2, t))
2848 /* Build parameters for provider-native keys */
2849 if (!TEST_ptr(param_bld = OSSL_PARAM_BLD_new())
2850 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld,
2851 OSSL_PKEY_PARAM_GROUP_NAME,
2853 || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld,
2854 OSSL_PKEY_PARAM_PUB_KEY,
2856 || !TEST_true(OSSL_PARAM_BLD_push_BN(param_bld,
2857 OSSL_PKEY_PARAM_PRIV_KEY,
2859 || !TEST_ptr(params1 = OSSL_PARAM_BLD_to_param(param_bld)))
2862 OSSL_PARAM_BLD_free(param_bld);
2863 if (!TEST_ptr(param_bld = OSSL_PARAM_BLD_new())
2864 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld,
2865 OSSL_PKEY_PARAM_GROUP_NAME,
2867 || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld,
2868 OSSL_PKEY_PARAM_PUB_KEY,
2870 || !TEST_ptr(params2 = OSSL_PARAM_BLD_to_param(param_bld)))
2873 /* create two new provider-native `EVP_PKEY`s */
2874 EVP_PKEY_CTX_free(pctx2);
2875 if (!TEST_ptr(pctx2 = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL))
2876 || !TEST_true(EVP_PKEY_key_fromdata_init(pctx2))
2877 || !TEST_true(EVP_PKEY_fromdata(pctx2, &pkey1, params1))
2878 || !TEST_true(EVP_PKEY_fromdata(pctx2, &pkey2, params2)))
2881 /* compute keyexchange once more using the provider keys */
2882 EVP_PKEY_CTX_free(pctx1);
2883 if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))
2884 || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1)
2885 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1)
2886 || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &t), 1)
2887 || !TEST_int_gt(bsize, t)
2888 || !TEST_int_le(sslen, t)
2889 || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &t), 1)
2890 /* compare with previous result */
2891 || !TEST_mem_eq(buf1, t, buf2, sslen))
2899 OSSL_PARAM_BLD_free(param_bld);
2900 OSSL_PARAM_BLD_free_params(params1);
2901 OSSL_PARAM_BLD_free_params(params2);
2905 EC_GROUP_free(group);
2906 EC_GROUP_free(altgroup);
2911 EC_KEY_free(eckey1);
2912 EC_KEY_free(eckey2);
2913 EVP_PKEY_free(pkey1);
2914 EVP_PKEY_free(pkey2);
2915 EVP_PKEY_CTX_free(pctx1);
2916 EVP_PKEY_CTX_free(pctx2);
2921 #endif /* OPENSSL_NO_EC */
2923 int setup_tests(void)
2925 #ifndef OPENSSL_NO_EC
2926 crv_len = EC_get_builtin_curves(NULL, 0);
2927 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2928 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2931 ADD_TEST(parameter_test);
2932 ADD_TEST(cofactor_range_test);
2933 ADD_ALL_TESTS(cardinality_test, crv_len);
2934 ADD_TEST(prime_field_tests);
2935 # ifndef OPENSSL_NO_EC2M
2936 ADD_TEST(char2_field_tests);
2937 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2939 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2940 ADD_ALL_TESTS(internal_curve_test, crv_len);
2941 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2942 ADD_TEST(group_field_test);
2943 ADD_ALL_TESTS(check_named_curve_test, crv_len);
2944 ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
2945 ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len);
2946 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2947 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2948 ADD_ALL_TESTS(custom_generator_test, crv_len);
2949 ADD_ALL_TESTS(custom_params_test, crv_len);
2950 #endif /* OPENSSL_NO_EC */
2954 void cleanup_tests(void)
2956 #ifndef OPENSSL_NO_EC
2957 OPENSSL_free(curves);