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
11 #include "internal/nelem.h"
15 # include <openssl/ec.h>
16 # ifndef OPENSSL_NO_ENGINE
17 # include <openssl/engine.h>
19 # include <openssl/err.h>
20 # include <openssl/obj_mac.h>
21 # include <openssl/objects.h>
22 # include <openssl/rand.h>
23 # include <openssl/bn.h>
24 # include <openssl/opensslconf.h>
26 static size_t crv_len = 0;
27 static EC_builtin_curve *curves = NULL;
29 /* test multiplication with group order, long and negative scalars */
30 static int group_order_tests(EC_GROUP *group)
32 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
33 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
34 const EC_POINT *G = NULL;
38 if (!TEST_ptr(n1 = BN_new())
39 || !TEST_ptr(n2 = BN_new())
40 || !TEST_ptr(order = BN_new())
41 || !TEST_ptr(ctx = BN_CTX_new())
42 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
43 || !TEST_ptr(P = EC_POINT_new(group))
44 || !TEST_ptr(Q = EC_POINT_new(group))
45 || !TEST_ptr(R = EC_POINT_new(group))
46 || !TEST_ptr(S = EC_POINT_new(group)))
49 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
50 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
51 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
52 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
53 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
54 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
55 || !TEST_true(EC_POINT_copy(P, G))
56 || !TEST_true(BN_one(n1))
57 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
58 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
59 || !TEST_true(BN_sub(n1, order, n1))
60 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
61 || !TEST_true(EC_POINT_invert(group, Q, ctx))
62 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
65 for (i = 1; i <= 2; i++) {
66 const BIGNUM *scalars[6];
67 const EC_POINT *points[6];
69 if (!TEST_true(BN_set_word(n1, i))
71 * If i == 1, P will be the predefined generator for which
72 * EC_GROUP_precompute_mult has set up precomputation.
74 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
75 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
76 || !TEST_true(BN_one(n1))
78 || !TEST_true(BN_sub(n1, n1, order))
79 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
80 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
83 || !TEST_true(BN_add(n2, order, BN_value_one()))
84 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
85 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
87 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
88 || !TEST_true(BN_mul(n2, n1, n2, ctx))
89 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
90 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
93 /* n2 = order^2 - 1 */
94 BN_set_negative(n2, 0);
95 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
96 /* Add P to verify the result. */
97 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
98 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
100 /* Exercise EC_POINTs_mul, including corner cases. */
101 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
104 scalars[0] = scalars[1] = BN_value_one();
105 points[0] = points[1] = P;
107 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
108 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
109 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
113 points[0] = Q; /* => infinity */
115 points[1] = P; /* => -P */
117 points[2] = Q; /* => infinity */
119 points[3] = Q; /* => infinity */
121 points[4] = P; /* => P */
123 points[5] = Q; /* => infinity */
124 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
125 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
131 if (r == 0 && i != 0)
132 TEST_info(i == 1 ? "allowing precomputation" :
133 "without precomputation");
145 static int prime_field_tests(void)
148 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
149 EC_GROUP *group = NULL, *tmp = NULL;
150 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
151 *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
152 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
153 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
154 const EC_POINT *points[4];
155 const BIGNUM *scalars[4];
156 unsigned char buf[100];
160 if (!TEST_ptr(ctx = BN_CTX_new())
161 || !TEST_ptr(p = BN_new())
162 || !TEST_ptr(a = BN_new())
163 || !TEST_ptr(b = BN_new())
164 || !TEST_true(BN_hex2bn(&p, "17"))
165 || !TEST_true(BN_hex2bn(&a, "1"))
166 || !TEST_true(BN_hex2bn(&b, "1"))
168 * applications should use EC_GROUP_new_curve_GFp so
169 * that the library gets to choose the EC_METHOD
171 || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
172 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
173 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
174 || !TEST_true(EC_GROUP_copy(tmp, group)))
176 EC_GROUP_free(group);
180 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
183 TEST_info("Curve defined by Weierstrass equation");
184 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
185 test_output_bignum("a", a);
186 test_output_bignum("b", b);
187 test_output_bignum("p", p);
190 if (!TEST_ptr(P = EC_POINT_new(group))
191 || !TEST_ptr(Q = EC_POINT_new(group))
192 || !TEST_ptr(R = EC_POINT_new(group))
193 || !TEST_true(EC_POINT_set_to_infinity(group, P))
194 || !TEST_true(EC_POINT_is_at_infinity(group, P))
195 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
196 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
197 || !TEST_true(EC_POINT_is_at_infinity(group, P))
198 || !TEST_ptr(x = BN_new())
199 || !TEST_ptr(y = BN_new())
200 || !TEST_ptr(z = BN_new())
201 || !TEST_ptr(yplusone = BN_new())
202 || !TEST_true(BN_hex2bn(&x, "D"))
203 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
206 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
207 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
209 TEST_info("Point is not on curve");
210 test_output_bignum("x", x);
211 test_output_bignum("y", y);
215 TEST_note("A cyclic subgroup:");
218 if (!TEST_int_ne(k--, 0))
221 if (EC_POINT_is_at_infinity(group, P)) {
222 TEST_note(" point at infinity");
224 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
228 test_output_bignum("x", x);
229 test_output_bignum("y", y);
232 if (!TEST_true(EC_POINT_copy(R, P))
233 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
236 } while (!EC_POINT_is_at_infinity(group, P));
238 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
239 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
243 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
245 if (!TEST_size_t_ne(len, 0)
246 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
247 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
249 test_output_memory("Generator as octet string, compressed form:",
252 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
253 buf, sizeof(buf), ctx);
254 if (!TEST_size_t_ne(len, 0)
255 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
256 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
258 test_output_memory("Generator as octet string, uncompressed form:",
261 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
262 buf, sizeof(buf), ctx);
263 if (!TEST_size_t_ne(len, 0)
264 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
265 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
267 test_output_memory("Generator as octet string, hybrid form:",
270 if (!TEST_true(EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z,
273 TEST_info("A representation of the inverse of that generator in");
274 TEST_note("Jacobian projective coordinates");
275 test_output_bignum("x", x);
276 test_output_bignum("y", y);
277 test_output_bignum("z", z);
279 if (!TEST_true(EC_POINT_invert(group, P, ctx))
280 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
283 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
284 * 2000) -- not a NIST curve, but commonly used
287 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
288 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
289 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
290 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
291 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
292 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
293 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
294 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
295 || !TEST_true(BN_hex2bn(&x, "4A96B568"
296 "8EF573284664698968C38BB913CBFC82"))
297 || !TEST_true(BN_hex2bn(&y, "23a62855"
298 "3168947d59dcc912042351377ac5fb32"))
299 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
301 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
302 * and therefore setting the coordinates should fail.
304 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
306 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
307 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
308 || !TEST_true(BN_hex2bn(&z, "0100000000"
309 "000000000001F4C8F927AED3CA752257"))
310 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
311 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
313 TEST_info("SEC2 curve secp160r1 -- Generator");
314 test_output_bignum("x", x);
315 test_output_bignum("y", y);
316 /* G_y value taken from the standard: */
317 if (!TEST_true(BN_hex2bn(&z, "23a62855"
318 "3168947d59dcc912042351377ac5fb32"))
320 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
321 || !group_order_tests(group)
322 || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))
323 || !TEST_true(EC_GROUP_copy(P_160, group))
325 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
327 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
328 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
329 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
330 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
331 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
332 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
333 "0FA7E9AB72243049FEB8DEECC146B9B1"))
334 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
335 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
336 "7CBF20EB43A18800F4FF0AFD82FF1012"))
337 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
338 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
339 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
340 "FFFFFFFF99DEF836146BC9B1B4D22831"))
341 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
342 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
345 TEST_info("NIST curve P-192 -- Generator");
346 test_output_bignum("x", x);
347 test_output_bignum("y", y);
348 /* G_y value taken from the standard: */
349 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
350 "631011ED6B24CDD573F977A11E794811"))
352 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
354 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
355 * and therefore setting the coordinates should fail.
357 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
359 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
360 || !group_order_tests(group)
361 || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))
362 || !TEST_true(EC_GROUP_copy(P_192, group))
364 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
366 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
367 "FFFFFFFF000000000000000000000001"))
368 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
369 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
370 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
371 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
372 "5044B0B7D7BFD8BA270B39432355FFB4"))
373 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
374 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
375 "4A03C1D356C21122343280D6115C1D21"))
376 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
377 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
378 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
379 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
380 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
381 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
384 TEST_info("NIST curve P-224 -- Generator");
385 test_output_bignum("x", x);
386 test_output_bignum("y", y);
387 /* G_y value taken from the standard: */
388 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
389 "CD4375A05A07476444D5819985007E34"))
391 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
393 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
394 * and therefore setting the coordinates should fail.
396 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
398 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
399 || !group_order_tests(group)
400 || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
401 || !TEST_true(EC_GROUP_copy(P_224, group))
403 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
405 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
406 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
407 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
408 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
409 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
410 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
411 "651D06B0CC53B0F63BCE3C3E27D2604B"))
412 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
414 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
415 "77037D812DEB33A0F4A13945D898C296"))
416 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
417 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
418 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
419 "BCE6FAADA7179E84F3B9CAC2FC632551"))
420 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
421 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
424 TEST_info("NIST curve P-256 -- Generator");
425 test_output_bignum("x", x);
426 test_output_bignum("y", y);
427 /* G_y value taken from the standard: */
428 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
429 "2BCE33576B315ECECBB6406837BF51F5"))
431 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
433 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
434 * and therefore setting the coordinates should fail.
436 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
438 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
439 || !group_order_tests(group)
440 || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
441 || !TEST_true(EC_GROUP_copy(P_256, group))
443 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
445 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
446 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
447 "FFFFFFFF0000000000000000FFFFFFFF"))
448 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
449 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
450 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
451 "FFFFFFFF0000000000000000FFFFFFFC"))
452 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
453 "181D9C6EFE8141120314088F5013875A"
454 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
455 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
457 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
458 "6E1D3B628BA79B9859F741E082542A38"
459 "5502F25DBF55296C3A545E3872760AB7"))
460 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
461 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
462 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
463 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
464 "581A0DB248B0A77AECEC196ACCC52973"))
465 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
466 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
469 TEST_info("NIST curve P-384 -- Generator");
470 test_output_bignum("x", x);
471 test_output_bignum("y", y);
472 /* G_y value taken from the standard: */
473 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
474 "F8F41DBD289A147CE9DA3113B5F0B8C0"
475 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
477 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
479 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
480 * and therefore setting the coordinates should fail.
482 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
484 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
485 || !group_order_tests(group)
486 || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
487 || !TEST_true(EC_GROUP_copy(P_384, group))
489 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
490 || !TEST_true(BN_hex2bn(&p, "1FF"
491 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
492 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
493 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
494 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
495 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
496 || !TEST_true(BN_hex2bn(&a, "1FF"
497 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
500 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
501 || !TEST_true(BN_hex2bn(&b, "051"
502 "953EB9618E1C9A1F929A21A0B68540EE"
503 "A2DA725B99B315F3B8B489918EF109E1"
504 "56193951EC7E937B1652C0BD3BB1BF07"
505 "3573DF883D2C34F1EF451FD46B503F00"))
506 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
507 || !TEST_true(BN_hex2bn(&x, "C6"
508 "858E06B70404E9CD9E3ECB662395B442"
509 "9C648139053FB521F828AF606B4D3DBA"
510 "A14B5E77EFE75928FE1DC127A2FFA8DE"
511 "3348B3C1856A429BF97E7E31C2E5BD66"))
512 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
513 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
514 || !TEST_true(BN_hex2bn(&z, "1FF"
515 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
516 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
517 "51868783BF2F966B7FCC0148F709A5D0"
518 "3BB5C9B8899C47AEBB6FB71E91386409"))
519 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
520 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
523 TEST_info("NIST curve P-521 -- Generator");
524 test_output_bignum("x", x);
525 test_output_bignum("y", y);
526 /* G_y value taken from the standard: */
527 if (!TEST_true(BN_hex2bn(&z, "118"
528 "39296A789A3BC0045C8A5FB42C7D1BD9"
529 "98F54449579B446817AFBD17273E662C"
530 "97EE72995EF42640C550B9013FAD0761"
531 "353C7086A272C24088BE94769FD16650"))
533 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
535 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
536 * and therefore setting the coordinates should fail.
538 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
540 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
541 || !group_order_tests(group)
542 || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
543 || !TEST_true(EC_GROUP_copy(P_521, group))
545 /* more tests using the last curve */
547 /* Restore the point that got mangled in the (x, y + 1) test. */
548 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
549 || !TEST_true(EC_POINT_copy(Q, P))
550 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
551 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
552 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
553 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
554 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
555 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
556 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
557 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
564 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
565 || !TEST_true(BN_add(y, z, BN_value_one()))
567 || !TEST_true(BN_rshift1(y, y)))
569 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
572 TEST_note("combined multiplication ...");
574 /* z is still the group order */
575 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
576 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
577 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
578 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
579 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
580 || !TEST_true(BN_add(z, z, y)))
582 BN_set_negative(z, 1);
584 scalars[1] = z; /* z = -(order + y) */
586 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
587 || !TEST_true(EC_POINT_is_at_infinity(group, P))
588 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
589 || !TEST_true(BN_add(z, x, y)))
591 BN_set_negative(z, 1);
594 scalars[2] = z; /* z = -(x+y) */
596 if (!TEST_ptr(scalar3 = BN_new()))
599 scalars[3] = scalar3;
601 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
602 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
614 EC_GROUP_free(group);
625 EC_GROUP_free(P_160);
626 EC_GROUP_free(P_192);
627 EC_GROUP_free(P_224);
628 EC_GROUP_free(P_256);
629 EC_GROUP_free(P_384);
630 EC_GROUP_free(P_521);
634 # ifndef OPENSSL_NO_EC2M
636 static struct c2_curve_test {
647 } char2_curve_tests[] = {
648 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
651 "0800000000000000000000000000000000000000C9",
654 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
655 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
656 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
658 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
661 "0800000000000000000000000000000000000000C9",
663 "020A601907B8C953CA1481EB10512F78744A3205FD",
664 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
665 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
666 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
668 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
671 "020000000000000000000000000000000000000004000000000000000001",
674 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
675 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
677 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
680 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
683 "020000000000000000000000000000000000000004000000000000000001",
684 "000000000000000000000000000000000000000000000000000000000001",
685 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
686 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
687 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
689 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
692 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
696 "00000000000000000000000000000000000000000000000000000000000010A1",
700 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
702 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
705 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
708 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
712 "00000000000000000000000000000000000000000000000000000000000010A1",
714 "0000000000000000000000000000000000000000000000000000000000000001",
716 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
718 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
720 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
723 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
726 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
729 "0200000000000000000000000000000000000000"
730 "0000000000000000000000000000000000000000008000000000000000000001",
733 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
734 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
735 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
736 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
738 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
739 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
742 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
745 "0200000000000000000000000000000000000000"
746 "0000000000000000000000000000000000000000008000000000000000000001",
747 "0000000000000000000000000000000000000000"
748 "0000000000000000000000000000000000000000000000000000000000000001",
749 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
750 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
751 "015D4860D088DDB3496B0C6064756260441CDE4A"
752 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
753 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
754 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
756 "0100000000000000000000000000000000000000"
757 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
760 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
764 "0000000000000000000000000000000000000000000000000000000000000000"
765 "0000000000000000000000000000000000000000000000000000000000000425",
769 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
770 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
772 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
773 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
776 "00000000000000000000000000000000000000000000000000000000131850E1"
777 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
780 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
784 "0000000000000000000000000000000000000000000000000000000000000000"
785 "0000000000000000000000000000000000000000000000000000000000000425",
787 "0000000000000000000000000000000000000000000000000000000000000000"
788 "0000000000000000000000000000000000000000000000000000000000000001",
790 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
791 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
793 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
794 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
796 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
797 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
800 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
801 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
806 static int char2_curve_test(int n)
810 BIGNUM *p = NULL, *a = NULL, *b = NULL;
811 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
812 EC_GROUP *group = NULL, *variable = NULL;
813 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
814 const EC_POINT *points[3];
815 const BIGNUM *scalars[3];
816 struct c2_curve_test *const test = char2_curve_tests + n;
818 if (!TEST_ptr(ctx = BN_CTX_new())
819 || !TEST_ptr(p = BN_new())
820 || !TEST_ptr(a = BN_new())
821 || !TEST_ptr(b = BN_new())
822 || !TEST_ptr(x = BN_new())
823 || !TEST_ptr(y = BN_new())
824 || !TEST_ptr(z = BN_new())
825 || !TEST_ptr(yplusone = BN_new())
826 || !TEST_true(BN_hex2bn(&p, test->p))
827 || !TEST_true(BN_hex2bn(&a, test->a))
828 || !TEST_true(BN_hex2bn(&b, test->b))
829 || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method()))
830 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
831 || !TEST_ptr(P = EC_POINT_new(group))
832 || !TEST_ptr(Q = EC_POINT_new(group))
833 || !TEST_ptr(R = EC_POINT_new(group))
834 || !TEST_true(BN_hex2bn(&x, test->x))
835 || !TEST_true(BN_hex2bn(&y, test->y))
836 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
839 /* Change test based on whether binary point compression is enabled or not. */
840 # ifdef OPENSSL_EC_BIN_PT_COMP
842 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
843 * and therefore setting the coordinates should fail.
845 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
846 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
849 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
850 || !TEST_true(BN_hex2bn(&z, test->order))
851 || !TEST_true(BN_hex2bn(&cof, test->cof))
852 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
853 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
855 TEST_info("%s -- Generator", test->name);
856 test_output_bignum("x", x);
857 test_output_bignum("y", y);
858 /* G_y value taken from the standard: */
859 if (!TEST_true(BN_hex2bn(&z, test->y))
860 || !TEST_BN_eq(y, z))
864 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
865 * and therefore setting the coordinates should fail.
867 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
868 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
869 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
870 || !TEST_true(BN_hex2bn(&z, test->order))
871 || !TEST_true(BN_hex2bn(&cof, test->cof))
872 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
874 TEST_info("%s -- Generator:", test->name);
875 test_output_bignum("x", x);
876 test_output_bignum("y", y);
879 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
880 || !group_order_tests(group)
881 || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group)))
882 || !TEST_true(EC_GROUP_copy(variable, group)))
885 /* more tests using the last curve */
886 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
887 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
888 || !TEST_true(EC_POINT_copy(Q, P))
889 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
890 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
891 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
892 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
893 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
894 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
895 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
896 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
903 if (!TEST_true(BN_add(y, z, BN_value_one()))
905 || !TEST_true(BN_rshift1(y, y)))
907 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
910 TEST_note("combined multiplication ...");
912 /* z is still the group order */
913 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
914 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
915 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
916 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
919 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
920 || !TEST_true(BN_add(z, z, y)))
922 BN_set_negative(z, 1);
924 scalars[1] = z; /* z = -(order + y) */
926 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
927 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
930 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
931 || !TEST_true(BN_add(z, x, y)))
933 BN_set_negative(z, 1);
936 scalars[2] = z; /* z = -(x+y) */
938 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
939 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
957 EC_GROUP_free(group);
958 EC_GROUP_free(variable);
962 static int char2_field_tests(void)
965 BIGNUM *p = NULL, *a = NULL, *b = NULL;
966 EC_GROUP *group = NULL, *tmp = NULL;
967 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
968 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
969 unsigned char buf[100];
973 if (!TEST_ptr(ctx = BN_CTX_new())
974 || !TEST_ptr(p = BN_new())
975 || !TEST_ptr(a = BN_new())
976 || !TEST_ptr(b = BN_new())
977 || !TEST_true(BN_hex2bn(&p, "13"))
978 || !TEST_true(BN_hex2bn(&a, "3"))
979 || !TEST_true(BN_hex2bn(&b, "1")))
982 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
983 * EC_GROUP_new_curve_GF2m
984 * so that the library gets
985 * to choose the EC_METHOD */
987 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
988 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
989 || !TEST_true(EC_GROUP_copy(tmp, group)))
991 EC_GROUP_free(group);
995 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
998 TEST_info("Curve defined by Weierstrass equation");
999 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
1000 test_output_bignum("a", a);
1001 test_output_bignum("b", b);
1002 test_output_bignum("p", p);
1004 if (!TEST_ptr(P = EC_POINT_new(group))
1005 || !TEST_ptr(Q = EC_POINT_new(group))
1006 || !TEST_ptr(R = EC_POINT_new(group))
1007 || !TEST_true(EC_POINT_set_to_infinity(group, P))
1008 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1012 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
1013 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
1014 || !TEST_true(EC_POINT_is_at_infinity(group, P))
1015 || !TEST_ptr(x = BN_new())
1016 || !TEST_ptr(y = BN_new())
1017 || !TEST_ptr(z = BN_new())
1018 || !TEST_ptr(cof = BN_new())
1019 || !TEST_ptr(yplusone = BN_new())
1020 || !TEST_true(BN_hex2bn(&x, "6"))
1021 /* Change test based on whether binary point compression is enabled or not. */
1022 # ifdef OPENSSL_EC_BIN_PT_COMP
1023 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
1025 || !TEST_true(BN_hex2bn(&y, "8"))
1026 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
1030 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
1031 /* Change test based on whether binary point compression is enabled or not. */
1032 # ifdef OPENSSL_EC_BIN_PT_COMP
1033 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
1036 TEST_info("Point is not on curve");
1037 test_output_bignum("x", x);
1038 test_output_bignum("y", y);
1042 TEST_note("A cyclic subgroup:");
1045 if (!TEST_int_ne(k--, 0))
1048 if (EC_POINT_is_at_infinity(group, P))
1049 TEST_note(" point at infinity");
1051 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1055 test_output_bignum("x", x);
1056 test_output_bignum("y", y);
1059 if (!TEST_true(EC_POINT_copy(R, P))
1060 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1063 while (!EC_POINT_is_at_infinity(group, P));
1065 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1066 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1069 /* Change test based on whether binary point compression is enabled or not. */
1070 # ifdef OPENSSL_EC_BIN_PT_COMP
1071 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1072 buf, sizeof(buf), ctx);
1073 if (!TEST_size_t_ne(len, 0)
1074 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1075 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1077 test_output_memory("Generator as octet string, compressed form:",
1081 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1082 buf, sizeof(buf), ctx);
1083 if (!TEST_size_t_ne(len, 0)
1084 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1085 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1087 test_output_memory("Generator as octet string, uncompressed form:",
1090 /* Change test based on whether binary point compression is enabled or not. */
1091 # ifdef OPENSSL_EC_BIN_PT_COMP
1093 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1095 if (!TEST_size_t_ne(len, 0)
1096 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1097 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1099 test_output_memory("Generator as octet string, hybrid form:",
1103 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1104 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1115 EC_GROUP_free(group);
1129 static int internal_curve_test(int n)
1131 EC_GROUP *group = NULL;
1132 int nid = curves[n].nid;
1134 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1135 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1139 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1140 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1141 EC_GROUP_free(group);
1144 EC_GROUP_free(group);
1148 static int internal_curve_test_method(int n)
1150 int r, nid = curves[n].nid;
1153 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1154 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1157 r = group_order_tests(group);
1158 EC_GROUP_free(group);
1162 static int group_field_test(void)
1165 BIGNUM *secp521r1_field = NULL;
1166 BIGNUM *sect163r2_field = NULL;
1167 EC_GROUP *secp521r1_group = NULL;
1168 EC_GROUP *sect163r2_group = NULL;
1170 BN_hex2bn(&secp521r1_field,
1171 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1172 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1173 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1174 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1178 BN_hex2bn(§163r2_field,
1179 "08000000000000000000000000000000"
1182 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1183 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1186 # ifndef OPENSSL_NO_EC2M
1187 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1188 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1192 EC_GROUP_free(secp521r1_group);
1193 EC_GROUP_free(sect163r2_group);
1194 BN_free(secp521r1_field);
1195 BN_free(sect163r2_field);
1199 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1201 * nistp_test_params contains magic numbers for testing our optimized
1202 * implementations of several NIST curves with characteristic > 3.
1204 struct nistp_test_params {
1205 const EC_METHOD *(*meth) (void);
1208 * Qx, Qy and D are taken from
1209 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1210 * Otherwise, values are standard curve parameters from FIPS 180-3
1212 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1215 static const struct nistp_test_params nistp_tests_params[] = {
1218 EC_GFp_nistp224_method,
1221 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1223 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1225 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1227 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1229 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1231 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1233 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1235 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1237 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1241 EC_GFp_nistp256_method,
1244 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1246 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1248 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1250 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1252 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1254 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1256 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1258 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1260 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1264 EC_GFp_nistp521_method,
1268 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1269 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1272 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1273 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1276 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1277 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1280 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1281 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1284 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1285 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1288 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1289 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1292 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1293 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1296 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1297 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1300 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1301 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1305 static int nistp_single_test(int idx)
1307 const struct nistp_test_params *test = nistp_tests_params + idx;
1309 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1310 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1311 EC_GROUP *NISTP = NULL;
1312 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1315 TEST_note("NIST curve P-%d (optimised implementation):",
1317 if (!TEST_ptr(ctx = BN_CTX_new())
1318 || !TEST_ptr(p = BN_new())
1319 || !TEST_ptr(a = BN_new())
1320 || !TEST_ptr(b = BN_new())
1321 || !TEST_ptr(x = BN_new())
1322 || !TEST_ptr(y = BN_new())
1323 || !TEST_ptr(m = BN_new())
1324 || !TEST_ptr(n = BN_new())
1325 || !TEST_ptr(order = BN_new())
1326 || !TEST_ptr(yplusone = BN_new())
1328 || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1329 || !TEST_true(BN_hex2bn(&p, test->p))
1330 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
1331 || !TEST_true(BN_hex2bn(&a, test->a))
1332 || !TEST_true(BN_hex2bn(&b, test->b))
1333 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1334 || !TEST_ptr(G = EC_POINT_new(NISTP))
1335 || !TEST_ptr(P = EC_POINT_new(NISTP))
1336 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1337 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1338 || !TEST_true(BN_hex2bn(&x, test->Qx))
1339 || !TEST_true(BN_hex2bn(&y, test->Qy))
1340 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1342 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1343 * and therefore setting the coordinates should fail.
1345 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1347 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1349 || !TEST_true(BN_hex2bn(&x, test->Gx))
1350 || !TEST_true(BN_hex2bn(&y, test->Gy))
1351 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1352 || !TEST_true(BN_hex2bn(&order, test->order))
1353 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1354 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1357 TEST_note("NIST test vectors ... ");
1358 if (!TEST_true(BN_hex2bn(&n, test->d)))
1360 /* fixed point multiplication */
1361 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1362 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1364 /* random point multiplication */
1365 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1366 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1368 /* set generator to P = 2*G, where G is the standard generator */
1369 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1370 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1371 /* set the scalar to m=n/2, where n is the NIST test scalar */
1372 || !TEST_true(BN_rshift(m, n, 1)))
1375 /* test the non-standard generator */
1376 /* fixed point multiplication */
1377 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1378 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1380 /* random point multiplication */
1381 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1382 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1385 * We have not performed precomputation so have_precompute mult should be
1388 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1390 /* now repeat all tests with precomputation */
1391 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1392 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
1395 /* fixed point multiplication */
1396 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1397 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1399 /* random point multiplication */
1400 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1401 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1403 /* reset generator */
1404 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1406 /* fixed point multiplication */
1407 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1408 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1410 /* random point multiplication */
1411 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1412 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1415 /* regression test for felem_neg bug */
1416 if (!TEST_true(BN_set_word(m, 32))
1417 || !TEST_true(BN_set_word(n, 31))
1418 || !TEST_true(EC_POINT_copy(P, G))
1419 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1420 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1421 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1424 r = group_order_tests(NISTP);
1426 EC_GROUP_free(NISTP);
1430 EC_POINT_free(Q_CHECK);
1445 static const unsigned char p521_named[] = {
1446 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1449 static const unsigned char p521_explicit[] = {
1450 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1451 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 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 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1456 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1457 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1458 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1459 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1460 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1461 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1462 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1463 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1464 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1465 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1466 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1467 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1468 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1469 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1470 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1471 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1472 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1473 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1474 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1475 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1476 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1477 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1478 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1479 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1480 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1481 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1482 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1483 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1484 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1485 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1486 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1487 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1490 static int parameter_test(void)
1492 EC_GROUP *group = NULL, *group2 = NULL;
1493 ECPARAMETERS *ecparameters = NULL;
1494 unsigned char *buf = NULL;
1497 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp112r1))
1498 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1499 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1500 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1503 EC_GROUP_free(group);
1506 /* Test the named curve encoding, which should be default. */
1507 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1508 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1509 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1516 * Test the explicit encoding. P-521 requires correctly zero-padding the
1517 * curve coefficients.
1519 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1520 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1521 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
1526 EC_GROUP_free(group);
1527 EC_GROUP_free(group2);
1528 ECPARAMETERS_free(ecparameters);
1534 int setup_tests(void)
1536 #ifndef OPENSSL_NO_EC
1537 crv_len = EC_get_builtin_curves(NULL, 0);
1538 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
1539 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
1542 ADD_TEST(parameter_test);
1543 ADD_TEST(prime_field_tests);
1544 # ifndef OPENSSL_NO_EC2M
1545 ADD_TEST(char2_field_tests);
1546 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
1548 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1549 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
1551 ADD_ALL_TESTS(internal_curve_test, crv_len);
1552 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
1553 ADD_TEST(group_field_test);
1558 void cleanup_tests(void)
1560 #ifndef OPENSSL_NO_EC
1561 OPENSSL_free(curves);