2 * Copyright 2001-2021 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 * EC_KEY low level APIs are deprecated for public use, but still ok for
15 #include "internal/deprecated.h"
18 #include "internal/nelem.h"
21 #include <openssl/ec.h>
22 #ifndef OPENSSL_NO_ENGINE
23 # include <openssl/engine.h>
25 #include <openssl/err.h>
26 #include <openssl/obj_mac.h>
27 #include <openssl/objects.h>
28 #include <openssl/rand.h>
29 #include <openssl/bn.h>
30 #include <openssl/opensslconf.h>
31 #include "openssl/core_names.h"
32 #include "openssl/param_build.h"
33 #include "openssl/evp.h"
35 static size_t crv_len = 0;
36 static EC_builtin_curve *curves = NULL;
38 /* test multiplication with group order, long and negative scalars */
39 static int group_order_tests(EC_GROUP *group)
41 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
42 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
43 const EC_POINT *G = NULL;
47 if (!TEST_ptr(n1 = BN_new())
48 || !TEST_ptr(n2 = BN_new())
49 || !TEST_ptr(order = BN_new())
50 || !TEST_ptr(ctx = BN_CTX_new())
51 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
52 || !TEST_ptr(P = EC_POINT_new(group))
53 || !TEST_ptr(Q = EC_POINT_new(group))
54 || !TEST_ptr(R = EC_POINT_new(group))
55 || !TEST_ptr(S = EC_POINT_new(group)))
58 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
59 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
60 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
61 #ifndef OPENSSL_NO_DEPRECATED_3_0
62 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
64 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
65 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
66 || !TEST_true(EC_POINT_copy(P, G))
67 || !TEST_true(BN_one(n1))
68 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
69 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
70 || !TEST_true(BN_sub(n1, order, n1))
71 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
72 || !TEST_true(EC_POINT_invert(group, Q, ctx))
73 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
76 for (i = 1; i <= 2; i++) {
77 #ifndef OPENSSL_NO_DEPRECATED_3_0
78 const BIGNUM *scalars[6];
79 const EC_POINT *points[6];
82 if (!TEST_true(BN_set_word(n1, i))
84 * If i == 1, P will be the predefined generator for which
85 * EC_GROUP_precompute_mult has set up precomputation.
87 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
88 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
89 || !TEST_true(BN_one(n1))
91 || !TEST_true(BN_sub(n1, n1, order))
92 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
93 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
96 || !TEST_true(BN_add(n2, order, BN_value_one()))
97 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
98 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
100 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
101 || !TEST_true(BN_mul(n2, n1, n2, ctx))
102 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
103 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
106 /* n2 = order^2 - 1 */
107 BN_set_negative(n2, 0);
108 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
109 /* Add P to verify the result. */
110 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
111 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
112 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
115 #ifndef OPENSSL_NO_DEPRECATED_3_0
116 /* Exercise EC_POINTs_mul, including corner cases. */
117 scalars[0] = scalars[1] = BN_value_one();
118 points[0] = points[1] = P;
120 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
121 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
122 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
126 points[0] = Q; /* => infinity */
128 points[1] = P; /* => -P */
130 points[2] = Q; /* => infinity */
132 points[3] = Q; /* => infinity */
134 points[4] = P; /* => P */
136 points[5] = Q; /* => infinity */
137 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
138 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
145 if (r == 0 && i != 0)
146 TEST_info(i == 1 ? "allowing precomputation" :
147 "without precomputation");
159 static int prime_field_tests(void)
162 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
163 EC_GROUP *group = NULL;
164 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
165 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
166 #ifndef OPENSSL_NO_DEPRECATED_3_0
167 const EC_POINT *points[4];
168 const BIGNUM *scalars[4];
170 unsigned char buf[100];
174 if (!TEST_ptr(ctx = BN_CTX_new())
175 || !TEST_ptr(p = BN_new())
176 || !TEST_ptr(a = BN_new())
177 || !TEST_ptr(b = BN_new())
178 || !TEST_true(BN_hex2bn(&p, "17"))
179 || !TEST_true(BN_hex2bn(&a, "1"))
180 || !TEST_true(BN_hex2bn(&b, "1"))
181 || !TEST_ptr(group = EC_GROUP_new_curve_GFp(p, a, b, ctx))
182 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
185 TEST_info("Curve defined by Weierstrass equation");
186 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
187 test_output_bignum("a", a);
188 test_output_bignum("b", b);
189 test_output_bignum("p", p);
192 if (!TEST_ptr(P = EC_POINT_new(group))
193 || !TEST_ptr(Q = EC_POINT_new(group))
194 || !TEST_ptr(R = EC_POINT_new(group))
195 || !TEST_true(EC_POINT_set_to_infinity(group, P))
196 || !TEST_true(EC_POINT_is_at_infinity(group, P))
197 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
198 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
199 || !TEST_true(EC_POINT_is_at_infinity(group, P))
200 || !TEST_ptr(x = BN_new())
201 || !TEST_ptr(y = BN_new())
202 || !TEST_ptr(z = BN_new())
203 || !TEST_ptr(yplusone = BN_new())
204 || !TEST_true(BN_hex2bn(&x, "D"))
205 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
208 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
209 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
211 TEST_info("Point is not on curve");
212 test_output_bignum("x", x);
213 test_output_bignum("y", y);
217 TEST_note("A cyclic subgroup:");
220 if (!TEST_int_ne(k--, 0))
223 if (EC_POINT_is_at_infinity(group, P)) {
224 TEST_note(" point at infinity");
226 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
230 test_output_bignum("x", x);
231 test_output_bignum("y", y);
234 if (!TEST_true(EC_POINT_copy(R, P))
235 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
238 } while (!EC_POINT_is_at_infinity(group, P));
240 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
241 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
245 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
247 if (!TEST_size_t_ne(len, 0)
248 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
249 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
251 test_output_memory("Generator as octet string, compressed form:",
254 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
255 buf, sizeof(buf), ctx);
256 if (!TEST_size_t_ne(len, 0)
257 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
258 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
260 test_output_memory("Generator as octet string, uncompressed form:",
263 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
264 buf, sizeof(buf), ctx);
265 if (!TEST_size_t_ne(len, 0)
266 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
267 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
269 test_output_memory("Generator as octet string, hybrid form:",
272 if (!TEST_true(EC_POINT_invert(group, P, ctx))
273 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
276 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
277 * 2000) -- not a NIST curve, but commonly used
280 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
281 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
282 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
283 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
284 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
285 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
286 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
287 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
288 || !TEST_true(BN_hex2bn(&x, "4A96B568"
289 "8EF573284664698968C38BB913CBFC82"))
290 || !TEST_true(BN_hex2bn(&y, "23a62855"
291 "3168947d59dcc912042351377ac5fb32"))
292 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
294 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
295 * and therefore setting the coordinates should fail.
297 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
299 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
300 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
301 || !TEST_true(BN_hex2bn(&z, "0100000000"
302 "000000000001F4C8F927AED3CA752257"))
303 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
304 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
306 TEST_info("SEC2 curve secp160r1 -- Generator");
307 test_output_bignum("x", x);
308 test_output_bignum("y", y);
309 /* G_y value taken from the standard: */
310 if (!TEST_true(BN_hex2bn(&z, "23a62855"
311 "3168947d59dcc912042351377ac5fb32"))
313 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
314 || !group_order_tests(group)
316 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
318 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
319 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
320 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
321 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
322 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
323 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
324 "0FA7E9AB72243049FEB8DEECC146B9B1"))
325 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
326 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
327 "7CBF20EB43A18800F4FF0AFD82FF1012"))
328 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
329 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
330 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
331 "FFFFFFFF99DEF836146BC9B1B4D22831"))
332 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
333 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
336 TEST_info("NIST curve P-192 -- Generator");
337 test_output_bignum("x", x);
338 test_output_bignum("y", y);
339 /* G_y value taken from the standard: */
340 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
341 "631011ED6B24CDD573F977A11E794811"))
343 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
345 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
346 * and therefore setting the coordinates should fail.
348 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
350 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
351 || !group_order_tests(group)
353 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
355 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
356 "FFFFFFFF000000000000000000000001"))
357 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
358 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
359 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
360 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
361 "5044B0B7D7BFD8BA270B39432355FFB4"))
362 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
363 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
364 "4A03C1D356C21122343280D6115C1D21"))
365 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
366 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
367 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
368 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
369 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
370 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
373 TEST_info("NIST curve P-224 -- Generator");
374 test_output_bignum("x", x);
375 test_output_bignum("y", y);
376 /* G_y value taken from the standard: */
377 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
378 "CD4375A05A07476444D5819985007E34"))
380 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
382 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
383 * and therefore setting the coordinates should fail.
385 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
387 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
388 || !group_order_tests(group)
390 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
392 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
393 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
394 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
395 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
396 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
397 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
398 "651D06B0CC53B0F63BCE3C3E27D2604B"))
399 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
401 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
402 "77037D812DEB33A0F4A13945D898C296"))
403 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
404 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
405 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
406 "BCE6FAADA7179E84F3B9CAC2FC632551"))
407 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
408 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
411 TEST_info("NIST curve P-256 -- Generator");
412 test_output_bignum("x", x);
413 test_output_bignum("y", y);
414 /* G_y value taken from the standard: */
415 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
416 "2BCE33576B315ECECBB6406837BF51F5"))
418 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
420 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
421 * and therefore setting the coordinates should fail.
423 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
425 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
426 || !group_order_tests(group)
428 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
430 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
431 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
432 "FFFFFFFF0000000000000000FFFFFFFF"))
433 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
434 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
435 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
436 "FFFFFFFF0000000000000000FFFFFFFC"))
437 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
438 "181D9C6EFE8141120314088F5013875A"
439 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
440 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
442 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
443 "6E1D3B628BA79B9859F741E082542A38"
444 "5502F25DBF55296C3A545E3872760AB7"))
445 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
446 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
447 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
448 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
449 "581A0DB248B0A77AECEC196ACCC52973"))
450 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
451 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
454 TEST_info("NIST curve P-384 -- Generator");
455 test_output_bignum("x", x);
456 test_output_bignum("y", y);
457 /* G_y value taken from the standard: */
458 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
459 "F8F41DBD289A147CE9DA3113B5F0B8C0"
460 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
462 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
464 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
465 * and therefore setting the coordinates should fail.
467 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
469 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
470 || !group_order_tests(group)
472 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
473 || !TEST_true(BN_hex2bn(&p, "1FF"
474 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
475 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
476 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
477 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
478 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
479 || !TEST_true(BN_hex2bn(&a, "1FF"
480 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
481 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
482 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
483 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
484 || !TEST_true(BN_hex2bn(&b, "051"
485 "953EB9618E1C9A1F929A21A0B68540EE"
486 "A2DA725B99B315F3B8B489918EF109E1"
487 "56193951EC7E937B1652C0BD3BB1BF07"
488 "3573DF883D2C34F1EF451FD46B503F00"))
489 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
490 || !TEST_true(BN_hex2bn(&x, "C6"
491 "858E06B70404E9CD9E3ECB662395B442"
492 "9C648139053FB521F828AF606B4D3DBA"
493 "A14B5E77EFE75928FE1DC127A2FFA8DE"
494 "3348B3C1856A429BF97E7E31C2E5BD66"))
495 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
496 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
497 || !TEST_true(BN_hex2bn(&z, "1FF"
498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
500 "51868783BF2F966B7FCC0148F709A5D0"
501 "3BB5C9B8899C47AEBB6FB71E91386409"))
502 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
503 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
506 TEST_info("NIST curve P-521 -- Generator");
507 test_output_bignum("x", x);
508 test_output_bignum("y", y);
509 /* G_y value taken from the standard: */
510 if (!TEST_true(BN_hex2bn(&z, "118"
511 "39296A789A3BC0045C8A5FB42C7D1BD9"
512 "98F54449579B446817AFBD17273E662C"
513 "97EE72995EF42640C550B9013FAD0761"
514 "353C7086A272C24088BE94769FD16650"))
516 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
518 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
519 * and therefore setting the coordinates should fail.
521 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
523 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
524 || !group_order_tests(group)
526 /* more tests using the last curve */
528 /* Restore the point that got mangled in the (x, y + 1) test. */
529 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
530 || !TEST_true(EC_POINT_copy(Q, P))
531 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
532 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
533 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
534 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
535 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
536 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
537 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
538 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
541 #ifndef OPENSSL_NO_DEPRECATED_3_0
542 TEST_note("combined multiplication ...");
548 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
549 || !TEST_true(BN_add(y, z, BN_value_one()))
551 || !TEST_true(BN_rshift1(y, y)))
554 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
557 /* z is still the group order */
558 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
559 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
560 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
561 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
562 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
563 || !TEST_true(BN_add(z, z, y)))
565 BN_set_negative(z, 1);
567 scalars[1] = z; /* z = -(order + y) */
569 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
570 || !TEST_true(EC_POINT_is_at_infinity(group, P))
571 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
572 || !TEST_true(BN_add(z, x, y)))
574 BN_set_negative(z, 1);
577 scalars[2] = z; /* z = -(x+y) */
579 if (!TEST_ptr(scalar3 = BN_new()))
582 scalars[3] = scalar3;
584 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
585 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
595 EC_GROUP_free(group);
607 #ifndef OPENSSL_NO_EC2M
609 static struct c2_curve_test {
620 } char2_curve_tests[] = {
621 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
624 "0800000000000000000000000000000000000000C9",
627 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
628 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
629 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
631 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
634 "0800000000000000000000000000000000000000C9",
636 "020A601907B8C953CA1481EB10512F78744A3205FD",
637 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
638 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
639 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
641 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
644 "020000000000000000000000000000000000000004000000000000000001",
647 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
648 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
650 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
653 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
656 "020000000000000000000000000000000000000004000000000000000001",
657 "000000000000000000000000000000000000000000000000000000000001",
658 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
659 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
660 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
662 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
665 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
669 "00000000000000000000000000000000000000000000000000000000000010A1",
673 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
675 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
678 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
681 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
685 "00000000000000000000000000000000000000000000000000000000000010A1",
687 "0000000000000000000000000000000000000000000000000000000000000001",
689 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
691 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
693 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
696 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
699 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
702 "0200000000000000000000000000000000000000"
703 "0000000000000000000000000000000000000000008000000000000000000001",
706 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
707 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
708 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
709 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
711 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
712 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
715 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
718 "0200000000000000000000000000000000000000"
719 "0000000000000000000000000000000000000000008000000000000000000001",
720 "0000000000000000000000000000000000000000"
721 "0000000000000000000000000000000000000000000000000000000000000001",
722 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
723 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
724 "015D4860D088DDB3496B0C6064756260441CDE4A"
725 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
726 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
727 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
729 "0100000000000000000000000000000000000000"
730 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
733 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
737 "0000000000000000000000000000000000000000000000000000000000000000"
738 "0000000000000000000000000000000000000000000000000000000000000425",
742 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
743 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
745 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
746 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
749 "00000000000000000000000000000000000000000000000000000000131850E1"
750 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
753 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
757 "0000000000000000000000000000000000000000000000000000000000000000"
758 "0000000000000000000000000000000000000000000000000000000000000425",
760 "0000000000000000000000000000000000000000000000000000000000000000"
761 "0000000000000000000000000000000000000000000000000000000000000001",
763 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
764 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
766 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
767 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
769 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
770 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
773 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
774 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
779 static int char2_curve_test(int n)
783 BIGNUM *p = NULL, *a = NULL, *b = NULL;
784 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
785 EC_GROUP *group = NULL;
786 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
787 # ifndef OPENSSL_NO_DEPRECATED_3_0
788 const EC_POINT *points[3];
789 const BIGNUM *scalars[3];
791 struct c2_curve_test *const test = char2_curve_tests + n;
793 if (!TEST_ptr(ctx = BN_CTX_new())
794 || !TEST_ptr(p = BN_new())
795 || !TEST_ptr(a = BN_new())
796 || !TEST_ptr(b = BN_new())
797 || !TEST_ptr(x = BN_new())
798 || !TEST_ptr(y = BN_new())
799 || !TEST_ptr(z = BN_new())
800 || !TEST_ptr(yplusone = BN_new())
801 || !TEST_true(BN_hex2bn(&p, test->p))
802 || !TEST_true(BN_hex2bn(&a, test->a))
803 || !TEST_true(BN_hex2bn(&b, test->b))
804 || !TEST_true(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx))
805 || !TEST_ptr(P = EC_POINT_new(group))
806 || !TEST_ptr(Q = EC_POINT_new(group))
807 || !TEST_ptr(R = EC_POINT_new(group))
808 || !TEST_true(BN_hex2bn(&x, test->x))
809 || !TEST_true(BN_hex2bn(&y, test->y))
810 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
813 /* Change test based on whether binary point compression is enabled or not. */
814 # ifdef OPENSSL_EC_BIN_PT_COMP
816 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
817 * and therefore setting the coordinates should fail.
819 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
820 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
823 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
824 || !TEST_true(BN_hex2bn(&z, test->order))
825 || !TEST_true(BN_hex2bn(&cof, test->cof))
826 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
827 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
829 TEST_info("%s -- Generator", test->name);
830 test_output_bignum("x", x);
831 test_output_bignum("y", y);
832 /* G_y value taken from the standard: */
833 if (!TEST_true(BN_hex2bn(&z, test->y))
834 || !TEST_BN_eq(y, z))
838 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
839 * and therefore setting the coordinates should fail.
841 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
842 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
843 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
844 || !TEST_true(BN_hex2bn(&z, test->order))
845 || !TEST_true(BN_hex2bn(&cof, test->cof))
846 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
848 TEST_info("%s -- Generator:", test->name);
849 test_output_bignum("x", x);
850 test_output_bignum("y", y);
853 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
854 || !group_order_tests(group))
857 /* more tests using the last curve */
858 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
859 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
860 || !TEST_true(EC_POINT_copy(Q, P))
861 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
862 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
863 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
864 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
865 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
866 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
867 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
868 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
871 # ifndef OPENSSL_NO_DEPRECATED_3_0
872 TEST_note("combined multiplication ...");
877 if (!TEST_true(BN_add(y, z, BN_value_one()))
879 || !TEST_true(BN_rshift1(y, y)))
881 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
884 /* z is still the group order */
885 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
886 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
887 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
888 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
891 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
892 || !TEST_true(BN_add(z, z, y)))
894 BN_set_negative(z, 1);
896 scalars[1] = z; /* z = -(order + y) */
898 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
899 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
902 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
903 || !TEST_true(BN_add(z, x, y)))
905 BN_set_negative(z, 1);
908 scalars[2] = z; /* z = -(x+y) */
910 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
911 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
930 EC_GROUP_free(group);
934 static int char2_field_tests(void)
937 BIGNUM *p = NULL, *a = NULL, *b = NULL;
938 EC_GROUP *group = NULL;
939 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
940 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
941 unsigned char buf[100];
945 if (!TEST_ptr(ctx = BN_CTX_new())
946 || !TEST_ptr(p = BN_new())
947 || !TEST_ptr(a = BN_new())
948 || !TEST_ptr(b = BN_new())
949 || !TEST_true(BN_hex2bn(&p, "13"))
950 || !TEST_true(BN_hex2bn(&a, "3"))
951 || !TEST_true(BN_hex2bn(&b, "1")))
954 if (!TEST_ptr(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx))
955 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
958 TEST_info("Curve defined by Weierstrass equation");
959 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
960 test_output_bignum("a", a);
961 test_output_bignum("b", b);
962 test_output_bignum("p", p);
964 if (!TEST_ptr(P = EC_POINT_new(group))
965 || !TEST_ptr(Q = EC_POINT_new(group))
966 || !TEST_ptr(R = EC_POINT_new(group))
967 || !TEST_true(EC_POINT_set_to_infinity(group, P))
968 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
972 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
973 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
974 || !TEST_true(EC_POINT_is_at_infinity(group, P))
975 || !TEST_ptr(x = BN_new())
976 || !TEST_ptr(y = BN_new())
977 || !TEST_ptr(z = BN_new())
978 || !TEST_ptr(cof = BN_new())
979 || !TEST_ptr(yplusone = BN_new())
980 || !TEST_true(BN_hex2bn(&x, "6"))
981 /* Change test based on whether binary point compression is enabled or not. */
982 # ifdef OPENSSL_EC_BIN_PT_COMP
983 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
985 || !TEST_true(BN_hex2bn(&y, "8"))
986 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
990 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
991 /* Change test based on whether binary point compression is enabled or not. */
992 # ifdef OPENSSL_EC_BIN_PT_COMP
993 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
996 TEST_info("Point is not on curve");
997 test_output_bignum("x", x);
998 test_output_bignum("y", y);
1002 TEST_note("A cyclic subgroup:");
1005 if (!TEST_int_ne(k--, 0))
1008 if (EC_POINT_is_at_infinity(group, P))
1009 TEST_note(" point at infinity");
1011 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1015 test_output_bignum("x", x);
1016 test_output_bignum("y", y);
1019 if (!TEST_true(EC_POINT_copy(R, P))
1020 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1023 while (!EC_POINT_is_at_infinity(group, P));
1025 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1026 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1029 /* Change test based on whether binary point compression is enabled or not. */
1030 # ifdef OPENSSL_EC_BIN_PT_COMP
1031 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1032 buf, sizeof(buf), ctx);
1033 if (!TEST_size_t_ne(len, 0)
1034 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1035 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1037 test_output_memory("Generator as octet string, compressed form:",
1041 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1042 buf, sizeof(buf), ctx);
1043 if (!TEST_size_t_ne(len, 0)
1044 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1045 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1047 test_output_memory("Generator as octet string, uncompressed form:",
1050 /* Change test based on whether binary point compression is enabled or not. */
1051 # ifdef OPENSSL_EC_BIN_PT_COMP
1053 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1055 if (!TEST_size_t_ne(len, 0)
1056 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1057 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1059 test_output_memory("Generator as octet string, hybrid form:",
1063 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1064 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1075 EC_GROUP_free(group);
1088 static int internal_curve_test(int n)
1090 EC_GROUP *group = NULL;
1091 int nid = curves[n].nid;
1093 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1094 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1098 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1099 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1100 EC_GROUP_free(group);
1103 EC_GROUP_free(group);
1107 static int internal_curve_test_method(int n)
1109 int r, nid = curves[n].nid;
1112 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1113 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1116 r = group_order_tests(group);
1117 EC_GROUP_free(group);
1121 static int group_field_test(void)
1124 BIGNUM *secp521r1_field = NULL;
1125 BIGNUM *sect163r2_field = NULL;
1126 EC_GROUP *secp521r1_group = NULL;
1127 EC_GROUP *sect163r2_group = NULL;
1129 BN_hex2bn(&secp521r1_field,
1130 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1131 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1132 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1133 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1137 BN_hex2bn(§163r2_field,
1138 "08000000000000000000000000000000"
1141 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1142 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1145 # ifndef OPENSSL_NO_EC2M
1146 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1147 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1151 EC_GROUP_free(secp521r1_group);
1152 EC_GROUP_free(sect163r2_group);
1153 BN_free(secp521r1_field);
1154 BN_free(sect163r2_field);
1159 * nistp_test_params contains magic numbers for testing
1160 * several NIST curves with characteristic > 3.
1162 struct nistp_test_params {
1166 * Qx, Qy and D are taken from
1167 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1168 * Otherwise, values are standard curve parameters from FIPS 180-3
1170 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1173 static const struct nistp_test_params nistp_tests_params[] = {
1179 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1181 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1183 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1185 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1187 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1189 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1191 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1193 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1195 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1199 NID_X9_62_prime256v1,
1202 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1204 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1206 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1208 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1210 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1212 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1214 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1216 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1218 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1226 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1227 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1230 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1231 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1234 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1235 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1238 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1239 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1242 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1243 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1246 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1247 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1250 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1251 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1254 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1255 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1258 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1259 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1263 static int nistp_single_test(int idx)
1265 const struct nistp_test_params *test = nistp_tests_params + idx;
1267 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1268 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1269 EC_GROUP *NISTP = NULL;
1270 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1273 TEST_note("NIST curve P-%d (optimised implementation):",
1275 if (!TEST_ptr(ctx = BN_CTX_new())
1276 || !TEST_ptr(p = BN_new())
1277 || !TEST_ptr(a = BN_new())
1278 || !TEST_ptr(b = BN_new())
1279 || !TEST_ptr(x = BN_new())
1280 || !TEST_ptr(y = BN_new())
1281 || !TEST_ptr(m = BN_new())
1282 || !TEST_ptr(n = BN_new())
1283 || !TEST_ptr(order = BN_new())
1284 || !TEST_ptr(yplusone = BN_new())
1286 || !TEST_ptr(NISTP = EC_GROUP_new_by_curve_name(test->nid))
1287 || !TEST_true(BN_hex2bn(&p, test->p))
1288 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
1289 || !TEST_true(BN_hex2bn(&a, test->a))
1290 || !TEST_true(BN_hex2bn(&b, test->b))
1291 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1292 || !TEST_ptr(G = EC_POINT_new(NISTP))
1293 || !TEST_ptr(P = EC_POINT_new(NISTP))
1294 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1295 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1296 || !TEST_true(BN_hex2bn(&x, test->Qx))
1297 || !TEST_true(BN_hex2bn(&y, test->Qy))
1298 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1300 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1301 * and therefore setting the coordinates should fail.
1303 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1305 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1307 || !TEST_true(BN_hex2bn(&x, test->Gx))
1308 || !TEST_true(BN_hex2bn(&y, test->Gy))
1309 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1310 || !TEST_true(BN_hex2bn(&order, test->order))
1311 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1312 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1315 TEST_note("NIST test vectors ... ");
1316 if (!TEST_true(BN_hex2bn(&n, test->d)))
1318 /* fixed point multiplication */
1319 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1320 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1322 /* random point multiplication */
1323 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1324 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1326 /* set generator to P = 2*G, where G is the standard generator */
1327 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1328 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1329 /* set the scalar to m=n/2, where n is the NIST test scalar */
1330 || !TEST_true(BN_rshift(m, n, 1)))
1333 /* test the non-standard generator */
1334 /* fixed point multiplication */
1335 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1336 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1338 /* random point multiplication */
1339 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1340 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1341 #ifndef OPENSSL_NO_DEPRECATED_3_0
1342 /* We have not performed precomp so this should be false */
1343 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1344 /* now repeat all tests with precomputation */
1345 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1350 /* fixed point multiplication */
1351 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1352 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1354 /* random point multiplication */
1355 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1356 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1358 /* reset generator */
1359 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1361 /* fixed point multiplication */
1362 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1363 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1365 /* random point multiplication */
1366 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1367 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1370 /* regression test for felem_neg bug */
1371 if (!TEST_true(BN_set_word(m, 32))
1372 || !TEST_true(BN_set_word(n, 31))
1373 || !TEST_true(EC_POINT_copy(P, G))
1374 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1375 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1376 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1381 EC_GROUP_free(NISTP);
1385 EC_POINT_free(Q_CHECK);
1399 static const unsigned char p521_named[] = {
1400 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1403 static const unsigned char p521_explicit[] = {
1404 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1405 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1406 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1407 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1408 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1409 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1410 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1411 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1416 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1417 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1418 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1419 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1420 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1421 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1422 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1423 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1424 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1425 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1426 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1427 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1428 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1429 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1430 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1431 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1432 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1433 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1434 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1435 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1436 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1437 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1438 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1439 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1440 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1441 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1445 * This test validates a named curve's group parameters using
1446 * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1447 * group parameters results in the curve not being valid.
1449 static int check_named_curve_test(int id)
1451 int ret = 0, nid, field_nid, has_seed;
1452 EC_GROUP *group = NULL, *gtest = NULL;
1453 const EC_POINT *group_gen = NULL;
1454 EC_POINT *other_gen = NULL;
1455 BIGNUM *group_p = NULL, *group_a = NULL, *group_b = NULL;
1456 BIGNUM *other_p = NULL, *other_a = NULL, *other_b = NULL;
1457 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1458 BIGNUM *other_order = NULL;
1459 const BIGNUM *group_order = NULL;
1460 BN_CTX *bn_ctx = NULL;
1461 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1462 static size_t invalid_seed_len = sizeof(invalid_seed);
1465 nid = curves[id].nid;
1466 if (!TEST_ptr(bn_ctx = BN_CTX_new())
1467 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1468 || !TEST_ptr(gtest = EC_GROUP_dup(group))
1469 || !TEST_ptr(group_p = BN_new())
1470 || !TEST_ptr(group_a = BN_new())
1471 || !TEST_ptr(group_b = BN_new())
1472 || !TEST_ptr(group_cofactor = BN_new())
1473 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1474 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1475 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1476 || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL))
1477 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1478 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1479 || !TEST_ptr(other_order = BN_dup(group_order))
1480 || !TEST_true(BN_add_word(other_order, 1))
1481 || !TEST_ptr(other_a = BN_dup(group_a))
1482 || !TEST_true(BN_add_word(other_a, 1))
1483 || !TEST_ptr(other_b = BN_dup(group_b))
1484 || !TEST_true(BN_add_word(other_b, 1))
1485 || !TEST_ptr(other_cofactor = BN_dup(group_cofactor))
1486 || !TEST_true(BN_add_word(other_cofactor, 1)))
1489 /* Determine if the built-in curve has a seed field set */
1490 has_seed = (EC_GROUP_get_seed_len(group) > 0);
1491 field_nid = EC_GROUP_get_field_type(group);
1492 if (field_nid == NID_X9_62_characteristic_two_field) {
1493 if (!TEST_ptr(other_p = BN_dup(group_p))
1494 || !TEST_true(BN_lshift1(other_p, other_p)))
1497 if (!TEST_ptr(other_p = BN_dup(group_p)))
1500 * Just choosing any arbitrary prime does not work..
1501 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1502 * nist prime. So only select one of these as an alternate prime.
1504 if (!TEST_ptr(BN_copy(other_p,
1505 BN_ucmp(BN_get0_nist_prime_192(), other_p) == 0 ?
1506 BN_get0_nist_prime_256() :
1507 BN_get0_nist_prime_192())))
1511 /* Passes because this is a valid curve */
1512 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)
1513 /* Only NIST curves pass */
1514 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 1, NULL),
1515 EC_curve_nid2nist(nid) != NULL ? nid : NID_undef))
1518 /* Fail if the curve name doesn't match the parameters */
1519 EC_GROUP_set_curve_name(group, nid + 1);
1521 if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1525 /* Restore curve name and ensure it's passing */
1526 EC_GROUP_set_curve_name(group, nid);
1527 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1530 if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len),
1536 * If the built-in curve has a seed and we set the seed to another value
1537 * then it will fail the check.
1539 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1543 * If the built-in curve does not have a seed then setting the seed will
1544 * pass the check (as the seed is optional).
1546 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1549 /* Pass if the seed is unknown (as it is optional) */
1550 if (!TEST_int_eq(EC_GROUP_set_seed(group, NULL, 0), 1)
1551 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1554 /* Check that a duped group passes */
1555 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1558 /* check that changing any generator parameter fails */
1559 if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order,
1561 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1562 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order,
1564 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1565 /* The order is not an optional field, so this should fail */
1566 || !TEST_false(EC_GROUP_set_generator(gtest, group_gen, NULL,
1568 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1570 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1571 /* Check that if the cofactor is not set then it still passes */
1572 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1574 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)
1575 /* check that restoring the generator 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))
1582 * check that changing any curve parameter fails
1584 * Setting arbitrary p, a or b might fail for some EC_GROUPs
1585 * depending on the internal EC_METHOD implementation, hence run
1586 * these tests conditionally to the success of EC_GROUP_set_curve().
1589 if (EC_GROUP_set_curve(gtest, other_p, group_a, group_b, NULL)) {
1590 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1593 /* clear the error stack if EC_GROUP_set_curve() failed */
1597 if (EC_GROUP_set_curve(gtest, group_p, other_a, group_b, NULL)) {
1598 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1601 /* clear the error stack if EC_GROUP_set_curve() failed */
1605 if (EC_GROUP_set_curve(gtest, group_p, group_a, other_b, NULL)) {
1606 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1609 /* clear the error stack if EC_GROUP_set_curve() failed */
1615 /* Check that restoring the curve parameters passes */
1616 if (!TEST_true(EC_GROUP_set_curve(gtest, group_p, group_a, group_b, NULL))
1617 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1628 BN_free(group_cofactor);
1629 BN_free(other_cofactor);
1630 BN_free(other_order);
1631 EC_POINT_free(other_gen);
1632 EC_GROUP_free(gtest);
1633 EC_GROUP_free(group);
1634 BN_CTX_free(bn_ctx);
1639 * This checks the lookup capability of EC_GROUP_check_named_curve()
1640 * when the given group was created with explicit parameters.
1642 * It is possible to retrieve an alternative alias that does not match
1643 * the original nid in this case.
1645 static int check_named_curve_lookup_test(int id)
1647 int ret = 0, nid, rv = 0;
1648 EC_GROUP *g = NULL , *ga = NULL;
1649 ECPARAMETERS *p = NULL, *pa = NULL;
1653 nid = curves[id].nid;
1654 if (!TEST_ptr(ctx = BN_CTX_new())
1655 || !TEST_ptr(g = EC_GROUP_new_by_curve_name(nid))
1656 || !TEST_ptr(p = EC_GROUP_get_ecparameters(g, NULL)))
1659 /* replace with group from explicit parameters */
1661 if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p)))
1664 if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0, NULL), 0))
1669 * fail if the returned nid is not an alias of the original group.
1671 * The comparison here is done by comparing two explicit
1672 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1673 * comparison happens with unnamed EC_GROUPs using the same
1676 if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv))
1677 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL)))
1680 /* replace with group from explicit parameters, then compare */
1682 if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa))
1683 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0))
1692 ECPARAMETERS_free(p);
1693 ECPARAMETERS_free(pa);
1700 * Sometime we cannot compare nids for equality, as the built-in curve table
1701 * includes aliases with different names for the same curve.
1703 * This function returns TRUE (1) if the checked nids are identical, or if they
1704 * alias to the same curve. FALSE (0) otherwise.
1707 int are_ec_nids_compatible(int n1d, int n2d)
1711 #ifndef OPENSSL_NO_EC2M
1713 case NID_wap_wsg_idm_ecid_wtls4:
1714 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1717 case NID_wap_wsg_idm_ecid_wtls3:
1718 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1721 case NID_wap_wsg_idm_ecid_wtls10:
1722 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1725 case NID_wap_wsg_idm_ecid_wtls11:
1726 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1728 case NID_X9_62_c2pnb163v1:
1729 case NID_wap_wsg_idm_ecid_wtls5:
1730 ret = (n2d == NID_X9_62_c2pnb163v1
1731 || n2d == NID_wap_wsg_idm_ecid_wtls5);
1733 #endif /* OPENSSL_NO_EC2M */
1735 case NID_wap_wsg_idm_ecid_wtls6:
1736 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1739 case NID_wap_wsg_idm_ecid_wtls7:
1740 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1742 #ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1744 case NID_wap_wsg_idm_ecid_wtls12:
1745 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1749 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1750 * that is associated with a specialized method.
1752 case NID_wap_wsg_idm_ecid_wtls12:
1753 ret = (n2d == NID_secp224r1);
1755 #endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1764 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1765 * EC_GROUP for built-in curves.
1767 * Note that it is possible to retrieve an alternative alias that does not match
1770 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1772 static int check_named_curve_from_ecparameters(int id)
1774 int ret = 0, nid, tnid;
1775 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1776 const EC_POINT *group_gen = NULL;
1777 EC_POINT *other_gen = NULL;
1778 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1779 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1780 const BIGNUM *group_order = NULL;
1781 BIGNUM *other_order = NULL;
1782 BN_CTX *bn_ctx = NULL;
1783 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1784 static size_t invalid_seed_len = sizeof(invalid_seed);
1785 ECPARAMETERS *params = NULL, *other_params = NULL;
1786 EC_GROUP *g_ary[8] = {NULL};
1787 EC_GROUP **g_next = &g_ary[0];
1788 ECPARAMETERS *p_ary[8] = {NULL};
1789 ECPARAMETERS **p_next = &p_ary[0];
1792 nid = curves[id].nid;
1793 TEST_note("Curve %s", OBJ_nid2sn(nid));
1794 if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1796 BN_CTX_start(bn_ctx);
1798 if (/* Allocations */
1799 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1800 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1801 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1802 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1803 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1804 /* Generate reference group and params */
1805 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1806 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1807 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1808 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1809 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1810 /* compute `other_*` values */
1811 || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1812 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1813 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1814 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1815 other_gen_x, other_gen_y, bn_ctx))
1816 || !TEST_true(BN_copy(other_order, group_order))
1817 || !TEST_true(BN_add_word(other_order, 1))
1818 || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1819 || !TEST_true(BN_add_word(other_cofactor, 1)))
1822 EC_POINT_free(other_gen);
1825 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1826 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1827 other_gen_x, other_gen_y,
1832 * ###########################
1833 * # Actual tests start here #
1834 * ###########################
1838 * Creating a group from built-in explicit parameters returns a
1841 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1842 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1845 * We cannot always guarantee the names match, as the built-in table
1846 * contains aliases for the same curve with different names.
1848 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1849 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1852 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1853 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1857 * An invalid seed in the parameters should be ignored: expect a "named"
1860 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1862 || !TEST_ptr(other_params = *p_next++ =
1863 EC_GROUP_get_ecparameters(tmpg, NULL))
1864 || !TEST_ptr(tgroup = *g_next++ =
1865 EC_GROUP_new_from_ecparameters(other_params))
1866 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1867 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1868 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1869 OPENSSL_EC_EXPLICIT_CURVE)) {
1870 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1875 * A null seed in the parameters should be ignored, as it is optional:
1876 * expect a "named" group.
1878 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1879 || !TEST_ptr(other_params = *p_next++ =
1880 EC_GROUP_get_ecparameters(tmpg, NULL))
1881 || !TEST_ptr(tgroup = *g_next++ =
1882 EC_GROUP_new_from_ecparameters(other_params))
1883 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1884 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1885 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1886 OPENSSL_EC_EXPLICIT_CURVE)) {
1887 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1892 * Check that changing any of the generator parameters does not yield a
1893 * match with the built-in curves
1895 if (/* Other gen, same group order & cofactor */
1896 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1898 || !TEST_ptr(other_params = *p_next++ =
1899 EC_GROUP_get_ecparameters(tmpg, NULL))
1900 || !TEST_ptr(tgroup = *g_next++ =
1901 EC_GROUP_new_from_ecparameters(other_params))
1902 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1903 /* Same gen & cofactor, different order */
1904 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1906 || !TEST_ptr(other_params = *p_next++ =
1907 EC_GROUP_get_ecparameters(tmpg, NULL))
1908 || !TEST_ptr(tgroup = *g_next++ =
1909 EC_GROUP_new_from_ecparameters(other_params))
1910 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1911 /* The order is not an optional field, so this should fail */
1912 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1914 /* Check that a wrong cofactor is ignored, and we still match */
1915 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1917 || !TEST_ptr(other_params = *p_next++ =
1918 EC_GROUP_get_ecparameters(tmpg, NULL))
1919 || !TEST_ptr(tgroup = *g_next++ =
1920 EC_GROUP_new_from_ecparameters(other_params))
1921 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1922 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1923 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1924 OPENSSL_EC_EXPLICIT_CURVE)
1925 /* Check that if the cofactor is not set then it still matches */
1926 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1928 || !TEST_ptr(other_params = *p_next++ =
1929 EC_GROUP_get_ecparameters(tmpg, NULL))
1930 || !TEST_ptr(tgroup = *g_next++ =
1931 EC_GROUP_new_from_ecparameters(other_params))
1932 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1933 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1934 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1935 OPENSSL_EC_EXPLICIT_CURVE)
1936 /* check that restoring the generator passes */
1937 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1939 || !TEST_ptr(other_params = *p_next++ =
1940 EC_GROUP_get_ecparameters(tmpg, NULL))
1941 || !TEST_ptr(tgroup = *g_next++ =
1942 EC_GROUP_new_from_ecparameters(other_params))
1943 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1944 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1945 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1946 OPENSSL_EC_EXPLICIT_CURVE))
1951 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
1952 EC_GROUP_free(*g_next);
1953 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
1954 ECPARAMETERS_free(*p_next);
1955 ECPARAMETERS_free(params);
1956 EC_POINT_free(other_gen);
1957 EC_GROUP_free(tmpg);
1958 EC_GROUP_free(group);
1960 BN_CTX_free(bn_ctx);
1965 static int parameter_test(void)
1967 EC_GROUP *group = NULL, *group2 = NULL;
1968 ECPARAMETERS *ecparameters = NULL;
1969 unsigned char *buf = NULL;
1972 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1))
1973 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1974 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1975 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1978 EC_GROUP_free(group);
1981 /* Test the named curve encoding, which should be default. */
1982 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1983 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1984 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1991 * Test the explicit encoding. P-521 requires correctly zero-padding the
1992 * curve coefficients.
1994 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1995 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1996 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
2001 EC_GROUP_free(group);
2002 EC_GROUP_free(group2);
2003 ECPARAMETERS_free(ecparameters);
2009 * random 256-bit explicit parameters curve, cofactor absent
2010 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
2011 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
2013 static const unsigned char params_cf_pass[] = {
2014 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2015 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
2016 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2017 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2018 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
2019 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2020 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2021 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
2022 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
2023 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
2024 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
2025 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
2026 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
2027 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
2028 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
2029 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
2030 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
2031 0x14, 0xa8, 0x2f, 0x4f
2035 * random 256-bit explicit parameters curve, cofactor absent
2036 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
2037 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
2039 static const unsigned char params_cf_fail[] = {
2040 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2041 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
2042 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2043 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2044 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
2045 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2046 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2047 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
2048 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
2049 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
2050 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
2051 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
2052 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
2053 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
2054 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
2055 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
2056 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
2057 0x34, 0xa2, 0x21, 0x01
2061 * Test two random 256-bit explicit parameters curves with absent cofactor.
2062 * The two curves are chosen to roughly straddle the bounds at which the lib
2063 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
2065 * - params_cf_pass: order is sufficiently close to p to compute cofactor
2066 * - params_cf_fail: order is too far away from p to compute cofactor
2068 * For standards-compliant curves, cofactor is chosen as small as possible.
2069 * So you can see neither of these curves are fit for cryptographic use.
2071 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
2072 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
2073 * will always succeed in computing the cofactor. Neither of these curves
2074 * conform to that -- this is just robustness testing.
2076 static int cofactor_range_test(void)
2078 EC_GROUP *group = NULL;
2081 const unsigned char *b1 = (const unsigned char *)params_cf_fail;
2082 const unsigned char *b2 = (const unsigned char *)params_cf_pass;
2084 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
2085 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
2086 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
2087 sizeof(params_cf_pass)))
2088 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
2089 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
2094 EC_GROUP_free(group);
2099 * For named curves, test that:
2100 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
2101 * - a nonsensical cofactor throws an error (negative test)
2102 * - nonsensical orders throw errors (negative tests)
2104 static int cardinality_test(int n)
2106 int ret = 0, is_binary = 0;
2107 int nid = curves[n].nid;
2109 EC_GROUP *g1 = NULL, *g2 = NULL;
2110 EC_POINT *g2_gen = NULL;
2111 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
2112 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
2114 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
2116 if (!TEST_ptr(ctx = BN_CTX_new())
2117 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))) {
2122 is_binary = (EC_GROUP_get_field_type(g1) == NID_X9_62_characteristic_two_field);
2125 g1_p = BN_CTX_get(ctx);
2126 g1_a = BN_CTX_get(ctx);
2127 g1_b = BN_CTX_get(ctx);
2128 g1_x = BN_CTX_get(ctx);
2129 g1_y = BN_CTX_get(ctx);
2130 g1_order = BN_CTX_get(ctx);
2131 g1_cf = BN_CTX_get(ctx);
2133 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
2134 /* pull out the explicit curve parameters */
2135 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
2136 || !TEST_true(EC_POINT_get_affine_coordinates(g1,
2137 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
2138 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
2139 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
2140 /* construct g2 manually with g1 parameters */
2141 #ifndef OPENSSL_NO_EC2M
2142 || !TEST_ptr(g2 = (is_binary) ?
2143 EC_GROUP_new_curve_GF2m(g1_p, g1_a, g1_b, ctx) :
2144 EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx))
2146 || !TEST_int_eq(0, is_binary)
2147 || !TEST_ptr(g2 = EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx))
2149 || !TEST_ptr(g2_gen = EC_POINT_new(g2))
2150 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
2151 /* pass NULL cofactor: lib should compute it */
2152 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2153 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2154 || !TEST_BN_eq(g1_cf, g2_cf)
2155 /* pass zero cofactor: lib should compute it */
2156 || !TEST_true(BN_set_word(g2_cf, 0))
2157 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2158 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2159 || !TEST_BN_eq(g1_cf, g2_cf)
2160 /* negative test for invalid cofactor */
2161 || !TEST_true(BN_set_word(g2_cf, 0))
2162 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2163 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2164 /* negative test for NULL order */
2165 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
2166 /* negative test for zero order */
2167 || !TEST_true(BN_set_word(g1_order, 0))
2168 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2169 /* negative test for negative order */
2170 || !TEST_true(BN_set_word(g2_cf, 0))
2171 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2172 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2173 /* negative test for too large order */
2174 || !TEST_true(BN_lshift(g1_order, g1_p, 2))
2175 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
2179 EC_POINT_free(g2_gen);
2187 static int check_ec_key_field_public_range_test(int id)
2189 int ret = 0, type = 0;
2190 const EC_POINT *pub = NULL;
2191 const EC_GROUP *group = NULL;
2192 const BIGNUM *field = NULL;
2193 BIGNUM *x = NULL, *y = NULL;
2196 if (!TEST_ptr(x = BN_new())
2197 || !TEST_ptr(y = BN_new())
2198 || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid))
2199 || !TEST_ptr(group = EC_KEY_get0_group(key))
2200 || !TEST_ptr(field = EC_GROUP_get0_field(group))
2201 || !TEST_int_gt(EC_KEY_generate_key(key), 0)
2202 || !TEST_int_gt(EC_KEY_check_key(key), 0)
2203 || !TEST_ptr(pub = EC_KEY_get0_public_key(key))
2204 || !TEST_int_gt(EC_POINT_get_affine_coordinates(group, pub, x, y,
2209 * Make the public point out of range by adding the field (which will still
2210 * be the same point on the curve). The add is different for char2 fields.
2212 type = EC_GROUP_get_field_type(group);
2213 #ifndef OPENSSL_NO_EC2M
2214 if (type == NID_X9_62_characteristic_two_field) {
2215 /* test for binary curves */
2216 if (!TEST_true(BN_GF2m_add(x, x, field)))
2220 if (type == NID_X9_62_prime_field) {
2221 /* test for prime curves */
2222 if (!TEST_true(BN_add(x, x, field)))
2225 /* this should never happen */
2226 TEST_error("Unsupported EC_METHOD field_type");
2229 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key, x, y), 0))
2241 * Helper for ec_point_hex2point_test
2243 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2246 * If P is NULL use point at infinity.
2249 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2250 point_conversion_form_t form,
2254 EC_POINT *Q = NULL, *Pinf = NULL;
2258 /* If P is NULL use point at infinity. */
2259 if (!TEST_ptr(Pinf = EC_POINT_new(group))
2260 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2265 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2266 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2267 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2271 * The next check is most likely superfluous, as EC_POINT_cmp should already
2273 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2274 * so we include it anyway!
2277 && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2283 EC_POINT_free(Pinf);
2291 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2293 static int ec_point_hex2point_test(int id)
2296 EC_GROUP *group = NULL;
2297 const EC_POINT *G = NULL;
2299 BN_CTX * bnctx = NULL;
2302 nid = curves[id].nid;
2303 if (!TEST_ptr(bnctx = BN_CTX_new())
2304 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2305 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2306 || !TEST_ptr(P = EC_POINT_dup(G, group)))
2309 if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2310 POINT_CONVERSION_COMPRESSED,
2312 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2313 POINT_CONVERSION_COMPRESSED,
2315 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2316 POINT_CONVERSION_UNCOMPRESSED,
2318 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2319 POINT_CONVERSION_UNCOMPRESSED,
2321 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2322 POINT_CONVERSION_HYBRID,
2324 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2325 POINT_CONVERSION_HYBRID,
2333 EC_GROUP_free(group);
2339 static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx,
2340 unsigned char *gen, int gen_size)
2343 EVP_PKEY_CTX *pctx = NULL;
2344 EVP_PKEY *pkeyparam = NULL;
2345 OSSL_PARAM_BLD *bld = NULL;
2346 const char *field_name;
2347 OSSL_PARAM *params = NULL;
2348 const OSSL_PARAM *gettable;
2350 BIGNUM *p_out = NULL, *a_out = NULL, *b_out = NULL;
2351 BIGNUM *order_out = NULL, *cofactor_out = NULL;
2353 unsigned char buf[1024];
2354 size_t buf_len, name_len;
2355 #ifndef OPENSSL_NO_EC2M
2356 unsigned int k1 = 0, k2 = 0, k3 = 0;
2357 const char *basis_name = NULL;
2360 p = BN_CTX_get(ctx);
2361 a = BN_CTX_get(ctx);
2362 b = BN_CTX_get(ctx);
2365 || !TEST_ptr(bld = OSSL_PARAM_BLD_new()))
2368 if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) {
2369 field_name = SN_X9_62_prime_field;
2371 field_name = SN_X9_62_characteristic_two_field;
2372 #ifndef OPENSSL_NO_EC2M
2373 if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) {
2374 basis_name = SN_X9_62_tpBasis;
2375 if (!TEST_true(EC_GROUP_get_trinomial_basis(group, &k1)))
2378 basis_name = SN_X9_62_ppBasis;
2379 if (!TEST_true(EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)))
2382 #endif /* OPENSSL_NO_EC2M */
2384 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))
2385 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
2386 OSSL_PKEY_PARAM_EC_FIELD_TYPE, field_name, 0))
2387 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, p))
2388 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
2389 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b)))
2392 if (EC_GROUP_get0_seed(group) != NULL) {
2393 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
2394 OSSL_PKEY_PARAM_EC_SEED, EC_GROUP_get0_seed(group),
2395 EC_GROUP_get_seed_len(group))))
2398 if (EC_GROUP_get0_cofactor(group) != NULL) {
2399 if (!TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
2400 EC_GROUP_get0_cofactor(group))))
2404 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
2405 OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_size))
2406 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER,
2407 EC_GROUP_get0_order(group))))
2410 if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))
2411 || !TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL))
2412 || !TEST_int_gt(EVP_PKEY_fromdata_init(pctx), 0)
2413 || !TEST_int_gt(EVP_PKEY_fromdata(pctx, &pkeyparam,
2414 EVP_PKEY_KEY_PARAMETERS, params), 0))
2417 /*- Check that all the set values are retrievable -*/
2419 /* There should be no match to a group name since the generator changed */
2420 if (!TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam,
2421 OSSL_PKEY_PARAM_GROUP_NAME, name, sizeof(name),
2425 /* The encoding should be explicit as it has no group */
2426 if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
2427 OSSL_PKEY_PARAM_EC_ENCODING,
2428 name, sizeof(name), &name_len))
2429 || !TEST_str_eq(name, OSSL_PKEY_EC_ENCODING_EXPLICIT))
2432 if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
2433 OSSL_PKEY_PARAM_EC_FIELD_TYPE, name, sizeof(name),
2435 || !TEST_str_eq(name, field_name))
2438 if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam,
2439 OSSL_PKEY_PARAM_EC_GENERATOR, buf, sizeof(buf), &buf_len))
2440 || !TEST_mem_eq(buf, (int)buf_len, gen, gen_size))
2443 if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_P, &p_out))
2444 || !TEST_BN_eq(p_out, p)
2445 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_A,
2447 || !TEST_BN_eq(a_out, a)
2448 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_B,
2450 || !TEST_BN_eq(b_out, b)
2451 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_ORDER,
2453 || !TEST_BN_eq(order_out, EC_GROUP_get0_order(group)))
2456 if (EC_GROUP_get0_cofactor(group) != NULL) {
2457 if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam,
2458 OSSL_PKEY_PARAM_EC_COFACTOR, &cofactor_out))
2459 || !TEST_BN_eq(cofactor_out, EC_GROUP_get0_cofactor(group)))
2462 if (EC_GROUP_get0_seed(group) != NULL) {
2463 if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam,
2464 OSSL_PKEY_PARAM_EC_SEED, buf, sizeof(buf), &buf_len))
2465 || !TEST_mem_eq(buf, buf_len, EC_GROUP_get0_seed(group),
2466 EC_GROUP_get_seed_len(group)))
2470 if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) {
2471 /* No extra fields should be set for a prime field */
2472 if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2473 OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out))
2474 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2475 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
2476 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2477 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
2478 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2479 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
2480 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2481 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out))
2482 || !TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam,
2483 OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name),
2487 #ifndef OPENSSL_NO_EC2M
2488 if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2489 OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out))
2490 || !TEST_int_eq(EC_GROUP_get_degree(group), i_out)
2491 || !TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
2492 OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name),
2494 || !TEST_str_eq(name, basis_name))
2497 if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) {
2498 if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2499 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
2500 || !TEST_int_eq(k1, i_out)
2501 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2502 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
2503 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2504 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
2505 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2506 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out)))
2509 if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2510 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
2511 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2512 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
2513 || !TEST_int_eq(k1, i_out)
2514 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2515 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
2516 || !TEST_int_eq(k2, i_out)
2517 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2518 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out))
2519 || !TEST_int_eq(k3, i_out))
2522 #endif /* OPENSSL_NO_EC2M */
2524 if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pkeyparam))
2525 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_GROUP_NAME))
2526 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ENCODING))
2527 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_FIELD_TYPE))
2528 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_P))
2529 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_A))
2530 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_B))
2531 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_GENERATOR))
2532 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ORDER))
2533 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_COFACTOR))
2534 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_SEED))
2535 #ifndef OPENSSL_NO_EC2M
2536 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_M))
2537 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TYPE))
2538 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS))
2539 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K1))
2540 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K2))
2541 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K3))
2548 BN_free(cofactor_out);
2552 OSSL_PARAM_free(params);
2553 OSSL_PARAM_BLD_free(bld);
2554 EVP_PKEY_free(pkeyparam);
2555 EVP_PKEY_CTX_free(pctx);
2560 * check the EC_METHOD respects the supplied EC_GROUP_set_generator G
2562 static int custom_generator_test(int id)
2564 int ret = 0, nid, bsize;
2565 EC_GROUP *group = NULL;
2566 EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL;
2569 unsigned char *b1 = NULL, *b2 = NULL;
2572 nid = curves[id].nid;
2573 TEST_note("Curve %s", OBJ_nid2sn(nid));
2574 if (!TEST_ptr(ctx = BN_CTX_new()))
2579 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)))
2582 /* expected byte length of encoded points */
2583 bsize = (EC_GROUP_get_degree(group) + 7) / 8;
2584 bsize = 1 + 2 * bsize; /* UNCOMPRESSED_POINT format */
2586 if (!TEST_ptr(k = BN_CTX_get(ctx))
2587 /* fetch a testing scalar k != 0,1 */
2588 || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1,
2589 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
2591 || !TEST_true(BN_clear_bit(k, 0))
2592 || !TEST_ptr(G2 = EC_POINT_new(group))
2593 || !TEST_ptr(Q1 = EC_POINT_new(group))
2595 || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx))
2596 /* pull out the bytes of that */
2597 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2598 POINT_CONVERSION_UNCOMPRESSED, NULL,
2600 || !TEST_ptr(b1 = OPENSSL_malloc(bsize))
2601 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2602 POINT_CONVERSION_UNCOMPRESSED, b1,
2604 /* new generator is G2 := 2G */
2605 || !TEST_true(EC_POINT_dbl(group, G2, EC_GROUP_get0_generator(group),
2607 || !TEST_true(EC_GROUP_set_generator(group, G2,
2608 EC_GROUP_get0_order(group),
2609 EC_GROUP_get0_cofactor(group)))
2610 || !TEST_ptr(Q2 = EC_POINT_new(group))
2611 || !TEST_true(BN_rshift1(k, k))
2613 || !TEST_true(EC_POINT_mul(group, Q2, k, NULL, NULL, ctx))
2614 || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
2615 POINT_CONVERSION_UNCOMPRESSED, NULL,
2617 || !TEST_ptr(b2 = OPENSSL_malloc(bsize))
2618 || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
2619 POINT_CONVERSION_UNCOMPRESSED, b2,
2621 /* Q1 = kG = k/2 G2 = Q2 should hold */
2622 || !TEST_mem_eq(b1, bsize, b2, bsize))
2625 if (!do_test_custom_explicit_fromdata(group, ctx, b1, bsize))
2634 EC_GROUP_free(group);
2644 * check creation of curves from explicit params through the public API
2646 static int custom_params_test(int id)
2648 int ret = 0, nid, bsize;
2649 const char *curve_name = NULL;
2650 EC_GROUP *group = NULL, *altgroup = NULL;
2651 EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL;
2652 const EC_POINT *Q = NULL;
2655 unsigned char *buf1 = NULL, *buf2 = NULL;
2656 const BIGNUM *z = NULL, *cof = NULL, *priv1 = NULL;
2657 BIGNUM *p = NULL, *a = NULL, *b = NULL;
2659 EC_KEY *eckey1 = NULL, *eckey2 = NULL;
2660 EVP_PKEY *pkey1 = NULL, *pkey2 = NULL;
2661 EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL;
2663 unsigned char *pub1 = NULL , *pub2 = NULL;
2664 OSSL_PARAM_BLD *param_bld = NULL;
2665 OSSL_PARAM *params1 = NULL, *params2 = NULL;
2668 nid = curves[id].nid;
2669 curve_name = OBJ_nid2sn(nid);
2670 TEST_note("Curve %s", curve_name);
2673 return TEST_skip("custom params not supported with SM2");
2675 if (!TEST_ptr(ctx = BN_CTX_new()))
2678 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)))
2681 is_prime = EC_GROUP_get_field_type(group) == NID_X9_62_prime_field;
2682 #ifdef OPENSSL_NO_EC2M
2684 ret = TEST_skip("binary curves not supported in this build");
2690 if (!TEST_ptr(p = BN_CTX_get(ctx))
2691 || !TEST_ptr(a = BN_CTX_get(ctx))
2692 || !TEST_ptr(b = BN_CTX_get(ctx))
2693 || !TEST_ptr(k = BN_CTX_get(ctx)))
2696 /* expected byte length of encoded points */
2697 bsize = (EC_GROUP_get_degree(group) + 7) / 8;
2698 bsize = 1 + 2 * bsize; /* UNCOMPRESSED_POINT format */
2700 /* extract parameters from built-in curve */
2701 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))
2702 || !TEST_ptr(G2 = EC_POINT_new(group))
2703 /* new generator is G2 := 2G */
2704 || !TEST_true(EC_POINT_dbl(group, G2,
2705 EC_GROUP_get0_generator(group), ctx))
2706 /* pull out the bytes of that */
2707 || !TEST_int_eq(EC_POINT_point2oct(group, G2,
2708 POINT_CONVERSION_UNCOMPRESSED,
2709 NULL, 0, ctx), bsize)
2710 || !TEST_ptr(buf1 = OPENSSL_malloc(bsize))
2711 || !TEST_int_eq(EC_POINT_point2oct(group, G2,
2712 POINT_CONVERSION_UNCOMPRESSED,
2713 buf1, bsize, ctx), bsize)
2714 || !TEST_ptr(z = EC_GROUP_get0_order(group))
2715 || !TEST_ptr(cof = EC_GROUP_get0_cofactor(group))
2719 /* create a new group using same params (but different generator) */
2721 if (!TEST_ptr(altgroup = EC_GROUP_new_curve_GFp(p, a, b, ctx)))
2724 #ifndef OPENSSL_NO_EC2M
2726 if (!TEST_ptr(altgroup = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
2731 /* set 2*G as the generator of altgroup */
2732 EC_POINT_free(G2); /* discard G2 as it refers to the original group */
2733 if (!TEST_ptr(G2 = EC_POINT_new(altgroup))
2734 || !TEST_true(EC_POINT_oct2point(altgroup, G2, buf1, bsize, ctx))
2735 || !TEST_int_eq(EC_POINT_is_on_curve(altgroup, G2, ctx), 1)
2736 || !TEST_true(EC_GROUP_set_generator(altgroup, G2, z, cof))
2740 /* verify math checks out */
2741 if (/* allocate temporary points on group and altgroup */
2742 !TEST_ptr(Q1 = EC_POINT_new(group))
2743 || !TEST_ptr(Q2 = EC_POINT_new(altgroup))
2744 /* fetch a testing scalar k != 0,1 */
2745 || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1,
2746 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
2748 || !TEST_true(BN_clear_bit(k, 0))
2749 /* Q1 := kG on group */
2750 || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx))
2751 /* pull out the bytes of that */
2752 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2753 POINT_CONVERSION_UNCOMPRESSED,
2754 NULL, 0, ctx), bsize)
2755 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2756 POINT_CONVERSION_UNCOMPRESSED,
2757 buf1, bsize, ctx), bsize)
2759 || !TEST_true(BN_rshift1(k, k))
2760 /* Q2 := k/2 G2 on altgroup */
2761 || !TEST_true(EC_POINT_mul(altgroup, Q2, k, NULL, NULL, ctx))
2762 /* pull out the bytes of that */
2763 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q2,
2764 POINT_CONVERSION_UNCOMPRESSED,
2765 NULL, 0, ctx), bsize)
2766 || !TEST_ptr(buf2 = OPENSSL_malloc(bsize))
2767 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q2,
2768 POINT_CONVERSION_UNCOMPRESSED,
2769 buf2, bsize, ctx), bsize)
2770 /* Q1 = kG = k/2 G2 = Q2 should hold */
2771 || !TEST_mem_eq(buf1, bsize, buf2, bsize))
2774 /* create two `EC_KEY`s on altgroup */
2775 if (!TEST_ptr(eckey1 = EC_KEY_new())
2776 || !TEST_true(EC_KEY_set_group(eckey1, altgroup))
2777 || !TEST_true(EC_KEY_generate_key(eckey1))
2778 || !TEST_ptr(eckey2 = EC_KEY_new())
2779 || !TEST_true(EC_KEY_set_group(eckey2, altgroup))
2780 || !TEST_true(EC_KEY_generate_key(eckey2)))
2783 /* retrieve priv1 for later */
2784 if (!TEST_ptr(priv1 = EC_KEY_get0_private_key(eckey1)))
2788 * retrieve bytes for pub1 for later
2790 * We compute the pub key in the original group as we will later use it to
2791 * define a provider key in the built-in group.
2793 if (!TEST_true(EC_POINT_mul(group, Q1, priv1, NULL, NULL, ctx))
2794 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2795 POINT_CONVERSION_UNCOMPRESSED,
2796 NULL, 0, ctx), bsize)
2797 || !TEST_ptr(pub1 = OPENSSL_malloc(bsize))
2798 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2799 POINT_CONVERSION_UNCOMPRESSED,
2800 pub1, bsize, ctx), bsize))
2803 /* retrieve bytes for pub2 for later */
2804 if (!TEST_ptr(Q = EC_KEY_get0_public_key(eckey2))
2805 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q,
2806 POINT_CONVERSION_UNCOMPRESSED,
2807 NULL, 0, ctx), bsize)
2808 || !TEST_ptr(pub2 = OPENSSL_malloc(bsize))
2809 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q,
2810 POINT_CONVERSION_UNCOMPRESSED,
2811 pub2, bsize, ctx), bsize))
2814 /* create two `EVP_PKEY`s from the `EC_KEY`s */
2815 if(!TEST_ptr(pkey1 = EVP_PKEY_new())
2816 || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey1, eckey1), 1))
2818 eckey1 = NULL; /* ownership passed to pkey1 */
2819 if(!TEST_ptr(pkey2 = EVP_PKEY_new())
2820 || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey2, eckey2), 1))
2822 eckey2 = NULL; /* ownership passed to pkey2 */
2824 /* Compute keyexchange in both directions */
2825 if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))
2826 || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1)
2827 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1)
2828 || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &sslen), 1)
2829 || !TEST_int_gt(bsize, sslen)
2830 || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &sslen), 1))
2832 if (!TEST_ptr(pctx2 = EVP_PKEY_CTX_new(pkey2, NULL))
2833 || !TEST_int_eq(EVP_PKEY_derive_init(pctx2), 1)
2834 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx2, pkey1), 1)
2835 || !TEST_int_eq(EVP_PKEY_derive(pctx2, NULL, &t), 1)
2836 || !TEST_int_gt(bsize, t)
2837 || !TEST_int_le(sslen, t)
2838 || !TEST_int_eq(EVP_PKEY_derive(pctx2, buf2, &t), 1))
2841 /* Both sides should expect the same shared secret */
2842 if (!TEST_mem_eq(buf1, sslen, buf2, t))
2845 /* Build parameters for provider-native keys */
2846 if (!TEST_ptr(param_bld = OSSL_PARAM_BLD_new())
2847 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld,
2848 OSSL_PKEY_PARAM_GROUP_NAME,
2850 || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld,
2851 OSSL_PKEY_PARAM_PUB_KEY,
2853 || !TEST_true(OSSL_PARAM_BLD_push_BN(param_bld,
2854 OSSL_PKEY_PARAM_PRIV_KEY,
2856 || !TEST_ptr(params1 = OSSL_PARAM_BLD_to_param(param_bld)))
2859 OSSL_PARAM_BLD_free(param_bld);
2860 if (!TEST_ptr(param_bld = OSSL_PARAM_BLD_new())
2861 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld,
2862 OSSL_PKEY_PARAM_GROUP_NAME,
2864 || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld,
2865 OSSL_PKEY_PARAM_PUB_KEY,
2867 || !TEST_ptr(params2 = OSSL_PARAM_BLD_to_param(param_bld)))
2870 /* create two new provider-native `EVP_PKEY`s */
2871 EVP_PKEY_CTX_free(pctx2);
2872 if (!TEST_ptr(pctx2 = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL))
2873 || !TEST_true(EVP_PKEY_fromdata_init(pctx2))
2874 || !TEST_true(EVP_PKEY_fromdata(pctx2, &pkey1, EVP_PKEY_KEYPAIR,
2876 || !TEST_true(EVP_PKEY_fromdata(pctx2, &pkey2, EVP_PKEY_PUBLIC_KEY,
2880 /* compute keyexchange once more using the provider keys */
2881 EVP_PKEY_CTX_free(pctx1);
2882 if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))
2883 || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1)
2884 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1)
2885 || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &t), 1)
2886 || !TEST_int_gt(bsize, t)
2887 || !TEST_int_le(sslen, t)
2888 || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &t), 1)
2889 /* compare with previous result */
2890 || !TEST_mem_eq(buf1, t, buf2, sslen))
2898 OSSL_PARAM_BLD_free(param_bld);
2899 OSSL_PARAM_free(params1);
2900 OSSL_PARAM_free(params2);
2904 EC_GROUP_free(group);
2905 EC_GROUP_free(altgroup);
2910 EC_KEY_free(eckey1);
2911 EC_KEY_free(eckey2);
2912 EVP_PKEY_free(pkey1);
2913 EVP_PKEY_free(pkey2);
2914 EVP_PKEY_CTX_free(pctx1);
2915 EVP_PKEY_CTX_free(pctx2);
2920 int setup_tests(void)
2922 crv_len = EC_get_builtin_curves(NULL, 0);
2923 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2924 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2927 ADD_TEST(parameter_test);
2928 ADD_TEST(cofactor_range_test);
2929 ADD_ALL_TESTS(cardinality_test, crv_len);
2930 ADD_TEST(prime_field_tests);
2931 #ifndef OPENSSL_NO_EC2M
2932 ADD_TEST(char2_field_tests);
2933 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2935 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2936 ADD_ALL_TESTS(internal_curve_test, crv_len);
2937 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2938 ADD_TEST(group_field_test);
2939 ADD_ALL_TESTS(check_named_curve_test, crv_len);
2940 ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
2941 ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len);
2942 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2943 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2944 ADD_ALL_TESTS(custom_generator_test, crv_len);
2945 ADD_ALL_TESTS(custom_params_test, crv_len);
2949 void cleanup_tests(void)
2951 OPENSSL_free(curves);