2 * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
12 #include "internal/nelem.h"
16 # include <openssl/ec.h>
17 # ifndef OPENSSL_NO_ENGINE
18 # include <openssl/engine.h>
20 # include <openssl/err.h>
21 # include <openssl/obj_mac.h>
22 # include <openssl/objects.h>
23 # include <openssl/rand.h>
24 # include <openssl/bn.h>
25 # include <openssl/opensslconf.h>
27 static size_t crv_len
= 0;
28 static EC_builtin_curve
*curves
= NULL
;
30 /* test multiplication with group order, long and negative scalars */
31 static int group_order_tests(EC_GROUP
*group
)
33 BIGNUM
*n1
= NULL
, *n2
= NULL
, *order
= NULL
;
34 EC_POINT
*P
= NULL
, *Q
= NULL
, *R
= NULL
, *S
= NULL
;
35 const EC_POINT
*G
= NULL
;
39 if (!TEST_ptr(n1
= BN_new())
40 || !TEST_ptr(n2
= BN_new())
41 || !TEST_ptr(order
= BN_new())
42 || !TEST_ptr(ctx
= BN_CTX_new())
43 || !TEST_ptr(G
= EC_GROUP_get0_generator(group
))
44 || !TEST_ptr(P
= EC_POINT_new(group
))
45 || !TEST_ptr(Q
= EC_POINT_new(group
))
46 || !TEST_ptr(R
= EC_POINT_new(group
))
47 || !TEST_ptr(S
= EC_POINT_new(group
)))
50 if (!TEST_true(EC_GROUP_get_order(group
, order
, ctx
))
51 || !TEST_true(EC_POINT_mul(group
, Q
, order
, NULL
, NULL
, ctx
))
52 || !TEST_true(EC_POINT_is_at_infinity(group
, Q
))
53 || !TEST_true(EC_GROUP_precompute_mult(group
, ctx
))
54 || !TEST_true(EC_POINT_mul(group
, Q
, order
, NULL
, NULL
, ctx
))
55 || !TEST_true(EC_POINT_is_at_infinity(group
, Q
))
56 || !TEST_true(EC_POINT_copy(P
, G
))
57 || !TEST_true(BN_one(n1
))
58 || !TEST_true(EC_POINT_mul(group
, Q
, n1
, NULL
, NULL
, ctx
))
59 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
))
60 || !TEST_true(BN_sub(n1
, order
, n1
))
61 || !TEST_true(EC_POINT_mul(group
, Q
, n1
, NULL
, NULL
, ctx
))
62 || !TEST_true(EC_POINT_invert(group
, Q
, ctx
))
63 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
)))
66 for (i
= 1; i
<= 2; i
++) {
67 const BIGNUM
*scalars
[6];
68 const EC_POINT
*points
[6];
70 if (!TEST_true(BN_set_word(n1
, i
))
72 * If i == 1, P will be the predefined generator for which
73 * EC_GROUP_precompute_mult has set up precomputation.
75 || !TEST_true(EC_POINT_mul(group
, P
, n1
, NULL
, NULL
, ctx
))
76 || (i
== 1 && !TEST_int_eq(0, EC_POINT_cmp(group
, P
, G
, ctx
)))
77 || !TEST_true(BN_one(n1
))
79 || !TEST_true(BN_sub(n1
, n1
, order
))
80 || !TEST_true(EC_POINT_mul(group
, Q
, NULL
, P
, n1
, ctx
))
81 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
))
84 || !TEST_true(BN_add(n2
, order
, BN_value_one()))
85 || !TEST_true(EC_POINT_mul(group
, Q
, NULL
, P
, n2
, ctx
))
86 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
))
88 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
89 || !TEST_true(BN_mul(n2
, n1
, n2
, ctx
))
90 || !TEST_true(EC_POINT_mul(group
, Q
, NULL
, P
, n2
, ctx
))
91 || !TEST_int_eq(0, EC_POINT_cmp(group
, Q
, P
, ctx
)))
94 /* n2 = order^2 - 1 */
95 BN_set_negative(n2
, 0);
96 if (!TEST_true(EC_POINT_mul(group
, Q
, NULL
, P
, n2
, ctx
))
97 /* Add P to verify the result. */
98 || !TEST_true(EC_POINT_add(group
, Q
, Q
, P
, ctx
))
99 || !TEST_true(EC_POINT_is_at_infinity(group
, Q
))
101 /* Exercise EC_POINTs_mul, including corner cases. */
102 || !TEST_false(EC_POINT_is_at_infinity(group
, P
)))
105 scalars
[0] = scalars
[1] = BN_value_one();
106 points
[0] = points
[1] = P
;
108 if (!TEST_true(EC_POINTs_mul(group
, R
, NULL
, 2, points
, scalars
, ctx
))
109 || !TEST_true(EC_POINT_dbl(group
, S
, points
[0], ctx
))
110 || !TEST_int_eq(0, EC_POINT_cmp(group
, R
, S
, ctx
)))
114 points
[0] = Q
; /* => infinity */
116 points
[1] = P
; /* => -P */
118 points
[2] = Q
; /* => infinity */
120 points
[3] = Q
; /* => infinity */
122 points
[4] = P
; /* => P */
124 points
[5] = Q
; /* => infinity */
125 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 6, points
, scalars
, ctx
))
126 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
132 if (r
== 0 && i
!= 0)
133 TEST_info(i
== 1 ? "allowing precomputation" :
134 "without precomputation");
146 static int prime_field_tests(void)
149 BIGNUM
*p
= NULL
, *a
= NULL
, *b
= NULL
, *scalar3
= NULL
;
150 EC_GROUP
*group
= NULL
, *tmp
= NULL
;
151 EC_GROUP
*P_160
= NULL
, *P_192
= NULL
, *P_224
= NULL
,
152 *P_256
= NULL
, *P_384
= NULL
, *P_521
= NULL
;
153 EC_POINT
*P
= NULL
, *Q
= NULL
, *R
= NULL
;
154 BIGNUM
*x
= NULL
, *y
= NULL
, *z
= NULL
, *yplusone
= NULL
;
155 const EC_POINT
*points
[4];
156 const BIGNUM
*scalars
[4];
157 unsigned char buf
[100];
161 if (!TEST_ptr(ctx
= BN_CTX_new())
162 || !TEST_ptr(p
= BN_new())
163 || !TEST_ptr(a
= BN_new())
164 || !TEST_ptr(b
= BN_new())
165 || !TEST_true(BN_hex2bn(&p
, "17"))
166 || !TEST_true(BN_hex2bn(&a
, "1"))
167 || !TEST_true(BN_hex2bn(&b
, "1"))
169 * applications should use EC_GROUP_new_curve_GFp so
170 * that the library gets to choose the EC_METHOD
172 || !TEST_ptr(group
= EC_GROUP_new(EC_GFp_mont_method()))
173 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
174 || !TEST_ptr(tmp
= EC_GROUP_new(EC_GROUP_method_of(group
)))
175 || !TEST_true(EC_GROUP_copy(tmp
, group
)))
177 EC_GROUP_free(group
);
181 if (!TEST_true(EC_GROUP_get_curve(group
, p
, a
, b
, ctx
)))
184 TEST_info("Curve defined by Weierstrass equation");
185 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
186 test_output_bignum("a", a
);
187 test_output_bignum("b", b
);
188 test_output_bignum("p", p
);
191 if (!TEST_ptr(P
= EC_POINT_new(group
))
192 || !TEST_ptr(Q
= EC_POINT_new(group
))
193 || !TEST_ptr(R
= EC_POINT_new(group
))
194 || !TEST_true(EC_POINT_set_to_infinity(group
, P
))
195 || !TEST_true(EC_POINT_is_at_infinity(group
, P
))
196 || !TEST_true(EC_POINT_oct2point(group
, Q
, buf
, 1, ctx
))
197 || !TEST_true(EC_POINT_add(group
, P
, P
, Q
, ctx
))
198 || !TEST_true(EC_POINT_is_at_infinity(group
, P
))
199 || !TEST_ptr(x
= BN_new())
200 || !TEST_ptr(y
= BN_new())
201 || !TEST_ptr(z
= BN_new())
202 || !TEST_ptr(yplusone
= BN_new())
203 || !TEST_true(BN_hex2bn(&x
, "D"))
204 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, Q
, x
, 1, ctx
)))
207 if (!TEST_int_gt(EC_POINT_is_on_curve(group
, Q
, ctx
), 0)) {
208 if (!TEST_true(EC_POINT_get_affine_coordinates(group
, Q
, x
, y
, ctx
)))
210 TEST_info("Point is not on curve");
211 test_output_bignum("x", x
);
212 test_output_bignum("y", y
);
216 TEST_note("A cyclic subgroup:");
219 if (!TEST_int_ne(k
--, 0))
222 if (EC_POINT_is_at_infinity(group
, P
)) {
223 TEST_note(" point at infinity");
225 if (!TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
,
229 test_output_bignum("x", x
);
230 test_output_bignum("y", y
);
233 if (!TEST_true(EC_POINT_copy(R
, P
))
234 || !TEST_true(EC_POINT_add(group
, P
, P
, Q
, ctx
)))
237 } while (!EC_POINT_is_at_infinity(group
, P
));
239 if (!TEST_true(EC_POINT_add(group
, P
, Q
, R
, ctx
))
240 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
244 EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_COMPRESSED
, buf
,
246 if (!TEST_size_t_ne(len
, 0)
247 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
248 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
250 test_output_memory("Generator as octet string, compressed form:",
253 len
= EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_UNCOMPRESSED
,
254 buf
, sizeof(buf
), ctx
);
255 if (!TEST_size_t_ne(len
, 0)
256 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
257 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
259 test_output_memory("Generator as octet string, uncompressed form:",
262 len
= EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_HYBRID
,
263 buf
, sizeof(buf
), ctx
);
264 if (!TEST_size_t_ne(len
, 0)
265 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
266 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
268 test_output_memory("Generator as octet string, hybrid form:",
271 if (!TEST_true(EC_POINT_get_Jprojective_coordinates_GFp(group
, R
, x
, y
, z
,
274 TEST_info("A representation of the inverse of that generator in");
275 TEST_note("Jacobian projective coordinates");
276 test_output_bignum("x", x
);
277 test_output_bignum("y", y
);
278 test_output_bignum("z", z
);
280 if (!TEST_true(EC_POINT_invert(group
, P
, ctx
))
281 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, R
, ctx
))
284 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
285 * 2000) -- not a NIST curve, but commonly used
288 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFF"
289 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
290 || !TEST_int_eq(1, BN_is_prime_ex(p
, BN_prime_checks
, ctx
, NULL
))
291 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFF"
292 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
293 || !TEST_true(BN_hex2bn(&b
, "1C97BEFC"
294 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
295 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
296 || !TEST_true(BN_hex2bn(&x
, "4A96B568"
297 "8EF573284664698968C38BB913CBFC82"))
298 || !TEST_true(BN_hex2bn(&y
, "23a62855"
299 "3168947d59dcc912042351377ac5fb32"))
300 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
302 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
303 * and therefore setting the coordinates should fail.
305 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
307 || !TEST_true(EC_POINT_set_affine_coordinates(group
, P
, x
, y
, ctx
))
308 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
309 || !TEST_true(BN_hex2bn(&z
, "0100000000"
310 "000000000001F4C8F927AED3CA752257"))
311 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
312 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
314 TEST_info("SEC2 curve secp160r1 -- Generator");
315 test_output_bignum("x", x
);
316 test_output_bignum("y", y
);
317 /* G_y value taken from the standard: */
318 if (!TEST_true(BN_hex2bn(&z
, "23a62855"
319 "3168947d59dcc912042351377ac5fb32"))
321 || !TEST_int_eq(EC_GROUP_get_degree(group
), 160)
322 || !group_order_tests(group
)
323 || !TEST_ptr(P_160
= EC_GROUP_new(EC_GROUP_method_of(group
)))
324 || !TEST_true(EC_GROUP_copy(P_160
, group
))
326 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
328 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFFFFFFFFFF"
329 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
330 || !TEST_int_eq(1, BN_is_prime_ex(p
, BN_prime_checks
, ctx
, NULL
))
331 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFFFFFFFFFF"
332 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
333 || !TEST_true(BN_hex2bn(&b
, "64210519E59C80E7"
334 "0FA7E9AB72243049FEB8DEECC146B9B1"))
335 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
336 || !TEST_true(BN_hex2bn(&x
, "188DA80EB03090F6"
337 "7CBF20EB43A18800F4FF0AFD82FF1012"))
338 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 1, ctx
))
339 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
340 || !TEST_true(BN_hex2bn(&z
, "FFFFFFFFFFFFFFFF"
341 "FFFFFFFF99DEF836146BC9B1B4D22831"))
342 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
343 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
346 TEST_info("NIST curve P-192 -- Generator");
347 test_output_bignum("x", x
);
348 test_output_bignum("y", y
);
349 /* G_y value taken from the standard: */
350 if (!TEST_true(BN_hex2bn(&z
, "07192B95FFC8DA78"
351 "631011ED6B24CDD573F977A11E794811"))
353 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
355 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
356 * and therefore setting the coordinates should fail.
358 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
360 || !TEST_int_eq(EC_GROUP_get_degree(group
), 192)
361 || !group_order_tests(group
)
362 || !TEST_ptr(P_192
= EC_GROUP_new(EC_GROUP_method_of(group
)))
363 || !TEST_true(EC_GROUP_copy(P_192
, group
))
365 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
367 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFFFFFFFFFFFFFFFFFF"
368 "FFFFFFFF000000000000000000000001"))
369 || !TEST_int_eq(1, BN_is_prime_ex(p
, BN_prime_checks
, ctx
, NULL
))
370 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFFFFFFFFFFFFFFFFFF"
371 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
372 || !TEST_true(BN_hex2bn(&b
, "B4050A850C04B3ABF5413256"
373 "5044B0B7D7BFD8BA270B39432355FFB4"))
374 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
375 || !TEST_true(BN_hex2bn(&x
, "B70E0CBD6BB4BF7F321390B9"
376 "4A03C1D356C21122343280D6115C1D21"))
377 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 0, ctx
))
378 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
379 || !TEST_true(BN_hex2bn(&z
, "FFFFFFFFFFFFFFFFFFFFFFFF"
380 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
381 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
382 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
385 TEST_info("NIST curve P-224 -- Generator");
386 test_output_bignum("x", x
);
387 test_output_bignum("y", y
);
388 /* G_y value taken from the standard: */
389 if (!TEST_true(BN_hex2bn(&z
, "BD376388B5F723FB4C22DFE6"
390 "CD4375A05A07476444D5819985007E34"))
392 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
394 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
395 * and therefore setting the coordinates should fail.
397 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
399 || !TEST_int_eq(EC_GROUP_get_degree(group
), 224)
400 || !group_order_tests(group
)
401 || !TEST_ptr(P_224
= EC_GROUP_new(EC_GROUP_method_of(group
)))
402 || !TEST_true(EC_GROUP_copy(P_224
, group
))
404 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
406 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFF000000010000000000000000"
407 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
408 || !TEST_int_eq(1, BN_is_prime_ex(p
, BN_prime_checks
, ctx
, NULL
))
409 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFF000000010000000000000000"
410 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
411 || !TEST_true(BN_hex2bn(&b
, "5AC635D8AA3A93E7B3EBBD55769886BC"
412 "651D06B0CC53B0F63BCE3C3E27D2604B"))
413 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
415 || !TEST_true(BN_hex2bn(&x
, "6B17D1F2E12C4247F8BCE6E563A440F2"
416 "77037D812DEB33A0F4A13945D898C296"))
417 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 1, ctx
))
418 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
419 || !TEST_true(BN_hex2bn(&z
, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
420 "BCE6FAADA7179E84F3B9CAC2FC632551"))
421 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
422 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
425 TEST_info("NIST curve P-256 -- Generator");
426 test_output_bignum("x", x
);
427 test_output_bignum("y", y
);
428 /* G_y value taken from the standard: */
429 if (!TEST_true(BN_hex2bn(&z
, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
430 "2BCE33576B315ECECBB6406837BF51F5"))
432 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
434 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
435 * and therefore setting the coordinates should fail.
437 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
439 || !TEST_int_eq(EC_GROUP_get_degree(group
), 256)
440 || !group_order_tests(group
)
441 || !TEST_ptr(P_256
= EC_GROUP_new(EC_GROUP_method_of(group
)))
442 || !TEST_true(EC_GROUP_copy(P_256
, group
))
444 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
446 || !TEST_true(BN_hex2bn(&p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
447 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
448 "FFFFFFFF0000000000000000FFFFFFFF"))
449 || !TEST_int_eq(1, BN_is_prime_ex(p
, BN_prime_checks
, ctx
, NULL
))
450 || !TEST_true(BN_hex2bn(&a
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
451 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
452 "FFFFFFFF0000000000000000FFFFFFFC"))
453 || !TEST_true(BN_hex2bn(&b
, "B3312FA7E23EE7E4988E056BE3F82D19"
454 "181D9C6EFE8141120314088F5013875A"
455 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
456 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
458 || !TEST_true(BN_hex2bn(&x
, "AA87CA22BE8B05378EB1C71EF320AD74"
459 "6E1D3B628BA79B9859F741E082542A38"
460 "5502F25DBF55296C3A545E3872760AB7"))
461 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 1, ctx
))
462 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
463 || !TEST_true(BN_hex2bn(&z
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
464 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
465 "581A0DB248B0A77AECEC196ACCC52973"))
466 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
467 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
470 TEST_info("NIST curve P-384 -- Generator");
471 test_output_bignum("x", x
);
472 test_output_bignum("y", y
);
473 /* G_y value taken from the standard: */
474 if (!TEST_true(BN_hex2bn(&z
, "3617DE4A96262C6F5D9E98BF9292DC29"
475 "F8F41DBD289A147CE9DA3113B5F0B8C0"
476 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
478 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
480 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
481 * and therefore setting the coordinates should fail.
483 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
485 || !TEST_int_eq(EC_GROUP_get_degree(group
), 384)
486 || !group_order_tests(group
)
487 || !TEST_ptr(P_384
= EC_GROUP_new(EC_GROUP_method_of(group
)))
488 || !TEST_true(EC_GROUP_copy(P_384
, group
))
490 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
491 || !TEST_true(BN_hex2bn(&p
, "1FF"
492 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
493 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
494 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
495 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
496 || !TEST_int_eq(1, BN_is_prime_ex(p
, BN_prime_checks
, ctx
, NULL
))
497 || !TEST_true(BN_hex2bn(&a
, "1FF"
498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
500 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
501 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
502 || !TEST_true(BN_hex2bn(&b
, "051"
503 "953EB9618E1C9A1F929A21A0B68540EE"
504 "A2DA725B99B315F3B8B489918EF109E1"
505 "56193951EC7E937B1652C0BD3BB1BF07"
506 "3573DF883D2C34F1EF451FD46B503F00"))
507 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
508 || !TEST_true(BN_hex2bn(&x
, "C6"
509 "858E06B70404E9CD9E3ECB662395B442"
510 "9C648139053FB521F828AF606B4D3DBA"
511 "A14B5E77EFE75928FE1DC127A2FFA8DE"
512 "3348B3C1856A429BF97E7E31C2E5BD66"))
513 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
, 0, ctx
))
514 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
515 || !TEST_true(BN_hex2bn(&z
, "1FF"
516 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
517 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
518 "51868783BF2F966B7FCC0148F709A5D0"
519 "3BB5C9B8899C47AEBB6FB71E91386409"))
520 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, BN_value_one()))
521 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
524 TEST_info("NIST curve P-521 -- Generator");
525 test_output_bignum("x", x
);
526 test_output_bignum("y", y
);
527 /* G_y value taken from the standard: */
528 if (!TEST_true(BN_hex2bn(&z
, "118"
529 "39296A789A3BC0045C8A5FB42C7D1BD9"
530 "98F54449579B446817AFBD17273E662C"
531 "97EE72995EF42640C550B9013FAD0761"
532 "353C7086A272C24088BE94769FD16650"))
534 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
536 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
537 * and therefore setting the coordinates should fail.
539 || !TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
,
541 || !TEST_int_eq(EC_GROUP_get_degree(group
), 521)
542 || !group_order_tests(group
)
543 || !TEST_ptr(P_521
= EC_GROUP_new(EC_GROUP_method_of(group
)))
544 || !TEST_true(EC_GROUP_copy(P_521
, group
))
546 /* more tests using the last curve */
548 /* Restore the point that got mangled in the (x, y + 1) test. */
549 || !TEST_true(EC_POINT_set_affine_coordinates(group
, P
, x
, y
, ctx
))
550 || !TEST_true(EC_POINT_copy(Q
, P
))
551 || !TEST_false(EC_POINT_is_at_infinity(group
, Q
))
552 || !TEST_true(EC_POINT_dbl(group
, P
, P
, ctx
))
553 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
554 || !TEST_true(EC_POINT_invert(group
, Q
, ctx
)) /* P = -2Q */
555 || !TEST_true(EC_POINT_add(group
, R
, P
, Q
, ctx
))
556 || !TEST_true(EC_POINT_add(group
, R
, R
, Q
, ctx
))
557 || !TEST_true(EC_POINT_is_at_infinity(group
, R
)) /* R = P + 2Q */
558 || !TEST_false(EC_POINT_is_at_infinity(group
, Q
)))
565 if (!TEST_true(EC_GROUP_get_order(group
, z
, ctx
))
566 || !TEST_true(BN_add(y
, z
, BN_value_one()))
568 || !TEST_true(BN_rshift1(y
, y
)))
570 scalars
[0] = y
; /* (group order + 1)/2, so y*Q + y*Q = Q */
573 TEST_note("combined multiplication ...");
575 /* z is still the group order */
576 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 2, points
, scalars
, ctx
))
577 || !TEST_true(EC_POINTs_mul(group
, R
, z
, 2, points
, scalars
, ctx
))
578 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, R
, ctx
))
579 || !TEST_int_eq(0, EC_POINT_cmp(group
, R
, Q
, ctx
))
580 || !TEST_true(BN_rand(y
, BN_num_bits(y
), 0, 0))
581 || !TEST_true(BN_add(z
, z
, y
)))
583 BN_set_negative(z
, 1);
585 scalars
[1] = z
; /* z = -(order + y) */
587 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 2, points
, scalars
, ctx
))
588 || !TEST_true(EC_POINT_is_at_infinity(group
, P
))
589 || !TEST_true(BN_rand(x
, BN_num_bits(y
) - 1, 0, 0))
590 || !TEST_true(BN_add(z
, x
, y
)))
592 BN_set_negative(z
, 1);
595 scalars
[2] = z
; /* z = -(x+y) */
597 if (!TEST_ptr(scalar3
= BN_new()))
600 scalars
[3] = scalar3
;
602 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 4, points
, scalars
, ctx
))
603 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
615 EC_GROUP_free(group
);
626 EC_GROUP_free(P_160
);
627 EC_GROUP_free(P_192
);
628 EC_GROUP_free(P_224
);
629 EC_GROUP_free(P_256
);
630 EC_GROUP_free(P_384
);
631 EC_GROUP_free(P_521
);
635 # ifndef OPENSSL_NO_EC2M
637 static struct c2_curve_test
{
648 } char2_curve_tests
[] = {
649 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
652 "0800000000000000000000000000000000000000C9",
655 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
656 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
657 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
659 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
662 "0800000000000000000000000000000000000000C9",
664 "020A601907B8C953CA1481EB10512F78744A3205FD",
665 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
666 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
667 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
669 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
672 "020000000000000000000000000000000000000004000000000000000001",
675 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
676 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
678 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
681 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
684 "020000000000000000000000000000000000000004000000000000000001",
685 "000000000000000000000000000000000000000000000000000000000001",
686 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
687 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
688 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
690 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
693 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
697 "00000000000000000000000000000000000000000000000000000000000010A1",
701 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
703 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
706 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
709 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
713 "00000000000000000000000000000000000000000000000000000000000010A1",
715 "0000000000000000000000000000000000000000000000000000000000000001",
717 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
719 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
721 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
724 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
727 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
730 "0200000000000000000000000000000000000000"
731 "0000000000000000000000000000000000000000008000000000000000000001",
734 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
735 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
736 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
737 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
739 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
740 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
743 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
746 "0200000000000000000000000000000000000000"
747 "0000000000000000000000000000000000000000008000000000000000000001",
748 "0000000000000000000000000000000000000000"
749 "0000000000000000000000000000000000000000000000000000000000000001",
750 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
751 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
752 "015D4860D088DDB3496B0C6064756260441CDE4A"
753 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
754 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
755 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
757 "0100000000000000000000000000000000000000"
758 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
761 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
765 "0000000000000000000000000000000000000000000000000000000000000000"
766 "0000000000000000000000000000000000000000000000000000000000000425",
770 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
771 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
773 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
774 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
777 "00000000000000000000000000000000000000000000000000000000131850E1"
778 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
781 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
785 "0000000000000000000000000000000000000000000000000000000000000000"
786 "0000000000000000000000000000000000000000000000000000000000000425",
788 "0000000000000000000000000000000000000000000000000000000000000000"
789 "0000000000000000000000000000000000000000000000000000000000000001",
791 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
792 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
794 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
795 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
797 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
798 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
801 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
802 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
807 static int char2_curve_test(int n
)
811 BIGNUM
*p
= NULL
, *a
= NULL
, *b
= NULL
;
812 BIGNUM
*x
= NULL
, *y
= NULL
, *z
= NULL
, *cof
= NULL
, *yplusone
= NULL
;
813 EC_GROUP
*group
= NULL
, *variable
= NULL
;
814 EC_POINT
*P
= NULL
, *Q
= NULL
, *R
= NULL
;
815 const EC_POINT
*points
[3];
816 const BIGNUM
*scalars
[3];
817 struct c2_curve_test
*const test
= char2_curve_tests
+ n
;
819 if (!TEST_ptr(ctx
= BN_CTX_new())
820 || !TEST_ptr(p
= BN_new())
821 || !TEST_ptr(a
= BN_new())
822 || !TEST_ptr(b
= BN_new())
823 || !TEST_ptr(x
= BN_new())
824 || !TEST_ptr(y
= BN_new())
825 || !TEST_ptr(z
= BN_new())
826 || !TEST_ptr(yplusone
= BN_new())
827 || !TEST_true(BN_hex2bn(&p
, test
->p
))
828 || !TEST_true(BN_hex2bn(&a
, test
->a
))
829 || !TEST_true(BN_hex2bn(&b
, test
->b
))
830 || !TEST_true(group
= EC_GROUP_new(EC_GF2m_simple_method()))
831 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
832 || !TEST_ptr(P
= EC_POINT_new(group
))
833 || !TEST_ptr(Q
= EC_POINT_new(group
))
834 || !TEST_ptr(R
= EC_POINT_new(group
))
835 || !TEST_true(BN_hex2bn(&x
, test
->x
))
836 || !TEST_true(BN_hex2bn(&y
, test
->y
))
837 || !TEST_true(BN_add(yplusone
, y
, BN_value_one())))
840 /* Change test based on whether binary point compression is enabled or not. */
841 # ifdef OPENSSL_EC_BIN_PT_COMP
843 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
844 * and therefore setting the coordinates should fail.
846 if (!TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
, ctx
))
847 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, P
, x
,
850 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
851 || !TEST_true(BN_hex2bn(&z
, test
->order
))
852 || !TEST_true(BN_hex2bn(&cof
, test
->cof
))
853 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, cof
))
854 || !TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
, ctx
)))
856 TEST_info("%s -- Generator", test
->name
);
857 test_output_bignum("x", x
);
858 test_output_bignum("y", y
);
859 /* G_y value taken from the standard: */
860 if (!TEST_true(BN_hex2bn(&z
, test
->y
))
861 || !TEST_BN_eq(y
, z
))
865 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
866 * and therefore setting the coordinates should fail.
868 if (!TEST_false(EC_POINT_set_affine_coordinates(group
, P
, x
, yplusone
, ctx
))
869 || !TEST_true(EC_POINT_set_affine_coordinates(group
, P
, x
, y
, ctx
))
870 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
871 || !TEST_true(BN_hex2bn(&z
, test
->order
))
872 || !TEST_true(BN_hex2bn(&cof
, test
->cof
))
873 || !TEST_true(EC_GROUP_set_generator(group
, P
, z
, cof
)))
875 TEST_info("%s -- Generator:", test
->name
);
876 test_output_bignum("x", x
);
877 test_output_bignum("y", y
);
880 if (!TEST_int_eq(EC_GROUP_get_degree(group
), test
->degree
)
881 || !group_order_tests(group
)
882 || !TEST_ptr(variable
= EC_GROUP_new(EC_GROUP_method_of(group
)))
883 || !TEST_true(EC_GROUP_copy(variable
, group
)))
886 /* more tests using the last curve */
887 if (n
== OSSL_NELEM(char2_curve_tests
) - 1) {
888 if (!TEST_true(EC_POINT_set_affine_coordinates(group
, P
, x
, y
, ctx
))
889 || !TEST_true(EC_POINT_copy(Q
, P
))
890 || !TEST_false(EC_POINT_is_at_infinity(group
, Q
))
891 || !TEST_true(EC_POINT_dbl(group
, P
, P
, ctx
))
892 || !TEST_int_gt(EC_POINT_is_on_curve(group
, P
, ctx
), 0)
893 || !TEST_true(EC_POINT_invert(group
, Q
, ctx
)) /* P = -2Q */
894 || !TEST_true(EC_POINT_add(group
, R
, P
, Q
, ctx
))
895 || !TEST_true(EC_POINT_add(group
, R
, R
, Q
, ctx
))
896 || !TEST_true(EC_POINT_is_at_infinity(group
, R
)) /* R = P + 2Q */
897 || !TEST_false(EC_POINT_is_at_infinity(group
, Q
)))
904 if (!TEST_true(BN_add(y
, z
, BN_value_one()))
906 || !TEST_true(BN_rshift1(y
, y
)))
908 scalars
[0] = y
; /* (group order + 1)/2, so y*Q + y*Q = Q */
911 TEST_note("combined multiplication ...");
913 /* z is still the group order */
914 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 2, points
, scalars
, ctx
))
915 || !TEST_true(EC_POINTs_mul(group
, R
, z
, 2, points
, scalars
, ctx
))
916 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, R
, ctx
))
917 || !TEST_int_eq(0, EC_POINT_cmp(group
, R
, Q
, ctx
)))
920 if (!TEST_true(BN_rand(y
, BN_num_bits(y
), 0, 0))
921 || !TEST_true(BN_add(z
, z
, y
)))
923 BN_set_negative(z
, 1);
925 scalars
[1] = z
; /* z = -(order + y) */
927 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 2, points
, scalars
, ctx
))
928 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
931 if (!TEST_true(BN_rand(x
, BN_num_bits(y
) - 1, 0, 0))
932 || !TEST_true(BN_add(z
, x
, y
)))
934 BN_set_negative(z
, 1);
937 scalars
[2] = z
; /* z = -(x+y) */
939 if (!TEST_true(EC_POINTs_mul(group
, P
, NULL
, 3, points
, scalars
, ctx
))
940 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
958 EC_GROUP_free(group
);
959 EC_GROUP_free(variable
);
963 static int char2_field_tests(void)
966 BIGNUM
*p
= NULL
, *a
= NULL
, *b
= NULL
;
967 EC_GROUP
*group
= NULL
, *tmp
= NULL
;
968 EC_POINT
*P
= NULL
, *Q
= NULL
, *R
= NULL
;
969 BIGNUM
*x
= NULL
, *y
= NULL
, *z
= NULL
, *cof
= NULL
, *yplusone
= NULL
;
970 unsigned char buf
[100];
974 if (!TEST_ptr(ctx
= BN_CTX_new())
975 || !TEST_ptr(p
= BN_new())
976 || !TEST_ptr(a
= BN_new())
977 || !TEST_ptr(b
= BN_new())
978 || !TEST_true(BN_hex2bn(&p
, "13"))
979 || !TEST_true(BN_hex2bn(&a
, "3"))
980 || !TEST_true(BN_hex2bn(&b
, "1")))
983 group
= EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
984 * EC_GROUP_new_curve_GF2m
985 * so that the library gets
986 * to choose the EC_METHOD */
988 || !TEST_true(EC_GROUP_set_curve(group
, p
, a
, b
, ctx
))
989 || !TEST_ptr(tmp
= EC_GROUP_new(EC_GROUP_method_of(group
)))
990 || !TEST_true(EC_GROUP_copy(tmp
, group
)))
992 EC_GROUP_free(group
);
996 if (!TEST_true(EC_GROUP_get_curve(group
, p
, a
, b
, ctx
)))
999 TEST_info("Curve defined by Weierstrass equation");
1000 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
1001 test_output_bignum("a", a
);
1002 test_output_bignum("b", b
);
1003 test_output_bignum("p", p
);
1005 if (!TEST_ptr(P
= EC_POINT_new(group
))
1006 || !TEST_ptr(Q
= EC_POINT_new(group
))
1007 || !TEST_ptr(R
= EC_POINT_new(group
))
1008 || !TEST_true(EC_POINT_set_to_infinity(group
, P
))
1009 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
1013 if (!TEST_true(EC_POINT_oct2point(group
, Q
, buf
, 1, ctx
))
1014 || !TEST_true(EC_POINT_add(group
, P
, P
, Q
, ctx
))
1015 || !TEST_true(EC_POINT_is_at_infinity(group
, P
))
1016 || !TEST_ptr(x
= BN_new())
1017 || !TEST_ptr(y
= BN_new())
1018 || !TEST_ptr(z
= BN_new())
1019 || !TEST_ptr(cof
= BN_new())
1020 || !TEST_ptr(yplusone
= BN_new())
1021 || !TEST_true(BN_hex2bn(&x
, "6"))
1022 /* Change test based on whether binary point compression is enabled or not. */
1023 # ifdef OPENSSL_EC_BIN_PT_COMP
1024 || !TEST_true(EC_POINT_set_compressed_coordinates(group
, Q
, x
, 1, ctx
))
1026 || !TEST_true(BN_hex2bn(&y
, "8"))
1027 || !TEST_true(EC_POINT_set_affine_coordinates(group
, Q
, x
, y
, ctx
))
1031 if (!TEST_int_gt(EC_POINT_is_on_curve(group
, Q
, ctx
), 0)) {
1032 /* Change test based on whether binary point compression is enabled or not. */
1033 # ifdef OPENSSL_EC_BIN_PT_COMP
1034 if (!TEST_true(EC_POINT_get_affine_coordinates(group
, Q
, x
, y
, ctx
)))
1037 TEST_info("Point is not on curve");
1038 test_output_bignum("x", x
);
1039 test_output_bignum("y", y
);
1043 TEST_note("A cyclic subgroup:");
1046 if (!TEST_int_ne(k
--, 0))
1049 if (EC_POINT_is_at_infinity(group
, P
))
1050 TEST_note(" point at infinity");
1052 if (!TEST_true(EC_POINT_get_affine_coordinates(group
, P
, x
, y
,
1056 test_output_bignum("x", x
);
1057 test_output_bignum("y", y
);
1060 if (!TEST_true(EC_POINT_copy(R
, P
))
1061 || !TEST_true(EC_POINT_add(group
, P
, P
, Q
, ctx
)))
1064 while (!EC_POINT_is_at_infinity(group
, P
));
1066 if (!TEST_true(EC_POINT_add(group
, P
, Q
, R
, ctx
))
1067 || !TEST_true(EC_POINT_is_at_infinity(group
, P
)))
1070 /* Change test based on whether binary point compression is enabled or not. */
1071 # ifdef OPENSSL_EC_BIN_PT_COMP
1072 len
= EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_COMPRESSED
,
1073 buf
, sizeof(buf
), ctx
);
1074 if (!TEST_size_t_ne(len
, 0)
1075 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
1076 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
1078 test_output_memory("Generator as octet string, compressed form:",
1082 len
= EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_UNCOMPRESSED
,
1083 buf
, sizeof(buf
), ctx
);
1084 if (!TEST_size_t_ne(len
, 0)
1085 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
1086 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
1088 test_output_memory("Generator as octet string, uncompressed form:",
1091 /* Change test based on whether binary point compression is enabled or not. */
1092 # ifdef OPENSSL_EC_BIN_PT_COMP
1094 EC_POINT_point2oct(group
, Q
, POINT_CONVERSION_HYBRID
, buf
, sizeof(buf
),
1096 if (!TEST_size_t_ne(len
, 0)
1097 || !TEST_true(EC_POINT_oct2point(group
, P
, buf
, len
, ctx
))
1098 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, Q
, ctx
)))
1100 test_output_memory("Generator as octet string, hybrid form:",
1104 if (!TEST_true(EC_POINT_invert(group
, P
, ctx
))
1105 || !TEST_int_eq(0, EC_POINT_cmp(group
, P
, R
, ctx
)))
1116 EC_GROUP_free(group
);
1130 static int internal_curve_test(int n
)
1132 EC_GROUP
*group
= NULL
;
1133 int nid
= curves
[n
].nid
;
1135 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
))) {
1136 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1140 if (!TEST_true(EC_GROUP_check(group
, NULL
))) {
1141 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid
));
1142 EC_GROUP_free(group
);
1145 EC_GROUP_free(group
);
1149 static int internal_curve_test_method(int n
)
1151 int r
, nid
= curves
[n
].nid
;
1154 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
))) {
1155 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid
));
1158 r
= group_order_tests(group
);
1159 EC_GROUP_free(group
);
1163 static int group_field_test(void)
1166 BIGNUM
*secp521r1_field
= NULL
;
1167 BIGNUM
*sect163r2_field
= NULL
;
1168 EC_GROUP
*secp521r1_group
= NULL
;
1169 EC_GROUP
*sect163r2_group
= NULL
;
1171 BN_hex2bn(&secp521r1_field
,
1172 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1173 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1174 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1175 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1179 BN_hex2bn(§163r2_field
,
1180 "08000000000000000000000000000000"
1183 secp521r1_group
= EC_GROUP_new_by_curve_name(NID_secp521r1
);
1184 if (BN_cmp(secp521r1_field
, EC_GROUP_get0_field(secp521r1_group
)))
1187 # ifndef OPENSSL_NO_EC2M
1188 sect163r2_group
= EC_GROUP_new_by_curve_name(NID_sect163r2
);
1189 if (BN_cmp(sect163r2_field
, EC_GROUP_get0_field(sect163r2_group
)))
1193 EC_GROUP_free(secp521r1_group
);
1194 EC_GROUP_free(sect163r2_group
);
1195 BN_free(secp521r1_field
);
1196 BN_free(sect163r2_field
);
1200 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1202 * nistp_test_params contains magic numbers for testing our optimized
1203 * implementations of several NIST curves with characteristic > 3.
1205 struct nistp_test_params
{
1206 const EC_METHOD
*(*meth
) (void);
1209 * Qx, Qy and D are taken from
1210 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1211 * Otherwise, values are standard curve parameters from FIPS 180-3
1213 const char *p
, *a
, *b
, *Qx
, *Qy
, *Gx
, *Gy
, *order
, *d
;
1216 static const struct nistp_test_params nistp_tests_params
[] = {
1219 EC_GFp_nistp224_method
,
1222 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1224 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1226 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1228 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1230 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1232 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1234 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1236 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1238 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1242 EC_GFp_nistp256_method
,
1245 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1247 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1249 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1251 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1253 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1255 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1257 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1259 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1261 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1265 EC_GFp_nistp521_method
,
1269 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1270 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1273 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1274 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1277 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1278 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1281 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1282 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1285 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1286 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1289 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1290 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1293 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1294 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1297 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1298 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1301 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1302 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1306 static int nistp_single_test(int idx
)
1308 const struct nistp_test_params
*test
= nistp_tests_params
+ idx
;
1310 BIGNUM
*p
= NULL
, *a
= NULL
, *b
= NULL
, *x
= NULL
, *y
= NULL
;
1311 BIGNUM
*n
= NULL
, *m
= NULL
, *order
= NULL
, *yplusone
= NULL
;
1312 EC_GROUP
*NISTP
= NULL
;
1313 EC_POINT
*G
= NULL
, *P
= NULL
, *Q
= NULL
, *Q_CHECK
= NULL
;
1316 TEST_note("NIST curve P-%d (optimised implementation):",
1318 if (!TEST_ptr(ctx
= BN_CTX_new())
1319 || !TEST_ptr(p
= BN_new())
1320 || !TEST_ptr(a
= BN_new())
1321 || !TEST_ptr(b
= BN_new())
1322 || !TEST_ptr(x
= BN_new())
1323 || !TEST_ptr(y
= BN_new())
1324 || !TEST_ptr(m
= BN_new())
1325 || !TEST_ptr(n
= BN_new())
1326 || !TEST_ptr(order
= BN_new())
1327 || !TEST_ptr(yplusone
= BN_new())
1329 || !TEST_ptr(NISTP
= EC_GROUP_new(test
->meth()))
1330 || !TEST_true(BN_hex2bn(&p
, test
->p
))
1331 || !TEST_int_eq(1, BN_is_prime_ex(p
, BN_prime_checks
, ctx
, NULL
))
1332 || !TEST_true(BN_hex2bn(&a
, test
->a
))
1333 || !TEST_true(BN_hex2bn(&b
, test
->b
))
1334 || !TEST_true(EC_GROUP_set_curve(NISTP
, p
, a
, b
, ctx
))
1335 || !TEST_ptr(G
= EC_POINT_new(NISTP
))
1336 || !TEST_ptr(P
= EC_POINT_new(NISTP
))
1337 || !TEST_ptr(Q
= EC_POINT_new(NISTP
))
1338 || !TEST_ptr(Q_CHECK
= EC_POINT_new(NISTP
))
1339 || !TEST_true(BN_hex2bn(&x
, test
->Qx
))
1340 || !TEST_true(BN_hex2bn(&y
, test
->Qy
))
1341 || !TEST_true(BN_add(yplusone
, y
, BN_value_one()))
1343 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1344 * and therefore setting the coordinates should fail.
1346 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP
, Q_CHECK
, x
,
1348 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP
, Q_CHECK
, x
, y
,
1350 || !TEST_true(BN_hex2bn(&x
, test
->Gx
))
1351 || !TEST_true(BN_hex2bn(&y
, test
->Gy
))
1352 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP
, G
, x
, y
, ctx
))
1353 || !TEST_true(BN_hex2bn(&order
, test
->order
))
1354 || !TEST_true(EC_GROUP_set_generator(NISTP
, G
, order
, BN_value_one()))
1355 || !TEST_int_eq(EC_GROUP_get_degree(NISTP
), test
->degree
))
1358 TEST_note("NIST test vectors ... ");
1359 if (!TEST_true(BN_hex2bn(&n
, test
->d
)))
1361 /* fixed point multiplication */
1362 EC_POINT_mul(NISTP
, Q
, n
, NULL
, NULL
, ctx
);
1363 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1365 /* random point multiplication */
1366 EC_POINT_mul(NISTP
, Q
, NULL
, G
, n
, ctx
);
1367 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
))
1369 /* set generator to P = 2*G, where G is the standard generator */
1370 || !TEST_true(EC_POINT_dbl(NISTP
, P
, G
, ctx
))
1371 || !TEST_true(EC_GROUP_set_generator(NISTP
, P
, order
, BN_value_one()))
1372 /* set the scalar to m=n/2, where n is the NIST test scalar */
1373 || !TEST_true(BN_rshift(m
, n
, 1)))
1376 /* test the non-standard generator */
1377 /* fixed point multiplication */
1378 EC_POINT_mul(NISTP
, Q
, m
, NULL
, NULL
, ctx
);
1379 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1381 /* random point multiplication */
1382 EC_POINT_mul(NISTP
, Q
, NULL
, P
, m
, ctx
);
1383 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
))
1386 * We have not performed precomputation so have_precompute mult should be
1389 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP
))
1391 /* now repeat all tests with precomputation */
1392 || !TEST_true(EC_GROUP_precompute_mult(NISTP
, ctx
))
1393 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP
)))
1396 /* fixed point multiplication */
1397 EC_POINT_mul(NISTP
, Q
, m
, NULL
, NULL
, ctx
);
1398 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1400 /* random point multiplication */
1401 EC_POINT_mul(NISTP
, Q
, NULL
, P
, m
, ctx
);
1402 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
))
1404 /* reset generator */
1405 || !TEST_true(EC_GROUP_set_generator(NISTP
, G
, order
, BN_value_one())))
1407 /* fixed point multiplication */
1408 EC_POINT_mul(NISTP
, Q
, n
, NULL
, NULL
, ctx
);
1409 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1411 /* random point multiplication */
1412 EC_POINT_mul(NISTP
, Q
, NULL
, G
, n
, ctx
);
1413 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, Q_CHECK
, ctx
)))
1416 /* regression test for felem_neg bug */
1417 if (!TEST_true(BN_set_word(m
, 32))
1418 || !TEST_true(BN_set_word(n
, 31))
1419 || !TEST_true(EC_POINT_copy(P
, G
))
1420 || !TEST_true(EC_POINT_invert(NISTP
, P
, ctx
))
1421 || !TEST_true(EC_POINT_mul(NISTP
, Q
, m
, P
, n
, ctx
))
1422 || !TEST_int_eq(0, EC_POINT_cmp(NISTP
, Q
, G
, ctx
)))
1425 r
= group_order_tests(NISTP
);
1427 EC_GROUP_free(NISTP
);
1431 EC_POINT_free(Q_CHECK
);
1446 * Tests a point known to cause an incorrect underflow in an old version of
1449 static int underflow_test(void)
1452 EC_GROUP
*grp
= NULL
;
1453 EC_POINT
*P
= NULL
, *Q
= NULL
, *R
= NULL
;
1454 BIGNUM
*x1
= NULL
, *y1
= NULL
, *z1
= NULL
, *x2
= NULL
, *y2
= NULL
;
1458 "1534f0077fffffe87e9adcfe000000000000000000003e05a21d2400002e031b1f4"
1459 "b80000c6fafa4f3c1288798d624a247b5e2ffffffffffffffefe099241900004";
1460 const char *p521m1
=
1461 "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1462 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe";
1469 x1
= BN_CTX_get(ctx
);
1470 y1
= BN_CTX_get(ctx
);
1471 z1
= BN_CTX_get(ctx
);
1472 x2
= BN_CTX_get(ctx
);
1473 y2
= BN_CTX_get(ctx
);
1474 k
= BN_CTX_get(ctx
);
1478 grp
= EC_GROUP_new_by_curve_name(NID_secp521r1
);
1479 P
= EC_POINT_new(grp
);
1480 Q
= EC_POINT_new(grp
);
1481 R
= EC_POINT_new(grp
);
1482 if (!TEST_ptr(grp
) || !TEST_ptr(P
) || !TEST_ptr(Q
) || !TEST_ptr(R
))
1485 if (!TEST_int_gt(BN_hex2bn(&x1
, x1str
), 0)
1486 || !TEST_int_gt(BN_hex2bn(&y1
, p521m1
), 0)
1487 || !TEST_int_gt(BN_hex2bn(&z1
, p521m1
), 0)
1488 || !TEST_int_gt(BN_hex2bn(&k
, "02"), 0)
1489 || !TEST_true(EC_POINT_set_Jprojective_coordinates_GFp(grp
, P
, x1
,
1491 || !TEST_true(EC_POINT_mul(grp
, Q
, NULL
, P
, k
, ctx
))
1492 || !TEST_true(EC_POINT_get_affine_coordinates(grp
, Q
, x1
, y1
, ctx
))
1493 || !TEST_true(EC_POINT_dbl(grp
, R
, P
, ctx
))
1494 || !TEST_true(EC_POINT_get_affine_coordinates(grp
, R
, x2
, y2
, ctx
)))
1497 if (!TEST_int_eq(BN_cmp(x1
, x2
), 0)
1498 || !TEST_int_eq(BN_cmp(y1
, y2
), 0))
1515 static const unsigned char p521_named
[] = {
1516 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1519 static const unsigned char p521_explicit
[] = {
1520 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1521 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1522 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1523 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1524 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1525 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1526 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1527 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1528 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1529 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1530 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1531 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1532 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1533 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1534 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1535 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1536 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1537 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1538 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1539 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1540 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1541 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1542 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1543 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1544 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1545 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1546 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1547 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1548 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1549 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1550 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1551 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1552 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1553 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1554 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1555 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1556 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1557 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1561 * This test validates a named curve's group parameters using
1562 * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1563 * group parameters results in the curve not being valid.
1565 static int check_named_curve_test(int id
)
1567 int ret
= 0, nid
, field_nid
, has_seed
;
1568 EC_GROUP
*group
= NULL
, *gtest
= NULL
;
1569 const EC_POINT
*group_gen
= NULL
;
1570 EC_POINT
*other_gen
= NULL
;
1571 BIGNUM
*group_p
= NULL
, *group_a
= NULL
, *group_b
= NULL
;
1572 BIGNUM
*other_p
= NULL
, *other_a
= NULL
, *other_b
= NULL
;
1573 BIGNUM
*group_cofactor
= NULL
, *other_cofactor
= NULL
;
1574 BIGNUM
*other_order
= NULL
;
1575 const BIGNUM
*group_order
= NULL
;
1576 BN_CTX
*bn_ctx
= NULL
;
1577 static const unsigned char invalid_seed
[] = "THIS IS NOT A VALID SEED";
1578 static size_t invalid_seed_len
= sizeof(invalid_seed
);
1581 nid
= curves
[id
].nid
;
1582 if (!TEST_ptr(bn_ctx
= BN_CTX_new())
1583 || !TEST_ptr(group
= EC_GROUP_new_by_curve_name(nid
))
1584 || !TEST_ptr(gtest
= EC_GROUP_dup(group
))
1585 || !TEST_ptr(group_p
= BN_new())
1586 || !TEST_ptr(group_a
= BN_new())
1587 || !TEST_ptr(group_b
= BN_new())
1588 || !TEST_ptr(group_cofactor
= BN_new())
1589 || !TEST_ptr(group_gen
= EC_GROUP_get0_generator(group
))
1590 || !TEST_ptr(group_order
= EC_GROUP_get0_order(group
))
1591 || !TEST_true(EC_GROUP_get_cofactor(group
, group_cofactor
, NULL
))
1592 || !TEST_true(EC_GROUP_get_curve(group
, group_p
, group_a
, group_b
, NULL
))
1593 || !TEST_ptr(other_gen
= EC_POINT_dup(group_gen
, group
))
1594 || !TEST_true(EC_POINT_add(group
, other_gen
, group_gen
, group_gen
, NULL
))
1595 || !TEST_ptr(other_order
= BN_dup(group_order
))
1596 || !TEST_true(BN_add_word(other_order
, 1))
1597 || !TEST_ptr(other_a
= BN_dup(group_a
))
1598 || !TEST_true(BN_add_word(other_a
, 1))
1599 || !TEST_ptr(other_b
= BN_dup(group_b
))
1600 || !TEST_true(BN_add_word(other_b
, 1))
1601 || !TEST_ptr(other_cofactor
= BN_dup(group_cofactor
))
1602 || !TEST_true(BN_add_word(other_cofactor
, 1)))
1605 /* Determine if the built-in curve has a seed field set */
1606 has_seed
= (EC_GROUP_get_seed_len(group
) > 0);
1607 field_nid
= EC_METHOD_get_field_type(EC_GROUP_method_of(group
));
1608 if (field_nid
== NID_X9_62_characteristic_two_field
) {
1609 if (!TEST_ptr(other_p
= BN_dup(group_p
))
1610 || !TEST_true(BN_lshift1(other_p
, other_p
)))
1613 if (!TEST_ptr(other_p
= BN_dup(group_p
)))
1616 * Just choosing any arbitrary prime does not work..
1617 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1618 * nist prime. So only select one of these as an alternate prime.
1620 if (!TEST_ptr(BN_copy(other_p
,
1621 BN_ucmp(BN_get0_nist_prime_192(), other_p
) == 0 ?
1622 BN_get0_nist_prime_256() :
1623 BN_get0_nist_prime_192())))
1627 /* Passes because this is a valid curve */
1628 if (!TEST_int_eq(EC_GROUP_check_named_curve(group
, 0), nid
)
1629 /* Only NIST curves pass */
1630 || !TEST_int_eq(EC_GROUP_check_named_curve(group
, 1),
1631 EC_curve_nid2nist(nid
) != NULL
? nid
: NID_undef
))
1634 /* Fail if the curve name doesn't match the parameters */
1635 EC_GROUP_set_curve_name(group
, nid
+ 1);
1637 if (!TEST_int_le(EC_GROUP_check_named_curve(group
, 0), 0))
1641 /* Restore curve name and ensure it's passing */
1642 EC_GROUP_set_curve_name(group
, nid
);
1643 if (!TEST_int_eq(EC_GROUP_check_named_curve(group
, 0), nid
))
1646 if (!TEST_int_eq(EC_GROUP_set_seed(group
, invalid_seed
, invalid_seed_len
),
1652 * If the built-in curve has a seed and we set the seed to another value
1653 * then it will fail the check.
1655 if (!TEST_int_eq(EC_GROUP_check_named_curve(group
, 0), 0))
1659 * If the built-in curve does not have a seed then setting the seed will
1660 * pass the check (as the seed is optional).
1662 if (!TEST_int_eq(EC_GROUP_check_named_curve(group
, 0), nid
))
1665 /* Pass if the seed is unknown (as it is optional) */
1666 if (!TEST_int_eq(EC_GROUP_set_seed(group
, NULL
, 0), 1)
1667 || !TEST_int_eq(EC_GROUP_check_named_curve(group
, 0), nid
))
1670 /* Check that a duped group passes */
1671 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0), nid
))
1674 /* check that changing any generator parameter fails */
1675 if (!TEST_true(EC_GROUP_set_generator(gtest
, other_gen
, group_order
,
1677 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0), 0)
1678 || !TEST_true(EC_GROUP_set_generator(gtest
, group_gen
, other_order
,
1680 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0), 0)
1681 /* The order is not an optional field, so this should fail */
1682 || !TEST_true(EC_GROUP_set_generator(gtest
, group_gen
, NULL
,
1684 || !TEST_int_le(EC_GROUP_check_named_curve(gtest
, 0), 0)
1685 || !TEST_true(EC_GROUP_set_generator(gtest
, group_gen
, group_order
,
1687 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0), 0)
1688 /* Check that if the cofactor is not set then it still passes */
1689 || !TEST_true(EC_GROUP_set_generator(gtest
, group_gen
, group_order
,
1691 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0), nid
)
1692 /* check that restoring the generator passes */
1693 || !TEST_true(EC_GROUP_set_generator(gtest
, group_gen
, group_order
,
1695 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0), nid
))
1699 * check that changing any curve parameter fails
1701 * Setting arbitrary p, a or b might fail for some EC_GROUPs
1702 * depending on the internal EC_METHOD implementation, hence run
1703 * these tests conditionally to the success of EC_GROUP_set_curve().
1706 if (EC_GROUP_set_curve(gtest
, other_p
, group_a
, group_b
, NULL
)) {
1707 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest
, 0), 0))
1710 /* clear the error stack if EC_GROUP_set_curve() failed */
1714 if (EC_GROUP_set_curve(gtest
, group_p
, other_a
, group_b
, NULL
)) {
1715 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest
, 0), 0))
1718 /* clear the error stack if EC_GROUP_set_curve() failed */
1722 if (EC_GROUP_set_curve(gtest
, group_p
, group_a
, other_b
, NULL
)) {
1723 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest
, 0), 0))
1726 /* clear the error stack if EC_GROUP_set_curve() failed */
1732 /* Check that restoring the curve parameters passes */
1733 if (!TEST_true(EC_GROUP_set_curve(gtest
, group_p
, group_a
, group_b
, NULL
))
1734 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest
, 0), nid
))
1745 BN_free(group_cofactor
);
1746 BN_free(other_cofactor
);
1747 BN_free(other_order
);
1748 EC_POINT_free(other_gen
);
1749 EC_GROUP_free(gtest
);
1750 EC_GROUP_free(group
);
1751 BN_CTX_free(bn_ctx
);
1756 * This checks the lookup capability of EC_GROUP_check_named_curve()
1757 * when the given group was created with explicit parameters.
1759 * It is possible to retrieve an alternative alias that does not match
1760 * the original nid in this case.
1762 static int check_named_curve_lookup_test(int id
)
1764 int ret
= 0, nid
, rv
= 0;
1765 EC_GROUP
*g
= NULL
, *ga
= NULL
;
1766 ECPARAMETERS
*p
= NULL
, *pa
= NULL
;
1770 nid
= curves
[id
].nid
;
1771 if (!TEST_ptr(ctx
= BN_CTX_new())
1772 || !TEST_ptr(g
= EC_GROUP_new_by_curve_name(nid
))
1773 || !TEST_ptr(p
= EC_GROUP_get_ecparameters(g
, NULL
)))
1776 /* replace with group from explicit parameters */
1778 if (!TEST_ptr(g
= EC_GROUP_new_from_ecparameters(p
)))
1781 if (!TEST_int_gt(rv
= EC_GROUP_check_named_curve(g
, 0), 0))
1786 * fail if the returned nid is not an alias of the original group.
1788 * The comparison here is done by comparing two explicit
1789 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1790 * comparison happens with unnamed EC_GROUPs using the same
1793 if (!TEST_ptr(ga
= EC_GROUP_new_by_curve_name(rv
))
1794 || !TEST_ptr(pa
= EC_GROUP_get_ecparameters(ga
, NULL
)))
1797 /* replace with group from explicit parameters, then compare */
1799 if (!TEST_ptr(ga
= EC_GROUP_new_from_ecparameters(pa
))
1800 || !TEST_int_eq(EC_GROUP_cmp(g
, ga
, ctx
), 0))
1809 ECPARAMETERS_free(p
);
1810 ECPARAMETERS_free(pa
);
1816 static int parameter_test(void)
1818 EC_GROUP
*group
= NULL
, *group2
= NULL
;
1819 ECPARAMETERS
*ecparameters
= NULL
;
1820 unsigned char *buf
= NULL
;
1823 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(NID_secp112r1
))
1824 || !TEST_ptr(ecparameters
= EC_GROUP_get_ecparameters(group
, NULL
))
1825 || !TEST_ptr(group2
= EC_GROUP_new_from_ecparameters(ecparameters
))
1826 || !TEST_int_eq(EC_GROUP_cmp(group
, group2
, NULL
), 0))
1829 EC_GROUP_free(group
);
1832 /* Test the named curve encoding, which should be default. */
1833 if (!TEST_ptr(group
= EC_GROUP_new_by_curve_name(NID_secp521r1
))
1834 || !TEST_true((len
= i2d_ECPKParameters(group
, &buf
)) >= 0)
1835 || !TEST_mem_eq(buf
, len
, p521_named
, sizeof(p521_named
)))
1842 * Test the explicit encoding. P-521 requires correctly zero-padding the
1843 * curve coefficients.
1845 EC_GROUP_set_asn1_flag(group
, OPENSSL_EC_EXPLICIT_CURVE
);
1846 if (!TEST_true((len
= i2d_ECPKParameters(group
, &buf
)) >= 0)
1847 || !TEST_mem_eq(buf
, len
, p521_explicit
, sizeof(p521_explicit
)))
1852 EC_GROUP_free(group
);
1853 EC_GROUP_free(group2
);
1854 ECPARAMETERS_free(ecparameters
);
1859 static int check_ec_key_field_public_range_test(int id
)
1861 int ret
= 0, type
= 0;
1862 const EC_POINT
*pub
= NULL
;
1863 const EC_GROUP
*group
= NULL
;
1864 const EC_METHOD
*meth
= NULL
;
1865 const BIGNUM
*field
= NULL
;
1866 BIGNUM
*x
= NULL
, *y
= NULL
;
1869 if (!(TEST_ptr(x
= BN_new())
1870 && TEST_ptr(y
= BN_new())
1871 && TEST_ptr(key
= EC_KEY_new_by_curve_name(curves
[id
].nid
))
1872 && TEST_ptr(group
= EC_KEY_get0_group(key
))
1873 && TEST_ptr(meth
= EC_GROUP_method_of(group
))
1874 && TEST_ptr(field
= EC_GROUP_get0_field(group
))
1875 && TEST_int_gt(EC_KEY_generate_key(key
), 0)
1876 && TEST_int_gt(EC_KEY_check_key(key
), 0)
1877 && TEST_ptr(pub
= EC_KEY_get0_public_key(key
))
1878 && TEST_int_gt(EC_POINT_get_affine_coordinates(group
, pub
, x
, y
,
1883 * Make the public point out of range by adding the field (which will still
1884 * be the same point on the curve). The add is different for char2 fields.
1886 type
= EC_METHOD_get_field_type(meth
);
1887 #ifndef OPENSSL_NO_EC2M
1888 if (type
== NID_X9_62_characteristic_two_field
) {
1889 /* test for binary curves */
1890 if (!TEST_true(BN_GF2m_add(x
, x
, field
)))
1894 if (type
== NID_X9_62_prime_field
) {
1895 /* test for prime curves */
1896 if (!TEST_true(BN_add(x
, x
, field
)))
1899 /* this should never happen */
1900 TEST_error("Unsupported EC_METHOD field_type");
1903 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key
, x
, y
), 0))
1913 #endif /* OPENSSL_NO_EC */
1915 int setup_tests(void)
1917 #ifndef OPENSSL_NO_EC
1918 crv_len
= EC_get_builtin_curves(NULL
, 0);
1919 if (!TEST_ptr(curves
= OPENSSL_malloc(sizeof(*curves
) * crv_len
))
1920 || !TEST_true(EC_get_builtin_curves(curves
, crv_len
)))
1923 ADD_TEST(parameter_test
);
1924 ADD_TEST(prime_field_tests
);
1925 # ifndef OPENSSL_NO_EC2M
1926 ADD_TEST(char2_field_tests
);
1927 ADD_ALL_TESTS(char2_curve_test
, OSSL_NELEM(char2_curve_tests
));
1929 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1930 ADD_ALL_TESTS(nistp_single_test
, OSSL_NELEM(nistp_tests_params
));
1931 ADD_TEST(underflow_test
);
1933 ADD_ALL_TESTS(internal_curve_test
, crv_len
);
1934 ADD_ALL_TESTS(internal_curve_test_method
, crv_len
);
1935 ADD_TEST(group_field_test
);
1936 ADD_ALL_TESTS(check_named_curve_test
, crv_len
);
1937 ADD_ALL_TESTS(check_named_curve_lookup_test
, crv_len
);
1938 ADD_ALL_TESTS(check_ec_key_field_public_range_test
, crv_len
);
1939 #endif /* OPENSSL_NO_EC */
1943 void cleanup_tests(void)
1945 #ifndef OPENSSL_NO_EC
1946 OPENSSL_free(curves
);