2 * Copyright 2001-2018 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 #include "internal/nelem.h"
16 # include <openssl/ec.h>
17 # ifndef OPENSSL_NO_ENGINE
18 # include <openssl/engine.h>
20 # include <openssl/err.h>
21 # include <openssl/obj_mac.h>
22 # include <openssl/objects.h>
23 # include <openssl/rand.h>
24 # include <openssl/bn.h>
25 # include <openssl/opensslconf.h>
27 static size_t crv_len = 0;
28 static EC_builtin_curve *curves = NULL;
30 /* test multiplication with group order, long and negative scalars */
31 static int group_order_tests(EC_GROUP *group)
33 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
34 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
35 const EC_POINT *G = NULL;
39 if (!TEST_ptr(n1 = BN_new())
40 || !TEST_ptr(n2 = BN_new())
41 || !TEST_ptr(order = BN_new())
42 || !TEST_ptr(ctx = BN_CTX_new())
43 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
44 || !TEST_ptr(P = EC_POINT_new(group))
45 || !TEST_ptr(Q = EC_POINT_new(group))
46 || !TEST_ptr(R = EC_POINT_new(group))
47 || !TEST_ptr(S = EC_POINT_new(group)))
50 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
51 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
52 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
53 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
54 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
55 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
56 || !TEST_true(EC_POINT_copy(P, G))
57 || !TEST_true(BN_one(n1))
58 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
59 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
60 || !TEST_true(BN_sub(n1, order, n1))
61 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
62 || !TEST_true(EC_POINT_invert(group, Q, ctx))
63 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
66 for (i = 1; i <= 2; i++) {
67 const BIGNUM *scalars[6];
68 const EC_POINT *points[6];
70 if (!TEST_true(BN_set_word(n1, i))
72 * If i == 1, P will be the predefined generator for which
73 * EC_GROUP_precompute_mult has set up precomputation.
75 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
76 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
77 || !TEST_true(BN_one(n1))
79 || !TEST_true(BN_sub(n1, n1, order))
80 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
81 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
84 || !TEST_true(BN_add(n2, order, BN_value_one()))
85 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
86 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
88 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
89 || !TEST_true(BN_mul(n2, n1, n2, ctx))
90 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
91 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
94 /* n2 = order^2 - 1 */
95 BN_set_negative(n2, 0);
96 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
97 /* Add P to verify the result. */
98 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
99 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
101 /* Exercise EC_POINTs_mul, including corner cases. */
102 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
105 scalars[0] = scalars[1] = BN_value_one();
106 points[0] = points[1] = P;
108 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
109 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
110 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
114 points[0] = Q; /* => infinity */
116 points[1] = P; /* => -P */
118 points[2] = Q; /* => infinity */
120 points[3] = Q; /* => infinity */
122 points[4] = P; /* => P */
124 points[5] = Q; /* => infinity */
125 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
126 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
132 if (r == 0 && i != 0)
133 TEST_info(i == 1 ? "allowing precomputation" :
134 "without precomputation");
146 static int prime_field_tests(void)
149 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
150 EC_GROUP *group = NULL, *tmp = NULL;
151 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
152 *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
153 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
154 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
155 const EC_POINT *points[4];
156 const BIGNUM *scalars[4];
157 unsigned char buf[100];
161 if (!TEST_ptr(ctx = BN_CTX_new())
162 || !TEST_ptr(p = BN_new())
163 || !TEST_ptr(a = BN_new())
164 || !TEST_ptr(b = BN_new())
165 || !TEST_true(BN_hex2bn(&p, "17"))
166 || !TEST_true(BN_hex2bn(&a, "1"))
167 || !TEST_true(BN_hex2bn(&b, "1"))
169 * applications should use EC_GROUP_new_curve_GFp so
170 * that the library gets to choose the EC_METHOD
172 || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
173 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
174 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
175 || !TEST_true(EC_GROUP_copy(tmp, group)))
177 EC_GROUP_free(group);
181 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
184 TEST_info("Curve defined by Weierstrass equation");
185 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
186 test_output_bignum("a", a);
187 test_output_bignum("b", b);
188 test_output_bignum("p", p);
191 if (!TEST_ptr(P = EC_POINT_new(group))
192 || !TEST_ptr(Q = EC_POINT_new(group))
193 || !TEST_ptr(R = EC_POINT_new(group))
194 || !TEST_true(EC_POINT_set_to_infinity(group, P))
195 || !TEST_true(EC_POINT_is_at_infinity(group, P))
196 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
197 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
198 || !TEST_true(EC_POINT_is_at_infinity(group, P))
199 || !TEST_ptr(x = BN_new())
200 || !TEST_ptr(y = BN_new())
201 || !TEST_ptr(z = BN_new())
202 || !TEST_ptr(yplusone = BN_new())
203 || !TEST_true(BN_hex2bn(&x, "D"))
204 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
207 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
208 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
210 TEST_info("Point is not on curve");
211 test_output_bignum("x", x);
212 test_output_bignum("y", y);
216 TEST_note("A cyclic subgroup:");
219 if (!TEST_int_ne(k--, 0))
222 if (EC_POINT_is_at_infinity(group, P)) {
223 TEST_note(" point at infinity");
225 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
229 test_output_bignum("x", x);
230 test_output_bignum("y", y);
233 if (!TEST_true(EC_POINT_copy(R, P))
234 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
237 } while (!EC_POINT_is_at_infinity(group, P));
239 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
240 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
244 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
246 if (!TEST_size_t_ne(len, 0)
247 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
248 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
250 test_output_memory("Generator as octet string, compressed form:",
253 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
254 buf, sizeof(buf), ctx);
255 if (!TEST_size_t_ne(len, 0)
256 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
257 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
259 test_output_memory("Generator as octet string, uncompressed form:",
262 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
263 buf, sizeof(buf), ctx);
264 if (!TEST_size_t_ne(len, 0)
265 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
266 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
268 test_output_memory("Generator as octet string, hybrid form:",
271 if (!TEST_true(EC_POINT_invert(group, P, ctx))
272 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
275 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
276 * 2000) -- not a NIST curve, but commonly used
279 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
280 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
281 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
282 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
283 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
284 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
285 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
286 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
287 || !TEST_true(BN_hex2bn(&x, "4A96B568"
288 "8EF573284664698968C38BB913CBFC82"))
289 || !TEST_true(BN_hex2bn(&y, "23a62855"
290 "3168947d59dcc912042351377ac5fb32"))
291 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
293 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
294 * and therefore setting the coordinates should fail.
296 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
298 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
299 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
300 || !TEST_true(BN_hex2bn(&z, "0100000000"
301 "000000000001F4C8F927AED3CA752257"))
302 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
303 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
305 TEST_info("SEC2 curve secp160r1 -- Generator");
306 test_output_bignum("x", x);
307 test_output_bignum("y", y);
308 /* G_y value taken from the standard: */
309 if (!TEST_true(BN_hex2bn(&z, "23a62855"
310 "3168947d59dcc912042351377ac5fb32"))
312 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
313 || !group_order_tests(group)
314 || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))
315 || !TEST_true(EC_GROUP_copy(P_160, 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)
353 || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))
354 || !TEST_true(EC_GROUP_copy(P_192, group))
356 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
358 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
359 "FFFFFFFF000000000000000000000001"))
360 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
361 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
362 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
363 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
364 "5044B0B7D7BFD8BA270B39432355FFB4"))
365 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
366 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
367 "4A03C1D356C21122343280D6115C1D21"))
368 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
369 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
370 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
371 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
372 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
373 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
376 TEST_info("NIST curve P-224 -- Generator");
377 test_output_bignum("x", x);
378 test_output_bignum("y", y);
379 /* G_y value taken from the standard: */
380 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
381 "CD4375A05A07476444D5819985007E34"))
383 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
385 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
386 * and therefore setting the coordinates should fail.
388 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
390 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
391 || !group_order_tests(group)
392 || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
393 || !TEST_true(EC_GROUP_copy(P_224, group))
395 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
397 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
398 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
399 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
400 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
401 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
402 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
403 "651D06B0CC53B0F63BCE3C3E27D2604B"))
404 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
406 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
407 "77037D812DEB33A0F4A13945D898C296"))
408 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
409 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
410 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
411 "BCE6FAADA7179E84F3B9CAC2FC632551"))
412 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
413 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
416 TEST_info("NIST curve P-256 -- Generator");
417 test_output_bignum("x", x);
418 test_output_bignum("y", y);
419 /* G_y value taken from the standard: */
420 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
421 "2BCE33576B315ECECBB6406837BF51F5"))
423 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
425 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
426 * and therefore setting the coordinates should fail.
428 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
430 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
431 || !group_order_tests(group)
432 || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
433 || !TEST_true(EC_GROUP_copy(P_256, group))
435 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
437 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
438 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
439 "FFFFFFFF0000000000000000FFFFFFFF"))
440 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
441 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
442 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
443 "FFFFFFFF0000000000000000FFFFFFFC"))
444 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
445 "181D9C6EFE8141120314088F5013875A"
446 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
447 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
449 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
450 "6E1D3B628BA79B9859F741E082542A38"
451 "5502F25DBF55296C3A545E3872760AB7"))
452 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
453 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
454 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
455 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
456 "581A0DB248B0A77AECEC196ACCC52973"))
457 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
458 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
461 TEST_info("NIST curve P-384 -- Generator");
462 test_output_bignum("x", x);
463 test_output_bignum("y", y);
464 /* G_y value taken from the standard: */
465 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
466 "F8F41DBD289A147CE9DA3113B5F0B8C0"
467 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
469 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
471 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
472 * and therefore setting the coordinates should fail.
474 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
476 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
477 || !group_order_tests(group)
478 || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
479 || !TEST_true(EC_GROUP_copy(P_384, group))
481 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
482 || !TEST_true(BN_hex2bn(&p, "1FF"
483 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
484 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
485 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
486 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
487 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
488 || !TEST_true(BN_hex2bn(&a, "1FF"
489 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
490 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
491 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
492 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
493 || !TEST_true(BN_hex2bn(&b, "051"
494 "953EB9618E1C9A1F929A21A0B68540EE"
495 "A2DA725B99B315F3B8B489918EF109E1"
496 "56193951EC7E937B1652C0BD3BB1BF07"
497 "3573DF883D2C34F1EF451FD46B503F00"))
498 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
499 || !TEST_true(BN_hex2bn(&x, "C6"
500 "858E06B70404E9CD9E3ECB662395B442"
501 "9C648139053FB521F828AF606B4D3DBA"
502 "A14B5E77EFE75928FE1DC127A2FFA8DE"
503 "3348B3C1856A429BF97E7E31C2E5BD66"))
504 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
505 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
506 || !TEST_true(BN_hex2bn(&z, "1FF"
507 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
508 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
509 "51868783BF2F966B7FCC0148F709A5D0"
510 "3BB5C9B8899C47AEBB6FB71E91386409"))
511 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
512 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
515 TEST_info("NIST curve P-521 -- Generator");
516 test_output_bignum("x", x);
517 test_output_bignum("y", y);
518 /* G_y value taken from the standard: */
519 if (!TEST_true(BN_hex2bn(&z, "118"
520 "39296A789A3BC0045C8A5FB42C7D1BD9"
521 "98F54449579B446817AFBD17273E662C"
522 "97EE72995EF42640C550B9013FAD0761"
523 "353C7086A272C24088BE94769FD16650"))
525 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
527 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
528 * and therefore setting the coordinates should fail.
530 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
532 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
533 || !group_order_tests(group)
534 || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
535 || !TEST_true(EC_GROUP_copy(P_521, group))
537 /* more tests using the last curve */
539 /* Restore the point that got mangled in the (x, y + 1) test. */
540 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
541 || !TEST_true(EC_POINT_copy(Q, P))
542 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
543 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
544 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
545 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
546 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
547 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
548 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
549 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
556 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
557 || !TEST_true(BN_add(y, z, BN_value_one()))
559 || !TEST_true(BN_rshift1(y, y)))
561 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
564 TEST_note("combined multiplication ...");
566 /* z is still the group order */
567 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
568 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
569 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
570 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
571 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
572 || !TEST_true(BN_add(z, z, y)))
574 BN_set_negative(z, 1);
576 scalars[1] = z; /* z = -(order + y) */
578 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
579 || !TEST_true(EC_POINT_is_at_infinity(group, P))
580 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
581 || !TEST_true(BN_add(z, x, y)))
583 BN_set_negative(z, 1);
586 scalars[2] = z; /* z = -(x+y) */
588 if (!TEST_ptr(scalar3 = BN_new()))
591 scalars[3] = scalar3;
593 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
594 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
606 EC_GROUP_free(group);
617 EC_GROUP_free(P_160);
618 EC_GROUP_free(P_192);
619 EC_GROUP_free(P_224);
620 EC_GROUP_free(P_256);
621 EC_GROUP_free(P_384);
622 EC_GROUP_free(P_521);
626 # ifndef OPENSSL_NO_EC2M
628 static struct c2_curve_test {
639 } char2_curve_tests[] = {
640 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
643 "0800000000000000000000000000000000000000C9",
646 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
647 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
648 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
650 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
653 "0800000000000000000000000000000000000000C9",
655 "020A601907B8C953CA1481EB10512F78744A3205FD",
656 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
657 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
658 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
660 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
663 "020000000000000000000000000000000000000004000000000000000001",
666 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
667 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
669 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
672 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
675 "020000000000000000000000000000000000000004000000000000000001",
676 "000000000000000000000000000000000000000000000000000000000001",
677 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
678 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
679 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
681 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
684 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
688 "00000000000000000000000000000000000000000000000000000000000010A1",
692 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
694 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
697 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
700 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
704 "00000000000000000000000000000000000000000000000000000000000010A1",
706 "0000000000000000000000000000000000000000000000000000000000000001",
708 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
710 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
712 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
715 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
718 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
721 "0200000000000000000000000000000000000000"
722 "0000000000000000000000000000000000000000008000000000000000000001",
725 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
726 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
727 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
728 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
730 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
731 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
734 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
737 "0200000000000000000000000000000000000000"
738 "0000000000000000000000000000000000000000008000000000000000000001",
739 "0000000000000000000000000000000000000000"
740 "0000000000000000000000000000000000000000000000000000000000000001",
741 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
742 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
743 "015D4860D088DDB3496B0C6064756260441CDE4A"
744 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
745 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
746 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
748 "0100000000000000000000000000000000000000"
749 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
752 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
756 "0000000000000000000000000000000000000000000000000000000000000000"
757 "0000000000000000000000000000000000000000000000000000000000000425",
761 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
762 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
764 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
765 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
768 "00000000000000000000000000000000000000000000000000000000131850E1"
769 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
772 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
776 "0000000000000000000000000000000000000000000000000000000000000000"
777 "0000000000000000000000000000000000000000000000000000000000000425",
779 "0000000000000000000000000000000000000000000000000000000000000000"
780 "0000000000000000000000000000000000000000000000000000000000000001",
782 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
783 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
785 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
786 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
788 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
789 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
792 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
793 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
798 static int char2_curve_test(int n)
802 BIGNUM *p = NULL, *a = NULL, *b = NULL;
803 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
804 EC_GROUP *group = NULL, *variable = NULL;
805 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
806 const EC_POINT *points[3];
807 const BIGNUM *scalars[3];
808 struct c2_curve_test *const test = char2_curve_tests + n;
810 if (!TEST_ptr(ctx = BN_CTX_new())
811 || !TEST_ptr(p = BN_new())
812 || !TEST_ptr(a = BN_new())
813 || !TEST_ptr(b = BN_new())
814 || !TEST_ptr(x = BN_new())
815 || !TEST_ptr(y = BN_new())
816 || !TEST_ptr(z = BN_new())
817 || !TEST_ptr(yplusone = BN_new())
818 || !TEST_true(BN_hex2bn(&p, test->p))
819 || !TEST_true(BN_hex2bn(&a, test->a))
820 || !TEST_true(BN_hex2bn(&b, test->b))
821 || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method()))
822 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
823 || !TEST_ptr(P = EC_POINT_new(group))
824 || !TEST_ptr(Q = EC_POINT_new(group))
825 || !TEST_ptr(R = EC_POINT_new(group))
826 || !TEST_true(BN_hex2bn(&x, test->x))
827 || !TEST_true(BN_hex2bn(&y, test->y))
828 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
831 /* Change test based on whether binary point compression is enabled or not. */
832 # ifdef OPENSSL_EC_BIN_PT_COMP
834 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
835 * and therefore setting the coordinates should fail.
837 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
838 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
841 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
842 || !TEST_true(BN_hex2bn(&z, test->order))
843 || !TEST_true(BN_hex2bn(&cof, test->cof))
844 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
845 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
847 TEST_info("%s -- Generator", test->name);
848 test_output_bignum("x", x);
849 test_output_bignum("y", y);
850 /* G_y value taken from the standard: */
851 if (!TEST_true(BN_hex2bn(&z, test->y))
852 || !TEST_BN_eq(y, z))
856 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
857 * and therefore setting the coordinates should fail.
859 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
860 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
861 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
862 || !TEST_true(BN_hex2bn(&z, test->order))
863 || !TEST_true(BN_hex2bn(&cof, test->cof))
864 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
866 TEST_info("%s -- Generator:", test->name);
867 test_output_bignum("x", x);
868 test_output_bignum("y", y);
871 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
872 || !group_order_tests(group)
873 || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group)))
874 || !TEST_true(EC_GROUP_copy(variable, group)))
877 /* more tests using the last curve */
878 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
879 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
880 || !TEST_true(EC_POINT_copy(Q, P))
881 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
882 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
883 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
884 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
885 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
886 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
887 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
888 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
895 if (!TEST_true(BN_add(y, z, BN_value_one()))
897 || !TEST_true(BN_rshift1(y, y)))
899 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
902 TEST_note("combined multiplication ...");
904 /* z is still the group order */
905 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
906 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
907 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
908 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
911 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
912 || !TEST_true(BN_add(z, z, y)))
914 BN_set_negative(z, 1);
916 scalars[1] = z; /* z = -(order + y) */
918 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
919 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
922 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
923 || !TEST_true(BN_add(z, x, y)))
925 BN_set_negative(z, 1);
928 scalars[2] = z; /* z = -(x+y) */
930 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
931 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
949 EC_GROUP_free(group);
950 EC_GROUP_free(variable);
954 static int char2_field_tests(void)
957 BIGNUM *p = NULL, *a = NULL, *b = NULL;
958 EC_GROUP *group = NULL, *tmp = NULL;
959 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
960 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
961 unsigned char buf[100];
965 if (!TEST_ptr(ctx = BN_CTX_new())
966 || !TEST_ptr(p = BN_new())
967 || !TEST_ptr(a = BN_new())
968 || !TEST_ptr(b = BN_new())
969 || !TEST_true(BN_hex2bn(&p, "13"))
970 || !TEST_true(BN_hex2bn(&a, "3"))
971 || !TEST_true(BN_hex2bn(&b, "1")))
974 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
975 * EC_GROUP_new_curve_GF2m
976 * so that the library gets
977 * to choose the EC_METHOD */
979 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
980 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
981 || !TEST_true(EC_GROUP_copy(tmp, group)))
983 EC_GROUP_free(group);
987 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
990 TEST_info("Curve defined by Weierstrass equation");
991 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
992 test_output_bignum("a", a);
993 test_output_bignum("b", b);
994 test_output_bignum("p", p);
996 if (!TEST_ptr(P = EC_POINT_new(group))
997 || !TEST_ptr(Q = EC_POINT_new(group))
998 || !TEST_ptr(R = EC_POINT_new(group))
999 || !TEST_true(EC_POINT_set_to_infinity(group, P))
1000 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1004 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
1005 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
1006 || !TEST_true(EC_POINT_is_at_infinity(group, P))
1007 || !TEST_ptr(x = BN_new())
1008 || !TEST_ptr(y = BN_new())
1009 || !TEST_ptr(z = BN_new())
1010 || !TEST_ptr(cof = BN_new())
1011 || !TEST_ptr(yplusone = BN_new())
1012 || !TEST_true(BN_hex2bn(&x, "6"))
1013 /* Change test based on whether binary point compression is enabled or not. */
1014 # ifdef OPENSSL_EC_BIN_PT_COMP
1015 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
1017 || !TEST_true(BN_hex2bn(&y, "8"))
1018 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
1022 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
1023 /* Change test based on whether binary point compression is enabled or not. */
1024 # ifdef OPENSSL_EC_BIN_PT_COMP
1025 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
1028 TEST_info("Point is not on curve");
1029 test_output_bignum("x", x);
1030 test_output_bignum("y", y);
1034 TEST_note("A cyclic subgroup:");
1037 if (!TEST_int_ne(k--, 0))
1040 if (EC_POINT_is_at_infinity(group, P))
1041 TEST_note(" point at infinity");
1043 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1047 test_output_bignum("x", x);
1048 test_output_bignum("y", y);
1051 if (!TEST_true(EC_POINT_copy(R, P))
1052 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1055 while (!EC_POINT_is_at_infinity(group, P));
1057 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1058 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1061 /* Change test based on whether binary point compression is enabled or not. */
1062 # ifdef OPENSSL_EC_BIN_PT_COMP
1063 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1064 buf, sizeof(buf), ctx);
1065 if (!TEST_size_t_ne(len, 0)
1066 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1067 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1069 test_output_memory("Generator as octet string, compressed form:",
1073 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1074 buf, sizeof(buf), ctx);
1075 if (!TEST_size_t_ne(len, 0)
1076 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1077 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1079 test_output_memory("Generator as octet string, uncompressed form:",
1082 /* Change test based on whether binary point compression is enabled or not. */
1083 # ifdef OPENSSL_EC_BIN_PT_COMP
1085 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1087 if (!TEST_size_t_ne(len, 0)
1088 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1089 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1091 test_output_memory("Generator as octet string, hybrid form:",
1095 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1096 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1107 EC_GROUP_free(group);
1121 static int internal_curve_test(int n)
1123 EC_GROUP *group = NULL;
1124 int nid = curves[n].nid;
1126 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1127 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1131 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1132 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1133 EC_GROUP_free(group);
1136 EC_GROUP_free(group);
1140 static int internal_curve_test_method(int n)
1142 int r, nid = curves[n].nid;
1145 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1146 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1149 r = group_order_tests(group);
1150 EC_GROUP_free(group);
1154 static int group_field_test(void)
1157 BIGNUM *secp521r1_field = NULL;
1158 BIGNUM *sect163r2_field = NULL;
1159 EC_GROUP *secp521r1_group = NULL;
1160 EC_GROUP *sect163r2_group = NULL;
1162 BN_hex2bn(&secp521r1_field,
1163 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1164 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1165 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1166 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1170 BN_hex2bn(§163r2_field,
1171 "08000000000000000000000000000000"
1174 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1175 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1178 # ifndef OPENSSL_NO_EC2M
1179 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1180 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1184 EC_GROUP_free(secp521r1_group);
1185 EC_GROUP_free(sect163r2_group);
1186 BN_free(secp521r1_field);
1187 BN_free(sect163r2_field);
1191 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1193 * nistp_test_params contains magic numbers for testing our optimized
1194 * implementations of several NIST curves with characteristic > 3.
1196 struct nistp_test_params {
1197 const EC_METHOD *(*meth) (void);
1200 * Qx, Qy and D are taken from
1201 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1202 * Otherwise, values are standard curve parameters from FIPS 180-3
1204 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1207 static const struct nistp_test_params nistp_tests_params[] = {
1210 EC_GFp_nistp224_method,
1213 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1215 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1217 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1219 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1221 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1223 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1225 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1227 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1229 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1233 EC_GFp_nistp256_method,
1236 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1238 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1240 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1242 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1244 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1246 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1248 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1250 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1252 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1256 EC_GFp_nistp521_method,
1260 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1261 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1264 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1265 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1268 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1269 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1272 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1273 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1276 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1277 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1280 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1281 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1284 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1285 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1288 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1289 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1292 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1293 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1297 static int nistp_single_test(int idx)
1299 const struct nistp_test_params *test = nistp_tests_params + idx;
1301 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1302 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1303 EC_GROUP *NISTP = NULL;
1304 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1307 TEST_note("NIST curve P-%d (optimised implementation):",
1309 if (!TEST_ptr(ctx = BN_CTX_new())
1310 || !TEST_ptr(p = BN_new())
1311 || !TEST_ptr(a = BN_new())
1312 || !TEST_ptr(b = BN_new())
1313 || !TEST_ptr(x = BN_new())
1314 || !TEST_ptr(y = BN_new())
1315 || !TEST_ptr(m = BN_new())
1316 || !TEST_ptr(n = BN_new())
1317 || !TEST_ptr(order = BN_new())
1318 || !TEST_ptr(yplusone = BN_new())
1320 || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1321 || !TEST_true(BN_hex2bn(&p, test->p))
1322 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
1323 || !TEST_true(BN_hex2bn(&a, test->a))
1324 || !TEST_true(BN_hex2bn(&b, test->b))
1325 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1326 || !TEST_ptr(G = EC_POINT_new(NISTP))
1327 || !TEST_ptr(P = EC_POINT_new(NISTP))
1328 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1329 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1330 || !TEST_true(BN_hex2bn(&x, test->Qx))
1331 || !TEST_true(BN_hex2bn(&y, test->Qy))
1332 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1334 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1335 * and therefore setting the coordinates should fail.
1337 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1339 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1341 || !TEST_true(BN_hex2bn(&x, test->Gx))
1342 || !TEST_true(BN_hex2bn(&y, test->Gy))
1343 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1344 || !TEST_true(BN_hex2bn(&order, test->order))
1345 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1346 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1349 TEST_note("NIST test vectors ... ");
1350 if (!TEST_true(BN_hex2bn(&n, test->d)))
1352 /* fixed point multiplication */
1353 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1354 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1356 /* random point multiplication */
1357 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1358 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1360 /* set generator to P = 2*G, where G is the standard generator */
1361 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1362 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1363 /* set the scalar to m=n/2, where n is the NIST test scalar */
1364 || !TEST_true(BN_rshift(m, n, 1)))
1367 /* test the non-standard generator */
1368 /* fixed point multiplication */
1369 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1370 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1372 /* random point multiplication */
1373 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1374 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1377 * We have not performed precomputation so have_precompute mult should be
1380 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1382 /* now repeat all tests with precomputation */
1383 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1384 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
1387 /* fixed point multiplication */
1388 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1389 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1391 /* random point multiplication */
1392 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1393 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1395 /* reset generator */
1396 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1398 /* fixed point multiplication */
1399 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1400 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1402 /* random point multiplication */
1403 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1404 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1407 /* regression test for felem_neg bug */
1408 if (!TEST_true(BN_set_word(m, 32))
1409 || !TEST_true(BN_set_word(n, 31))
1410 || !TEST_true(EC_POINT_copy(P, G))
1411 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1412 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1413 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1416 r = group_order_tests(NISTP);
1418 EC_GROUP_free(NISTP);
1422 EC_POINT_free(Q_CHECK);
1437 static const unsigned char p521_named[] = {
1438 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1441 static const unsigned char p521_explicit[] = {
1442 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1443 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1444 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1445 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1446 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1447 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1448 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1449 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1450 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1451 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1452 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1453 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1454 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1455 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1456 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1457 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1458 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1459 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1460 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1461 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1462 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1463 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1464 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1465 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1466 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1467 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1468 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1469 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1470 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1471 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1472 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1473 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1474 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1475 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1476 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1477 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1478 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1479 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1483 * This test validates a named curve's group parameters using
1484 * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1485 * group parameters results in the curve not being valid.
1487 static int check_named_curve_test(int id)
1489 int ret = 0, nid, field_nid, has_seed;
1490 EC_GROUP *group = NULL, *gtest = NULL;
1491 const EC_POINT *group_gen = NULL;
1492 EC_POINT *other_gen = NULL;
1493 BIGNUM *group_p = NULL, *group_a = NULL, *group_b = NULL;
1494 BIGNUM *other_p = NULL, *other_a = NULL, *other_b = NULL;
1495 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1496 BIGNUM *other_order = NULL;
1497 const BIGNUM *group_order = NULL;
1498 BN_CTX *bn_ctx = NULL;
1499 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1500 static size_t invalid_seed_len = sizeof(invalid_seed);
1503 nid = curves[id].nid;
1504 if (!TEST_ptr(bn_ctx = BN_CTX_new())
1505 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1506 || !TEST_ptr(gtest = EC_GROUP_dup(group))
1507 || !TEST_ptr(group_p = BN_new())
1508 || !TEST_ptr(group_a = BN_new())
1509 || !TEST_ptr(group_b = BN_new())
1510 || !TEST_ptr(group_cofactor = BN_new())
1511 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1512 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1513 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1514 || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL))
1515 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1516 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1517 || !TEST_ptr(other_order = BN_dup(group_order))
1518 || !TEST_true(BN_add_word(other_order, 1))
1519 || !TEST_ptr(other_a = BN_dup(group_a))
1520 || !TEST_true(BN_add_word(other_a, 1))
1521 || !TEST_ptr(other_b = BN_dup(group_b))
1522 || !TEST_true(BN_add_word(other_b, 1))
1523 || !TEST_ptr(other_cofactor = BN_dup(group_cofactor))
1524 || !TEST_true(BN_add_word(other_cofactor, 1)))
1527 /* Determine if the built-in curve has a seed field set */
1528 has_seed = (EC_GROUP_get_seed_len(group) > 0);
1529 field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
1530 if (field_nid == NID_X9_62_characteristic_two_field) {
1531 if (!TEST_ptr(other_p = BN_dup(group_p))
1532 || !TEST_true(BN_lshift1(other_p, other_p)))
1535 if (!TEST_ptr(other_p = BN_dup(group_p)))
1538 * Just choosing any arbitrary prime does not work..
1539 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1540 * nist prime. So only select one of these as an alternate prime.
1542 if (!TEST_ptr(BN_copy(other_p,
1543 BN_ucmp(BN_get0_nist_prime_192(), other_p) == 0 ?
1544 BN_get0_nist_prime_256() :
1545 BN_get0_nist_prime_192())))
1549 /* Passes because this is a valid curve */
1550 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)
1551 /* Only NIST curves pass */
1552 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 1, NULL),
1553 EC_curve_nid2nist(nid) != NULL ? nid : NID_undef))
1556 /* Fail if the curve name doesn't match the parameters */
1557 EC_GROUP_set_curve_name(group, nid + 1);
1559 if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1563 /* Restore curve name and ensure it's passing */
1564 EC_GROUP_set_curve_name(group, nid);
1565 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1568 if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len),
1574 * If the built-in curve has a seed and we set the seed to another value
1575 * then it will fail the check.
1577 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1581 * If the built-in curve does not have a seed then setting the seed will
1582 * pass the check (as the seed is optional).
1584 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1587 /* Pass if the seed is unknown (as it is optional) */
1588 if (!TEST_int_eq(EC_GROUP_set_seed(group, NULL, 0), 1)
1589 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1592 /* Check that a duped group passes */
1593 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1596 /* check that changing any generator parameter fails */
1597 if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order,
1599 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1600 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order,
1602 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1603 /* The order is not an optional field, so this should fail */
1604 || !TEST_false(EC_GROUP_set_generator(gtest, group_gen, NULL,
1606 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1608 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1609 /* Check that if the cofactor is not set then it still passes */
1610 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1612 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)
1613 /* check that restoring the generator passes */
1614 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1616 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1620 * check that changing any curve parameter fails
1622 * Setting arbitrary p, a or b might fail for some EC_GROUPs
1623 * depending on the internal EC_METHOD implementation, hence run
1624 * these tests conditionally to the success of EC_GROUP_set_curve().
1627 if (EC_GROUP_set_curve(gtest, other_p, group_a, group_b, NULL)) {
1628 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1631 /* clear the error stack if EC_GROUP_set_curve() failed */
1635 if (EC_GROUP_set_curve(gtest, group_p, other_a, group_b, NULL)) {
1636 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1639 /* clear the error stack if EC_GROUP_set_curve() failed */
1643 if (EC_GROUP_set_curve(gtest, group_p, group_a, other_b, NULL)) {
1644 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1647 /* clear the error stack if EC_GROUP_set_curve() failed */
1653 /* Check that restoring the curve parameters passes */
1654 if (!TEST_true(EC_GROUP_set_curve(gtest, group_p, group_a, group_b, NULL))
1655 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1666 BN_free(group_cofactor);
1667 BN_free(other_cofactor);
1668 BN_free(other_order);
1669 EC_POINT_free(other_gen);
1670 EC_GROUP_free(gtest);
1671 EC_GROUP_free(group);
1672 BN_CTX_free(bn_ctx);
1677 * This checks the lookup capability of EC_GROUP_check_named_curve()
1678 * when the given group was created with explicit parameters.
1680 * It is possible to retrieve an alternative alias that does not match
1681 * the original nid in this case.
1683 static int check_named_curve_lookup_test(int id)
1685 int ret = 0, nid, rv = 0;
1686 EC_GROUP *g = NULL , *ga = NULL;
1687 ECPARAMETERS *p = NULL, *pa = NULL;
1691 nid = curves[id].nid;
1692 if (!TEST_ptr(ctx = BN_CTX_new())
1693 || !TEST_ptr(g = EC_GROUP_new_by_curve_name(nid))
1694 || !TEST_ptr(p = EC_GROUP_get_ecparameters(g, NULL)))
1697 /* replace with group from explicit parameters */
1699 if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p)))
1702 if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0, NULL), 0))
1707 * fail if the returned nid is not an alias of the original group.
1709 * The comparison here is done by comparing two explicit
1710 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1711 * comparison happens with unnamed EC_GROUPs using the same
1714 if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv))
1715 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL)))
1718 /* replace with group from explicit parameters, then compare */
1720 if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa))
1721 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0))
1730 ECPARAMETERS_free(p);
1731 ECPARAMETERS_free(pa);
1738 * Sometime we cannot compare nids for equality, as the built-in curve table
1739 * includes aliases with different names for the same curve.
1741 * This function returns TRUE (1) if the checked nids are identical, or if they
1742 * alias to the same curve. FALSE (0) otherwise.
1745 int are_ec_nids_compatible(int n1d, int n2d)
1749 # ifndef OPENSSL_NO_EC2M
1751 case NID_wap_wsg_idm_ecid_wtls4:
1752 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1755 case NID_wap_wsg_idm_ecid_wtls3:
1756 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1759 case NID_wap_wsg_idm_ecid_wtls10:
1760 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1763 case NID_wap_wsg_idm_ecid_wtls11:
1764 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1766 case NID_X9_62_c2pnb163v1:
1767 case NID_wap_wsg_idm_ecid_wtls5:
1768 ret = (n2d == NID_X9_62_c2pnb163v1
1769 || n2d == NID_wap_wsg_idm_ecid_wtls5);
1771 # endif /* OPENSSL_NO_EC2M */
1773 case NID_wap_wsg_idm_ecid_wtls6:
1774 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1777 case NID_wap_wsg_idm_ecid_wtls7:
1778 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1780 # ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1782 case NID_wap_wsg_idm_ecid_wtls12:
1783 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1787 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1788 * that is associated with a specialized method.
1790 case NID_wap_wsg_idm_ecid_wtls12:
1791 ret = (n2d == NID_secp224r1);
1793 # endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1802 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1803 * EC_GROUP for built-in curves.
1805 * Note that it is possible to retrieve an alternative alias that does not match
1808 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1810 static int check_named_curve_from_ecparameters(int id)
1812 int ret = 0, nid, tnid;
1813 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1814 const EC_POINT *group_gen = NULL;
1815 EC_POINT *other_gen = NULL;
1816 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1817 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1818 const BIGNUM *group_order = NULL;
1819 BIGNUM *other_order = NULL;
1820 BN_CTX *bn_ctx = NULL;
1821 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1822 static size_t invalid_seed_len = sizeof(invalid_seed);
1823 ECPARAMETERS *params = NULL, *other_params = NULL;
1824 EC_GROUP *g_ary[8] = {NULL};
1825 EC_GROUP **g_next = &g_ary[0];
1826 ECPARAMETERS *p_ary[8] = {NULL};
1827 ECPARAMETERS **p_next = &p_ary[0];
1830 nid = curves[id].nid;
1831 TEST_note("Curve %s", OBJ_nid2sn(nid));
1832 if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1834 BN_CTX_start(bn_ctx);
1836 if (/* Allocations */
1837 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1838 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1839 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1840 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1841 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1842 /* Generate reference group and params */
1843 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1844 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1845 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1846 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1847 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1848 /* compute `other_*` values */
1849 || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1850 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1851 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1852 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1853 other_gen_x, other_gen_y, bn_ctx))
1854 || !TEST_true(BN_copy(other_order, group_order))
1855 || !TEST_true(BN_add_word(other_order, 1))
1856 || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1857 || !TEST_true(BN_add_word(other_cofactor, 1)))
1860 EC_POINT_free(other_gen);
1863 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1864 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1865 other_gen_x, other_gen_y,
1870 * ###########################
1871 * # Actual tests start here #
1872 * ###########################
1876 * Creating a group from built-in explicit parameters returns a
1879 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1880 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1883 * We cannot always guarantee the names match, as the built-in table
1884 * contains aliases for the same curve with different names.
1886 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1887 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1890 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1891 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1895 * An invalid seed in the parameters should be ignored: expect a "named"
1898 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1900 || !TEST_ptr(other_params = *p_next++ =
1901 EC_GROUP_get_ecparameters(tmpg, NULL))
1902 || !TEST_ptr(tgroup = *g_next++ =
1903 EC_GROUP_new_from_ecparameters(other_params))
1904 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1905 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1906 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1907 OPENSSL_EC_EXPLICIT_CURVE)) {
1908 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1913 * A null seed in the parameters should be ignored, as it is optional:
1914 * expect a "named" group.
1916 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1917 || !TEST_ptr(other_params = *p_next++ =
1918 EC_GROUP_get_ecparameters(tmpg, NULL))
1919 || !TEST_ptr(tgroup = *g_next++ =
1920 EC_GROUP_new_from_ecparameters(other_params))
1921 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1922 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1923 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1924 OPENSSL_EC_EXPLICIT_CURVE)) {
1925 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1930 * Check that changing any of the generator parameters does not yield a
1931 * match with the built-in curves
1933 if (/* Other gen, same group order & cofactor */
1934 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1936 || !TEST_ptr(other_params = *p_next++ =
1937 EC_GROUP_get_ecparameters(tmpg, NULL))
1938 || !TEST_ptr(tgroup = *g_next++ =
1939 EC_GROUP_new_from_ecparameters(other_params))
1940 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1941 /* Same gen & cofactor, different order */
1942 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1944 || !TEST_ptr(other_params = *p_next++ =
1945 EC_GROUP_get_ecparameters(tmpg, NULL))
1946 || !TEST_ptr(tgroup = *g_next++ =
1947 EC_GROUP_new_from_ecparameters(other_params))
1948 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1949 /* The order is not an optional field, so this should fail */
1950 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1952 /* Check that a wrong cofactor is ignored, and we still match */
1953 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1955 || !TEST_ptr(other_params = *p_next++ =
1956 EC_GROUP_get_ecparameters(tmpg, NULL))
1957 || !TEST_ptr(tgroup = *g_next++ =
1958 EC_GROUP_new_from_ecparameters(other_params))
1959 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1960 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1961 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1962 OPENSSL_EC_EXPLICIT_CURVE)
1963 /* Check that if the cofactor is not set then it still matches */
1964 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1966 || !TEST_ptr(other_params = *p_next++ =
1967 EC_GROUP_get_ecparameters(tmpg, NULL))
1968 || !TEST_ptr(tgroup = *g_next++ =
1969 EC_GROUP_new_from_ecparameters(other_params))
1970 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1971 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1972 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1973 OPENSSL_EC_EXPLICIT_CURVE)
1974 /* check that restoring the generator passes */
1975 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1977 || !TEST_ptr(other_params = *p_next++ =
1978 EC_GROUP_get_ecparameters(tmpg, NULL))
1979 || !TEST_ptr(tgroup = *g_next++ =
1980 EC_GROUP_new_from_ecparameters(other_params))
1981 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1982 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1983 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1984 OPENSSL_EC_EXPLICIT_CURVE))
1989 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
1990 EC_GROUP_free(*g_next);
1991 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
1992 ECPARAMETERS_free(*p_next);
1993 ECPARAMETERS_free(params);
1994 EC_POINT_free(other_gen);
1995 EC_GROUP_free(tmpg);
1996 EC_GROUP_free(group);
1998 BN_CTX_free(bn_ctx);
2003 static int parameter_test(void)
2005 EC_GROUP *group = NULL, *group2 = NULL;
2006 ECPARAMETERS *ecparameters = NULL;
2007 unsigned char *buf = NULL;
2010 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1))
2011 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
2012 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
2013 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
2016 EC_GROUP_free(group);
2019 /* Test the named curve encoding, which should be default. */
2020 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
2021 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
2022 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
2029 * Test the explicit encoding. P-521 requires correctly zero-padding the
2030 * curve coefficients.
2032 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
2033 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
2034 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
2039 EC_GROUP_free(group);
2040 EC_GROUP_free(group2);
2041 ECPARAMETERS_free(ecparameters);
2047 * random 256-bit explicit parameters curve, cofactor absent
2048 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
2049 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
2051 static const unsigned char params_cf_pass[] = {
2052 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2053 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
2054 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2055 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2056 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
2057 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2058 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2059 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
2060 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
2061 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
2062 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
2063 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
2064 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
2065 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
2066 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
2067 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
2068 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
2069 0x14, 0xa8, 0x2f, 0x4f
2073 * random 256-bit explicit parameters curve, cofactor absent
2074 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
2075 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
2077 static const unsigned char params_cf_fail[] = {
2078 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2079 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
2080 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2081 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2082 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
2083 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2084 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2085 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
2086 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
2087 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
2088 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
2089 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
2090 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
2091 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
2092 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
2093 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
2094 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
2095 0x34, 0xa2, 0x21, 0x01
2099 * Test two random 256-bit explicit parameters curves with absent cofactor.
2100 * The two curves are chosen to roughly straddle the bounds at which the lib
2101 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
2103 * - params_cf_pass: order is sufficiently close to p to compute cofactor
2104 * - params_cf_fail: order is too far away from p to compute cofactor
2106 * For standards-compliant curves, cofactor is chosen as small as possible.
2107 * So you can see neither of these curves are fit for cryptographic use.
2109 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
2110 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
2111 * will always succeed in computing the cofactor. Neither of these curves
2112 * conform to that -- this is just robustness testing.
2114 static int cofactor_range_test(void)
2116 EC_GROUP *group = NULL;
2119 const unsigned char *b1 = (const unsigned char *)params_cf_fail;
2120 const unsigned char *b2 = (const unsigned char *)params_cf_pass;
2122 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
2123 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
2124 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
2125 sizeof(params_cf_pass)))
2126 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
2127 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
2132 EC_GROUP_free(group);
2137 * For named curves, test that:
2138 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
2139 * - a nonsensical cofactor throws an error (negative test)
2140 * - nonsensical orders throw errors (negative tests)
2142 static int cardinality_test(int n)
2145 int nid = curves[n].nid;
2147 EC_GROUP *g1 = NULL, *g2 = NULL;
2148 EC_POINT *g2_gen = NULL;
2149 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
2150 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
2152 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
2154 if (!TEST_ptr(ctx = BN_CTX_new())
2155 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))
2156 || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) {
2164 g1_p = BN_CTX_get(ctx);
2165 g1_a = BN_CTX_get(ctx);
2166 g1_b = BN_CTX_get(ctx);
2167 g1_x = BN_CTX_get(ctx);
2168 g1_y = BN_CTX_get(ctx);
2169 g1_order = BN_CTX_get(ctx);
2170 g1_cf = BN_CTX_get(ctx);
2172 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
2173 /* pull out the explicit curve parameters */
2174 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
2175 || !TEST_true(EC_POINT_get_affine_coordinates(g1,
2176 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
2177 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
2178 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
2179 /* construct g2 manually with g1 parameters */
2180 || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx))
2181 || !TEST_ptr(g2_gen = EC_POINT_new(g2))
2182 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
2183 /* pass NULL cofactor: lib should compute it */
2184 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2185 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2186 || !TEST_BN_eq(g1_cf, g2_cf)
2187 /* pass zero cofactor: lib should compute it */
2188 || !TEST_true(BN_set_word(g2_cf, 0))
2189 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2190 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2191 || !TEST_BN_eq(g1_cf, g2_cf)
2192 /* negative test for invalid cofactor */
2193 || !TEST_true(BN_set_word(g2_cf, 0))
2194 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2195 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2196 /* negative test for NULL order */
2197 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
2198 /* negative test for zero order */
2199 || !TEST_true(BN_set_word(g1_order, 0))
2200 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2201 /* negative test for negative order */
2202 || !TEST_true(BN_set_word(g2_cf, 0))
2203 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2204 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2205 /* negative test for too large order */
2206 || !TEST_true(BN_lshift(g1_order, g1_p, 2))
2207 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
2211 EC_POINT_free(g2_gen);
2219 static int check_ec_key_field_public_range_test(int id)
2221 int ret = 0, type = 0;
2222 const EC_POINT *pub = NULL;
2223 const EC_GROUP *group = NULL;
2224 const EC_METHOD *meth = NULL;
2225 const BIGNUM *field = NULL;
2226 BIGNUM *x = NULL, *y = NULL;
2229 if (!TEST_ptr(x = BN_new())
2230 || !TEST_ptr(y = BN_new())
2231 || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid))
2232 || !TEST_ptr(group = EC_KEY_get0_group(key))
2233 || !TEST_ptr(meth = EC_GROUP_method_of(group))
2234 || !TEST_ptr(field = EC_GROUP_get0_field(group))
2235 || !TEST_int_gt(EC_KEY_generate_key(key), 0)
2236 || !TEST_int_gt(EC_KEY_check_key(key), 0)
2237 || !TEST_ptr(pub = EC_KEY_get0_public_key(key))
2238 || !TEST_int_gt(EC_POINT_get_affine_coordinates(group, pub, x, y,
2243 * Make the public point out of range by adding the field (which will still
2244 * be the same point on the curve). The add is different for char2 fields.
2246 type = EC_METHOD_get_field_type(meth);
2247 #ifndef OPENSSL_NO_EC2M
2248 if (type == NID_X9_62_characteristic_two_field) {
2249 /* test for binary curves */
2250 if (!TEST_true(BN_GF2m_add(x, x, field)))
2254 if (type == NID_X9_62_prime_field) {
2255 /* test for prime curves */
2256 if (!TEST_true(BN_add(x, x, field)))
2259 /* this should never happen */
2260 TEST_error("Unsupported EC_METHOD field_type");
2263 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key, x, y), 0))
2275 * Helper for ec_point_hex2point_test
2277 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2280 * If P is NULL use point at infinity.
2283 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2284 point_conversion_form_t form,
2288 EC_POINT *Q = NULL, *Pinf = NULL;
2292 /* If P is NULL use point at infinity. */
2293 if (!TEST_ptr(Pinf = EC_POINT_new(group))
2294 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2299 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2300 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2301 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2305 * The next check is most likely superfluous, as EC_POINT_cmp should already
2307 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2308 * so we include it anyway!
2311 && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2317 EC_POINT_free(Pinf);
2325 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2327 static int ec_point_hex2point_test(int id)
2330 EC_GROUP *group = NULL;
2331 const EC_POINT *G = NULL;
2333 BN_CTX * bnctx = NULL;
2336 nid = curves[id].nid;
2337 if (!TEST_ptr(bnctx = BN_CTX_new())
2338 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2339 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2340 || !TEST_ptr(P = EC_POINT_dup(G, group)))
2343 if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2344 POINT_CONVERSION_COMPRESSED,
2346 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2347 POINT_CONVERSION_COMPRESSED,
2349 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2350 POINT_CONVERSION_UNCOMPRESSED,
2352 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2353 POINT_CONVERSION_UNCOMPRESSED,
2355 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2356 POINT_CONVERSION_HYBRID,
2358 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2359 POINT_CONVERSION_HYBRID,
2367 EC_GROUP_free(group);
2373 #endif /* OPENSSL_NO_EC */
2375 int setup_tests(void)
2377 #ifndef OPENSSL_NO_EC
2378 crv_len = EC_get_builtin_curves(NULL, 0);
2379 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2380 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2383 ADD_TEST(parameter_test);
2384 ADD_TEST(cofactor_range_test);
2385 ADD_ALL_TESTS(cardinality_test, crv_len);
2386 ADD_TEST(prime_field_tests);
2387 # ifndef OPENSSL_NO_EC2M
2388 ADD_TEST(char2_field_tests);
2389 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2391 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
2392 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2394 ADD_ALL_TESTS(internal_curve_test, crv_len);
2395 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2396 ADD_TEST(group_field_test);
2397 ADD_ALL_TESTS(check_named_curve_test, crv_len);
2398 ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
2399 ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len);
2400 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2401 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2402 #endif /* OPENSSL_NO_EC */
2406 void cleanup_tests(void)
2408 #ifndef OPENSSL_NO_EC
2409 OPENSSL_free(curves);