2 * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
12 * EC_KEY low level APIs are deprecated for public use, but still ok for
15 #include "internal/deprecated.h"
18 #include "internal/nelem.h"
21 #include <openssl/ec.h>
22 #ifndef OPENSSL_NO_ENGINE
23 # include <openssl/engine.h>
25 #include <openssl/err.h>
26 #include <openssl/obj_mac.h>
27 #include <openssl/objects.h>
28 #include <openssl/rand.h>
29 #include <openssl/bn.h>
30 #include <openssl/opensslconf.h>
31 #include "openssl/core_names.h"
32 #include "openssl/param_build.h"
33 #include "openssl/evp.h"
35 static size_t crv_len
= 0;
36 static EC_builtin_curve
*curves
= NULL
;
38 /* test multiplication with group order, long and negative scalars */
39 static int group_order_tests(EC_GROUP
*group
)
41 BIGNUM
*n1
= NULL
, *n2
= NULL
, *order
= NULL
;
42 EC_POINT
*P
= NULL
, *Q
= NULL
, *R
= NULL
, *S
= NULL
;
43 const EC_POINT
*G
= NULL
;
47 if (!TEST_ptr(n1
= BN_new())
48 || !TEST_ptr(n2
= BN_new())
49 || !TEST_ptr(order
= BN_new())
50 || !TEST_ptr(ctx
= BN_CTX_new())
51 || !TEST_ptr(G
= EC_GROUP_get0_generator(group
))
52 || !TEST_ptr(P
= EC_POINT_new(group
))
53 || !TEST_ptr(Q
= EC_POINT_new(group
))
54 || !TEST_ptr(R
= EC_POINT_new(group
))
55 || !TEST_ptr(S
= EC_POINT_new(group
)))
58 if (!TEST_true(EC_GROUP_get_order(group
, order
, ctx
))
59 || !TEST_true(EC_POINT_mul(group
, Q
, order
, NULL
, NULL
, ctx
))
60 || !TEST_true(EC_POINT_is_at_infinity(group
, Q
))
61 #ifndef OPENSSL_NO_DEPRECATED_3_0
62 || !TEST_true(EC_GROUP_precompute_mult(group
, ctx
))
64 || !TEST_true(EC_POINT_mul(group
, Q
, order
, NULL
, NULL
, ctx
))
65 || !TEST_true(EC_POINT_is_at_infinity(group
, Q
))
66 || !TEST_true(EC_POINT_copy(P
, G
))
67 || !TEST_true(BN_one(n1
))
68 || !TEST_true(EC_POINT_mul(group
, Q
, n1
, NULL
, NULL
, ctx
))
69 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
))
70 || !TEST_true(BN_sub(n1
, order
, n1
))
71 || !TEST_true(EC_POINT_mul(group
, Q
, n1
, NULL
, NULL
, ctx
))
72 || !TEST_true(EC_POINT_invert(group
, Q
, ctx
))
73 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
)))
76 for (i
= 1; i
<= 2; i
++) {
77 #ifndef OPENSSL_NO_DEPRECATED_3_0
78 const BIGNUM
*scalars
[6];
79 const EC_POINT
*points
[6];
82 if (!TEST_true(BN_set_word(n1
, i
))
84 * If i == 1, P will be the predefined generator for which
85 * EC_GROUP_precompute_mult has set up precomputation.
87 || !TEST_true(EC_POINT_mul(group
, P
, n1
, NULL
, NULL
, ctx
))
88 || (i
== 1 && !TEST_int_eq(0, EC_POINT_cmp(group
, P
, G
, ctx
)))
89 || !TEST_true(BN_one(n1
))
91 || !TEST_true(BN_sub(n1
, n1
, order
))
92 || !TEST_true(EC_POINT_mul(group
, Q
, NULL
, P
, n1
, ctx
))
93 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
))
96 || !TEST_true(BN_add(n2
, order
, BN_value_one()))
97 || !TEST_true(EC_POINT_mul(group
, Q
, NULL
, P
, n2
, ctx
))
98 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
))
100 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
101 || !TEST_true(BN_mul(n2
, n1
, n2
, ctx
))
102 || !TEST_true(EC_POINT_mul(group
, Q
, NULL
, P
, n2
, ctx
))
103 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
)))
106 /* n2 = order^2 - 1 */
107 BN_set_negative(n2
, 0);
108 if (!TEST_true(EC_POINT_mul(group
, Q
, NULL
, P
, n2
, ctx
))
109 /* Add P to verify the result. */
110 || !TEST_true(EC_POINT_add(group
, Q
, Q
, P
, ctx
))
111 || !TEST_true(EC_POINT_is_at_infinity(group
, Q
))
112 || !TEST_false(EC_POINT_is_at_infinity(group
, P
)))
115 #ifndef OPENSSL_NO_DEPRECATED_3_0
116 /* Exercise EC_POINTs_mul, including corner cases. */
117 scalars
[0] = scalars
[1] = BN_value_one();
118 points
[0] = points
[1] = P
;
120 if (!TEST_true(EC_POINTs_mul(group
, R
, NULL
, 2, points
, scalars
, ctx
))
121 || !TEST_true(EC_POINT_dbl(group
, S
, points
[0], ctx
))
122 || !TEST_int_eq(0, EC_POINT_cmp(group
, R
, S
, ctx
)))
126 points
[0] = Q
; /* => infinity */
128 points
[1] = P
; /* => -P */
130 points
[2] = Q
; /* => infinity */
132 points
[3] = Q
; /* => infinity */
134 points
[4] = P
; /* => P */
136 points
[5] = Q
; /* => infinity */
137 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 6, points
, scalars
, ctx
))
138 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
145 if (r
== 0 && i
!= 0)
146 TEST_info(i
== 1 ? "allowing precomputation" :
147 "without precomputation");
159 static int prime_field_tests(void)
162 BIGNUM
*p
= NULL
, *a
= NULL
, *b
= NULL
, *scalar3
= NULL
;
163 EC_GROUP
*group
= NULL
;
164 EC_POINT
*P
= NULL
, *Q
= NULL
, *R
= NULL
;
165 BIGNUM
*x
= NULL
, *y
= NULL
, *z
= NULL
, *yplusone
= NULL
;
166 #ifndef OPENSSL_NO_DEPRECATED_3_0
167 const EC_POINT
*points
[4];
168 const BIGNUM
*scalars
[4];
170 unsigned char buf
[100];
174 if (!TEST_ptr(ctx
= BN_CTX_new())
175 || !TEST_ptr(p
= BN_new())
176 || !TEST_ptr(a
= BN_new())
177 || !TEST_ptr(b
= BN_new())
178 || !TEST_true(BN_hex2bn(&p
, "17"))
179 || !TEST_true(BN_hex2bn(&a
, "1"))
180 || !TEST_true(BN_hex2bn(&b
, "1"))
181 || !TEST_ptr(group
= EC_GROUP_new_curve_GFp(p
, a
, b
, ctx
))
182 || !TEST_true(EC_GROUP_get_curve(group
, p
, a
, b
, ctx
)))
185 TEST_info("Curve defined by Weierstrass equation");
186 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
187 test_output_bignum("a", a
);
188 test_output_bignum("b", b
);
189 test_output_bignum("p", p
);
192 if (!TEST_ptr(P
= EC_POINT_new(group
))
193 || !TEST_ptr(Q
= EC_POINT_new(group
))
194 || !TEST_ptr(R
= EC_POINT_new(group
))
195 || !TEST_true(EC_POINT_set_to_infinity(group
, P
))
196 || !TEST_true(EC_POINT_is_at_infinity(group
, P
))
197 || !TEST_true(EC_POINT_oct2point(group
, Q
, buf
, 1, ctx
))
198 || !TEST_true(EC_POINT_add(group
, P
, P
, Q
, ctx
))
199 || !TEST_true(EC_POINT_is_at_infinity(group
, P
))
200 || !TEST_ptr(x
= BN_new())
201 || !TEST_ptr(y
= BN_new())
202 || !TEST_ptr(z
= BN_new())
203 || !TEST_ptr(yplusone
= BN_new())
204 || !TEST_true(BN_hex2bn(&x
, "D"))
205 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, Q
, x
, 1, ctx
)))
208 if (!TEST_int_gt(EC_POINT_is_on_curve(group
, Q
, ctx
), 0)) {
209 if (!TEST_true(EC_POINT_get_affine_coordinates(group
, Q
, x
, y
, ctx
)))
211 TEST_info("Point is not on curve");
212 test_output_bignum("x", x
);
213 test_output_bignum("y", y
);
217 TEST_note("A cyclic subgroup:");
220 if (!TEST_int_ne(k
--, 0))
223 if (EC_POINT_is_at_infinity(group
, P
)) {
224 TEST_note(" point at infinity");
226 if (!TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
,
230 test_output_bignum("x", x
);
231 test_output_bignum("y", y
);
234 if (!TEST_true(EC_POINT_copy(R
, P
))
235 || !TEST_true(EC_POINT_add(group
, P
, P
, Q
, ctx
)))
238 } while (!EC_POINT_is_at_infinity(group
, P
));
240 if (!TEST_true(EC_POINT_add(group
, P
, Q
, R
, ctx
))
241 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
245 EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_COMPRESSED
, buf
,
247 if (!TEST_size_t_ne(len
, 0)
248 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
249 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
251 test_output_memory("Generator as octet string, compressed form:",
254 len
= EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_UNCOMPRESSED
,
255 buf
, sizeof(buf
), ctx
);
256 if (!TEST_size_t_ne(len
, 0)
257 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
258 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
260 test_output_memory("Generator as octet string, uncompressed form:",
263 len
= EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_HYBRID
,
264 buf
, sizeof(buf
), ctx
);
265 if (!TEST_size_t_ne(len
, 0)
266 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
267 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
269 test_output_memory("Generator as octet string, hybrid form:",
272 if (!TEST_true(EC_POINT_invert(group
, P
, ctx
))
273 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, R
, ctx
))
276 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
277 * 2000) -- not a NIST curve, but commonly used
280 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFF"
281 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
282 || !TEST_int_eq(1, BN_check_prime(p
, ctx
, NULL
))
283 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFF"
284 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
285 || !TEST_true(BN_hex2bn(&b
, "1C97BEFC"
286 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
287 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
288 || !TEST_true(BN_hex2bn(&x
, "4A96B568"
289 "8EF573284664698968C38BB913CBFC82"))
290 || !TEST_true(BN_hex2bn(&y
, "23a62855"
291 "3168947d59dcc912042351377ac5fb32"))
292 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
294 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
295 * and therefore setting the coordinates should fail.
297 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
299 || !TEST_true(EC_POINT_set_affine_coordinates(group
, P
, x
, y
, ctx
))
300 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
301 || !TEST_true(BN_hex2bn(&z
, "0100000000"
302 "000000000001F4C8F927AED3CA752257"))
303 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
304 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
306 TEST_info("SEC2 curve secp160r1 -- Generator");
307 test_output_bignum("x", x
);
308 test_output_bignum("y", y
);
309 /* G_y value taken from the standard: */
310 if (!TEST_true(BN_hex2bn(&z
, "23a62855"
311 "3168947d59dcc912042351377ac5fb32"))
313 || !TEST_int_eq(EC_GROUP_get_degree(group
), 160)
314 || !group_order_tests(group
)
316 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
318 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFFFFFFFFFF"
319 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
320 || !TEST_int_eq(1, BN_check_prime(p
, ctx
, NULL
))
321 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFFFFFFFFFF"
322 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
323 || !TEST_true(BN_hex2bn(&b
, "64210519E59C80E7"
324 "0FA7E9AB72243049FEB8DEECC146B9B1"))
325 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
326 || !TEST_true(BN_hex2bn(&x
, "188DA80EB03090F6"
327 "7CBF20EB43A18800F4FF0AFD82FF1012"))
328 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 1, ctx
))
329 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
330 || !TEST_true(BN_hex2bn(&z
, "FFFFFFFFFFFFFFFF"
331 "FFFFFFFF99DEF836146BC9B1B4D22831"))
332 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
333 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
336 TEST_info("NIST curve P-192 -- Generator");
337 test_output_bignum("x", x
);
338 test_output_bignum("y", y
);
339 /* G_y value taken from the standard: */
340 if (!TEST_true(BN_hex2bn(&z
, "07192B95FFC8DA78"
341 "631011ED6B24CDD573F977A11E794811"))
343 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
345 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
346 * and therefore setting the coordinates should fail.
348 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
350 || !TEST_int_eq(EC_GROUP_get_degree(group
), 192)
351 || !group_order_tests(group
)
353 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
355 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFFFFFFFFFFFFFFFFFF"
356 "FFFFFFFF000000000000000000000001"))
357 || !TEST_int_eq(1, BN_check_prime(p
, ctx
, NULL
))
358 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFFFFFFFFFFFFFFFFFF"
359 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
360 || !TEST_true(BN_hex2bn(&b
, "B4050A850C04B3ABF5413256"
361 "5044B0B7D7BFD8BA270B39432355FFB4"))
362 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
363 || !TEST_true(BN_hex2bn(&x
, "B70E0CBD6BB4BF7F321390B9"
364 "4A03C1D356C21122343280D6115C1D21"))
365 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 0, ctx
))
366 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
367 || !TEST_true(BN_hex2bn(&z
, "FFFFFFFFFFFFFFFFFFFFFFFF"
368 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
369 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
370 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
373 TEST_info("NIST curve P-224 -- Generator");
374 test_output_bignum("x", x
);
375 test_output_bignum("y", y
);
376 /* G_y value taken from the standard: */
377 if (!TEST_true(BN_hex2bn(&z
, "BD376388B5F723FB4C22DFE6"
378 "CD4375A05A07476444D5819985007E34"))
380 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
382 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
383 * and therefore setting the coordinates should fail.
385 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
387 || !TEST_int_eq(EC_GROUP_get_degree(group
), 224)
388 || !group_order_tests(group
)
390 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
392 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFF000000010000000000000000"
393 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
394 || !TEST_int_eq(1, BN_check_prime(p
, ctx
, NULL
))
395 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFF000000010000000000000000"
396 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
397 || !TEST_true(BN_hex2bn(&b
, "5AC635D8AA3A93E7B3EBBD55769886BC"
398 "651D06B0CC53B0F63BCE3C3E27D2604B"))
399 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
401 || !TEST_true(BN_hex2bn(&x
, "6B17D1F2E12C4247F8BCE6E563A440F2"
402 "77037D812DEB33A0F4A13945D898C296"))
403 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 1, ctx
))
404 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
405 || !TEST_true(BN_hex2bn(&z
, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
406 "BCE6FAADA7179E84F3B9CAC2FC632551"))
407 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
408 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
411 TEST_info("NIST curve P-256 -- Generator");
412 test_output_bignum("x", x
);
413 test_output_bignum("y", y
);
414 /* G_y value taken from the standard: */
415 if (!TEST_true(BN_hex2bn(&z
, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
416 "2BCE33576B315ECECBB6406837BF51F5"))
418 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
420 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
421 * and therefore setting the coordinates should fail.
423 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
425 || !TEST_int_eq(EC_GROUP_get_degree(group
), 256)
426 || !group_order_tests(group
)
428 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
430 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
431 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
432 "FFFFFFFF0000000000000000FFFFFFFF"))
433 || !TEST_int_eq(1, BN_check_prime(p
, ctx
, NULL
))
434 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
435 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
436 "FFFFFFFF0000000000000000FFFFFFFC"))
437 || !TEST_true(BN_hex2bn(&b
, "B3312FA7E23EE7E4988E056BE3F82D19"
438 "181D9C6EFE8141120314088F5013875A"
439 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
440 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
442 || !TEST_true(BN_hex2bn(&x
, "AA87CA22BE8B05378EB1C71EF320AD74"
443 "6E1D3B628BA79B9859F741E082542A38"
444 "5502F25DBF55296C3A545E3872760AB7"))
445 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 1, ctx
))
446 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
447 || !TEST_true(BN_hex2bn(&z
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
448 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
449 "581A0DB248B0A77AECEC196ACCC52973"))
450 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
451 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
454 TEST_info("NIST curve P-384 -- Generator");
455 test_output_bignum("x", x
);
456 test_output_bignum("y", y
);
457 /* G_y value taken from the standard: */
458 if (!TEST_true(BN_hex2bn(&z
, "3617DE4A96262C6F5D9E98BF9292DC29"
459 "F8F41DBD289A147CE9DA3113B5F0B8C0"
460 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
462 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
464 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
465 * and therefore setting the coordinates should fail.
467 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
469 || !TEST_int_eq(EC_GROUP_get_degree(group
), 384)
470 || !group_order_tests(group
)
472 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
473 || !TEST_true(BN_hex2bn(&p
, "1FF"
474 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
475 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
476 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
477 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
478 || !TEST_int_eq(1, BN_check_prime(p
, ctx
, NULL
))
479 || !TEST_true(BN_hex2bn(&a
, "1FF"
480 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
481 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
482 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
483 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
484 || !TEST_true(BN_hex2bn(&b
, "051"
485 "953EB9618E1C9A1F929A21A0B68540EE"
486 "A2DA725B99B315F3B8B489918EF109E1"
487 "56193951EC7E937B1652C0BD3BB1BF07"
488 "3573DF883D2C34F1EF451FD46B503F00"))
489 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
490 || !TEST_true(BN_hex2bn(&x
, "C6"
491 "858E06B70404E9CD9E3ECB662395B442"
492 "9C648139053FB521F828AF606B4D3DBA"
493 "A14B5E77EFE75928FE1DC127A2FFA8DE"
494 "3348B3C1856A429BF97E7E31C2E5BD66"))
495 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 0, ctx
))
496 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
497 || !TEST_true(BN_hex2bn(&z
, "1FF"
498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
500 "51868783BF2F966B7FCC0148F709A5D0"
501 "3BB5C9B8899C47AEBB6FB71E91386409"))
502 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
503 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
506 TEST_info("NIST curve P-521 -- Generator");
507 test_output_bignum("x", x
);
508 test_output_bignum("y", y
);
509 /* G_y value taken from the standard: */
510 if (!TEST_true(BN_hex2bn(&z
, "118"
511 "39296A789A3BC0045C8A5FB42C7D1BD9"
512 "98F54449579B446817AFBD17273E662C"
513 "97EE72995EF42640C550B9013FAD0761"
514 "353C7086A272C24088BE94769FD16650"))
516 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
518 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
519 * and therefore setting the coordinates should fail.
521 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
523 || !TEST_int_eq(EC_GROUP_get_degree(group
), 521)
524 || !group_order_tests(group
)
526 /* more tests using the last curve */
528 /* Restore the point that got mangled in the (x, y + 1) test. */
529 || !TEST_true(EC_POINT_set_affine_coordinates(group
, P
, x
, y
, ctx
))
530 || !TEST_true(EC_POINT_copy(Q
, P
))
531 || !TEST_false(EC_POINT_is_at_infinity(group
, Q
))
532 || !TEST_true(EC_POINT_dbl(group
, P
, P
, ctx
))
533 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
534 || !TEST_true(EC_POINT_invert(group
, Q
, ctx
)) /* P = -2Q */
535 || !TEST_true(EC_POINT_add(group
, R
, P
, Q
, ctx
))
536 || !TEST_true(EC_POINT_add(group
, R
, R
, Q
, ctx
))
537 || !TEST_true(EC_POINT_is_at_infinity(group
, R
)) /* R = P + 2Q */
538 || !TEST_false(EC_POINT_is_at_infinity(group
, Q
)))
541 #ifndef OPENSSL_NO_DEPRECATED_3_0
542 TEST_note("combined multiplication ...");
548 if (!TEST_true(EC_GROUP_get_order(group
, z
, ctx
))
549 || !TEST_true(BN_add(y
, z
, BN_value_one()))
551 || !TEST_true(BN_rshift1(y
, y
)))
554 scalars
[0] = y
; /* (group order + 1)/2, so y*Q + y*Q = Q */
557 /* z is still the group order */
558 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 2, points
, scalars
, ctx
))
559 || !TEST_true(EC_POINTs_mul(group
, R
, z
, 2, points
, scalars
, ctx
))
560 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, R
, ctx
))
561 || !TEST_int_eq(0, EC_POINT_cmp(group
, R
, Q
, ctx
))
562 || !TEST_true(BN_rand(y
, BN_num_bits(y
), 0, 0))
563 || !TEST_true(BN_add(z
, z
, y
)))
565 BN_set_negative(z
, 1);
567 scalars
[1] = z
; /* z = -(order + y) */
569 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 2, points
, scalars
, ctx
))
570 || !TEST_true(EC_POINT_is_at_infinity(group
, P
))
571 || !TEST_true(BN_rand(x
, BN_num_bits(y
) - 1, 0, 0))
572 || !TEST_true(BN_add(z
, x
, y
)))
574 BN_set_negative(z
, 1);
577 scalars
[2] = z
; /* z = -(x+y) */
579 if (!TEST_ptr(scalar3
= BN_new()))
582 scalars
[3] = scalar3
;
584 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 4, points
, scalars
, ctx
))
585 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
595 EC_GROUP_free(group
);
607 #ifndef OPENSSL_NO_EC2M
609 static struct c2_curve_test
{
620 } char2_curve_tests
[] = {
621 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
624 "0800000000000000000000000000000000000000C9",
627 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
628 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
629 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
631 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
634 "0800000000000000000000000000000000000000C9",
636 "020A601907B8C953CA1481EB10512F78744A3205FD",
637 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
638 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
639 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
641 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
644 "020000000000000000000000000000000000000004000000000000000001",
647 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
648 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
650 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
653 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
656 "020000000000000000000000000000000000000004000000000000000001",
657 "000000000000000000000000000000000000000000000000000000000001",
658 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
659 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
660 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
662 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
665 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
669 "00000000000000000000000000000000000000000000000000000000000010A1",
673 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
675 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
678 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
681 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
685 "00000000000000000000000000000000000000000000000000000000000010A1",
687 "0000000000000000000000000000000000000000000000000000000000000001",
689 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
691 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
693 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
696 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
699 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
702 "0200000000000000000000000000000000000000"
703 "0000000000000000000000000000000000000000008000000000000000000001",
706 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
707 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
708 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
709 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
711 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
712 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
715 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
718 "0200000000000000000000000000000000000000"
719 "0000000000000000000000000000000000000000008000000000000000000001",
720 "0000000000000000000000000000000000000000"
721 "0000000000000000000000000000000000000000000000000000000000000001",
722 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
723 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
724 "015D4860D088DDB3496B0C6064756260441CDE4A"
725 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
726 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
727 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
729 "0100000000000000000000000000000000000000"
730 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
733 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
737 "0000000000000000000000000000000000000000000000000000000000000000"
738 "0000000000000000000000000000000000000000000000000000000000000425",
742 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
743 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
745 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
746 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
749 "00000000000000000000000000000000000000000000000000000000131850E1"
750 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
753 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
757 "0000000000000000000000000000000000000000000000000000000000000000"
758 "0000000000000000000000000000000000000000000000000000000000000425",
760 "0000000000000000000000000000000000000000000000000000000000000000"
761 "0000000000000000000000000000000000000000000000000000000000000001",
763 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
764 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
766 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
767 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
769 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
770 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
773 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
774 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
779 static int char2_curve_test(int n
)
783 BIGNUM
*p
= NULL
, *a
= NULL
, *b
= NULL
;
784 BIGNUM
*x
= NULL
, *y
= NULL
, *z
= NULL
, *cof
= NULL
, *yplusone
= NULL
;
785 EC_GROUP
*group
= NULL
;
786 EC_POINT
*P
= NULL
, *Q
= NULL
, *R
= NULL
;
787 # ifndef OPENSSL_NO_DEPRECATED_3_0
788 const EC_POINT
*points
[3];
789 const BIGNUM
*scalars
[3];
791 struct c2_curve_test
*const test
= char2_curve_tests
+ n
;
793 if (!TEST_ptr(ctx
= BN_CTX_new())
794 || !TEST_ptr(p
= BN_new())
795 || !TEST_ptr(a
= BN_new())
796 || !TEST_ptr(b
= BN_new())
797 || !TEST_ptr(x
= BN_new())
798 || !TEST_ptr(y
= BN_new())
799 || !TEST_ptr(z
= BN_new())
800 || !TEST_ptr(yplusone
= BN_new())
801 || !TEST_true(BN_hex2bn(&p
, test
->p
))
802 || !TEST_true(BN_hex2bn(&a
, test
->a
))
803 || !TEST_true(BN_hex2bn(&b
, test
->b
))
804 || !TEST_true(group
= EC_GROUP_new_curve_GF2m(p
, a
, b
, ctx
))
805 || !TEST_ptr(P
= EC_POINT_new(group
))
806 || !TEST_ptr(Q
= EC_POINT_new(group
))
807 || !TEST_ptr(R
= EC_POINT_new(group
))
808 || !TEST_true(BN_hex2bn(&x
, test
->x
))
809 || !TEST_true(BN_hex2bn(&y
, test
->y
))
810 || !TEST_true(BN_add(yplusone
, y
, BN_value_one())))
813 /* Change test based on whether binary point compression is enabled or not. */
814 # ifdef OPENSSL_EC_BIN_PT_COMP
816 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
817 * and therefore setting the coordinates should fail.
819 if (!TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
, ctx
))
820 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
,
823 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
824 || !TEST_true(BN_hex2bn(&z
, test
->order
))
825 || !TEST_true(BN_hex2bn(&cof
, test
->cof
))
826 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, cof
))
827 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
829 TEST_info("%s -- Generator", test
->name
);
830 test_output_bignum("x", x
);
831 test_output_bignum("y", y
);
832 /* G_y value taken from the standard: */
833 if (!TEST_true(BN_hex2bn(&z
, test
->y
))
834 || !TEST_BN_eq(y
, z
))
838 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
839 * and therefore setting the coordinates should fail.
841 if (!TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
, ctx
))
842 || !TEST_true(EC_POINT_set_affine_coordinates(group
, P
, x
, y
, ctx
))
843 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
844 || !TEST_true(BN_hex2bn(&z
, test
->order
))
845 || !TEST_true(BN_hex2bn(&cof
, test
->cof
))
846 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, cof
)))
848 TEST_info("%s -- Generator:", test
->name
);
849 test_output_bignum("x", x
);
850 test_output_bignum("y", y
);
853 if (!TEST_int_eq(EC_GROUP_get_degree(group
), test
->degree
)
854 || !group_order_tests(group
))
857 /* more tests using the last curve */
858 if (n
== OSSL_NELEM(char2_curve_tests
) - 1) {
859 if (!TEST_true(EC_POINT_set_affine_coordinates(group
, P
, x
, y
, ctx
))
860 || !TEST_true(EC_POINT_copy(Q
, P
))
861 || !TEST_false(EC_POINT_is_at_infinity(group
, Q
))
862 || !TEST_true(EC_POINT_dbl(group
, P
, P
, ctx
))
863 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
864 || !TEST_true(EC_POINT_invert(group
, Q
, ctx
)) /* P = -2Q */
865 || !TEST_true(EC_POINT_add(group
, R
, P
, Q
, ctx
))
866 || !TEST_true(EC_POINT_add(group
, R
, R
, Q
, ctx
))
867 || !TEST_true(EC_POINT_is_at_infinity(group
, R
)) /* R = P + 2Q */
868 || !TEST_false(EC_POINT_is_at_infinity(group
, Q
)))
871 # ifndef OPENSSL_NO_DEPRECATED_3_0
872 TEST_note("combined multiplication ...");
877 if (!TEST_true(BN_add(y
, z
, BN_value_one()))
879 || !TEST_true(BN_rshift1(y
, y
)))
881 scalars
[0] = y
; /* (group order + 1)/2, so y*Q + y*Q = Q */
884 /* z is still the group order */
885 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 2, points
, scalars
, ctx
))
886 || !TEST_true(EC_POINTs_mul(group
, R
, z
, 2, points
, scalars
, ctx
))
887 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, R
, ctx
))
888 || !TEST_int_eq(0, EC_POINT_cmp(group
, R
, Q
, ctx
)))
891 if (!TEST_true(BN_rand(y
, BN_num_bits(y
), 0, 0))
892 || !TEST_true(BN_add(z
, z
, y
)))
894 BN_set_negative(z
, 1);
896 scalars
[1] = z
; /* z = -(order + y) */
898 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 2, points
, scalars
, ctx
))
899 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
902 if (!TEST_true(BN_rand(x
, BN_num_bits(y
) - 1, 0, 0))
903 || !TEST_true(BN_add(z
, x
, y
)))
905 BN_set_negative(z
, 1);
908 scalars
[2] = z
; /* z = -(x+y) */
910 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 3, points
, scalars
, ctx
))
911 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
930 EC_GROUP_free(group
);
934 static int char2_field_tests(void)
937 BIGNUM
*p
= NULL
, *a
= NULL
, *b
= NULL
;
938 EC_GROUP
*group
= NULL
;
939 EC_POINT
*P
= NULL
, *Q
= NULL
, *R
= NULL
;
940 BIGNUM
*x
= NULL
, *y
= NULL
, *z
= NULL
, *cof
= NULL
, *yplusone
= NULL
;
941 unsigned char buf
[100];
945 if (!TEST_ptr(ctx
= BN_CTX_new())
946 || !TEST_ptr(p
= BN_new())
947 || !TEST_ptr(a
= BN_new())
948 || !TEST_ptr(b
= BN_new())
949 || !TEST_true(BN_hex2bn(&p
, "13"))
950 || !TEST_true(BN_hex2bn(&a
, "3"))
951 || !TEST_true(BN_hex2bn(&b
, "1")))
954 if (!TEST_ptr(group
= EC_GROUP_new_curve_GF2m(p
, a
, b
, ctx
))
955 || !TEST_true(EC_GROUP_get_curve(group
, p
, a
, b
, ctx
)))
958 TEST_info("Curve defined by Weierstrass equation");
959 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
960 test_output_bignum("a", a
);
961 test_output_bignum("b", b
);
962 test_output_bignum("p", p
);
964 if (!TEST_ptr(P
= EC_POINT_new(group
))
965 || !TEST_ptr(Q
= EC_POINT_new(group
))
966 || !TEST_ptr(R
= EC_POINT_new(group
))
967 || !TEST_true(EC_POINT_set_to_infinity(group
, P
))
968 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
972 if (!TEST_true(EC_POINT_oct2point(group
, Q
, buf
, 1, ctx
))
973 || !TEST_true(EC_POINT_add(group
, P
, P
, Q
, ctx
))
974 || !TEST_true(EC_POINT_is_at_infinity(group
, P
))
975 || !TEST_ptr(x
= BN_new())
976 || !TEST_ptr(y
= BN_new())
977 || !TEST_ptr(z
= BN_new())
978 || !TEST_ptr(cof
= BN_new())
979 || !TEST_ptr(yplusone
= BN_new())
980 || !TEST_true(BN_hex2bn(&x
, "6"))
981 /* Change test based on whether binary point compression is enabled or not. */
982 # ifdef OPENSSL_EC_BIN_PT_COMP
983 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, Q
, x
, 1, ctx
))
985 || !TEST_true(BN_hex2bn(&y
, "8"))
986 || !TEST_true(EC_POINT_set_affine_coordinates(group
, Q
, x
, y
, ctx
))
990 if (!TEST_int_gt(EC_POINT_is_on_curve(group
, Q
, ctx
), 0)) {
991 /* Change test based on whether binary point compression is enabled or not. */
992 # ifdef OPENSSL_EC_BIN_PT_COMP
993 if (!TEST_true(EC_POINT_get_affine_coordinates(group
, Q
, x
, y
, ctx
)))
996 TEST_info("Point is not on curve");
997 test_output_bignum("x", x
);
998 test_output_bignum("y", y
);
1002 TEST_note("A cyclic subgroup:");
1005 if (!TEST_int_ne(k
--, 0))
1008 if (EC_POINT_is_at_infinity(group
, P
))
1009 TEST_note(" point at infinity");
1011 if (!TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
,
1015 test_output_bignum("x", x
);
1016 test_output_bignum("y", y
);
1019 if (!TEST_true(EC_POINT_copy(R
, P
))
1020 || !TEST_true(EC_POINT_add(group
, P
, P
, Q
, ctx
)))
1023 while (!EC_POINT_is_at_infinity(group
, P
));
1025 if (!TEST_true(EC_POINT_add(group
, P
, Q
, R
, ctx
))
1026 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
1029 /* Change test based on whether binary point compression is enabled or not. */
1030 # ifdef OPENSSL_EC_BIN_PT_COMP
1031 len
= EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_COMPRESSED
,
1032 buf
, sizeof(buf
), ctx
);
1033 if (!TEST_size_t_ne(len
, 0)
1034 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
1035 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
1037 test_output_memory("Generator as octet string, compressed form:",
1041 len
= EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_UNCOMPRESSED
,
1042 buf
, sizeof(buf
), ctx
);
1043 if (!TEST_size_t_ne(len
, 0)
1044 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
1045 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
1047 test_output_memory("Generator as octet string, uncompressed form:",
1050 /* Change test based on whether binary point compression is enabled or not. */
1051 # ifdef OPENSSL_EC_BIN_PT_COMP
1053 EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_HYBRID
, buf
, sizeof(buf
),
1055 if (!TEST_size_t_ne(len
, 0)
1056 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
1057 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
1059 test_output_memory("Generator as octet string, hybrid form:",
1063 if (!TEST_true(EC_POINT_invert(group
, P
, ctx
))
1064 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, R
, ctx
)))
1075 EC_GROUP_free(group
);
1087 static int hybrid_point_encoding_test(void)
1089 BIGNUM
*x
= NULL
, *y
= NULL
;
1090 EC_GROUP
*group
= NULL
;
1091 EC_POINT
*point
= NULL
;
1092 unsigned char *buf
= NULL
;
1096 if (!TEST_true(BN_dec2bn(&x
, "0"))
1097 || !TEST_true(BN_dec2bn(&y
, "1"))
1098 || !TEST_ptr(group
= EC_GROUP_new_by_curve_name(NID_sect571k1
))
1099 || !TEST_ptr(point
= EC_POINT_new(group
))
1100 || !TEST_true(EC_POINT_set_affine_coordinates(group
, point
, x
, y
, NULL
))
1101 || !TEST_size_t_ne(0, (len
= EC_POINT_point2oct(group
,
1103 POINT_CONVERSION_HYBRID
,
1107 || !TEST_ptr(buf
= OPENSSL_malloc(len
))
1108 || !TEST_size_t_eq(len
, EC_POINT_point2oct(group
,
1110 POINT_CONVERSION_HYBRID
,
1118 /* buf contains a valid hybrid point, check that we can decode it. */
1119 if (!TEST_true(EC_POINT_oct2point(group
, point
, buf
, len
, NULL
)))
1122 /* Flip the y_bit and verify that the invalid encoding is rejected. */
1124 if (!TEST_false(EC_POINT_oct2point(group
, point
, buf
, len
, NULL
)))
1130 EC_GROUP_free(group
);
1131 EC_POINT_free(point
);
1137 static int internal_curve_test(int n
)
1139 EC_GROUP
*group
= NULL
;
1140 int nid
= curves
[n
].nid
;
1142 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
))) {
1143 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1147 if (!TEST_true(EC_GROUP_check(group
, NULL
))) {
1148 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid
));
1149 EC_GROUP_free(group
);
1152 EC_GROUP_free(group
);
1156 static int internal_curve_test_method(int n
)
1158 int r
, nid
= curves
[n
].nid
;
1161 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
))) {
1162 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid
));
1165 r
= group_order_tests(group
);
1166 EC_GROUP_free(group
);
1170 static int group_field_test(void)
1173 BIGNUM
*secp521r1_field
= NULL
;
1174 BIGNUM
*sect163r2_field
= NULL
;
1175 EC_GROUP
*secp521r1_group
= NULL
;
1176 EC_GROUP
*sect163r2_group
= NULL
;
1178 BN_hex2bn(&secp521r1_field
,
1179 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1180 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1181 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1182 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1186 BN_hex2bn(§163r2_field
,
1187 "08000000000000000000000000000000"
1190 secp521r1_group
= EC_GROUP_new_by_curve_name(NID_secp521r1
);
1191 if (BN_cmp(secp521r1_field
, EC_GROUP_get0_field(secp521r1_group
)))
1194 # ifndef OPENSSL_NO_EC2M
1195 sect163r2_group
= EC_GROUP_new_by_curve_name(NID_sect163r2
);
1196 if (BN_cmp(sect163r2_field
, EC_GROUP_get0_field(sect163r2_group
)))
1200 EC_GROUP_free(secp521r1_group
);
1201 EC_GROUP_free(sect163r2_group
);
1202 BN_free(secp521r1_field
);
1203 BN_free(sect163r2_field
);
1208 * nistp_test_params contains magic numbers for testing
1209 * several NIST curves with characteristic > 3.
1211 struct nistp_test_params
{
1215 * Qx, Qy and D are taken from
1216 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1217 * Otherwise, values are standard curve parameters from FIPS 180-3
1219 const char *p
, *a
, *b
, *Qx
, *Qy
, *Gx
, *Gy
, *order
, *d
;
1222 static const struct nistp_test_params nistp_tests_params
[] = {
1228 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1230 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1232 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1234 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1236 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1238 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1240 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1242 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1244 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1248 NID_X9_62_prime256v1
,
1251 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1253 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1255 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1257 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1259 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1261 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1263 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1265 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1267 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1275 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1276 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1279 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1280 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1283 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1284 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1287 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1288 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1291 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1292 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1295 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1296 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1299 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1300 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1303 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1304 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1307 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1308 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1312 static int nistp_single_test(int idx
)
1314 const struct nistp_test_params
*test
= nistp_tests_params
+ idx
;
1316 BIGNUM
*p
= NULL
, *a
= NULL
, *b
= NULL
, *x
= NULL
, *y
= NULL
;
1317 BIGNUM
*n
= NULL
, *m
= NULL
, *order
= NULL
, *yplusone
= NULL
;
1318 EC_GROUP
*NISTP
= NULL
;
1319 EC_POINT
*G
= NULL
, *P
= NULL
, *Q
= NULL
, *Q_CHECK
= NULL
;
1322 TEST_note("NIST curve P-%d (optimised implementation):",
1324 if (!TEST_ptr(ctx
= BN_CTX_new())
1325 || !TEST_ptr(p
= BN_new())
1326 || !TEST_ptr(a
= BN_new())
1327 || !TEST_ptr(b
= BN_new())
1328 || !TEST_ptr(x
= BN_new())
1329 || !TEST_ptr(y
= BN_new())
1330 || !TEST_ptr(m
= BN_new())
1331 || !TEST_ptr(n
= BN_new())
1332 || !TEST_ptr(order
= BN_new())
1333 || !TEST_ptr(yplusone
= BN_new())
1335 || !TEST_ptr(NISTP
= EC_GROUP_new_by_curve_name(test
->nid
))
1336 || !TEST_true(BN_hex2bn(&p
, test
->p
))
1337 || !TEST_int_eq(1, BN_check_prime(p
, ctx
, NULL
))
1338 || !TEST_true(BN_hex2bn(&a
, test
->a
))
1339 || !TEST_true(BN_hex2bn(&b
, test
->b
))
1340 || !TEST_true(EC_GROUP_set_curve(NISTP
, p
, a
, b
, ctx
))
1341 || !TEST_ptr(G
= EC_POINT_new(NISTP
))
1342 || !TEST_ptr(P
= EC_POINT_new(NISTP
))
1343 || !TEST_ptr(Q
= EC_POINT_new(NISTP
))
1344 || !TEST_ptr(Q_CHECK
= EC_POINT_new(NISTP
))
1345 || !TEST_true(BN_hex2bn(&x
, test
->Qx
))
1346 || !TEST_true(BN_hex2bn(&y
, test
->Qy
))
1347 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
1349 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1350 * and therefore setting the coordinates should fail.
1352 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP
, Q_CHECK
, x
,
1354 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP
, Q_CHECK
, x
, y
,
1356 || !TEST_true(BN_hex2bn(&x
, test
->Gx
))
1357 || !TEST_true(BN_hex2bn(&y
, test
->Gy
))
1358 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP
, G
, x
, y
, ctx
))
1359 || !TEST_true(BN_hex2bn(&order
, test
->order
))
1360 || !TEST_true(EC_GROUP_set_generator(NISTP
, G
, order
, BN_value_one()))
1361 || !TEST_int_eq(EC_GROUP_get_degree(NISTP
), test
->degree
))
1364 TEST_note("NIST test vectors ... ");
1365 if (!TEST_true(BN_hex2bn(&n
, test
->d
)))
1367 /* fixed point multiplication */
1368 EC_POINT_mul(NISTP
, Q
, n
, NULL
, NULL
, ctx
);
1369 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1371 /* random point multiplication */
1372 EC_POINT_mul(NISTP
, Q
, NULL
, G
, n
, ctx
);
1373 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
))
1375 /* set generator to P = 2*G, where G is the standard generator */
1376 || !TEST_true(EC_POINT_dbl(NISTP
, P
, G
, ctx
))
1377 || !TEST_true(EC_GROUP_set_generator(NISTP
, P
, order
, BN_value_one()))
1378 /* set the scalar to m=n/2, where n is the NIST test scalar */
1379 || !TEST_true(BN_rshift(m
, n
, 1)))
1382 /* test the non-standard generator */
1383 /* fixed point multiplication */
1384 EC_POINT_mul(NISTP
, Q
, m
, NULL
, NULL
, ctx
);
1385 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1387 /* random point multiplication */
1388 EC_POINT_mul(NISTP
, Q
, NULL
, P
, m
, ctx
);
1389 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
))
1390 #ifndef OPENSSL_NO_DEPRECATED_3_0
1391 /* We have not performed precomp so this should be false */
1392 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP
))
1393 /* now repeat all tests with precomputation */
1394 || !TEST_true(EC_GROUP_precompute_mult(NISTP
, ctx
))
1399 /* fixed point multiplication */
1400 EC_POINT_mul(NISTP
, Q
, m
, NULL
, NULL
, ctx
);
1401 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1403 /* random point multiplication */
1404 EC_POINT_mul(NISTP
, Q
, NULL
, P
, m
, ctx
);
1405 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
))
1407 /* reset generator */
1408 || !TEST_true(EC_GROUP_set_generator(NISTP
, G
, order
, BN_value_one())))
1410 /* fixed point multiplication */
1411 EC_POINT_mul(NISTP
, Q
, n
, NULL
, NULL
, ctx
);
1412 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1414 /* random point multiplication */
1415 EC_POINT_mul(NISTP
, Q
, NULL
, G
, n
, ctx
);
1416 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1419 /* regression test for felem_neg bug */
1420 if (!TEST_true(BN_set_word(m
, 32))
1421 || !TEST_true(BN_set_word(n
, 31))
1422 || !TEST_true(EC_POINT_copy(P
, G
))
1423 || !TEST_true(EC_POINT_invert(NISTP
, P
, ctx
))
1424 || !TEST_true(EC_POINT_mul(NISTP
, Q
, m
, P
, n
, ctx
))
1425 || !TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, G
, ctx
)))
1430 EC_GROUP_free(NISTP
);
1434 EC_POINT_free(Q_CHECK
);
1448 static const unsigned char p521_named
[] = {
1449 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1452 static const unsigned char p521_explicit
[] = {
1453 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1454 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 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 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1464 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1465 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1466 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1467 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1468 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1469 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1470 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1471 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1472 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1473 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1474 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1475 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1476 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1477 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1478 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1479 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1480 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1481 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1482 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1483 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1484 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1485 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1486 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1487 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1488 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1489 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1490 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1494 * This test validates a named curve's group parameters using
1495 * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1496 * group parameters results in the curve not being valid.
1498 static int check_named_curve_test(int id
)
1500 int ret
= 0, nid
, field_nid
, has_seed
;
1501 EC_GROUP
*group
= NULL
, *gtest
= NULL
;
1502 const EC_POINT
*group_gen
= NULL
;
1503 EC_POINT
*other_gen
= NULL
;
1504 BIGNUM
*group_p
= NULL
, *group_a
= NULL
, *group_b
= NULL
;
1505 BIGNUM
*other_p
= NULL
, *other_a
= NULL
, *other_b
= NULL
;
1506 BIGNUM
*group_cofactor
= NULL
, *other_cofactor
= NULL
;
1507 BIGNUM
*other_order
= NULL
;
1508 const BIGNUM
*group_order
= NULL
;
1509 BN_CTX
*bn_ctx
= NULL
;
1510 static const unsigned char invalid_seed
[] = "THIS IS NOT A VALID SEED";
1511 static size_t invalid_seed_len
= sizeof(invalid_seed
);
1514 nid
= curves
[id
].nid
;
1515 if (!TEST_ptr(bn_ctx
= BN_CTX_new())
1516 || !TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
))
1517 || !TEST_ptr(gtest
= EC_GROUP_dup(group
))
1518 || !TEST_ptr(group_p
= BN_new())
1519 || !TEST_ptr(group_a
= BN_new())
1520 || !TEST_ptr(group_b
= BN_new())
1521 || !TEST_ptr(group_cofactor
= BN_new())
1522 || !TEST_ptr(group_gen
= EC_GROUP_get0_generator(group
))
1523 || !TEST_ptr(group_order
= EC_GROUP_get0_order(group
))
1524 || !TEST_true(EC_GROUP_get_cofactor(group
, group_cofactor
, NULL
))
1525 || !TEST_true(EC_GROUP_get_curve(group
, group_p
, group_a
, group_b
, NULL
))
1526 || !TEST_ptr(other_gen
= EC_POINT_dup(group_gen
, group
))
1527 || !TEST_true(EC_POINT_add(group
, other_gen
, group_gen
, group_gen
, NULL
))
1528 || !TEST_ptr(other_order
= BN_dup(group_order
))
1529 || !TEST_true(BN_add_word(other_order
, 1))
1530 || !TEST_ptr(other_a
= BN_dup(group_a
))
1531 || !TEST_true(BN_add_word(other_a
, 1))
1532 || !TEST_ptr(other_b
= BN_dup(group_b
))
1533 || !TEST_true(BN_add_word(other_b
, 1))
1534 || !TEST_ptr(other_cofactor
= BN_dup(group_cofactor
))
1535 || !TEST_true(BN_add_word(other_cofactor
, 1)))
1538 /* Determine if the built-in curve has a seed field set */
1539 has_seed
= (EC_GROUP_get_seed_len(group
) > 0);
1540 field_nid
= EC_GROUP_get_field_type(group
);
1541 if (field_nid
== NID_X9_62_characteristic_two_field
) {
1542 if (!TEST_ptr(other_p
= BN_dup(group_p
))
1543 || !TEST_true(BN_lshift1(other_p
, other_p
)))
1546 if (!TEST_ptr(other_p
= BN_dup(group_p
)))
1549 * Just choosing any arbitrary prime does not work..
1550 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1551 * nist prime. So only select one of these as an alternate prime.
1553 if (!TEST_ptr(BN_copy(other_p
,
1554 BN_ucmp(BN_get0_nist_prime_192(), other_p
) == 0 ?
1555 BN_get0_nist_prime_256() :
1556 BN_get0_nist_prime_192())))
1560 /* Passes because this is a valid curve */
1561 if (!TEST_int_eq(EC_GROUP_check_named_curve(group
, 0, NULL
), nid
)
1562 /* Only NIST curves pass */
1563 || !TEST_int_eq(EC_GROUP_check_named_curve(group
, 1, NULL
),
1564 EC_curve_nid2nist(nid
) != NULL
? nid
: NID_undef
))
1567 /* Fail if the curve name doesn't match the parameters */
1568 EC_GROUP_set_curve_name(group
, nid
+ 1);
1570 if (!TEST_int_le(EC_GROUP_check_named_curve(group
, 0, NULL
), 0))
1574 /* Restore curve name and ensure it's passing */
1575 EC_GROUP_set_curve_name(group
, nid
);
1576 if (!TEST_int_eq(EC_GROUP_check_named_curve(group
, 0, NULL
), nid
))
1579 if (!TEST_int_eq(EC_GROUP_set_seed(group
, invalid_seed
, invalid_seed_len
),
1585 * If the built-in curve has a seed and we set the seed to another value
1586 * then it will fail the check.
1588 if (!TEST_int_eq(EC_GROUP_check_named_curve(group
, 0, NULL
), 0))
1592 * If the built-in curve does not have a seed then setting the seed will
1593 * pass the check (as the seed is optional).
1595 if (!TEST_int_eq(EC_GROUP_check_named_curve(group
, 0, NULL
), nid
))
1598 /* Pass if the seed is unknown (as it is optional) */
1599 if (!TEST_int_eq(EC_GROUP_set_seed(group
, NULL
, 0), 1)
1600 || !TEST_int_eq(EC_GROUP_check_named_curve(group
, 0, NULL
), nid
))
1603 /* Check that a duped group passes */
1604 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0, NULL
), nid
))
1607 /* check that changing any generator parameter fails */
1608 if (!TEST_true(EC_GROUP_set_generator(gtest
, other_gen
, group_order
,
1610 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0, NULL
), 0)
1611 || !TEST_true(EC_GROUP_set_generator(gtest
, group_gen
, other_order
,
1613 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0, NULL
), 0)
1614 /* The order is not an optional field, so this should fail */
1615 || !TEST_false(EC_GROUP_set_generator(gtest
, group_gen
, NULL
,
1617 || !TEST_true(EC_GROUP_set_generator(gtest
, group_gen
, group_order
,
1619 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0, NULL
), 0)
1620 /* Check that if the cofactor is not set then it still passes */
1621 || !TEST_true(EC_GROUP_set_generator(gtest
, group_gen
, group_order
,
1623 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0, NULL
), nid
)
1624 /* check that restoring the generator passes */
1625 || !TEST_true(EC_GROUP_set_generator(gtest
, group_gen
, group_order
,
1627 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0, NULL
), nid
))
1631 * check that changing any curve parameter fails
1633 * Setting arbitrary p, a or b might fail for some EC_GROUPs
1634 * depending on the internal EC_METHOD implementation, hence run
1635 * these tests conditionally to the success of EC_GROUP_set_curve().
1638 if (EC_GROUP_set_curve(gtest
, other_p
, group_a
, group_b
, NULL
)) {
1639 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest
, 0, NULL
), 0))
1642 /* clear the error stack if EC_GROUP_set_curve() failed */
1646 if (EC_GROUP_set_curve(gtest
, group_p
, other_a
, group_b
, NULL
)) {
1647 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest
, 0, NULL
), 0))
1650 /* clear the error stack if EC_GROUP_set_curve() failed */
1654 if (EC_GROUP_set_curve(gtest
, group_p
, group_a
, other_b
, NULL
)) {
1655 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest
, 0, NULL
), 0))
1658 /* clear the error stack if EC_GROUP_set_curve() failed */
1664 /* Check that restoring the curve parameters passes */
1665 if (!TEST_true(EC_GROUP_set_curve(gtest
, group_p
, group_a
, group_b
, NULL
))
1666 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0, NULL
), nid
))
1677 BN_free(group_cofactor
);
1678 BN_free(other_cofactor
);
1679 BN_free(other_order
);
1680 EC_POINT_free(other_gen
);
1681 EC_GROUP_free(gtest
);
1682 EC_GROUP_free(group
);
1683 BN_CTX_free(bn_ctx
);
1688 * This checks the lookup capability of EC_GROUP_check_named_curve()
1689 * when the given group was created with explicit parameters.
1691 * It is possible to retrieve an alternative alias that does not match
1692 * the original nid in this case.
1694 static int check_named_curve_lookup_test(int id
)
1696 int ret
= 0, nid
, rv
= 0;
1697 EC_GROUP
*g
= NULL
, *ga
= NULL
;
1698 ECPARAMETERS
*p
= NULL
, *pa
= NULL
;
1702 nid
= curves
[id
].nid
;
1703 if (!TEST_ptr(ctx
= BN_CTX_new())
1704 || !TEST_ptr(g
= EC_GROUP_new_by_curve_name(nid
))
1705 || !TEST_ptr(p
= EC_GROUP_get_ecparameters(g
, NULL
)))
1708 /* replace with group from explicit parameters */
1710 if (!TEST_ptr(g
= EC_GROUP_new_from_ecparameters(p
)))
1713 if (!TEST_int_gt(rv
= EC_GROUP_check_named_curve(g
, 0, NULL
), 0))
1718 * fail if the returned nid is not an alias of the original group.
1720 * The comparison here is done by comparing two explicit
1721 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1722 * comparison happens with unnamed EC_GROUPs using the same
1725 if (!TEST_ptr(ga
= EC_GROUP_new_by_curve_name(rv
))
1726 || !TEST_ptr(pa
= EC_GROUP_get_ecparameters(ga
, NULL
)))
1729 /* replace with group from explicit parameters, then compare */
1731 if (!TEST_ptr(ga
= EC_GROUP_new_from_ecparameters(pa
))
1732 || !TEST_int_eq(EC_GROUP_cmp(g
, ga
, ctx
), 0))
1741 ECPARAMETERS_free(p
);
1742 ECPARAMETERS_free(pa
);
1749 * Sometime we cannot compare nids for equality, as the built-in curve table
1750 * includes aliases with different names for the same curve.
1752 * This function returns TRUE (1) if the checked nids are identical, or if they
1753 * alias to the same curve. FALSE (0) otherwise.
1756 int are_ec_nids_compatible(int n1d
, int n2d
)
1760 #ifndef OPENSSL_NO_EC2M
1762 case NID_wap_wsg_idm_ecid_wtls4
:
1763 ret
= (n2d
== NID_sect113r1
|| n2d
== NID_wap_wsg_idm_ecid_wtls4
);
1766 case NID_wap_wsg_idm_ecid_wtls3
:
1767 ret
= (n2d
== NID_sect163k1
|| n2d
== NID_wap_wsg_idm_ecid_wtls3
);
1770 case NID_wap_wsg_idm_ecid_wtls10
:
1771 ret
= (n2d
== NID_sect233k1
|| n2d
== NID_wap_wsg_idm_ecid_wtls10
);
1774 case NID_wap_wsg_idm_ecid_wtls11
:
1775 ret
= (n2d
== NID_sect233r1
|| n2d
== NID_wap_wsg_idm_ecid_wtls11
);
1777 case NID_X9_62_c2pnb163v1
:
1778 case NID_wap_wsg_idm_ecid_wtls5
:
1779 ret
= (n2d
== NID_X9_62_c2pnb163v1
1780 || n2d
== NID_wap_wsg_idm_ecid_wtls5
);
1782 #endif /* OPENSSL_NO_EC2M */
1784 case NID_wap_wsg_idm_ecid_wtls6
:
1785 ret
= (n2d
== NID_secp112r1
|| n2d
== NID_wap_wsg_idm_ecid_wtls6
);
1788 case NID_wap_wsg_idm_ecid_wtls7
:
1789 ret
= (n2d
== NID_secp160r2
|| n2d
== NID_wap_wsg_idm_ecid_wtls7
);
1791 #ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1793 case NID_wap_wsg_idm_ecid_wtls12
:
1794 ret
= (n2d
== NID_secp224r1
|| n2d
== NID_wap_wsg_idm_ecid_wtls12
);
1798 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1799 * that is associated with a specialized method.
1801 case NID_wap_wsg_idm_ecid_wtls12
:
1802 ret
= (n2d
== NID_secp224r1
);
1804 #endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1813 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1814 * EC_GROUP for built-in curves.
1816 * Note that it is possible to retrieve an alternative alias that does not match
1819 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1821 static int check_named_curve_from_ecparameters(int id
)
1823 int ret
= 0, nid
, tnid
;
1824 EC_GROUP
*group
= NULL
, *tgroup
= NULL
, *tmpg
= NULL
;
1825 const EC_POINT
*group_gen
= NULL
;
1826 EC_POINT
*other_gen
= NULL
;
1827 BIGNUM
*group_cofactor
= NULL
, *other_cofactor
= NULL
;
1828 BIGNUM
*other_gen_x
= NULL
, *other_gen_y
= NULL
;
1829 const BIGNUM
*group_order
= NULL
;
1830 BIGNUM
*other_order
= NULL
;
1831 BN_CTX
*bn_ctx
= NULL
;
1832 static const unsigned char invalid_seed
[] = "THIS IS NOT A VALID SEED";
1833 static size_t invalid_seed_len
= sizeof(invalid_seed
);
1834 ECPARAMETERS
*params
= NULL
, *other_params
= NULL
;
1835 EC_GROUP
*g_ary
[8] = {NULL
};
1836 EC_GROUP
**g_next
= &g_ary
[0];
1837 ECPARAMETERS
*p_ary
[8] = {NULL
};
1838 ECPARAMETERS
**p_next
= &p_ary
[0];
1841 nid
= curves
[id
].nid
;
1842 TEST_note("Curve %s", OBJ_nid2sn(nid
));
1843 if (!TEST_ptr(bn_ctx
= BN_CTX_new()))
1845 BN_CTX_start(bn_ctx
);
1847 if (/* Allocations */
1848 !TEST_ptr(group_cofactor
= BN_CTX_get(bn_ctx
))
1849 || !TEST_ptr(other_gen_x
= BN_CTX_get(bn_ctx
))
1850 || !TEST_ptr(other_gen_y
= BN_CTX_get(bn_ctx
))
1851 || !TEST_ptr(other_order
= BN_CTX_get(bn_ctx
))
1852 || !TEST_ptr(other_cofactor
= BN_CTX_get(bn_ctx
))
1853 /* Generate reference group and params */
1854 || !TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
))
1855 || !TEST_ptr(params
= EC_GROUP_get_ecparameters(group
, NULL
))
1856 || !TEST_ptr(group_gen
= EC_GROUP_get0_generator(group
))
1857 || !TEST_ptr(group_order
= EC_GROUP_get0_order(group
))
1858 || !TEST_true(EC_GROUP_get_cofactor(group
, group_cofactor
, NULL
))
1859 /* compute `other_*` values */
1860 || !TEST_ptr(tmpg
= EC_GROUP_dup(group
))
1861 || !TEST_ptr(other_gen
= EC_POINT_dup(group_gen
, group
))
1862 || !TEST_true(EC_POINT_add(group
, other_gen
, group_gen
, group_gen
, NULL
))
1863 || !TEST_true(EC_POINT_get_affine_coordinates(group
, other_gen
,
1864 other_gen_x
, other_gen_y
, bn_ctx
))
1865 || !TEST_true(BN_copy(other_order
, group_order
))
1866 || !TEST_true(BN_add_word(other_order
, 1))
1867 || !TEST_true(BN_copy(other_cofactor
, group_cofactor
))
1868 || !TEST_true(BN_add_word(other_cofactor
, 1)))
1871 EC_POINT_free(other_gen
);
1874 if (!TEST_ptr(other_gen
= EC_POINT_new(tmpg
))
1875 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg
, other_gen
,
1876 other_gen_x
, other_gen_y
,
1881 * ###########################
1882 * # Actual tests start here #
1883 * ###########################
1887 * Creating a group from built-in explicit parameters returns a
1890 if (!TEST_ptr(tgroup
= *g_next
++ = EC_GROUP_new_from_ecparameters(params
))
1891 || !TEST_int_ne((tnid
= EC_GROUP_get_curve_name(tgroup
)), NID_undef
))
1894 * We cannot always guarantee the names match, as the built-in table
1895 * contains aliases for the same curve with different names.
1897 if (!TEST_true(are_ec_nids_compatible(nid
, tnid
))) {
1898 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid
), OBJ_nid2sn(tnid
));
1901 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1902 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup
), OPENSSL_EC_EXPLICIT_CURVE
))
1906 * An invalid seed in the parameters should be ignored: expect a "named"
1909 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg
, invalid_seed
, invalid_seed_len
),
1911 || !TEST_ptr(other_params
= *p_next
++ =
1912 EC_GROUP_get_ecparameters(tmpg
, NULL
))
1913 || !TEST_ptr(tgroup
= *g_next
++ =
1914 EC_GROUP_new_from_ecparameters(other_params
))
1915 || !TEST_int_ne((tnid
= EC_GROUP_get_curve_name(tgroup
)), NID_undef
)
1916 || !TEST_true(are_ec_nids_compatible(nid
, tnid
))
1917 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup
),
1918 OPENSSL_EC_EXPLICIT_CURVE
)) {
1919 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid
), OBJ_nid2sn(tnid
));
1924 * A null seed in the parameters should be ignored, as it is optional:
1925 * expect a "named" group.
1927 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg
, NULL
, 0), 1)
1928 || !TEST_ptr(other_params
= *p_next
++ =
1929 EC_GROUP_get_ecparameters(tmpg
, NULL
))
1930 || !TEST_ptr(tgroup
= *g_next
++ =
1931 EC_GROUP_new_from_ecparameters(other_params
))
1932 || !TEST_int_ne((tnid
= EC_GROUP_get_curve_name(tgroup
)), NID_undef
)
1933 || !TEST_true(are_ec_nids_compatible(nid
, tnid
))
1934 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup
),
1935 OPENSSL_EC_EXPLICIT_CURVE
)) {
1936 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid
), OBJ_nid2sn(tnid
));
1941 * Check that changing any of the generator parameters does not yield a
1942 * match with the built-in curves
1944 if (/* Other gen, same group order & cofactor */
1945 !TEST_true(EC_GROUP_set_generator(tmpg
, other_gen
, group_order
,
1947 || !TEST_ptr(other_params
= *p_next
++ =
1948 EC_GROUP_get_ecparameters(tmpg
, NULL
))
1949 || !TEST_ptr(tgroup
= *g_next
++ =
1950 EC_GROUP_new_from_ecparameters(other_params
))
1951 || !TEST_int_eq((tnid
= EC_GROUP_get_curve_name(tgroup
)), NID_undef
)
1952 /* Same gen & cofactor, different order */
1953 || !TEST_true(EC_GROUP_set_generator(tmpg
, group_gen
, other_order
,
1955 || !TEST_ptr(other_params
= *p_next
++ =
1956 EC_GROUP_get_ecparameters(tmpg
, NULL
))
1957 || !TEST_ptr(tgroup
= *g_next
++ =
1958 EC_GROUP_new_from_ecparameters(other_params
))
1959 || !TEST_int_eq((tnid
= EC_GROUP_get_curve_name(tgroup
)), NID_undef
)
1960 /* The order is not an optional field, so this should fail */
1961 || !TEST_false(EC_GROUP_set_generator(tmpg
, group_gen
, NULL
,
1963 /* Check that a wrong cofactor is ignored, and we still match */
1964 || !TEST_true(EC_GROUP_set_generator(tmpg
, group_gen
, group_order
,
1966 || !TEST_ptr(other_params
= *p_next
++ =
1967 EC_GROUP_get_ecparameters(tmpg
, NULL
))
1968 || !TEST_ptr(tgroup
= *g_next
++ =
1969 EC_GROUP_new_from_ecparameters(other_params
))
1970 || !TEST_int_ne((tnid
= EC_GROUP_get_curve_name(tgroup
)), NID_undef
)
1971 || !TEST_true(are_ec_nids_compatible(nid
, tnid
))
1972 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup
),
1973 OPENSSL_EC_EXPLICIT_CURVE
)
1974 /* Check that if the cofactor is not set then it still matches */
1975 || !TEST_true(EC_GROUP_set_generator(tmpg
, group_gen
, group_order
,
1977 || !TEST_ptr(other_params
= *p_next
++ =
1978 EC_GROUP_get_ecparameters(tmpg
, NULL
))
1979 || !TEST_ptr(tgroup
= *g_next
++ =
1980 EC_GROUP_new_from_ecparameters(other_params
))
1981 || !TEST_int_ne((tnid
= EC_GROUP_get_curve_name(tgroup
)), NID_undef
)
1982 || !TEST_true(are_ec_nids_compatible(nid
, tnid
))
1983 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup
),
1984 OPENSSL_EC_EXPLICIT_CURVE
)
1985 /* check that restoring the generator passes */
1986 || !TEST_true(EC_GROUP_set_generator(tmpg
, group_gen
, group_order
,
1988 || !TEST_ptr(other_params
= *p_next
++ =
1989 EC_GROUP_get_ecparameters(tmpg
, NULL
))
1990 || !TEST_ptr(tgroup
= *g_next
++ =
1991 EC_GROUP_new_from_ecparameters(other_params
))
1992 || !TEST_int_ne((tnid
= EC_GROUP_get_curve_name(tgroup
)), NID_undef
)
1993 || !TEST_true(are_ec_nids_compatible(nid
, tnid
))
1994 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup
),
1995 OPENSSL_EC_EXPLICIT_CURVE
))
2000 for (g_next
= &g_ary
[0]; g_next
< g_ary
+ OSSL_NELEM(g_ary
); g_next
++)
2001 EC_GROUP_free(*g_next
);
2002 for (p_next
= &p_ary
[0]; p_next
< p_ary
+ OSSL_NELEM(g_ary
); p_next
++)
2003 ECPARAMETERS_free(*p_next
);
2004 ECPARAMETERS_free(params
);
2005 EC_POINT_free(other_gen
);
2006 EC_GROUP_free(tmpg
);
2007 EC_GROUP_free(group
);
2009 BN_CTX_free(bn_ctx
);
2014 static int parameter_test(void)
2016 EC_GROUP
*group
= NULL
, *group2
= NULL
;
2017 ECPARAMETERS
*ecparameters
= NULL
;
2018 unsigned char *buf
= NULL
;
2021 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(NID_secp384r1
))
2022 || !TEST_ptr(ecparameters
= EC_GROUP_get_ecparameters(group
, NULL
))
2023 || !TEST_ptr(group2
= EC_GROUP_new_from_ecparameters(ecparameters
))
2024 || !TEST_int_eq(EC_GROUP_cmp(group
, group2
, NULL
), 0))
2027 EC_GROUP_free(group
);
2030 /* Test the named curve encoding, which should be default. */
2031 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(NID_secp521r1
))
2032 || !TEST_true((len
= i2d_ECPKParameters(group
, &buf
)) >= 0)
2033 || !TEST_mem_eq(buf
, len
, p521_named
, sizeof(p521_named
)))
2040 * Test the explicit encoding. P-521 requires correctly zero-padding the
2041 * curve coefficients.
2043 EC_GROUP_set_asn1_flag(group
, OPENSSL_EC_EXPLICIT_CURVE
);
2044 if (!TEST_true((len
= i2d_ECPKParameters(group
, &buf
)) >= 0)
2045 || !TEST_mem_eq(buf
, len
, p521_explicit
, sizeof(p521_explicit
)))
2050 EC_GROUP_free(group
);
2051 EC_GROUP_free(group2
);
2052 ECPARAMETERS_free(ecparameters
);
2058 * random 256-bit explicit parameters curve, cofactor absent
2059 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
2060 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
2062 static const unsigned char params_cf_pass
[] = {
2063 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2064 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
2065 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2066 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2067 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
2068 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2069 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2070 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
2071 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
2072 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
2073 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
2074 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
2075 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
2076 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
2077 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
2078 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
2079 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
2080 0x14, 0xa8, 0x2f, 0x4f
2084 * random 256-bit explicit parameters curve, cofactor absent
2085 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
2086 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
2088 static const unsigned char params_cf_fail
[] = {
2089 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2090 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
2091 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2092 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2093 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
2094 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2095 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2096 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
2097 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
2098 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
2099 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
2100 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
2101 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
2102 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
2103 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
2104 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
2105 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
2106 0x34, 0xa2, 0x21, 0x01
2110 * Test two random 256-bit explicit parameters curves with absent cofactor.
2111 * The two curves are chosen to roughly straddle the bounds at which the lib
2112 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
2114 * - params_cf_pass: order is sufficiently close to p to compute cofactor
2115 * - params_cf_fail: order is too far away from p to compute cofactor
2117 * For standards-compliant curves, cofactor is chosen as small as possible.
2118 * So you can see neither of these curves are fit for cryptographic use.
2120 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
2121 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
2122 * will always succeed in computing the cofactor. Neither of these curves
2123 * conform to that -- this is just robustness testing.
2125 static int cofactor_range_test(void)
2127 EC_GROUP
*group
= NULL
;
2130 const unsigned char *b1
= (const unsigned char *)params_cf_fail
;
2131 const unsigned char *b2
= (const unsigned char *)params_cf_pass
;
2133 if (!TEST_ptr(group
= d2i_ECPKParameters(NULL
, &b1
, sizeof(params_cf_fail
)))
2134 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group
))
2135 || !TEST_ptr(group
= d2i_ECPKParameters(&group
, &b2
,
2136 sizeof(params_cf_pass
)))
2137 || !TEST_int_gt(BN_hex2bn(&cf
, "12bc94785251297abfafddf1565100da"), 0)
2138 || !TEST_BN_eq(cf
, EC_GROUP_get0_cofactor(group
)))
2143 EC_GROUP_free(group
);
2148 * For named curves, test that:
2149 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
2150 * - a nonsensical cofactor throws an error (negative test)
2151 * - nonsensical orders throw errors (negative tests)
2153 static int cardinality_test(int n
)
2155 int ret
= 0, is_binary
= 0;
2156 int nid
= curves
[n
].nid
;
2158 EC_GROUP
*g1
= NULL
, *g2
= NULL
;
2159 EC_POINT
*g2_gen
= NULL
;
2160 BIGNUM
*g1_p
= NULL
, *g1_a
= NULL
, *g1_b
= NULL
, *g1_x
= NULL
, *g1_y
= NULL
,
2161 *g1_order
= NULL
, *g1_cf
= NULL
, *g2_cf
= NULL
;
2163 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid
));
2165 if (!TEST_ptr(ctx
= BN_CTX_new())
2166 || !TEST_ptr(g1
= EC_GROUP_new_by_curve_name(nid
))) {
2171 is_binary
= (EC_GROUP_get_field_type(g1
) == NID_X9_62_characteristic_two_field
);
2174 g1_p
= BN_CTX_get(ctx
);
2175 g1_a
= BN_CTX_get(ctx
);
2176 g1_b
= BN_CTX_get(ctx
);
2177 g1_x
= BN_CTX_get(ctx
);
2178 g1_y
= BN_CTX_get(ctx
);
2179 g1_order
= BN_CTX_get(ctx
);
2180 g1_cf
= BN_CTX_get(ctx
);
2182 if (!TEST_ptr(g2_cf
= BN_CTX_get(ctx
))
2183 /* pull out the explicit curve parameters */
2184 || !TEST_true(EC_GROUP_get_curve(g1
, g1_p
, g1_a
, g1_b
, ctx
))
2185 || !TEST_true(EC_POINT_get_affine_coordinates(g1
,
2186 EC_GROUP_get0_generator(g1
), g1_x
, g1_y
, ctx
))
2187 || !TEST_true(BN_copy(g1_order
, EC_GROUP_get0_order(g1
)))
2188 || !TEST_true(EC_GROUP_get_cofactor(g1
, g1_cf
, ctx
))
2189 /* construct g2 manually with g1 parameters */
2190 #ifndef OPENSSL_NO_EC2M
2191 || !TEST_ptr(g2
= (is_binary
) ?
2192 EC_GROUP_new_curve_GF2m(g1_p
, g1_a
, g1_b
, ctx
) :
2193 EC_GROUP_new_curve_GFp(g1_p
, g1_a
, g1_b
, ctx
))
2195 || !TEST_int_eq(0, is_binary
)
2196 || !TEST_ptr(g2
= EC_GROUP_new_curve_GFp(g1_p
, g1_a
, g1_b
, ctx
))
2198 || !TEST_ptr(g2_gen
= EC_POINT_new(g2
))
2199 || !TEST_true(EC_POINT_set_affine_coordinates(g2
, g2_gen
, g1_x
, g1_y
, ctx
))
2200 /* pass NULL cofactor: lib should compute it */
2201 || !TEST_true(EC_GROUP_set_generator(g2
, g2_gen
, g1_order
, NULL
))
2202 || !TEST_true(EC_GROUP_get_cofactor(g2
, g2_cf
, ctx
))
2203 || !TEST_BN_eq(g1_cf
, g2_cf
)
2204 /* pass zero cofactor: lib should compute it */
2205 || !TEST_true(BN_set_word(g2_cf
, 0))
2206 || !TEST_true(EC_GROUP_set_generator(g2
, g2_gen
, g1_order
, g2_cf
))
2207 || !TEST_true(EC_GROUP_get_cofactor(g2
, g2_cf
, ctx
))
2208 || !TEST_BN_eq(g1_cf
, g2_cf
)
2209 /* negative test for invalid cofactor */
2210 || !TEST_true(BN_set_word(g2_cf
, 0))
2211 || !TEST_true(BN_sub(g2_cf
, g2_cf
, BN_value_one()))
2212 || !TEST_false(EC_GROUP_set_generator(g2
, g2_gen
, g1_order
, g2_cf
))
2213 /* negative test for NULL order */
2214 || !TEST_false(EC_GROUP_set_generator(g2
, g2_gen
, NULL
, NULL
))
2215 /* negative test for zero order */
2216 || !TEST_true(BN_set_word(g1_order
, 0))
2217 || !TEST_false(EC_GROUP_set_generator(g2
, g2_gen
, g1_order
, NULL
))
2218 /* negative test for negative order */
2219 || !TEST_true(BN_set_word(g2_cf
, 0))
2220 || !TEST_true(BN_sub(g2_cf
, g2_cf
, BN_value_one()))
2221 || !TEST_false(EC_GROUP_set_generator(g2
, g2_gen
, g1_order
, NULL
))
2222 /* negative test for too large order */
2223 || !TEST_true(BN_lshift(g1_order
, g1_p
, 2))
2224 || !TEST_false(EC_GROUP_set_generator(g2
, g2_gen
, g1_order
, NULL
)))
2228 EC_POINT_free(g2_gen
);
2236 static int check_ec_key_field_public_range_test(int id
)
2238 int ret
= 0, type
= 0;
2239 const EC_POINT
*pub
= NULL
;
2240 const EC_GROUP
*group
= NULL
;
2241 const BIGNUM
*field
= NULL
;
2242 BIGNUM
*x
= NULL
, *y
= NULL
;
2245 if (!TEST_ptr(x
= BN_new())
2246 || !TEST_ptr(y
= BN_new())
2247 || !TEST_ptr(key
= EC_KEY_new_by_curve_name(curves
[id
].nid
))
2248 || !TEST_ptr(group
= EC_KEY_get0_group(key
))
2249 || !TEST_ptr(field
= EC_GROUP_get0_field(group
))
2250 || !TEST_int_gt(EC_KEY_generate_key(key
), 0)
2251 || !TEST_int_gt(EC_KEY_check_key(key
), 0)
2252 || !TEST_ptr(pub
= EC_KEY_get0_public_key(key
))
2253 || !TEST_int_gt(EC_POINT_get_affine_coordinates(group
, pub
, x
, y
,
2258 * Make the public point out of range by adding the field (which will still
2259 * be the same point on the curve). The add is different for char2 fields.
2261 type
= EC_GROUP_get_field_type(group
);
2262 #ifndef OPENSSL_NO_EC2M
2263 if (type
== NID_X9_62_characteristic_two_field
) {
2264 /* test for binary curves */
2265 if (!TEST_true(BN_GF2m_add(x
, x
, field
)))
2269 if (type
== NID_X9_62_prime_field
) {
2270 /* test for prime curves */
2271 if (!TEST_true(BN_add(x
, x
, field
)))
2274 /* this should never happen */
2275 TEST_error("Unsupported EC_METHOD field_type");
2278 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key
, x
, y
), 0))
2290 * Helper for ec_point_hex2point_test
2292 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2295 * If P is NULL use point at infinity.
2298 int ec_point_hex2point_test_helper(const EC_GROUP
*group
, const EC_POINT
*P
,
2299 point_conversion_form_t form
,
2303 EC_POINT
*Q
= NULL
, *Pinf
= NULL
;
2307 /* If P is NULL use point at infinity. */
2308 if (!TEST_ptr(Pinf
= EC_POINT_new(group
))
2309 || !TEST_true(EC_POINT_set_to_infinity(group
, Pinf
)))
2314 if (!TEST_ptr(hex
= EC_POINT_point2hex(group
, P
, form
, bnctx
))
2315 || !TEST_ptr(Q
= EC_POINT_hex2point(group
, hex
, NULL
, bnctx
))
2316 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, bnctx
)))
2320 * The next check is most likely superfluous, as EC_POINT_cmp should already
2322 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2323 * so we include it anyway!
2326 && !TEST_true(EC_POINT_is_at_infinity(group
, Q
)))
2332 EC_POINT_free(Pinf
);
2340 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2342 static int ec_point_hex2point_test(int id
)
2345 EC_GROUP
*group
= NULL
;
2346 const EC_POINT
*G
= NULL
;
2348 BN_CTX
* bnctx
= NULL
;
2351 nid
= curves
[id
].nid
;
2352 if (!TEST_ptr(bnctx
= BN_CTX_new())
2353 || !TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
))
2354 || !TEST_ptr(G
= EC_GROUP_get0_generator(group
))
2355 || !TEST_ptr(P
= EC_POINT_dup(G
, group
)))
2358 if (!TEST_true(ec_point_hex2point_test_helper(group
, P
,
2359 POINT_CONVERSION_COMPRESSED
,
2361 || !TEST_true(ec_point_hex2point_test_helper(group
, NULL
,
2362 POINT_CONVERSION_COMPRESSED
,
2364 || !TEST_true(ec_point_hex2point_test_helper(group
, P
,
2365 POINT_CONVERSION_UNCOMPRESSED
,
2367 || !TEST_true(ec_point_hex2point_test_helper(group
, NULL
,
2368 POINT_CONVERSION_UNCOMPRESSED
,
2370 || !TEST_true(ec_point_hex2point_test_helper(group
, P
,
2371 POINT_CONVERSION_HYBRID
,
2373 || !TEST_true(ec_point_hex2point_test_helper(group
, NULL
,
2374 POINT_CONVERSION_HYBRID
,
2382 EC_GROUP_free(group
);
2388 static int do_test_custom_explicit_fromdata(EC_GROUP
*group
, BN_CTX
*ctx
,
2389 unsigned char *gen
, int gen_size
)
2392 EVP_PKEY_CTX
*pctx
= NULL
;
2393 EVP_PKEY
*pkeyparam
= NULL
;
2394 OSSL_PARAM_BLD
*bld
= NULL
;
2395 const char *field_name
;
2396 OSSL_PARAM
*params
= NULL
;
2397 const OSSL_PARAM
*gettable
;
2399 BIGNUM
*p_out
= NULL
, *a_out
= NULL
, *b_out
= NULL
;
2400 BIGNUM
*order_out
= NULL
, *cofactor_out
= NULL
;
2402 unsigned char buf
[1024];
2403 size_t buf_len
, name_len
;
2404 #ifndef OPENSSL_NO_EC2M
2405 unsigned int k1
= 0, k2
= 0, k3
= 0;
2406 const char *basis_name
= NULL
;
2409 p
= BN_CTX_get(ctx
);
2410 a
= BN_CTX_get(ctx
);
2411 b
= BN_CTX_get(ctx
);
2414 || !TEST_ptr(bld
= OSSL_PARAM_BLD_new()))
2417 if (EC_GROUP_get_field_type(group
) == NID_X9_62_prime_field
) {
2418 field_name
= SN_X9_62_prime_field
;
2420 field_name
= SN_X9_62_characteristic_two_field
;
2421 #ifndef OPENSSL_NO_EC2M
2422 if (EC_GROUP_get_basis_type(group
) == NID_X9_62_tpBasis
) {
2423 basis_name
= SN_X9_62_tpBasis
;
2424 if (!TEST_true(EC_GROUP_get_trinomial_basis(group
, &k1
)))
2427 basis_name
= SN_X9_62_ppBasis
;
2428 if (!TEST_true(EC_GROUP_get_pentanomial_basis(group
, &k1
, &k2
, &k3
)))
2431 #endif /* OPENSSL_NO_EC2M */
2433 if (!TEST_true(EC_GROUP_get_curve(group
, p
, a
, b
, ctx
))
2434 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld
,
2435 OSSL_PKEY_PARAM_EC_FIELD_TYPE
, field_name
, 0))
2436 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld
, OSSL_PKEY_PARAM_EC_P
, p
))
2437 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld
, OSSL_PKEY_PARAM_EC_A
, a
))
2438 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld
, OSSL_PKEY_PARAM_EC_B
, b
)))
2441 if (EC_GROUP_get0_seed(group
) != NULL
) {
2442 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld
,
2443 OSSL_PKEY_PARAM_EC_SEED
, EC_GROUP_get0_seed(group
),
2444 EC_GROUP_get_seed_len(group
))))
2447 if (EC_GROUP_get0_cofactor(group
) != NULL
) {
2448 if (!TEST_true(OSSL_PARAM_BLD_push_BN(bld
, OSSL_PKEY_PARAM_EC_COFACTOR
,
2449 EC_GROUP_get0_cofactor(group
))))
2453 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld
,
2454 OSSL_PKEY_PARAM_EC_GENERATOR
, gen
, gen_size
))
2455 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld
, OSSL_PKEY_PARAM_EC_ORDER
,
2456 EC_GROUP_get0_order(group
))))
2459 if (!TEST_ptr(params
= OSSL_PARAM_BLD_to_param(bld
))
2460 || !TEST_ptr(pctx
= EVP_PKEY_CTX_new_from_name(NULL
, "EC", NULL
))
2461 || !TEST_int_gt(EVP_PKEY_fromdata_init(pctx
), 0)
2462 || !TEST_int_gt(EVP_PKEY_fromdata(pctx
, &pkeyparam
,
2463 EVP_PKEY_KEY_PARAMETERS
, params
), 0))
2466 /*- Check that all the set values are retrievable -*/
2468 /* There should be no match to a group name since the generator changed */
2469 if (!TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam
,
2470 OSSL_PKEY_PARAM_GROUP_NAME
, name
, sizeof(name
),
2474 /* The encoding should be explicit as it has no group */
2475 if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam
,
2476 OSSL_PKEY_PARAM_EC_ENCODING
,
2477 name
, sizeof(name
), &name_len
))
2478 || !TEST_str_eq(name
, OSSL_PKEY_EC_ENCODING_EXPLICIT
))
2481 if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam
,
2482 OSSL_PKEY_PARAM_EC_FIELD_TYPE
, name
, sizeof(name
),
2484 || !TEST_str_eq(name
, field_name
))
2487 if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam
,
2488 OSSL_PKEY_PARAM_EC_GENERATOR
, buf
, sizeof(buf
), &buf_len
))
2489 || !TEST_mem_eq(buf
, (int)buf_len
, gen
, gen_size
))
2492 if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam
, OSSL_PKEY_PARAM_EC_P
, &p_out
))
2493 || !TEST_BN_eq(p_out
, p
)
2494 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam
, OSSL_PKEY_PARAM_EC_A
,
2496 || !TEST_BN_eq(a_out
, a
)
2497 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam
, OSSL_PKEY_PARAM_EC_B
,
2499 || !TEST_BN_eq(b_out
, b
)
2500 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam
, OSSL_PKEY_PARAM_EC_ORDER
,
2502 || !TEST_BN_eq(order_out
, EC_GROUP_get0_order(group
)))
2505 if (EC_GROUP_get0_cofactor(group
) != NULL
) {
2506 if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam
,
2507 OSSL_PKEY_PARAM_EC_COFACTOR
, &cofactor_out
))
2508 || !TEST_BN_eq(cofactor_out
, EC_GROUP_get0_cofactor(group
)))
2511 if (EC_GROUP_get0_seed(group
) != NULL
) {
2512 if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam
,
2513 OSSL_PKEY_PARAM_EC_SEED
, buf
, sizeof(buf
), &buf_len
))
2514 || !TEST_mem_eq(buf
, buf_len
, EC_GROUP_get0_seed(group
),
2515 EC_GROUP_get_seed_len(group
)))
2519 if (EC_GROUP_get_field_type(group
) == NID_X9_62_prime_field
) {
2520 /* No extra fields should be set for a prime field */
2521 if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam
,
2522 OSSL_PKEY_PARAM_EC_CHAR2_M
, &i_out
))
2523 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam
,
2524 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS
, &i_out
))
2525 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam
,
2526 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1
, &i_out
))
2527 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam
,
2528 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2
, &i_out
))
2529 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam
,
2530 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3
, &i_out
))
2531 || !TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam
,
2532 OSSL_PKEY_PARAM_EC_CHAR2_TYPE
, name
, sizeof(name
),
2536 #ifndef OPENSSL_NO_EC2M
2537 if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam
,
2538 OSSL_PKEY_PARAM_EC_CHAR2_M
, &i_out
))
2539 || !TEST_int_eq(EC_GROUP_get_degree(group
), i_out
)
2540 || !TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam
,
2541 OSSL_PKEY_PARAM_EC_CHAR2_TYPE
, name
, sizeof(name
),
2543 || !TEST_str_eq(name
, basis_name
))
2546 if (EC_GROUP_get_basis_type(group
) == NID_X9_62_tpBasis
) {
2547 if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam
,
2548 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS
, &i_out
))
2549 || !TEST_int_eq(k1
, i_out
)
2550 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam
,
2551 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1
, &i_out
))
2552 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam
,
2553 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2
, &i_out
))
2554 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam
,
2555 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3
, &i_out
)))
2558 if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam
,
2559 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS
, &i_out
))
2560 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam
,
2561 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1
, &i_out
))
2562 || !TEST_int_eq(k1
, i_out
)
2563 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam
,
2564 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2
, &i_out
))
2565 || !TEST_int_eq(k2
, i_out
)
2566 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam
,
2567 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3
, &i_out
))
2568 || !TEST_int_eq(k3
, i_out
))
2571 #endif /* OPENSSL_NO_EC2M */
2573 if (!TEST_ptr(gettable
= EVP_PKEY_gettable_params(pkeyparam
))
2574 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_GROUP_NAME
))
2575 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_ENCODING
))
2576 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_FIELD_TYPE
))
2577 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_P
))
2578 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_A
))
2579 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_B
))
2580 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_GENERATOR
))
2581 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_ORDER
))
2582 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_COFACTOR
))
2583 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_SEED
))
2584 #ifndef OPENSSL_NO_EC2M
2585 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_CHAR2_M
))
2586 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_CHAR2_TYPE
))
2587 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS
))
2588 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_CHAR2_PP_K1
))
2589 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_CHAR2_PP_K2
))
2590 || !TEST_ptr(OSSL_PARAM_locate_const(gettable
, OSSL_PKEY_PARAM_EC_CHAR2_PP_K3
))
2597 BN_free(cofactor_out
);
2601 OSSL_PARAM_free(params
);
2602 OSSL_PARAM_BLD_free(bld
);
2603 EVP_PKEY_free(pkeyparam
);
2604 EVP_PKEY_CTX_free(pctx
);
2609 * check the EC_METHOD respects the supplied EC_GROUP_set_generator G
2611 static int custom_generator_test(int id
)
2613 int ret
= 0, nid
, bsize
;
2614 EC_GROUP
*group
= NULL
;
2615 EC_POINT
*G2
= NULL
, *Q1
= NULL
, *Q2
= NULL
;
2618 unsigned char *b1
= NULL
, *b2
= NULL
;
2621 nid
= curves
[id
].nid
;
2622 TEST_note("Curve %s", OBJ_nid2sn(nid
));
2623 if (!TEST_ptr(ctx
= BN_CTX_new()))
2628 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
)))
2631 /* expected byte length of encoded points */
2632 bsize
= (EC_GROUP_get_degree(group
) + 7) / 8;
2633 bsize
= 1 + 2 * bsize
; /* UNCOMPRESSED_POINT format */
2635 if (!TEST_ptr(k
= BN_CTX_get(ctx
))
2636 /* fetch a testing scalar k != 0,1 */
2637 || !TEST_true(BN_rand(k
, EC_GROUP_order_bits(group
) - 1,
2638 BN_RAND_TOP_ONE
, BN_RAND_BOTTOM_ANY
))
2640 || !TEST_true(BN_clear_bit(k
, 0))
2641 || !TEST_ptr(G2
= EC_POINT_new(group
))
2642 || !TEST_ptr(Q1
= EC_POINT_new(group
))
2644 || !TEST_true(EC_POINT_mul(group
, Q1
, k
, NULL
, NULL
, ctx
))
2645 /* pull out the bytes of that */
2646 || !TEST_int_eq(EC_POINT_point2oct(group
, Q1
,
2647 POINT_CONVERSION_UNCOMPRESSED
, NULL
,
2649 || !TEST_ptr(b1
= OPENSSL_malloc(bsize
))
2650 || !TEST_int_eq(EC_POINT_point2oct(group
, Q1
,
2651 POINT_CONVERSION_UNCOMPRESSED
, b1
,
2653 /* new generator is G2 := 2G */
2654 || !TEST_true(EC_POINT_dbl(group
, G2
, EC_GROUP_get0_generator(group
),
2656 || !TEST_true(EC_GROUP_set_generator(group
, G2
,
2657 EC_GROUP_get0_order(group
),
2658 EC_GROUP_get0_cofactor(group
)))
2659 || !TEST_ptr(Q2
= EC_POINT_new(group
))
2660 || !TEST_true(BN_rshift1(k
, k
))
2662 || !TEST_true(EC_POINT_mul(group
, Q2
, k
, NULL
, NULL
, ctx
))
2663 || !TEST_int_eq(EC_POINT_point2oct(group
, Q2
,
2664 POINT_CONVERSION_UNCOMPRESSED
, NULL
,
2666 || !TEST_ptr(b2
= OPENSSL_malloc(bsize
))
2667 || !TEST_int_eq(EC_POINT_point2oct(group
, Q2
,
2668 POINT_CONVERSION_UNCOMPRESSED
, b2
,
2670 /* Q1 = kG = k/2 G2 = Q2 should hold */
2671 || !TEST_mem_eq(b1
, bsize
, b2
, bsize
))
2674 if (!do_test_custom_explicit_fromdata(group
, ctx
, b1
, bsize
))
2683 EC_GROUP_free(group
);
2693 * check creation of curves from explicit params through the public API
2695 static int custom_params_test(int id
)
2697 int ret
= 0, nid
, bsize
;
2698 const char *curve_name
= NULL
;
2699 EC_GROUP
*group
= NULL
, *altgroup
= NULL
;
2700 EC_POINT
*G2
= NULL
, *Q1
= NULL
, *Q2
= NULL
;
2701 const EC_POINT
*Q
= NULL
;
2704 unsigned char *buf1
= NULL
, *buf2
= NULL
;
2705 const BIGNUM
*z
= NULL
, *cof
= NULL
, *priv1
= NULL
;
2706 BIGNUM
*p
= NULL
, *a
= NULL
, *b
= NULL
;
2708 EC_KEY
*eckey1
= NULL
, *eckey2
= NULL
;
2709 EVP_PKEY
*pkey1
= NULL
, *pkey2
= NULL
;
2710 EVP_PKEY_CTX
*pctx1
= NULL
, *pctx2
= NULL
;
2712 unsigned char *pub1
= NULL
, *pub2
= NULL
;
2713 OSSL_PARAM_BLD
*param_bld
= NULL
;
2714 OSSL_PARAM
*params1
= NULL
, *params2
= NULL
;
2717 nid
= curves
[id
].nid
;
2718 curve_name
= OBJ_nid2sn(nid
);
2719 TEST_note("Curve %s", curve_name
);
2722 return TEST_skip("custom params not supported with SM2");
2724 if (!TEST_ptr(ctx
= BN_CTX_new()))
2727 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
)))
2730 is_prime
= EC_GROUP_get_field_type(group
) == NID_X9_62_prime_field
;
2731 #ifdef OPENSSL_NO_EC2M
2733 ret
= TEST_skip("binary curves not supported in this build");
2739 if (!TEST_ptr(p
= BN_CTX_get(ctx
))
2740 || !TEST_ptr(a
= BN_CTX_get(ctx
))
2741 || !TEST_ptr(b
= BN_CTX_get(ctx
))
2742 || !TEST_ptr(k
= BN_CTX_get(ctx
)))
2745 /* expected byte length of encoded points */
2746 bsize
= (EC_GROUP_get_degree(group
) + 7) / 8;
2747 bsize
= 1 + 2 * bsize
; /* UNCOMPRESSED_POINT format */
2749 /* extract parameters from built-in curve */
2750 if (!TEST_true(EC_GROUP_get_curve(group
, p
, a
, b
, ctx
))
2751 || !TEST_ptr(G2
= EC_POINT_new(group
))
2752 /* new generator is G2 := 2G */
2753 || !TEST_true(EC_POINT_dbl(group
, G2
,
2754 EC_GROUP_get0_generator(group
), ctx
))
2755 /* pull out the bytes of that */
2756 || !TEST_int_eq(EC_POINT_point2oct(group
, G2
,
2757 POINT_CONVERSION_UNCOMPRESSED
,
2758 NULL
, 0, ctx
), bsize
)
2759 || !TEST_ptr(buf1
= OPENSSL_malloc(bsize
))
2760 || !TEST_int_eq(EC_POINT_point2oct(group
, G2
,
2761 POINT_CONVERSION_UNCOMPRESSED
,
2762 buf1
, bsize
, ctx
), bsize
)
2763 || !TEST_ptr(z
= EC_GROUP_get0_order(group
))
2764 || !TEST_ptr(cof
= EC_GROUP_get0_cofactor(group
))
2768 /* create a new group using same params (but different generator) */
2770 if (!TEST_ptr(altgroup
= EC_GROUP_new_curve_GFp(p
, a
, b
, ctx
)))
2773 #ifndef OPENSSL_NO_EC2M
2775 if (!TEST_ptr(altgroup
= EC_GROUP_new_curve_GF2m(p
, a
, b
, ctx
)))
2780 /* set 2*G as the generator of altgroup */
2781 EC_POINT_free(G2
); /* discard G2 as it refers to the original group */
2782 if (!TEST_ptr(G2
= EC_POINT_new(altgroup
))
2783 || !TEST_true(EC_POINT_oct2point(altgroup
, G2
, buf1
, bsize
, ctx
))
2784 || !TEST_int_eq(EC_POINT_is_on_curve(altgroup
, G2
, ctx
), 1)
2785 || !TEST_true(EC_GROUP_set_generator(altgroup
, G2
, z
, cof
))
2789 /* verify math checks out */
2790 if (/* allocate temporary points on group and altgroup */
2791 !TEST_ptr(Q1
= EC_POINT_new(group
))
2792 || !TEST_ptr(Q2
= EC_POINT_new(altgroup
))
2793 /* fetch a testing scalar k != 0,1 */
2794 || !TEST_true(BN_rand(k
, EC_GROUP_order_bits(group
) - 1,
2795 BN_RAND_TOP_ONE
, BN_RAND_BOTTOM_ANY
))
2797 || !TEST_true(BN_clear_bit(k
, 0))
2798 /* Q1 := kG on group */
2799 || !TEST_true(EC_POINT_mul(group
, Q1
, k
, NULL
, NULL
, ctx
))
2800 /* pull out the bytes of that */
2801 || !TEST_int_eq(EC_POINT_point2oct(group
, Q1
,
2802 POINT_CONVERSION_UNCOMPRESSED
,
2803 NULL
, 0, ctx
), bsize
)
2804 || !TEST_int_eq(EC_POINT_point2oct(group
, Q1
,
2805 POINT_CONVERSION_UNCOMPRESSED
,
2806 buf1
, bsize
, ctx
), bsize
)
2808 || !TEST_true(BN_rshift1(k
, k
))
2809 /* Q2 := k/2 G2 on altgroup */
2810 || !TEST_true(EC_POINT_mul(altgroup
, Q2
, k
, NULL
, NULL
, ctx
))
2811 /* pull out the bytes of that */
2812 || !TEST_int_eq(EC_POINT_point2oct(altgroup
, Q2
,
2813 POINT_CONVERSION_UNCOMPRESSED
,
2814 NULL
, 0, ctx
), bsize
)
2815 || !TEST_ptr(buf2
= OPENSSL_malloc(bsize
))
2816 || !TEST_int_eq(EC_POINT_point2oct(altgroup
, Q2
,
2817 POINT_CONVERSION_UNCOMPRESSED
,
2818 buf2
, bsize
, ctx
), bsize
)
2819 /* Q1 = kG = k/2 G2 = Q2 should hold */
2820 || !TEST_mem_eq(buf1
, bsize
, buf2
, bsize
))
2823 /* create two `EC_KEY`s on altgroup */
2824 if (!TEST_ptr(eckey1
= EC_KEY_new())
2825 || !TEST_true(EC_KEY_set_group(eckey1
, altgroup
))
2826 || !TEST_true(EC_KEY_generate_key(eckey1
))
2827 || !TEST_ptr(eckey2
= EC_KEY_new())
2828 || !TEST_true(EC_KEY_set_group(eckey2
, altgroup
))
2829 || !TEST_true(EC_KEY_generate_key(eckey2
)))
2832 /* retrieve priv1 for later */
2833 if (!TEST_ptr(priv1
= EC_KEY_get0_private_key(eckey1
)))
2837 * retrieve bytes for pub1 for later
2839 * We compute the pub key in the original group as we will later use it to
2840 * define a provider key in the built-in group.
2842 if (!TEST_true(EC_POINT_mul(group
, Q1
, priv1
, NULL
, NULL
, ctx
))
2843 || !TEST_int_eq(EC_POINT_point2oct(group
, Q1
,
2844 POINT_CONVERSION_UNCOMPRESSED
,
2845 NULL
, 0, ctx
), bsize
)
2846 || !TEST_ptr(pub1
= OPENSSL_malloc(bsize
))
2847 || !TEST_int_eq(EC_POINT_point2oct(group
, Q1
,
2848 POINT_CONVERSION_UNCOMPRESSED
,
2849 pub1
, bsize
, ctx
), bsize
))
2852 /* retrieve bytes for pub2 for later */
2853 if (!TEST_ptr(Q
= EC_KEY_get0_public_key(eckey2
))
2854 || !TEST_int_eq(EC_POINT_point2oct(altgroup
, Q
,
2855 POINT_CONVERSION_UNCOMPRESSED
,
2856 NULL
, 0, ctx
), bsize
)
2857 || !TEST_ptr(pub2
= OPENSSL_malloc(bsize
))
2858 || !TEST_int_eq(EC_POINT_point2oct(altgroup
, Q
,
2859 POINT_CONVERSION_UNCOMPRESSED
,
2860 pub2
, bsize
, ctx
), bsize
))
2863 /* create two `EVP_PKEY`s from the `EC_KEY`s */
2864 if(!TEST_ptr(pkey1
= EVP_PKEY_new())
2865 || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey1
, eckey1
), 1))
2867 eckey1
= NULL
; /* ownership passed to pkey1 */
2868 if(!TEST_ptr(pkey2
= EVP_PKEY_new())
2869 || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey2
, eckey2
), 1))
2871 eckey2
= NULL
; /* ownership passed to pkey2 */
2873 /* Compute keyexchange in both directions */
2874 if (!TEST_ptr(pctx1
= EVP_PKEY_CTX_new(pkey1
, NULL
))
2875 || !TEST_int_eq(EVP_PKEY_derive_init(pctx1
), 1)
2876 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1
, pkey2
), 1)
2877 || !TEST_int_eq(EVP_PKEY_derive(pctx1
, NULL
, &sslen
), 1)
2878 || !TEST_int_gt(bsize
, sslen
)
2879 || !TEST_int_eq(EVP_PKEY_derive(pctx1
, buf1
, &sslen
), 1))
2881 if (!TEST_ptr(pctx2
= EVP_PKEY_CTX_new(pkey2
, NULL
))
2882 || !TEST_int_eq(EVP_PKEY_derive_init(pctx2
), 1)
2883 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx2
, pkey1
), 1)
2884 || !TEST_int_eq(EVP_PKEY_derive(pctx2
, NULL
, &t
), 1)
2885 || !TEST_int_gt(bsize
, t
)
2886 || !TEST_int_le(sslen
, t
)
2887 || !TEST_int_eq(EVP_PKEY_derive(pctx2
, buf2
, &t
), 1))
2890 /* Both sides should expect the same shared secret */
2891 if (!TEST_mem_eq(buf1
, sslen
, buf2
, t
))
2894 /* Build parameters for provider-native keys */
2895 if (!TEST_ptr(param_bld
= OSSL_PARAM_BLD_new())
2896 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld
,
2897 OSSL_PKEY_PARAM_GROUP_NAME
,
2899 || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld
,
2900 OSSL_PKEY_PARAM_PUB_KEY
,
2902 || !TEST_true(OSSL_PARAM_BLD_push_BN(param_bld
,
2903 OSSL_PKEY_PARAM_PRIV_KEY
,
2905 || !TEST_ptr(params1
= OSSL_PARAM_BLD_to_param(param_bld
)))
2908 OSSL_PARAM_BLD_free(param_bld
);
2909 if (!TEST_ptr(param_bld
= OSSL_PARAM_BLD_new())
2910 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld
,
2911 OSSL_PKEY_PARAM_GROUP_NAME
,
2913 || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld
,
2914 OSSL_PKEY_PARAM_PUB_KEY
,
2916 || !TEST_ptr(params2
= OSSL_PARAM_BLD_to_param(param_bld
)))
2919 /* create two new provider-native `EVP_PKEY`s */
2920 EVP_PKEY_CTX_free(pctx2
);
2921 if (!TEST_ptr(pctx2
= EVP_PKEY_CTX_new_from_name(NULL
, "EC", NULL
))
2922 || !TEST_true(EVP_PKEY_fromdata_init(pctx2
))
2923 || !TEST_true(EVP_PKEY_fromdata(pctx2
, &pkey1
, EVP_PKEY_KEYPAIR
,
2925 || !TEST_true(EVP_PKEY_fromdata(pctx2
, &pkey2
, EVP_PKEY_PUBLIC_KEY
,
2929 /* compute keyexchange once more using the provider keys */
2930 EVP_PKEY_CTX_free(pctx1
);
2931 if (!TEST_ptr(pctx1
= EVP_PKEY_CTX_new(pkey1
, NULL
))
2932 || !TEST_int_eq(EVP_PKEY_derive_init(pctx1
), 1)
2933 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1
, pkey2
), 1)
2934 || !TEST_int_eq(EVP_PKEY_derive(pctx1
, NULL
, &t
), 1)
2935 || !TEST_int_gt(bsize
, t
)
2936 || !TEST_int_le(sslen
, t
)
2937 || !TEST_int_eq(EVP_PKEY_derive(pctx1
, buf1
, &t
), 1)
2938 /* compare with previous result */
2939 || !TEST_mem_eq(buf1
, t
, buf2
, sslen
))
2947 OSSL_PARAM_BLD_free(param_bld
);
2948 OSSL_PARAM_free(params1
);
2949 OSSL_PARAM_free(params2
);
2953 EC_GROUP_free(group
);
2954 EC_GROUP_free(altgroup
);
2959 EC_KEY_free(eckey1
);
2960 EC_KEY_free(eckey2
);
2961 EVP_PKEY_free(pkey1
);
2962 EVP_PKEY_free(pkey2
);
2963 EVP_PKEY_CTX_free(pctx1
);
2964 EVP_PKEY_CTX_free(pctx2
);
2969 int setup_tests(void)
2971 crv_len
= EC_get_builtin_curves(NULL
, 0);
2972 if (!TEST_ptr(curves
= OPENSSL_malloc(sizeof(*curves
) * crv_len
))
2973 || !TEST_true(EC_get_builtin_curves(curves
, crv_len
)))
2976 ADD_TEST(parameter_test
);
2977 ADD_TEST(cofactor_range_test
);
2978 ADD_ALL_TESTS(cardinality_test
, crv_len
);
2979 ADD_TEST(prime_field_tests
);
2980 #ifndef OPENSSL_NO_EC2M
2981 ADD_TEST(hybrid_point_encoding_test
);
2982 ADD_TEST(char2_field_tests
);
2983 ADD_ALL_TESTS(char2_curve_test
, OSSL_NELEM(char2_curve_tests
));
2985 ADD_ALL_TESTS(nistp_single_test
, OSSL_NELEM(nistp_tests_params
));
2986 ADD_ALL_TESTS(internal_curve_test
, crv_len
);
2987 ADD_ALL_TESTS(internal_curve_test_method
, crv_len
);
2988 ADD_TEST(group_field_test
);
2989 ADD_ALL_TESTS(check_named_curve_test
, crv_len
);
2990 ADD_ALL_TESTS(check_named_curve_lookup_test
, crv_len
);
2991 ADD_ALL_TESTS(check_ec_key_field_public_range_test
, crv_len
);
2992 ADD_ALL_TESTS(check_named_curve_from_ecparameters
, crv_len
);
2993 ADD_ALL_TESTS(ec_point_hex2point_test
, crv_len
);
2994 ADD_ALL_TESTS(custom_generator_test
, crv_len
);
2995 ADD_ALL_TESTS(custom_params_test
, crv_len
);
2999 void cleanup_tests(void)
3001 OPENSSL_free(curves
);