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 OpenSSL license (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_GFp(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_GFp(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_GFp(group, Q, x, 1,
207 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
208 if (!TEST_true(EC_POINT_get_affine_coordinates_GFp(group, Q, x, y,
211 TEST_info("Point is not on curve");
212 test_output_bignum("x", x);
213 test_output_bignum("y", y);
217 TEST_note("A cyclic subgroup:");
220 if (!TEST_int_ne(k--, 0))
223 if (EC_POINT_is_at_infinity(group, P)) {
224 TEST_note(" point at infinity");
226 if (!TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y,
230 test_output_bignum("x", x);
231 test_output_bignum("y", y);
234 if (!TEST_true(EC_POINT_copy(R, P))
235 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
238 } while (!EC_POINT_is_at_infinity(group, P));
240 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
241 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
245 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
247 if (!TEST_size_t_ne(len, 0)
248 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
249 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
251 test_output_memory("Generator as octet string, compressed form:",
254 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
255 buf, sizeof(buf), ctx);
256 if (!TEST_size_t_ne(len, 0)
257 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
258 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
260 test_output_memory("Generator as octet string, uncompressed form:",
263 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
264 buf, sizeof(buf), ctx);
265 if (!TEST_size_t_ne(len, 0)
266 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
267 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
269 test_output_memory("Generator as octet string, hybrid form:",
272 if (!TEST_true(EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z,
275 TEST_info("A representation of the inverse of that generator in");
276 TEST_note("Jacobian projective coordinates");
277 test_output_bignum("x", x);
278 test_output_bignum("y", y);
279 test_output_bignum("z", z);
281 if (!TEST_true(EC_POINT_invert(group, P, ctx))
282 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
285 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
286 * 2000) -- not a NIST curve, but commonly used
289 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
290 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
291 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
292 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
293 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
294 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
295 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
296 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
297 || !TEST_true(BN_hex2bn(&x, "4A96B568"
298 "8EF573284664698968C38BB913CBFC82"))
299 || !TEST_true(BN_hex2bn(&y, "23a62855"
300 "3168947d59dcc912042351377ac5fb32"))
301 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
303 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
304 * and therefore setting the coordinates should fail.
306 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
308 || !TEST_true(EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
309 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
310 || !TEST_true(BN_hex2bn(&z, "0100000000"
311 "000000000001F4C8F927AED3CA752257"))
312 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
313 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
315 TEST_info("SEC2 curve secp160r1 -- Generator");
316 test_output_bignum("x", x);
317 test_output_bignum("y", y);
318 /* G_y value taken from the standard: */
319 if (!TEST_true(BN_hex2bn(&z, "23a62855"
320 "3168947d59dcc912042351377ac5fb32"))
322 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
323 || !group_order_tests(group)
324 || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))
325 || !TEST_true(EC_GROUP_copy(P_160, group))
327 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
329 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
330 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
331 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
332 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
333 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
334 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
335 "0FA7E9AB72243049FEB8DEECC146B9B1"))
336 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
337 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
338 "7CBF20EB43A18800F4FF0AFD82FF1012"))
339 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1,
341 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
342 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
343 "FFFFFFFF99DEF836146BC9B1B4D22831"))
344 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
345 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
348 TEST_info("NIST curve P-192 -- Generator");
349 test_output_bignum("x", x);
350 test_output_bignum("y", y);
351 /* G_y value taken from the standard: */
352 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
353 "631011ED6B24CDD573F977A11E794811"))
355 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
357 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
358 * and therefore setting the coordinates should fail.
360 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
362 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
363 || !group_order_tests(group)
364 || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))
365 || !TEST_true(EC_GROUP_copy(P_192, group))
367 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
369 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
370 "FFFFFFFF000000000000000000000001"))
371 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
372 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
373 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
374 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
375 "5044B0B7D7BFD8BA270B39432355FFB4"))
376 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
377 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
378 "4A03C1D356C21122343280D6115C1D21"))
379 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0,
381 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
382 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
383 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
384 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
385 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
388 TEST_info("NIST curve P-224 -- Generator");
389 test_output_bignum("x", x);
390 test_output_bignum("y", y);
391 /* G_y value taken from the standard: */
392 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
393 "CD4375A05A07476444D5819985007E34"))
395 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
397 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
398 * and therefore setting the coordinates should fail.
400 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
402 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
403 || !group_order_tests(group)
404 || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
405 || !TEST_true(EC_GROUP_copy(P_224, group))
407 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
409 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
410 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
411 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
412 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
413 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
414 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
415 "651D06B0CC53B0F63BCE3C3E27D2604B"))
416 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
418 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
419 "77037D812DEB33A0F4A13945D898C296"))
420 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1,
422 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
423 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
424 "BCE6FAADA7179E84F3B9CAC2FC632551"))
425 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
426 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
429 TEST_info("NIST curve P-256 -- Generator");
430 test_output_bignum("x", x);
431 test_output_bignum("y", y);
432 /* G_y value taken from the standard: */
433 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
434 "2BCE33576B315ECECBB6406837BF51F5"))
436 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
438 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
439 * and therefore setting the coordinates should fail.
441 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
443 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
444 || !group_order_tests(group)
445 || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
446 || !TEST_true(EC_GROUP_copy(P_256, group))
448 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
450 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
451 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
452 "FFFFFFFF0000000000000000FFFFFFFF"))
453 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
454 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
455 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
456 "FFFFFFFF0000000000000000FFFFFFFC"))
457 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
458 "181D9C6EFE8141120314088F5013875A"
459 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
460 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
462 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
463 "6E1D3B628BA79B9859F741E082542A38"
464 "5502F25DBF55296C3A545E3872760AB7"))
465 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1,
467 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
468 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
469 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
470 "581A0DB248B0A77AECEC196ACCC52973"))
471 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
472 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
475 TEST_info("NIST curve P-384 -- Generator");
476 test_output_bignum("x", x);
477 test_output_bignum("y", y);
478 /* G_y value taken from the standard: */
479 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
480 "F8F41DBD289A147CE9DA3113B5F0B8C0"
481 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
483 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
485 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
486 * and therefore setting the coordinates should fail.
488 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
490 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
491 || !group_order_tests(group)
492 || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
493 || !TEST_true(EC_GROUP_copy(P_384, group))
495 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
496 || !TEST_true(BN_hex2bn(&p, "1FF"
497 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
500 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
501 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
502 || !TEST_true(BN_hex2bn(&a, "1FF"
503 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
504 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
505 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
506 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
507 || !TEST_true(BN_hex2bn(&b, "051"
508 "953EB9618E1C9A1F929A21A0B68540EE"
509 "A2DA725B99B315F3B8B489918EF109E1"
510 "56193951EC7E937B1652C0BD3BB1BF07"
511 "3573DF883D2C34F1EF451FD46B503F00"))
512 || !TEST_true(EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
513 || !TEST_true(BN_hex2bn(&x, "C6"
514 "858E06B70404E9CD9E3ECB662395B442"
515 "9C648139053FB521F828AF606B4D3DBA"
516 "A14B5E77EFE75928FE1DC127A2FFA8DE"
517 "3348B3C1856A429BF97E7E31C2E5BD66"))
518 || !TEST_true(EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0,
520 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
521 || !TEST_true(BN_hex2bn(&z, "1FF"
522 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
523 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
524 "51868783BF2F966B7FCC0148F709A5D0"
525 "3BB5C9B8899C47AEBB6FB71E91386409"))
526 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
527 || !TEST_true(EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)))
530 TEST_info("NIST curve P-521 -- Generator");
531 test_output_bignum("x", x);
532 test_output_bignum("y", y);
533 /* G_y value taken from the standard: */
534 if (!TEST_true(BN_hex2bn(&z, "118"
535 "39296A789A3BC0045C8A5FB42C7D1BD9"
536 "98F54449579B446817AFBD17273E662C"
537 "97EE72995EF42640C550B9013FAD0761"
538 "353C7086A272C24088BE94769FD16650"))
540 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
542 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
543 * and therefore setting the coordinates should fail.
545 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(group, P, x,
547 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
548 || !group_order_tests(group)
549 || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
550 || !TEST_true(EC_GROUP_copy(P_521, group))
552 /* more tests using the last curve */
554 /* Restore the point that got mangled in the (x, y + 1) test. */
555 || !TEST_true(EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
556 || !TEST_true(EC_POINT_copy(Q, P))
557 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
558 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
559 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
560 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
561 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
562 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
563 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
564 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
571 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
572 || !TEST_true(BN_add(y, z, BN_value_one()))
574 || !TEST_true(BN_rshift1(y, y)))
576 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
579 TEST_note("combined multiplication ...");
581 /* z is still the group order */
582 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
583 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
584 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
585 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
586 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
587 || !TEST_true(BN_add(z, z, y)))
589 BN_set_negative(z, 1);
591 scalars[1] = z; /* z = -(order + y) */
593 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
594 || !TEST_true(EC_POINT_is_at_infinity(group, P))
595 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
596 || !TEST_true(BN_add(z, x, y)))
598 BN_set_negative(z, 1);
601 scalars[2] = z; /* z = -(x+y) */
603 if (!TEST_ptr(scalar3 = BN_new()))
606 scalars[3] = scalar3;
608 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
609 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
621 EC_GROUP_free(group);
632 EC_GROUP_free(P_160);
633 EC_GROUP_free(P_192);
634 EC_GROUP_free(P_224);
635 EC_GROUP_free(P_256);
636 EC_GROUP_free(P_384);
637 EC_GROUP_free(P_521);
641 # ifndef OPENSSL_NO_EC2M
643 static struct c2_curve_test {
654 } char2_curve_tests[] = {
655 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
658 "0800000000000000000000000000000000000000C9",
661 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
662 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
663 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
665 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
668 "0800000000000000000000000000000000000000C9",
670 "020A601907B8C953CA1481EB10512F78744A3205FD",
671 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
672 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
673 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
675 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
678 "020000000000000000000000000000000000000004000000000000000001",
681 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
682 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
684 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
687 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
690 "020000000000000000000000000000000000000004000000000000000001",
691 "000000000000000000000000000000000000000000000000000000000001",
692 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
693 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
694 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
696 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
699 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
703 "00000000000000000000000000000000000000000000000000000000000010A1",
707 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
709 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
712 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
715 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
719 "00000000000000000000000000000000000000000000000000000000000010A1",
721 "0000000000000000000000000000000000000000000000000000000000000001",
723 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
725 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
727 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
730 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
733 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
736 "0200000000000000000000000000000000000000"
737 "0000000000000000000000000000000000000000008000000000000000000001",
740 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
741 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
742 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
743 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
745 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
746 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
749 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
752 "0200000000000000000000000000000000000000"
753 "0000000000000000000000000000000000000000008000000000000000000001",
754 "0000000000000000000000000000000000000000"
755 "0000000000000000000000000000000000000000000000000000000000000001",
756 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
757 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
758 "015D4860D088DDB3496B0C6064756260441CDE4A"
759 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
760 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
761 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
763 "0100000000000000000000000000000000000000"
764 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
767 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
771 "0000000000000000000000000000000000000000000000000000000000000000"
772 "0000000000000000000000000000000000000000000000000000000000000425",
776 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
777 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
779 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
780 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
783 "00000000000000000000000000000000000000000000000000000000131850E1"
784 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
787 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
791 "0000000000000000000000000000000000000000000000000000000000000000"
792 "0000000000000000000000000000000000000000000000000000000000000425",
794 "0000000000000000000000000000000000000000000000000000000000000000"
795 "0000000000000000000000000000000000000000000000000000000000000001",
797 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
798 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
800 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
801 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
803 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
804 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
807 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
808 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
813 static int char2_curve_test(int n)
817 BIGNUM *p = NULL, *a = NULL, *b = NULL;
818 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
819 EC_GROUP *group = NULL, *variable = NULL;
820 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
821 const EC_POINT *points[3];
822 const BIGNUM *scalars[3];
823 struct c2_curve_test *const test = char2_curve_tests + n;
825 if (!TEST_ptr(ctx = BN_CTX_new())
826 || !TEST_ptr(p = BN_new())
827 || !TEST_ptr(a = BN_new())
828 || !TEST_ptr(b = BN_new())
829 || !TEST_ptr(x = BN_new())
830 || !TEST_ptr(y = BN_new())
831 || !TEST_ptr(z = BN_new())
832 || !TEST_ptr(yplusone = BN_new())
833 || !TEST_true(BN_hex2bn(&p, test->p))
834 || !TEST_true(BN_hex2bn(&a, test->a))
835 || !TEST_true(BN_hex2bn(&b, test->b))
836 || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method()))
837 || !TEST_true(EC_GROUP_set_curve_GF2m(group, p, a, b, ctx))
838 || !TEST_ptr(P = EC_POINT_new(group))
839 || !TEST_ptr(Q = EC_POINT_new(group))
840 || !TEST_ptr(R = EC_POINT_new(group))
841 || !TEST_true(BN_hex2bn(&x, test->x))
842 || !TEST_true(BN_hex2bn(&y, test->y))
843 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
846 /* Change test based on whether binary point compression is enabled or not. */
847 # ifdef OPENSSL_EC_BIN_PT_COMP
849 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
850 * and therefore setting the coordinates should fail.
852 if (!TEST_false(EC_POINT_set_affine_coordinates_GF2m(group, P, x, yplusone,
854 || !TEST_true(EC_POINT_set_compressed_coordinates_GF2m(group, P, x,
857 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
858 || !TEST_true(BN_hex2bn(&z, test->order))
859 || !TEST_true(BN_hex2bn(&cof, test->cof))
860 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
861 || !TEST_true(EC_POINT_get_affine_coordinates_GF2m(group, P, x, y,
864 TEST_info("%s -- Generator", test->name);
865 test_output_bignum("x", x);
866 test_output_bignum("y", y);
867 /* G_y value taken from the standard: */
868 if (!TEST_true(BN_hex2bn(&z, test->y))
869 || !TEST_BN_eq(y, z))
873 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
874 * and therefore setting the coordinates should fail.
876 if (!TEST_false(EC_POINT_set_affine_coordinates_GF2m(group, P, x, yplusone,
878 || !TEST_true(EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx))
879 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
880 || !TEST_true(BN_hex2bn(&z, test->order))
881 || !TEST_true(BN_hex2bn(&cof, test->cof))
882 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
884 TEST_info("%s -- Generator:", test->name);
885 test_output_bignum("x", x);
886 test_output_bignum("y", y);
889 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
890 || !group_order_tests(group)
891 || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group)))
892 || !TEST_true(EC_GROUP_copy(variable, group)))
895 /* more tests using the last curve */
896 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
897 if (!TEST_true(EC_POINT_set_affine_coordinates_GF2m(group, P, x, y,
899 || !TEST_true(EC_POINT_copy(Q, P))
900 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
901 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
902 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
903 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
904 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
905 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
906 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
907 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
914 if (!TEST_true(BN_add(y, z, BN_value_one()))
916 || !TEST_true(BN_rshift1(y, y)))
918 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
921 TEST_note("combined multiplication ...");
923 /* z is still the group order */
924 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
925 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
926 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
927 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
930 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
931 || !TEST_true(BN_add(z, z, y)))
933 BN_set_negative(z, 1);
935 scalars[1] = z; /* z = -(order + y) */
937 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
938 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
941 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
942 || !TEST_true(BN_add(z, x, y)))
944 BN_set_negative(z, 1);
947 scalars[2] = z; /* z = -(x+y) */
949 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
950 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
968 EC_GROUP_free(group);
969 EC_GROUP_free(variable);
973 static int char2_field_tests(void)
976 BIGNUM *p = NULL, *a = NULL, *b = NULL;
977 EC_GROUP *group = NULL, *tmp = NULL;
978 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
979 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
980 unsigned char buf[100];
984 if (!TEST_ptr(ctx = BN_CTX_new())
985 || !TEST_ptr(p = BN_new())
986 || !TEST_ptr(a = BN_new())
987 || !TEST_ptr(b = BN_new())
988 || !TEST_true(BN_hex2bn(&p, "13"))
989 || !TEST_true(BN_hex2bn(&a, "3"))
990 || !TEST_true(BN_hex2bn(&b, "1")))
993 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
994 * EC_GROUP_new_curve_GF2m
995 * so that the library gets
996 * to choose the EC_METHOD */
998 || !TEST_true(EC_GROUP_set_curve_GF2m(group, p, a, b, ctx))
999 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
1000 || !TEST_true(EC_GROUP_copy(tmp, group)))
1002 EC_GROUP_free(group);
1006 if (!TEST_true(EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)))
1009 TEST_info("Curve defined by Weierstrass equation");
1010 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
1011 test_output_bignum("a", a);
1012 test_output_bignum("b", b);
1013 test_output_bignum("p", p);
1015 if (!TEST_ptr(P = EC_POINT_new(group))
1016 || !TEST_ptr(Q = EC_POINT_new(group))
1017 || !TEST_ptr(R = EC_POINT_new(group))
1018 || !TEST_true(EC_POINT_set_to_infinity(group, P))
1019 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1023 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
1024 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
1025 || !TEST_true(EC_POINT_is_at_infinity(group, P))
1026 || !TEST_ptr(x = BN_new())
1027 || !TEST_ptr(y = BN_new())
1028 || !TEST_ptr(z = BN_new())
1029 || !TEST_ptr(cof = BN_new())
1030 || !TEST_ptr(yplusone = BN_new())
1031 || !TEST_true(BN_hex2bn(&x, "6"))
1032 /* Change test based on whether binary point compression is enabled or not. */
1033 # ifdef OPENSSL_EC_BIN_PT_COMP
1034 || !TEST_true(EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1,
1037 || !TEST_true(BN_hex2bn(&y, "8"))
1038 || !TEST_true(EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx))
1042 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
1043 /* Change test based on whether binary point compression is enabled or not. */
1044 # ifdef OPENSSL_EC_BIN_PT_COMP
1045 if (!TEST_true(EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y,
1049 TEST_info("Point is not on curve");
1050 test_output_bignum("x", x);
1051 test_output_bignum("y", y);
1055 TEST_note("A cyclic subgroup:");
1058 if (!TEST_int_ne(k--, 0))
1061 if (EC_POINT_is_at_infinity(group, P))
1062 TEST_note(" point at infinity");
1064 if (!TEST_true(EC_POINT_get_affine_coordinates_GF2m(group, P, x, y,
1068 test_output_bignum("x", x);
1069 test_output_bignum("y", y);
1072 if (!TEST_true(EC_POINT_copy(R, P))
1073 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1076 while (!EC_POINT_is_at_infinity(group, P));
1078 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1079 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1082 /* Change test based on whether binary point compression is enabled or not. */
1083 # ifdef OPENSSL_EC_BIN_PT_COMP
1084 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1085 buf, sizeof(buf), ctx);
1086 if (!TEST_size_t_ne(len, 0)
1087 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1088 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1090 test_output_memory("Generator as octet string, compressed form:",
1094 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1095 buf, sizeof(buf), ctx);
1096 if (!TEST_size_t_ne(len, 0)
1097 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1098 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1100 test_output_memory("Generator as octet string, uncompressed form:",
1103 /* Change test based on whether binary point compression is enabled or not. */
1104 # ifdef OPENSSL_EC_BIN_PT_COMP
1106 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1108 if (!TEST_size_t_ne(len, 0)
1109 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1110 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1112 test_output_memory("Generator as octet string, hybrid form:",
1116 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1117 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1128 EC_GROUP_free(group);
1142 static int internal_curve_test(int n)
1144 EC_GROUP *group = NULL;
1145 int nid = curves[n].nid;
1147 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1148 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1152 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1153 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1154 EC_GROUP_free(group);
1157 EC_GROUP_free(group);
1161 static int internal_curve_test_method(int n)
1163 int r, nid = curves[n].nid;
1166 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1167 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1170 r = group_order_tests(group);
1171 EC_GROUP_free(group);
1175 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1177 * nistp_test_params contains magic numbers for testing our optimized
1178 * implementations of several NIST curves with characteristic > 3.
1180 struct nistp_test_params {
1181 const EC_METHOD *(*meth) (void);
1184 * Qx, Qy and D are taken from
1185 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1186 * Otherwise, values are standard curve parameters from FIPS 180-3
1188 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1191 static const struct nistp_test_params nistp_tests_params[] = {
1194 EC_GFp_nistp224_method,
1197 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1199 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1201 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1203 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1205 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1207 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1209 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1211 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1213 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1217 EC_GFp_nistp256_method,
1220 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1222 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1224 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1226 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1228 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1230 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1232 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1234 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1236 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1240 EC_GFp_nistp521_method,
1244 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1245 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1248 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1249 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1252 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1253 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1256 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1257 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1260 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1261 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1264 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1265 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1268 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1269 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1272 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1273 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1276 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1277 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1281 static int nistp_single_test(int idx)
1283 const struct nistp_test_params *test = nistp_tests_params + idx;
1285 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1286 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1287 EC_GROUP *NISTP = NULL;
1288 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1291 TEST_note("NIST curve P-%d (optimised implementation):",
1293 if (!TEST_ptr(ctx = BN_CTX_new())
1294 || !TEST_ptr(p = BN_new())
1295 || !TEST_ptr(a = BN_new())
1296 || !TEST_ptr(b = BN_new())
1297 || !TEST_ptr(x = BN_new())
1298 || !TEST_ptr(y = BN_new())
1299 || !TEST_ptr(m = BN_new())
1300 || !TEST_ptr(n = BN_new())
1301 || !TEST_ptr(order = BN_new())
1302 || !TEST_ptr(yplusone = BN_new())
1304 || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1305 || !TEST_true(BN_hex2bn(&p, test->p))
1306 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
1307 || !TEST_true(BN_hex2bn(&a, test->a))
1308 || !TEST_true(BN_hex2bn(&b, test->b))
1309 || !TEST_true(EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx))
1310 || !TEST_ptr(G = EC_POINT_new(NISTP))
1311 || !TEST_ptr(P = EC_POINT_new(NISTP))
1312 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1313 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1314 || !TEST_true(BN_hex2bn(&x, test->Qx))
1315 || !TEST_true(BN_hex2bn(&y, test->Qy))
1316 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1318 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1319 * and therefore setting the coordinates should fail.
1321 || !TEST_false(EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x,
1323 || !TEST_true(EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y,
1325 || !TEST_true(BN_hex2bn(&x, test->Gx))
1326 || !TEST_true(BN_hex2bn(&y, test->Gy))
1327 || !TEST_true(EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx))
1328 || !TEST_true(BN_hex2bn(&order, test->order))
1329 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1330 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1333 TEST_note("NIST test vectors ... ");
1334 if (!TEST_true(BN_hex2bn(&n, test->d)))
1336 /* fixed point multiplication */
1337 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1338 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1340 /* random point multiplication */
1341 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1342 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1344 /* set generator to P = 2*G, where G is the standard generator */
1345 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1346 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1347 /* set the scalar to m=n/2, where n is the NIST test scalar */
1348 || !TEST_true(BN_rshift(m, n, 1)))
1351 /* test the non-standard generator */
1352 /* fixed point multiplication */
1353 EC_POINT_mul(NISTP, Q, m, 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, P, m, ctx);
1358 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1361 * We have not performed precomputation so have_precompute mult should be
1364 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1366 /* now repeat all tests with precomputation */
1367 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1368 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
1371 /* fixed point multiplication */
1372 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1373 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1375 /* random point multiplication */
1376 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1377 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1379 /* reset generator */
1380 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1382 /* fixed point multiplication */
1383 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1384 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1386 /* random point multiplication */
1387 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1388 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1391 /* regression test for felem_neg bug */
1392 if (!TEST_true(BN_set_word(m, 32))
1393 || !TEST_true(BN_set_word(n, 31))
1394 || !TEST_true(EC_POINT_copy(P, G))
1395 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1396 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1397 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1400 r = group_order_tests(NISTP);
1402 EC_GROUP_free(NISTP);
1406 EC_POINT_free(Q_CHECK);
1421 static const unsigned char p521_named[] = {
1422 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1425 static const unsigned char p521_explicit[] = {
1426 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1427 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1428 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1429 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1430 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1431 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1432 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1433 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1434 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1435 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1436 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1437 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1438 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1439 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1440 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1441 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1442 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1443 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1444 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1445 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1446 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1447 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1448 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1449 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1450 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1451 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1452 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1453 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1454 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1455 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1456 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1457 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1458 0x02, 0x42, 0x01, 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, 0xfa,
1461 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1462 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1463 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1466 static int parameter_test(void)
1468 EC_GROUP *group = NULL, *group2 = NULL;
1469 ECPARAMETERS *ecparameters = NULL;
1470 unsigned char *buf = NULL;
1473 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp112r1))
1474 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1475 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1476 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1479 EC_GROUP_free(group);
1482 /* Test the named curve encoding, which should be default. */
1483 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1484 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1485 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1492 * Test the explicit encoding. P-521 requires correctly zero-padding the
1493 * curve coefficients.
1495 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1496 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1497 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
1502 EC_GROUP_free(group);
1503 EC_GROUP_free(group2);
1504 ECPARAMETERS_free(ecparameters);
1510 int setup_tests(void)
1512 #ifndef OPENSSL_NO_EC
1513 crv_len = EC_get_builtin_curves(NULL, 0);
1514 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
1515 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
1518 ADD_TEST(parameter_test);
1519 ADD_TEST(prime_field_tests);
1520 # ifndef OPENSSL_NO_EC2M
1521 ADD_TEST(char2_field_tests);
1522 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
1524 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1525 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
1527 ADD_ALL_TESTS(internal_curve_test, crv_len);
1528 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
1533 void cleanup_tests(void)
1535 #ifndef OPENSSL_NO_EC
1536 OPENSSL_free(curves);