2 * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
12 * We need access to the deprecated EC_POINTs_mul, EC_GROUP_precompute_mult,
13 * and EC_GROUP_have_precompute_mult for testing purposes
14 * when the deprecated calls are not hidden
16 #ifndef OPENSSL_NO_DEPRECATED_3_0
17 # define OPENSSL_SUPPRESS_DEPRECATED
21 #include "internal/nelem.h"
25 # include <openssl/ec.h>
26 # ifndef OPENSSL_NO_ENGINE
27 # include <openssl/engine.h>
29 # include <openssl/err.h>
30 # include <openssl/obj_mac.h>
31 # include <openssl/objects.h>
32 # include <openssl/rand.h>
33 # include <openssl/bn.h>
34 # include <openssl/opensslconf.h>
36 static size_t crv_len = 0;
37 static EC_builtin_curve *curves = NULL;
39 /* test multiplication with group order, long and negative scalars */
40 static int group_order_tests(EC_GROUP *group)
42 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
43 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
44 const EC_POINT *G = NULL;
48 if (!TEST_ptr(n1 = BN_new())
49 || !TEST_ptr(n2 = BN_new())
50 || !TEST_ptr(order = BN_new())
51 || !TEST_ptr(ctx = BN_CTX_new())
52 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
53 || !TEST_ptr(P = EC_POINT_new(group))
54 || !TEST_ptr(Q = EC_POINT_new(group))
55 || !TEST_ptr(R = EC_POINT_new(group))
56 || !TEST_ptr(S = EC_POINT_new(group)))
59 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
60 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
61 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
62 # ifndef OPENSSL_NO_DEPRECATED_3_0
63 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
65 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
66 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
67 || !TEST_true(EC_POINT_copy(P, G))
68 || !TEST_true(BN_one(n1))
69 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
70 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
71 || !TEST_true(BN_sub(n1, order, n1))
72 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
73 || !TEST_true(EC_POINT_invert(group, Q, ctx))
74 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
77 for (i = 1; i <= 2; i++) {
78 # ifndef OPENSSL_NO_DEPRECATED_3_0
79 const BIGNUM *scalars[6];
80 const EC_POINT *points[6];
83 if (!TEST_true(BN_set_word(n1, i))
85 * If i == 1, P will be the predefined generator for which
86 * EC_GROUP_precompute_mult has set up precomputation.
88 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
89 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
90 || !TEST_true(BN_one(n1))
92 || !TEST_true(BN_sub(n1, n1, order))
93 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
94 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
97 || !TEST_true(BN_add(n2, order, BN_value_one()))
98 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
99 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
101 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
102 || !TEST_true(BN_mul(n2, n1, n2, ctx))
103 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
104 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
107 /* n2 = order^2 - 1 */
108 BN_set_negative(n2, 0);
109 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
110 /* Add P to verify the result. */
111 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
112 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
113 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
116 # ifndef OPENSSL_NO_DEPRECATED_3_0
117 /* Exercise EC_POINTs_mul, including corner cases. */
118 scalars[0] = scalars[1] = BN_value_one();
119 points[0] = points[1] = P;
121 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
122 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
123 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
127 points[0] = Q; /* => infinity */
129 points[1] = P; /* => -P */
131 points[2] = Q; /* => infinity */
133 points[3] = Q; /* => infinity */
135 points[4] = P; /* => P */
137 points[5] = Q; /* => infinity */
138 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
139 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
146 if (r == 0 && i != 0)
147 TEST_info(i == 1 ? "allowing precomputation" :
148 "without precomputation");
160 static int prime_field_tests(void)
163 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
164 EC_GROUP *group = NULL;
165 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
166 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
167 # ifndef OPENSSL_NO_DEPRECATED_3_0
168 const EC_POINT *points[4];
169 const BIGNUM *scalars[4];
171 unsigned char buf[100];
175 if (!TEST_ptr(ctx = BN_CTX_new())
176 || !TEST_ptr(p = BN_new())
177 || !TEST_ptr(a = BN_new())
178 || !TEST_ptr(b = BN_new())
179 || !TEST_true(BN_hex2bn(&p, "17"))
180 || !TEST_true(BN_hex2bn(&a, "1"))
181 || !TEST_true(BN_hex2bn(&b, "1"))
182 || !TEST_ptr(group = EC_GROUP_new_curve_GFp(p, a, b, ctx))
183 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
186 TEST_info("Curve defined by Weierstrass equation");
187 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
188 test_output_bignum("a", a);
189 test_output_bignum("b", b);
190 test_output_bignum("p", p);
193 if (!TEST_ptr(P = EC_POINT_new(group))
194 || !TEST_ptr(Q = EC_POINT_new(group))
195 || !TEST_ptr(R = EC_POINT_new(group))
196 || !TEST_true(EC_POINT_set_to_infinity(group, P))
197 || !TEST_true(EC_POINT_is_at_infinity(group, P))
198 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
199 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
200 || !TEST_true(EC_POINT_is_at_infinity(group, P))
201 || !TEST_ptr(x = BN_new())
202 || !TEST_ptr(y = BN_new())
203 || !TEST_ptr(z = BN_new())
204 || !TEST_ptr(yplusone = BN_new())
205 || !TEST_true(BN_hex2bn(&x, "D"))
206 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
209 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
210 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
212 TEST_info("Point is not on curve");
213 test_output_bignum("x", x);
214 test_output_bignum("y", y);
218 TEST_note("A cyclic subgroup:");
221 if (!TEST_int_ne(k--, 0))
224 if (EC_POINT_is_at_infinity(group, P)) {
225 TEST_note(" point at infinity");
227 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
231 test_output_bignum("x", x);
232 test_output_bignum("y", y);
235 if (!TEST_true(EC_POINT_copy(R, P))
236 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
239 } while (!EC_POINT_is_at_infinity(group, P));
241 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
242 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
246 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
248 if (!TEST_size_t_ne(len, 0)
249 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
250 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
252 test_output_memory("Generator as octet string, compressed form:",
255 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
256 buf, sizeof(buf), ctx);
257 if (!TEST_size_t_ne(len, 0)
258 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
259 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
261 test_output_memory("Generator as octet string, uncompressed form:",
264 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
265 buf, sizeof(buf), ctx);
266 if (!TEST_size_t_ne(len, 0)
267 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
268 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
270 test_output_memory("Generator as octet string, hybrid form:",
273 if (!TEST_true(EC_POINT_invert(group, P, ctx))
274 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
277 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
278 * 2000) -- not a NIST curve, but commonly used
281 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
282 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
283 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
284 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
285 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
286 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
287 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
288 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
289 || !TEST_true(BN_hex2bn(&x, "4A96B568"
290 "8EF573284664698968C38BB913CBFC82"))
291 || !TEST_true(BN_hex2bn(&y, "23a62855"
292 "3168947d59dcc912042351377ac5fb32"))
293 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
295 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
296 * and therefore setting the coordinates should fail.
298 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
300 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
301 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
302 || !TEST_true(BN_hex2bn(&z, "0100000000"
303 "000000000001F4C8F927AED3CA752257"))
304 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
305 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
307 TEST_info("SEC2 curve secp160r1 -- Generator");
308 test_output_bignum("x", x);
309 test_output_bignum("y", y);
310 /* G_y value taken from the standard: */
311 if (!TEST_true(BN_hex2bn(&z, "23a62855"
312 "3168947d59dcc912042351377ac5fb32"))
314 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
315 || !group_order_tests(group)
317 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
319 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
320 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
321 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
322 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
323 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
324 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
325 "0FA7E9AB72243049FEB8DEECC146B9B1"))
326 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
327 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
328 "7CBF20EB43A18800F4FF0AFD82FF1012"))
329 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
330 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
331 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
332 "FFFFFFFF99DEF836146BC9B1B4D22831"))
333 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
334 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
337 TEST_info("NIST curve P-192 -- Generator");
338 test_output_bignum("x", x);
339 test_output_bignum("y", y);
340 /* G_y value taken from the standard: */
341 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
342 "631011ED6B24CDD573F977A11E794811"))
344 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
346 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
347 * and therefore setting the coordinates should fail.
349 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
351 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
352 || !group_order_tests(group)
354 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
356 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
357 "FFFFFFFF000000000000000000000001"))
358 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
359 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
360 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
361 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
362 "5044B0B7D7BFD8BA270B39432355FFB4"))
363 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
364 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
365 "4A03C1D356C21122343280D6115C1D21"))
366 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
367 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
368 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
369 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
370 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
371 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
374 TEST_info("NIST curve P-224 -- Generator");
375 test_output_bignum("x", x);
376 test_output_bignum("y", y);
377 /* G_y value taken from the standard: */
378 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
379 "CD4375A05A07476444D5819985007E34"))
381 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
383 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
384 * and therefore setting the coordinates should fail.
386 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
388 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
389 || !group_order_tests(group)
391 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
393 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
394 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
395 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
396 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
397 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
398 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
399 "651D06B0CC53B0F63BCE3C3E27D2604B"))
400 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
402 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
403 "77037D812DEB33A0F4A13945D898C296"))
404 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
405 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
406 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
407 "BCE6FAADA7179E84F3B9CAC2FC632551"))
408 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
409 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
412 TEST_info("NIST curve P-256 -- Generator");
413 test_output_bignum("x", x);
414 test_output_bignum("y", y);
415 /* G_y value taken from the standard: */
416 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
417 "2BCE33576B315ECECBB6406837BF51F5"))
419 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
421 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
422 * and therefore setting the coordinates should fail.
424 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
426 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
427 || !group_order_tests(group)
429 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
431 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
432 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
433 "FFFFFFFF0000000000000000FFFFFFFF"))
434 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
435 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
436 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
437 "FFFFFFFF0000000000000000FFFFFFFC"))
438 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
439 "181D9C6EFE8141120314088F5013875A"
440 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
441 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
443 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
444 "6E1D3B628BA79B9859F741E082542A38"
445 "5502F25DBF55296C3A545E3872760AB7"))
446 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
447 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
448 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
449 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
450 "581A0DB248B0A77AECEC196ACCC52973"))
451 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
452 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
455 TEST_info("NIST curve P-384 -- Generator");
456 test_output_bignum("x", x);
457 test_output_bignum("y", y);
458 /* G_y value taken from the standard: */
459 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
460 "F8F41DBD289A147CE9DA3113B5F0B8C0"
461 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
463 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
465 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
466 * and therefore setting the coordinates should fail.
468 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
470 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
471 || !group_order_tests(group)
473 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
474 || !TEST_true(BN_hex2bn(&p, "1FF"
475 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
476 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
477 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
478 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
479 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
480 || !TEST_true(BN_hex2bn(&a, "1FF"
481 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
482 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
483 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
484 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
485 || !TEST_true(BN_hex2bn(&b, "051"
486 "953EB9618E1C9A1F929A21A0B68540EE"
487 "A2DA725B99B315F3B8B489918EF109E1"
488 "56193951EC7E937B1652C0BD3BB1BF07"
489 "3573DF883D2C34F1EF451FD46B503F00"))
490 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
491 || !TEST_true(BN_hex2bn(&x, "C6"
492 "858E06B70404E9CD9E3ECB662395B442"
493 "9C648139053FB521F828AF606B4D3DBA"
494 "A14B5E77EFE75928FE1DC127A2FFA8DE"
495 "3348B3C1856A429BF97E7E31C2E5BD66"))
496 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
497 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
498 || !TEST_true(BN_hex2bn(&z, "1FF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
500 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
501 "51868783BF2F966B7FCC0148F709A5D0"
502 "3BB5C9B8899C47AEBB6FB71E91386409"))
503 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
504 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
507 TEST_info("NIST curve P-521 -- Generator");
508 test_output_bignum("x", x);
509 test_output_bignum("y", y);
510 /* G_y value taken from the standard: */
511 if (!TEST_true(BN_hex2bn(&z, "118"
512 "39296A789A3BC0045C8A5FB42C7D1BD9"
513 "98F54449579B446817AFBD17273E662C"
514 "97EE72995EF42640C550B9013FAD0761"
515 "353C7086A272C24088BE94769FD16650"))
517 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
519 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
520 * and therefore setting the coordinates should fail.
522 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
524 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
525 || !group_order_tests(group)
527 /* more tests using the last curve */
529 /* Restore the point that got mangled in the (x, y + 1) test. */
530 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
531 || !TEST_true(EC_POINT_copy(Q, P))
532 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
533 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
534 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
535 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
536 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
537 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
538 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
539 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
542 # ifndef OPENSSL_NO_DEPRECATED_3_0
543 TEST_note("combined multiplication ...");
549 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
550 || !TEST_true(BN_add(y, z, BN_value_one()))
552 || !TEST_true(BN_rshift1(y, y)))
555 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
558 /* z is still the group order */
559 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
560 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
561 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
562 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
563 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
564 || !TEST_true(BN_add(z, z, y)))
566 BN_set_negative(z, 1);
568 scalars[1] = z; /* z = -(order + y) */
570 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
571 || !TEST_true(EC_POINT_is_at_infinity(group, P))
572 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
573 || !TEST_true(BN_add(z, x, y)))
575 BN_set_negative(z, 1);
578 scalars[2] = z; /* z = -(x+y) */
580 if (!TEST_ptr(scalar3 = BN_new()))
583 scalars[3] = scalar3;
585 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
586 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
596 EC_GROUP_free(group);
608 # ifndef OPENSSL_NO_EC2M
610 static struct c2_curve_test {
621 } char2_curve_tests[] = {
622 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
625 "0800000000000000000000000000000000000000C9",
628 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
629 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
630 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
632 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
635 "0800000000000000000000000000000000000000C9",
637 "020A601907B8C953CA1481EB10512F78744A3205FD",
638 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
639 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
640 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
642 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
645 "020000000000000000000000000000000000000004000000000000000001",
648 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
649 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
651 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
654 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
657 "020000000000000000000000000000000000000004000000000000000001",
658 "000000000000000000000000000000000000000000000000000000000001",
659 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
660 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
661 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
663 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
666 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
670 "00000000000000000000000000000000000000000000000000000000000010A1",
674 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
676 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
679 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
682 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
686 "00000000000000000000000000000000000000000000000000000000000010A1",
688 "0000000000000000000000000000000000000000000000000000000000000001",
690 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
692 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
694 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
697 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
700 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
703 "0200000000000000000000000000000000000000"
704 "0000000000000000000000000000000000000000008000000000000000000001",
707 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
708 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
709 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
710 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
712 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
713 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
716 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
719 "0200000000000000000000000000000000000000"
720 "0000000000000000000000000000000000000000008000000000000000000001",
721 "0000000000000000000000000000000000000000"
722 "0000000000000000000000000000000000000000000000000000000000000001",
723 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
724 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
725 "015D4860D088DDB3496B0C6064756260441CDE4A"
726 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
727 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
728 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
730 "0100000000000000000000000000000000000000"
731 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
734 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
738 "0000000000000000000000000000000000000000000000000000000000000000"
739 "0000000000000000000000000000000000000000000000000000000000000425",
743 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
744 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
746 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
747 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
750 "00000000000000000000000000000000000000000000000000000000131850E1"
751 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
754 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
758 "0000000000000000000000000000000000000000000000000000000000000000"
759 "0000000000000000000000000000000000000000000000000000000000000425",
761 "0000000000000000000000000000000000000000000000000000000000000000"
762 "0000000000000000000000000000000000000000000000000000000000000001",
764 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
765 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
767 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
768 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
770 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
771 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
774 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
775 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
780 static int char2_curve_test(int n)
784 BIGNUM *p = NULL, *a = NULL, *b = NULL;
785 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
786 EC_GROUP *group = NULL;
787 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
788 # ifndef OPENSSL_NO_DEPRECATED_3_0
789 const EC_POINT *points[3];
790 const BIGNUM *scalars[3];
792 struct c2_curve_test *const test = char2_curve_tests + n;
794 if (!TEST_ptr(ctx = BN_CTX_new())
795 || !TEST_ptr(p = BN_new())
796 || !TEST_ptr(a = BN_new())
797 || !TEST_ptr(b = BN_new())
798 || !TEST_ptr(x = BN_new())
799 || !TEST_ptr(y = BN_new())
800 || !TEST_ptr(z = BN_new())
801 || !TEST_ptr(yplusone = BN_new())
802 || !TEST_true(BN_hex2bn(&p, test->p))
803 || !TEST_true(BN_hex2bn(&a, test->a))
804 || !TEST_true(BN_hex2bn(&b, test->b))
805 || !TEST_true(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx))
806 || !TEST_ptr(P = EC_POINT_new(group))
807 || !TEST_ptr(Q = EC_POINT_new(group))
808 || !TEST_ptr(R = EC_POINT_new(group))
809 || !TEST_true(BN_hex2bn(&x, test->x))
810 || !TEST_true(BN_hex2bn(&y, test->y))
811 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
814 /* Change test based on whether binary point compression is enabled or not. */
815 # ifdef OPENSSL_EC_BIN_PT_COMP
817 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
818 * and therefore setting the coordinates should fail.
820 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
821 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
824 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
825 || !TEST_true(BN_hex2bn(&z, test->order))
826 || !TEST_true(BN_hex2bn(&cof, test->cof))
827 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
828 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
830 TEST_info("%s -- Generator", test->name);
831 test_output_bignum("x", x);
832 test_output_bignum("y", y);
833 /* G_y value taken from the standard: */
834 if (!TEST_true(BN_hex2bn(&z, test->y))
835 || !TEST_BN_eq(y, z))
839 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
840 * and therefore setting the coordinates should fail.
842 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
843 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
844 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
845 || !TEST_true(BN_hex2bn(&z, test->order))
846 || !TEST_true(BN_hex2bn(&cof, test->cof))
847 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
849 TEST_info("%s -- Generator:", test->name);
850 test_output_bignum("x", x);
851 test_output_bignum("y", y);
854 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
855 || !group_order_tests(group))
858 /* more tests using the last curve */
859 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
860 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
861 || !TEST_true(EC_POINT_copy(Q, P))
862 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
863 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
864 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
865 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
866 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
867 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
868 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
869 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
872 # ifndef OPENSSL_NO_DEPRECATED_3_0
873 TEST_note("combined multiplication ...");
878 if (!TEST_true(BN_add(y, z, BN_value_one()))
880 || !TEST_true(BN_rshift1(y, y)))
882 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
885 /* z is still the group order */
886 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
887 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
888 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
889 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
892 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
893 || !TEST_true(BN_add(z, z, y)))
895 BN_set_negative(z, 1);
897 scalars[1] = z; /* z = -(order + y) */
899 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
900 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
903 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
904 || !TEST_true(BN_add(z, x, y)))
906 BN_set_negative(z, 1);
909 scalars[2] = z; /* z = -(x+y) */
911 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
912 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
931 EC_GROUP_free(group);
935 static int char2_field_tests(void)
938 BIGNUM *p = NULL, *a = NULL, *b = NULL;
939 EC_GROUP *group = NULL;
940 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
941 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
942 unsigned char buf[100];
946 if (!TEST_ptr(ctx = BN_CTX_new())
947 || !TEST_ptr(p = BN_new())
948 || !TEST_ptr(a = BN_new())
949 || !TEST_ptr(b = BN_new())
950 || !TEST_true(BN_hex2bn(&p, "13"))
951 || !TEST_true(BN_hex2bn(&a, "3"))
952 || !TEST_true(BN_hex2bn(&b, "1")))
955 if (!TEST_ptr(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx))
956 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
959 TEST_info("Curve defined by Weierstrass equation");
960 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
961 test_output_bignum("a", a);
962 test_output_bignum("b", b);
963 test_output_bignum("p", p);
965 if (!TEST_ptr(P = EC_POINT_new(group))
966 || !TEST_ptr(Q = EC_POINT_new(group))
967 || !TEST_ptr(R = EC_POINT_new(group))
968 || !TEST_true(EC_POINT_set_to_infinity(group, P))
969 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
973 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
974 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
975 || !TEST_true(EC_POINT_is_at_infinity(group, P))
976 || !TEST_ptr(x = BN_new())
977 || !TEST_ptr(y = BN_new())
978 || !TEST_ptr(z = BN_new())
979 || !TEST_ptr(cof = BN_new())
980 || !TEST_ptr(yplusone = BN_new())
981 || !TEST_true(BN_hex2bn(&x, "6"))
982 /* Change test based on whether binary point compression is enabled or not. */
983 # ifdef OPENSSL_EC_BIN_PT_COMP
984 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
986 || !TEST_true(BN_hex2bn(&y, "8"))
987 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
991 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
992 /* Change test based on whether binary point compression is enabled or not. */
993 # ifdef OPENSSL_EC_BIN_PT_COMP
994 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
997 TEST_info("Point is not on curve");
998 test_output_bignum("x", x);
999 test_output_bignum("y", y);
1003 TEST_note("A cyclic subgroup:");
1006 if (!TEST_int_ne(k--, 0))
1009 if (EC_POINT_is_at_infinity(group, P))
1010 TEST_note(" point at infinity");
1012 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1016 test_output_bignum("x", x);
1017 test_output_bignum("y", y);
1020 if (!TEST_true(EC_POINT_copy(R, P))
1021 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1024 while (!EC_POINT_is_at_infinity(group, P));
1026 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1027 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1030 /* Change test based on whether binary point compression is enabled or not. */
1031 # ifdef OPENSSL_EC_BIN_PT_COMP
1032 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1033 buf, sizeof(buf), ctx);
1034 if (!TEST_size_t_ne(len, 0)
1035 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1036 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1038 test_output_memory("Generator as octet string, compressed form:",
1042 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1043 buf, sizeof(buf), ctx);
1044 if (!TEST_size_t_ne(len, 0)
1045 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1046 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1048 test_output_memory("Generator as octet string, uncompressed form:",
1051 /* Change test based on whether binary point compression is enabled or not. */
1052 # ifdef OPENSSL_EC_BIN_PT_COMP
1054 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1056 if (!TEST_size_t_ne(len, 0)
1057 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1058 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1060 test_output_memory("Generator as octet string, hybrid form:",
1064 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1065 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1076 EC_GROUP_free(group);
1089 static int internal_curve_test(int n)
1091 EC_GROUP *group = NULL;
1092 int nid = curves[n].nid;
1094 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1095 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1099 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1100 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1101 EC_GROUP_free(group);
1104 EC_GROUP_free(group);
1108 static int internal_curve_test_method(int n)
1110 int r, nid = curves[n].nid;
1113 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1114 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1117 r = group_order_tests(group);
1118 EC_GROUP_free(group);
1122 static int group_field_test(void)
1125 BIGNUM *secp521r1_field = NULL;
1126 BIGNUM *sect163r2_field = NULL;
1127 EC_GROUP *secp521r1_group = NULL;
1128 EC_GROUP *sect163r2_group = NULL;
1130 BN_hex2bn(&secp521r1_field,
1131 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1132 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1133 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1134 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1138 BN_hex2bn(§163r2_field,
1139 "08000000000000000000000000000000"
1142 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1143 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1146 # ifndef OPENSSL_NO_EC2M
1147 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1148 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1152 EC_GROUP_free(secp521r1_group);
1153 EC_GROUP_free(sect163r2_group);
1154 BN_free(secp521r1_field);
1155 BN_free(sect163r2_field);
1160 * nistp_test_params contains magic numbers for testing
1161 * several NIST curves with characteristic > 3.
1163 struct nistp_test_params {
1167 * Qx, Qy and D are taken from
1168 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1169 * Otherwise, values are standard curve parameters from FIPS 180-3
1171 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1174 static const struct nistp_test_params nistp_tests_params[] = {
1180 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1182 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1184 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1186 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1188 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1190 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1192 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1194 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1196 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1200 NID_X9_62_prime256v1,
1203 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1205 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1207 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1209 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1211 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1213 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1215 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1217 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1219 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1227 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1228 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1231 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1232 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1235 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1236 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1239 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1240 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1243 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1244 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1247 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1248 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1251 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1252 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1255 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1256 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1259 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1260 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1264 static int nistp_single_test(int idx)
1266 const struct nistp_test_params *test = nistp_tests_params + idx;
1268 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1269 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1270 EC_GROUP *NISTP = NULL;
1271 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1274 TEST_note("NIST curve P-%d (optimised implementation):",
1276 if (!TEST_ptr(ctx = BN_CTX_new())
1277 || !TEST_ptr(p = BN_new())
1278 || !TEST_ptr(a = BN_new())
1279 || !TEST_ptr(b = BN_new())
1280 || !TEST_ptr(x = BN_new())
1281 || !TEST_ptr(y = BN_new())
1282 || !TEST_ptr(m = BN_new())
1283 || !TEST_ptr(n = BN_new())
1284 || !TEST_ptr(order = BN_new())
1285 || !TEST_ptr(yplusone = BN_new())
1287 || !TEST_ptr(NISTP = EC_GROUP_new_by_curve_name(test->nid))
1288 || !TEST_true(BN_hex2bn(&p, test->p))
1289 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
1290 || !TEST_true(BN_hex2bn(&a, test->a))
1291 || !TEST_true(BN_hex2bn(&b, test->b))
1292 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1293 || !TEST_ptr(G = EC_POINT_new(NISTP))
1294 || !TEST_ptr(P = EC_POINT_new(NISTP))
1295 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1296 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1297 || !TEST_true(BN_hex2bn(&x, test->Qx))
1298 || !TEST_true(BN_hex2bn(&y, test->Qy))
1299 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1301 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1302 * and therefore setting the coordinates should fail.
1304 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1306 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1308 || !TEST_true(BN_hex2bn(&x, test->Gx))
1309 || !TEST_true(BN_hex2bn(&y, test->Gy))
1310 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1311 || !TEST_true(BN_hex2bn(&order, test->order))
1312 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1313 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1316 TEST_note("NIST test vectors ... ");
1317 if (!TEST_true(BN_hex2bn(&n, test->d)))
1319 /* fixed point multiplication */
1320 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1321 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1323 /* random point multiplication */
1324 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1325 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1327 /* set generator to P = 2*G, where G is the standard generator */
1328 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1329 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1330 /* set the scalar to m=n/2, where n is the NIST test scalar */
1331 || !TEST_true(BN_rshift(m, n, 1)))
1334 /* test the non-standard generator */
1335 /* fixed point multiplication */
1336 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1337 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1339 /* random point multiplication */
1340 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1341 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1342 # ifndef OPENSSL_NO_DEPRECATED_3_0
1343 /* We have not performed precomp so this should be false */
1344 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1345 /* now repeat all tests with precomputation */
1346 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1351 /* fixed point multiplication */
1352 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1353 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1355 /* random point multiplication */
1356 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1357 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1359 /* reset generator */
1360 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1362 /* fixed point multiplication */
1363 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1364 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1366 /* random point multiplication */
1367 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1368 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1371 /* regression test for felem_neg bug */
1372 if (!TEST_true(BN_set_word(m, 32))
1373 || !TEST_true(BN_set_word(n, 31))
1374 || !TEST_true(EC_POINT_copy(P, G))
1375 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1376 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1377 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1382 EC_GROUP_free(NISTP);
1386 EC_POINT_free(Q_CHECK);
1400 static const unsigned char p521_named[] = {
1401 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1404 static const unsigned char p521_explicit[] = {
1405 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1406 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1412 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 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 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1418 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1419 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1420 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1421 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1422 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1423 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1424 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1425 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1426 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1427 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1428 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1429 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1430 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1431 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1432 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1433 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1434 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1435 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1436 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1437 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1438 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1439 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1440 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1441 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1442 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1446 * This test validates a named curve's group parameters using
1447 * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1448 * group parameters results in the curve not being valid.
1450 static int check_named_curve_test(int id)
1452 int ret = 0, nid, field_nid, has_seed;
1453 EC_GROUP *group = NULL, *gtest = NULL;
1454 const EC_POINT *group_gen = NULL;
1455 EC_POINT *other_gen = NULL;
1456 BIGNUM *group_p = NULL, *group_a = NULL, *group_b = NULL;
1457 BIGNUM *other_p = NULL, *other_a = NULL, *other_b = NULL;
1458 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1459 BIGNUM *other_order = NULL;
1460 const BIGNUM *group_order = NULL;
1461 BN_CTX *bn_ctx = NULL;
1462 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1463 static size_t invalid_seed_len = sizeof(invalid_seed);
1466 nid = curves[id].nid;
1467 if (!TEST_ptr(bn_ctx = BN_CTX_new())
1468 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1469 || !TEST_ptr(gtest = EC_GROUP_dup(group))
1470 || !TEST_ptr(group_p = BN_new())
1471 || !TEST_ptr(group_a = BN_new())
1472 || !TEST_ptr(group_b = BN_new())
1473 || !TEST_ptr(group_cofactor = BN_new())
1474 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1475 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1476 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1477 || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL))
1478 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1479 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1480 || !TEST_ptr(other_order = BN_dup(group_order))
1481 || !TEST_true(BN_add_word(other_order, 1))
1482 || !TEST_ptr(other_a = BN_dup(group_a))
1483 || !TEST_true(BN_add_word(other_a, 1))
1484 || !TEST_ptr(other_b = BN_dup(group_b))
1485 || !TEST_true(BN_add_word(other_b, 1))
1486 || !TEST_ptr(other_cofactor = BN_dup(group_cofactor))
1487 || !TEST_true(BN_add_word(other_cofactor, 1)))
1490 /* Determine if the built-in curve has a seed field set */
1491 has_seed = (EC_GROUP_get_seed_len(group) > 0);
1492 field_nid = EC_GROUP_get_field_type(group);
1493 if (field_nid == NID_X9_62_characteristic_two_field) {
1494 if (!TEST_ptr(other_p = BN_dup(group_p))
1495 || !TEST_true(BN_lshift1(other_p, other_p)))
1498 if (!TEST_ptr(other_p = BN_dup(group_p)))
1501 * Just choosing any arbitrary prime does not work..
1502 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1503 * nist prime. So only select one of these as an alternate prime.
1505 if (!TEST_ptr(BN_copy(other_p,
1506 BN_ucmp(BN_get0_nist_prime_192(), other_p) == 0 ?
1507 BN_get0_nist_prime_256() :
1508 BN_get0_nist_prime_192())))
1512 /* Passes because this is a valid curve */
1513 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)
1514 /* Only NIST curves pass */
1515 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 1, NULL),
1516 EC_curve_nid2nist(nid) != NULL ? nid : NID_undef))
1519 /* Fail if the curve name doesn't match the parameters */
1520 EC_GROUP_set_curve_name(group, nid + 1);
1522 if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1526 /* Restore curve name and ensure it's passing */
1527 EC_GROUP_set_curve_name(group, nid);
1528 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1531 if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len),
1537 * If the built-in curve has a seed and we set the seed to another value
1538 * then it will fail the check.
1540 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1544 * If the built-in curve does not have a seed then setting the seed will
1545 * pass the check (as the seed is optional).
1547 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1550 /* Pass if the seed is unknown (as it is optional) */
1551 if (!TEST_int_eq(EC_GROUP_set_seed(group, NULL, 0), 1)
1552 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1555 /* Check that a duped group passes */
1556 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1559 /* check that changing any generator parameter fails */
1560 if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order,
1562 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1563 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order,
1565 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1566 /* The order is not an optional field, so this should fail */
1567 || !TEST_false(EC_GROUP_set_generator(gtest, group_gen, NULL,
1569 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1571 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1572 /* Check that if the cofactor is not set then it still passes */
1573 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1575 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)
1576 /* check that restoring the generator passes */
1577 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1579 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1583 * check that changing any curve parameter fails
1585 * Setting arbitrary p, a or b might fail for some EC_GROUPs
1586 * depending on the internal EC_METHOD implementation, hence run
1587 * these tests conditionally to the success of EC_GROUP_set_curve().
1590 if (EC_GROUP_set_curve(gtest, other_p, group_a, group_b, NULL)) {
1591 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1594 /* clear the error stack if EC_GROUP_set_curve() failed */
1598 if (EC_GROUP_set_curve(gtest, group_p, other_a, group_b, NULL)) {
1599 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1602 /* clear the error stack if EC_GROUP_set_curve() failed */
1606 if (EC_GROUP_set_curve(gtest, group_p, group_a, other_b, NULL)) {
1607 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1610 /* clear the error stack if EC_GROUP_set_curve() failed */
1616 /* Check that restoring the curve parameters passes */
1617 if (!TEST_true(EC_GROUP_set_curve(gtest, group_p, group_a, group_b, NULL))
1618 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1629 BN_free(group_cofactor);
1630 BN_free(other_cofactor);
1631 BN_free(other_order);
1632 EC_POINT_free(other_gen);
1633 EC_GROUP_free(gtest);
1634 EC_GROUP_free(group);
1635 BN_CTX_free(bn_ctx);
1640 * This checks the lookup capability of EC_GROUP_check_named_curve()
1641 * when the given group was created with explicit parameters.
1643 * It is possible to retrieve an alternative alias that does not match
1644 * the original nid in this case.
1646 static int check_named_curve_lookup_test(int id)
1648 int ret = 0, nid, rv = 0;
1649 EC_GROUP *g = NULL , *ga = NULL;
1650 ECPARAMETERS *p = NULL, *pa = NULL;
1654 nid = curves[id].nid;
1655 if (!TEST_ptr(ctx = BN_CTX_new())
1656 || !TEST_ptr(g = EC_GROUP_new_by_curve_name(nid))
1657 || !TEST_ptr(p = EC_GROUP_get_ecparameters(g, NULL)))
1660 /* replace with group from explicit parameters */
1662 if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p)))
1665 if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0, NULL), 0))
1670 * fail if the returned nid is not an alias of the original group.
1672 * The comparison here is done by comparing two explicit
1673 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1674 * comparison happens with unnamed EC_GROUPs using the same
1677 if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv))
1678 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL)))
1681 /* replace with group from explicit parameters, then compare */
1683 if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa))
1684 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0))
1693 ECPARAMETERS_free(p);
1694 ECPARAMETERS_free(pa);
1701 * Sometime we cannot compare nids for equality, as the built-in curve table
1702 * includes aliases with different names for the same curve.
1704 * This function returns TRUE (1) if the checked nids are identical, or if they
1705 * alias to the same curve. FALSE (0) otherwise.
1708 int are_ec_nids_compatible(int n1d, int n2d)
1712 # ifndef OPENSSL_NO_EC2M
1714 case NID_wap_wsg_idm_ecid_wtls4:
1715 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1718 case NID_wap_wsg_idm_ecid_wtls3:
1719 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1722 case NID_wap_wsg_idm_ecid_wtls10:
1723 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1726 case NID_wap_wsg_idm_ecid_wtls11:
1727 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1729 case NID_X9_62_c2pnb163v1:
1730 case NID_wap_wsg_idm_ecid_wtls5:
1731 ret = (n2d == NID_X9_62_c2pnb163v1
1732 || n2d == NID_wap_wsg_idm_ecid_wtls5);
1734 # endif /* OPENSSL_NO_EC2M */
1736 case NID_wap_wsg_idm_ecid_wtls6:
1737 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1740 case NID_wap_wsg_idm_ecid_wtls7:
1741 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1743 # ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1745 case NID_wap_wsg_idm_ecid_wtls12:
1746 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1750 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1751 * that is associated with a specialized method.
1753 case NID_wap_wsg_idm_ecid_wtls12:
1754 ret = (n2d == NID_secp224r1);
1756 # endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1765 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1766 * EC_GROUP for built-in curves.
1768 * Note that it is possible to retrieve an alternative alias that does not match
1771 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1773 static int check_named_curve_from_ecparameters(int id)
1775 int ret = 0, nid, tnid;
1776 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1777 const EC_POINT *group_gen = NULL;
1778 EC_POINT *other_gen = NULL;
1779 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1780 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1781 const BIGNUM *group_order = NULL;
1782 BIGNUM *other_order = NULL;
1783 BN_CTX *bn_ctx = NULL;
1784 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1785 static size_t invalid_seed_len = sizeof(invalid_seed);
1786 ECPARAMETERS *params = NULL, *other_params = NULL;
1787 EC_GROUP *g_ary[8] = {NULL};
1788 EC_GROUP **g_next = &g_ary[0];
1789 ECPARAMETERS *p_ary[8] = {NULL};
1790 ECPARAMETERS **p_next = &p_ary[0];
1793 nid = curves[id].nid;
1794 TEST_note("Curve %s", OBJ_nid2sn(nid));
1795 if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1797 BN_CTX_start(bn_ctx);
1799 if (/* Allocations */
1800 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1801 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1802 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1803 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1804 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1805 /* Generate reference group and params */
1806 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1807 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1808 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1809 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1810 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1811 /* compute `other_*` values */
1812 || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1813 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1814 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1815 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1816 other_gen_x, other_gen_y, bn_ctx))
1817 || !TEST_true(BN_copy(other_order, group_order))
1818 || !TEST_true(BN_add_word(other_order, 1))
1819 || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1820 || !TEST_true(BN_add_word(other_cofactor, 1)))
1823 EC_POINT_free(other_gen);
1826 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1827 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1828 other_gen_x, other_gen_y,
1833 * ###########################
1834 * # Actual tests start here #
1835 * ###########################
1839 * Creating a group from built-in explicit parameters returns a
1842 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1843 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1846 * We cannot always guarantee the names match, as the built-in table
1847 * contains aliases for the same curve with different names.
1849 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1850 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1853 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1854 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1858 * An invalid seed in the parameters should be ignored: expect a "named"
1861 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1863 || !TEST_ptr(other_params = *p_next++ =
1864 EC_GROUP_get_ecparameters(tmpg, NULL))
1865 || !TEST_ptr(tgroup = *g_next++ =
1866 EC_GROUP_new_from_ecparameters(other_params))
1867 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1868 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1869 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1870 OPENSSL_EC_EXPLICIT_CURVE)) {
1871 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1876 * A null seed in the parameters should be ignored, as it is optional:
1877 * expect a "named" group.
1879 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1880 || !TEST_ptr(other_params = *p_next++ =
1881 EC_GROUP_get_ecparameters(tmpg, NULL))
1882 || !TEST_ptr(tgroup = *g_next++ =
1883 EC_GROUP_new_from_ecparameters(other_params))
1884 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1885 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1886 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1887 OPENSSL_EC_EXPLICIT_CURVE)) {
1888 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1893 * Check that changing any of the generator parameters does not yield a
1894 * match with the built-in curves
1896 if (/* Other gen, same group order & cofactor */
1897 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1899 || !TEST_ptr(other_params = *p_next++ =
1900 EC_GROUP_get_ecparameters(tmpg, NULL))
1901 || !TEST_ptr(tgroup = *g_next++ =
1902 EC_GROUP_new_from_ecparameters(other_params))
1903 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1904 /* Same gen & cofactor, different order */
1905 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1907 || !TEST_ptr(other_params = *p_next++ =
1908 EC_GROUP_get_ecparameters(tmpg, NULL))
1909 || !TEST_ptr(tgroup = *g_next++ =
1910 EC_GROUP_new_from_ecparameters(other_params))
1911 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1912 /* The order is not an optional field, so this should fail */
1913 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1915 /* Check that a wrong cofactor is ignored, and we still match */
1916 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1918 || !TEST_ptr(other_params = *p_next++ =
1919 EC_GROUP_get_ecparameters(tmpg, NULL))
1920 || !TEST_ptr(tgroup = *g_next++ =
1921 EC_GROUP_new_from_ecparameters(other_params))
1922 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1923 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1924 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1925 OPENSSL_EC_EXPLICIT_CURVE)
1926 /* Check that if the cofactor is not set then it still matches */
1927 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1929 || !TEST_ptr(other_params = *p_next++ =
1930 EC_GROUP_get_ecparameters(tmpg, NULL))
1931 || !TEST_ptr(tgroup = *g_next++ =
1932 EC_GROUP_new_from_ecparameters(other_params))
1933 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1934 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1935 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1936 OPENSSL_EC_EXPLICIT_CURVE)
1937 /* check that restoring the generator passes */
1938 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1940 || !TEST_ptr(other_params = *p_next++ =
1941 EC_GROUP_get_ecparameters(tmpg, NULL))
1942 || !TEST_ptr(tgroup = *g_next++ =
1943 EC_GROUP_new_from_ecparameters(other_params))
1944 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1945 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1946 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1947 OPENSSL_EC_EXPLICIT_CURVE))
1952 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
1953 EC_GROUP_free(*g_next);
1954 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
1955 ECPARAMETERS_free(*p_next);
1956 ECPARAMETERS_free(params);
1957 EC_POINT_free(other_gen);
1958 EC_GROUP_free(tmpg);
1959 EC_GROUP_free(group);
1961 BN_CTX_free(bn_ctx);
1966 static int parameter_test(void)
1968 EC_GROUP *group = NULL, *group2 = NULL;
1969 ECPARAMETERS *ecparameters = NULL;
1970 unsigned char *buf = NULL;
1973 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1))
1974 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1975 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1976 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1979 EC_GROUP_free(group);
1982 /* Test the named curve encoding, which should be default. */
1983 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1984 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1985 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1992 * Test the explicit encoding. P-521 requires correctly zero-padding the
1993 * curve coefficients.
1995 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1996 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1997 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
2002 EC_GROUP_free(group);
2003 EC_GROUP_free(group2);
2004 ECPARAMETERS_free(ecparameters);
2010 * random 256-bit explicit parameters curve, cofactor absent
2011 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
2012 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
2014 static const unsigned char params_cf_pass[] = {
2015 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2016 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
2017 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2018 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2019 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
2020 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2021 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2022 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
2023 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
2024 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
2025 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
2026 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
2027 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
2028 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
2029 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
2030 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
2031 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
2032 0x14, 0xa8, 0x2f, 0x4f
2036 * random 256-bit explicit parameters curve, cofactor absent
2037 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
2038 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
2040 static const unsigned char params_cf_fail[] = {
2041 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2042 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
2043 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2044 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2045 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
2046 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2047 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2048 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
2049 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
2050 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
2051 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
2052 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
2053 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
2054 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
2055 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
2056 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
2057 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
2058 0x34, 0xa2, 0x21, 0x01
2062 * Test two random 256-bit explicit parameters curves with absent cofactor.
2063 * The two curves are chosen to roughly straddle the bounds at which the lib
2064 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
2066 * - params_cf_pass: order is sufficiently close to p to compute cofactor
2067 * - params_cf_fail: order is too far away from p to compute cofactor
2069 * For standards-compliant curves, cofactor is chosen as small as possible.
2070 * So you can see neither of these curves are fit for cryptographic use.
2072 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
2073 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
2074 * will always succeed in computing the cofactor. Neither of these curves
2075 * conform to that -- this is just robustness testing.
2077 static int cofactor_range_test(void)
2079 EC_GROUP *group = NULL;
2082 const unsigned char *b1 = (const unsigned char *)params_cf_fail;
2083 const unsigned char *b2 = (const unsigned char *)params_cf_pass;
2085 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
2086 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
2087 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
2088 sizeof(params_cf_pass)))
2089 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
2090 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
2095 EC_GROUP_free(group);
2100 * For named curves, test that:
2101 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
2102 * - a nonsensical cofactor throws an error (negative test)
2103 * - nonsensical orders throw errors (negative tests)
2105 static int cardinality_test(int n)
2107 int ret = 0, is_binary = 0;
2108 int nid = curves[n].nid;
2110 EC_GROUP *g1 = NULL, *g2 = NULL;
2111 EC_POINT *g2_gen = NULL;
2112 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
2113 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
2115 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
2117 if (!TEST_ptr(ctx = BN_CTX_new())
2118 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))) {
2123 is_binary = (EC_GROUP_get_field_type(g1) == NID_X9_62_characteristic_two_field);
2126 g1_p = BN_CTX_get(ctx);
2127 g1_a = BN_CTX_get(ctx);
2128 g1_b = BN_CTX_get(ctx);
2129 g1_x = BN_CTX_get(ctx);
2130 g1_y = BN_CTX_get(ctx);
2131 g1_order = BN_CTX_get(ctx);
2132 g1_cf = BN_CTX_get(ctx);
2134 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
2135 /* pull out the explicit curve parameters */
2136 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
2137 || !TEST_true(EC_POINT_get_affine_coordinates(g1,
2138 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
2139 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
2140 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
2141 /* construct g2 manually with g1 parameters */
2142 # ifndef OPENSSL_NO_EC2M
2143 || !TEST_ptr(g2 = (is_binary) ?
2144 EC_GROUP_new_curve_GF2m(g1_p, g1_a, g1_b, ctx) :
2145 EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx))
2147 || !TEST_int_eq(0, is_binary)
2148 || !TEST_ptr(g2 = EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx))
2150 || !TEST_ptr(g2_gen = EC_POINT_new(g2))
2151 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
2152 /* pass NULL cofactor: lib should compute it */
2153 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2154 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2155 || !TEST_BN_eq(g1_cf, g2_cf)
2156 /* pass zero cofactor: lib should compute it */
2157 || !TEST_true(BN_set_word(g2_cf, 0))
2158 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2159 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2160 || !TEST_BN_eq(g1_cf, g2_cf)
2161 /* negative test for invalid cofactor */
2162 || !TEST_true(BN_set_word(g2_cf, 0))
2163 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2164 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2165 /* negative test for NULL order */
2166 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
2167 /* negative test for zero order */
2168 || !TEST_true(BN_set_word(g1_order, 0))
2169 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2170 /* negative test for negative order */
2171 || !TEST_true(BN_set_word(g2_cf, 0))
2172 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2173 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2174 /* negative test for too large order */
2175 || !TEST_true(BN_lshift(g1_order, g1_p, 2))
2176 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
2180 EC_POINT_free(g2_gen);
2188 static int check_ec_key_field_public_range_test(int id)
2190 int ret = 0, type = 0;
2191 const EC_POINT *pub = NULL;
2192 const EC_GROUP *group = NULL;
2193 const BIGNUM *field = NULL;
2194 BIGNUM *x = NULL, *y = NULL;
2197 if (!TEST_ptr(x = BN_new())
2198 || !TEST_ptr(y = BN_new())
2199 || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid))
2200 || !TEST_ptr(group = EC_KEY_get0_group(key))
2201 || !TEST_ptr(field = EC_GROUP_get0_field(group))
2202 || !TEST_int_gt(EC_KEY_generate_key(key), 0)
2203 || !TEST_int_gt(EC_KEY_check_key(key), 0)
2204 || !TEST_ptr(pub = EC_KEY_get0_public_key(key))
2205 || !TEST_int_gt(EC_POINT_get_affine_coordinates(group, pub, x, y,
2210 * Make the public point out of range by adding the field (which will still
2211 * be the same point on the curve). The add is different for char2 fields.
2213 type = EC_GROUP_get_field_type(group);
2214 #ifndef OPENSSL_NO_EC2M
2215 if (type == NID_X9_62_characteristic_two_field) {
2216 /* test for binary curves */
2217 if (!TEST_true(BN_GF2m_add(x, x, field)))
2221 if (type == NID_X9_62_prime_field) {
2222 /* test for prime curves */
2223 if (!TEST_true(BN_add(x, x, field)))
2226 /* this should never happen */
2227 TEST_error("Unsupported EC_METHOD field_type");
2230 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key, x, y), 0))
2242 * Helper for ec_point_hex2point_test
2244 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2247 * If P is NULL use point at infinity.
2250 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2251 point_conversion_form_t form,
2255 EC_POINT *Q = NULL, *Pinf = NULL;
2259 /* If P is NULL use point at infinity. */
2260 if (!TEST_ptr(Pinf = EC_POINT_new(group))
2261 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2266 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2267 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2268 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2272 * The next check is most likely superfluous, as EC_POINT_cmp should already
2274 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2275 * so we include it anyway!
2278 && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2284 EC_POINT_free(Pinf);
2292 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2294 static int ec_point_hex2point_test(int id)
2297 EC_GROUP *group = NULL;
2298 const EC_POINT *G = NULL;
2300 BN_CTX * bnctx = NULL;
2303 nid = curves[id].nid;
2304 if (!TEST_ptr(bnctx = BN_CTX_new())
2305 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2306 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2307 || !TEST_ptr(P = EC_POINT_dup(G, group)))
2310 if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2311 POINT_CONVERSION_COMPRESSED,
2313 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2314 POINT_CONVERSION_COMPRESSED,
2316 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2317 POINT_CONVERSION_UNCOMPRESSED,
2319 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2320 POINT_CONVERSION_UNCOMPRESSED,
2322 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2323 POINT_CONVERSION_HYBRID,
2325 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2326 POINT_CONVERSION_HYBRID,
2334 EC_GROUP_free(group);
2340 #endif /* OPENSSL_NO_EC */
2342 int setup_tests(void)
2344 #ifndef OPENSSL_NO_EC
2345 crv_len = EC_get_builtin_curves(NULL, 0);
2346 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2347 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2350 ADD_TEST(parameter_test);
2351 ADD_TEST(cofactor_range_test);
2352 ADD_ALL_TESTS(cardinality_test, crv_len);
2353 ADD_TEST(prime_field_tests);
2354 # ifndef OPENSSL_NO_EC2M
2355 ADD_TEST(char2_field_tests);
2356 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2358 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2359 ADD_ALL_TESTS(internal_curve_test, crv_len);
2360 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2361 ADD_TEST(group_field_test);
2362 ADD_ALL_TESTS(check_named_curve_test, crv_len);
2363 ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
2364 ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len);
2365 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2366 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2367 #endif /* OPENSSL_NO_EC */
2371 void cleanup_tests(void)
2373 #ifndef OPENSSL_NO_EC
2374 OPENSSL_free(curves);