]> git.ipfire.org Git - thirdparty/openssl.git/blob - test/ectest.c
Create a new embeddedSCTs1 that's signed using SHA256
[thirdparty/openssl.git] / test / ectest.c
1 /*
2 * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4 *
5 * Licensed under the OpenSSL license (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11 #include "internal/nelem.h"
12 #include "testutil.h"
13
14 #ifndef OPENSSL_NO_EC
15 # include <openssl/ec.h>
16 # ifndef OPENSSL_NO_ENGINE
17 # include <openssl/engine.h>
18 # endif
19 # include <openssl/err.h>
20 # include <openssl/obj_mac.h>
21 # include <openssl/objects.h>
22 # include <openssl/rand.h>
23 # include <openssl/bn.h>
24 # include <openssl/opensslconf.h>
25
26 static size_t crv_len = 0;
27 static EC_builtin_curve *curves = NULL;
28
29 /* test multiplication with group order, long and negative scalars */
30 static int group_order_tests(EC_GROUP *group)
31 {
32 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
33 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
34 const EC_POINT *G = NULL;
35 BN_CTX *ctx = NULL;
36 int i = 0, r = 0;
37
38 if (!TEST_ptr(n1 = BN_new())
39 || !TEST_ptr(n2 = BN_new())
40 || !TEST_ptr(order = BN_new())
41 || !TEST_ptr(ctx = BN_CTX_new())
42 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
43 || !TEST_ptr(P = EC_POINT_new(group))
44 || !TEST_ptr(Q = EC_POINT_new(group))
45 || !TEST_ptr(R = EC_POINT_new(group))
46 || !TEST_ptr(S = EC_POINT_new(group)))
47 goto err;
48
49 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
50 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
51 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
52 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
53 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
54 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
55 || !TEST_true(EC_POINT_copy(P, G))
56 || !TEST_true(BN_one(n1))
57 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
58 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
59 || !TEST_true(BN_sub(n1, order, n1))
60 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
61 || !TEST_true(EC_POINT_invert(group, Q, ctx))
62 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
63 goto err;
64
65 for (i = 1; i <= 2; i++) {
66 const BIGNUM *scalars[6];
67 const EC_POINT *points[6];
68
69 if (!TEST_true(BN_set_word(n1, i))
70 /*
71 * If i == 1, P will be the predefined generator for which
72 * EC_GROUP_precompute_mult has set up precomputation.
73 */
74 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
75 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
76 || !TEST_true(BN_one(n1))
77 /* n1 = 1 - order */
78 || !TEST_true(BN_sub(n1, n1, order))
79 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
80 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
81
82 /* n2 = 1 + order */
83 || !TEST_true(BN_add(n2, order, BN_value_one()))
84 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
85 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
86
87 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
88 || !TEST_true(BN_mul(n2, n1, n2, ctx))
89 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
90 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
91 goto err;
92
93 /* n2 = order^2 - 1 */
94 BN_set_negative(n2, 0);
95 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
96 /* Add P to verify the result. */
97 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
98 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
99
100 /* Exercise EC_POINTs_mul, including corner cases. */
101 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
102 goto err;
103
104 scalars[0] = scalars[1] = BN_value_one();
105 points[0] = points[1] = P;
106
107 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
108 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
109 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
110 goto err;
111
112 scalars[0] = n1;
113 points[0] = Q; /* => infinity */
114 scalars[1] = n2;
115 points[1] = P; /* => -P */
116 scalars[2] = n1;
117 points[2] = Q; /* => infinity */
118 scalars[3] = n2;
119 points[3] = Q; /* => infinity */
120 scalars[4] = n1;
121 points[4] = P; /* => P */
122 scalars[5] = n2;
123 points[5] = Q; /* => infinity */
124 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
125 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
126 goto err;
127 }
128
129 r = 1;
130 err:
131 if (r == 0 && i != 0)
132 TEST_info(i == 1 ? "allowing precomputation" :
133 "without precomputation");
134 EC_POINT_free(P);
135 EC_POINT_free(Q);
136 EC_POINT_free(R);
137 EC_POINT_free(S);
138 BN_free(n1);
139 BN_free(n2);
140 BN_free(order);
141 BN_CTX_free(ctx);
142 return r;
143 }
144
145 static int prime_field_tests(void)
146 {
147 BN_CTX *ctx = NULL;
148 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
149 EC_GROUP *group = NULL, *tmp = NULL;
150 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
151 *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
152 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
153 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
154 const EC_POINT *points[4];
155 const BIGNUM *scalars[4];
156 unsigned char buf[100];
157 size_t len, r = 0;
158 int k;
159
160 if (!TEST_ptr(ctx = BN_CTX_new())
161 || !TEST_ptr(p = BN_new())
162 || !TEST_ptr(a = BN_new())
163 || !TEST_ptr(b = BN_new())
164 || !TEST_true(BN_hex2bn(&p, "17"))
165 || !TEST_true(BN_hex2bn(&a, "1"))
166 || !TEST_true(BN_hex2bn(&b, "1"))
167 /*
168 * applications should use EC_GROUP_new_curve_GFp so
169 * that the library gets to choose the EC_METHOD
170 */
171 || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
172 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
173 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
174 || !TEST_true(EC_GROUP_copy(tmp, group)))
175 goto err;
176 EC_GROUP_free(group);
177 group = tmp;
178 tmp = NULL;
179
180 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
181 goto err;
182
183 TEST_info("Curve defined by Weierstrass equation");
184 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
185 test_output_bignum("a", a);
186 test_output_bignum("b", b);
187 test_output_bignum("p", p);
188
189 buf[0] = 0;
190 if (!TEST_ptr(P = EC_POINT_new(group))
191 || !TEST_ptr(Q = EC_POINT_new(group))
192 || !TEST_ptr(R = EC_POINT_new(group))
193 || !TEST_true(EC_POINT_set_to_infinity(group, P))
194 || !TEST_true(EC_POINT_is_at_infinity(group, P))
195 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
196 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
197 || !TEST_true(EC_POINT_is_at_infinity(group, P))
198 || !TEST_ptr(x = BN_new())
199 || !TEST_ptr(y = BN_new())
200 || !TEST_ptr(z = BN_new())
201 || !TEST_ptr(yplusone = BN_new())
202 || !TEST_true(BN_hex2bn(&x, "D"))
203 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
204 goto err;
205
206 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
207 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
208 goto err;
209 TEST_info("Point is not on curve");
210 test_output_bignum("x", x);
211 test_output_bignum("y", y);
212 goto err;
213 }
214
215 TEST_note("A cyclic subgroup:");
216 k = 100;
217 do {
218 if (!TEST_int_ne(k--, 0))
219 goto err;
220
221 if (EC_POINT_is_at_infinity(group, P)) {
222 TEST_note(" point at infinity");
223 } else {
224 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
225 ctx)))
226 goto err;
227
228 test_output_bignum("x", x);
229 test_output_bignum("y", y);
230 }
231
232 if (!TEST_true(EC_POINT_copy(R, P))
233 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
234 goto err;
235
236 } while (!EC_POINT_is_at_infinity(group, P));
237
238 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
239 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
240 goto err;
241
242 len =
243 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
244 sizeof(buf), ctx);
245 if (!TEST_size_t_ne(len, 0)
246 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
247 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
248 goto err;
249 test_output_memory("Generator as octet string, compressed form:",
250 buf, len);
251
252 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
253 buf, sizeof(buf), ctx);
254 if (!TEST_size_t_ne(len, 0)
255 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
256 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
257 goto err;
258 test_output_memory("Generator as octet string, uncompressed form:",
259 buf, len);
260
261 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
262 buf, sizeof(buf), ctx);
263 if (!TEST_size_t_ne(len, 0)
264 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
265 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
266 goto err;
267 test_output_memory("Generator as octet string, hybrid form:",
268 buf, len);
269
270 if (!TEST_true(EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z,
271 ctx)))
272 goto err;
273 TEST_info("A representation of the inverse of that generator in");
274 TEST_note("Jacobian projective coordinates");
275 test_output_bignum("x", x);
276 test_output_bignum("y", y);
277 test_output_bignum("z", z);
278
279 if (!TEST_true(EC_POINT_invert(group, P, ctx))
280 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
281
282 /*
283 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
284 * 2000) -- not a NIST curve, but commonly used
285 */
286
287 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
288 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
289 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
290 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
291 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
292 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
293 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
294 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
295 || !TEST_true(BN_hex2bn(&x, "4A96B568"
296 "8EF573284664698968C38BB913CBFC82"))
297 || !TEST_true(BN_hex2bn(&y, "23a62855"
298 "3168947d59dcc912042351377ac5fb32"))
299 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
300 /*
301 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
302 * and therefore setting the coordinates should fail.
303 */
304 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
305 ctx))
306 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
307 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
308 || !TEST_true(BN_hex2bn(&z, "0100000000"
309 "000000000001F4C8F927AED3CA752257"))
310 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
311 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
312 goto err;
313 TEST_info("SEC2 curve secp160r1 -- Generator");
314 test_output_bignum("x", x);
315 test_output_bignum("y", y);
316 /* G_y value taken from the standard: */
317 if (!TEST_true(BN_hex2bn(&z, "23a62855"
318 "3168947d59dcc912042351377ac5fb32"))
319 || !TEST_BN_eq(y, z)
320 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
321 || !group_order_tests(group)
322 || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))
323 || !TEST_true(EC_GROUP_copy(P_160, group))
324
325 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
326
327 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
328 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
329 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
330 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
331 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
332 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
333 "0FA7E9AB72243049FEB8DEECC146B9B1"))
334 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
335 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
336 "7CBF20EB43A18800F4FF0AFD82FF1012"))
337 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
338 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
339 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
340 "FFFFFFFF99DEF836146BC9B1B4D22831"))
341 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
342 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
343 goto err;
344
345 TEST_info("NIST curve P-192 -- Generator");
346 test_output_bignum("x", x);
347 test_output_bignum("y", y);
348 /* G_y value taken from the standard: */
349 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
350 "631011ED6B24CDD573F977A11E794811"))
351 || !TEST_BN_eq(y, z)
352 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
353 /*
354 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
355 * and therefore setting the coordinates should fail.
356 */
357 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
358 ctx))
359 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
360 || !group_order_tests(group)
361 || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))
362 || !TEST_true(EC_GROUP_copy(P_192, group))
363
364 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
365
366 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
367 "FFFFFFFF000000000000000000000001"))
368 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
369 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
370 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
371 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
372 "5044B0B7D7BFD8BA270B39432355FFB4"))
373 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
374 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
375 "4A03C1D356C21122343280D6115C1D21"))
376 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
377 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
378 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
379 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
380 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
381 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
382 goto err;
383
384 TEST_info("NIST curve P-224 -- Generator");
385 test_output_bignum("x", x);
386 test_output_bignum("y", y);
387 /* G_y value taken from the standard: */
388 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
389 "CD4375A05A07476444D5819985007E34"))
390 || !TEST_BN_eq(y, z)
391 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
392 /*
393 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
394 * and therefore setting the coordinates should fail.
395 */
396 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
397 ctx))
398 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
399 || !group_order_tests(group)
400 || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
401 || !TEST_true(EC_GROUP_copy(P_224, group))
402
403 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
404
405 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
406 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
407 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
408 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
409 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
410 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
411 "651D06B0CC53B0F63BCE3C3E27D2604B"))
412 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
413
414 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
415 "77037D812DEB33A0F4A13945D898C296"))
416 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
417 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
418 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
419 "BCE6FAADA7179E84F3B9CAC2FC632551"))
420 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
421 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
422 goto err;
423
424 TEST_info("NIST curve P-256 -- Generator");
425 test_output_bignum("x", x);
426 test_output_bignum("y", y);
427 /* G_y value taken from the standard: */
428 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
429 "2BCE33576B315ECECBB6406837BF51F5"))
430 || !TEST_BN_eq(y, z)
431 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
432 /*
433 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
434 * and therefore setting the coordinates should fail.
435 */
436 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
437 ctx))
438 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
439 || !group_order_tests(group)
440 || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
441 || !TEST_true(EC_GROUP_copy(P_256, group))
442
443 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
444
445 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
446 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
447 "FFFFFFFF0000000000000000FFFFFFFF"))
448 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
449 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
450 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
451 "FFFFFFFF0000000000000000FFFFFFFC"))
452 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
453 "181D9C6EFE8141120314088F5013875A"
454 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
455 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
456
457 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
458 "6E1D3B628BA79B9859F741E082542A38"
459 "5502F25DBF55296C3A545E3872760AB7"))
460 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
461 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
462 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
463 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
464 "581A0DB248B0A77AECEC196ACCC52973"))
465 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
466 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
467 goto err;
468
469 TEST_info("NIST curve P-384 -- Generator");
470 test_output_bignum("x", x);
471 test_output_bignum("y", y);
472 /* G_y value taken from the standard: */
473 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
474 "F8F41DBD289A147CE9DA3113B5F0B8C0"
475 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
476 || !TEST_BN_eq(y, z)
477 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
478 /*
479 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
480 * and therefore setting the coordinates should fail.
481 */
482 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
483 ctx))
484 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
485 || !group_order_tests(group)
486 || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
487 || !TEST_true(EC_GROUP_copy(P_384, group))
488
489 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
490 || !TEST_true(BN_hex2bn(&p, "1FF"
491 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
492 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
493 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
494 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
495 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
496 || !TEST_true(BN_hex2bn(&a, "1FF"
497 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
500 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
501 || !TEST_true(BN_hex2bn(&b, "051"
502 "953EB9618E1C9A1F929A21A0B68540EE"
503 "A2DA725B99B315F3B8B489918EF109E1"
504 "56193951EC7E937B1652C0BD3BB1BF07"
505 "3573DF883D2C34F1EF451FD46B503F00"))
506 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
507 || !TEST_true(BN_hex2bn(&x, "C6"
508 "858E06B70404E9CD9E3ECB662395B442"
509 "9C648139053FB521F828AF606B4D3DBA"
510 "A14B5E77EFE75928FE1DC127A2FFA8DE"
511 "3348B3C1856A429BF97E7E31C2E5BD66"))
512 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
513 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
514 || !TEST_true(BN_hex2bn(&z, "1FF"
515 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
516 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
517 "51868783BF2F966B7FCC0148F709A5D0"
518 "3BB5C9B8899C47AEBB6FB71E91386409"))
519 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
520 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
521 goto err;
522
523 TEST_info("NIST curve P-521 -- Generator");
524 test_output_bignum("x", x);
525 test_output_bignum("y", y);
526 /* G_y value taken from the standard: */
527 if (!TEST_true(BN_hex2bn(&z, "118"
528 "39296A789A3BC0045C8A5FB42C7D1BD9"
529 "98F54449579B446817AFBD17273E662C"
530 "97EE72995EF42640C550B9013FAD0761"
531 "353C7086A272C24088BE94769FD16650"))
532 || !TEST_BN_eq(y, z)
533 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
534 /*
535 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
536 * and therefore setting the coordinates should fail.
537 */
538 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
539 ctx))
540 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
541 || !group_order_tests(group)
542 || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
543 || !TEST_true(EC_GROUP_copy(P_521, group))
544
545 /* more tests using the last curve */
546
547 /* Restore the point that got mangled in the (x, y + 1) test. */
548 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
549 || !TEST_true(EC_POINT_copy(Q, P))
550 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
551 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
552 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
553 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
554 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
555 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
556 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
557 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
558 goto err;
559 points[0] = Q;
560 points[1] = Q;
561 points[2] = Q;
562 points[3] = Q;
563
564 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
565 || !TEST_true(BN_add(y, z, BN_value_one()))
566 || !TEST_BN_even(y)
567 || !TEST_true(BN_rshift1(y, y)))
568 goto err;
569 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
570 scalars[1] = y;
571
572 TEST_note("combined multiplication ...");
573
574 /* z is still the group order */
575 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
576 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
577 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
578 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
579 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
580 || !TEST_true(BN_add(z, z, y)))
581 goto err;
582 BN_set_negative(z, 1);
583 scalars[0] = y;
584 scalars[1] = z; /* z = -(order + y) */
585
586 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
587 || !TEST_true(EC_POINT_is_at_infinity(group, P))
588 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
589 || !TEST_true(BN_add(z, x, y)))
590 goto err;
591 BN_set_negative(z, 1);
592 scalars[0] = x;
593 scalars[1] = y;
594 scalars[2] = z; /* z = -(x+y) */
595
596 if (!TEST_ptr(scalar3 = BN_new()))
597 goto err;
598 BN_zero(scalar3);
599 scalars[3] = scalar3;
600
601 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
602 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
603 goto err;
604
605 TEST_note(" ok\n");
606
607
608 r = 1;
609 err:
610 BN_CTX_free(ctx);
611 BN_free(p);
612 BN_free(a);
613 BN_free(b);
614 EC_GROUP_free(group);
615 EC_GROUP_free(tmp);
616 EC_POINT_free(P);
617 EC_POINT_free(Q);
618 EC_POINT_free(R);
619 BN_free(x);
620 BN_free(y);
621 BN_free(z);
622 BN_free(yplusone);
623 BN_free(scalar3);
624
625 EC_GROUP_free(P_160);
626 EC_GROUP_free(P_192);
627 EC_GROUP_free(P_224);
628 EC_GROUP_free(P_256);
629 EC_GROUP_free(P_384);
630 EC_GROUP_free(P_521);
631 return r;
632 }
633
634 # ifndef OPENSSL_NO_EC2M
635
636 static struct c2_curve_test {
637 const char *name;
638 const char *p;
639 const char *a;
640 const char *b;
641 const char *x;
642 const char *y;
643 int ybit;
644 const char *order;
645 const char *cof;
646 int degree;
647 } char2_curve_tests[] = {
648 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
649 {
650 "NIST curve K-163",
651 "0800000000000000000000000000000000000000C9",
652 "1",
653 "1",
654 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
655 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
656 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
657 },
658 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
659 {
660 "NIST curve B-163",
661 "0800000000000000000000000000000000000000C9",
662 "1",
663 "020A601907B8C953CA1481EB10512F78744A3205FD",
664 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
665 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
666 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
667 },
668 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
669 {
670 "NIST curve K-233",
671 "020000000000000000000000000000000000000004000000000000000001",
672 "0",
673 "1",
674 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
675 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
676 0,
677 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
678 "4", 233
679 },
680 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
681 {
682 "NIST curve B-233",
683 "020000000000000000000000000000000000000004000000000000000001",
684 "000000000000000000000000000000000000000000000000000000000001",
685 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
686 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
687 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
688 1,
689 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
690 "2", 233
691 },
692 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
693 {
694 "NIST curve K-283",
695 "08000000"
696 "00000000000000000000000000000000000000000000000000000000000010A1",
697 "0",
698 "1",
699 "0503213F"
700 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
701 "01CCDA38"
702 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
703 0,
704 "01FFFFFF"
705 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
706 "4", 283
707 },
708 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
709 {
710 "NIST curve B-283",
711 "08000000"
712 "00000000000000000000000000000000000000000000000000000000000010A1",
713 "00000000"
714 "0000000000000000000000000000000000000000000000000000000000000001",
715 "027B680A"
716 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
717 "05F93925"
718 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
719 "03676854"
720 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
721 1,
722 "03FFFFFF"
723 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
724 "2", 283
725 },
726 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
727 {
728 "NIST curve K-409",
729 "0200000000000000000000000000000000000000"
730 "0000000000000000000000000000000000000000008000000000000000000001",
731 "0",
732 "1",
733 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
734 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
735 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
736 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
737 1,
738 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
739 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
740 "4", 409
741 },
742 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
743 {
744 "NIST curve B-409",
745 "0200000000000000000000000000000000000000"
746 "0000000000000000000000000000000000000000008000000000000000000001",
747 "0000000000000000000000000000000000000000"
748 "0000000000000000000000000000000000000000000000000000000000000001",
749 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
750 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
751 "015D4860D088DDB3496B0C6064756260441CDE4A"
752 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
753 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
754 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
755 1,
756 "0100000000000000000000000000000000000000"
757 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
758 "2", 409
759 },
760 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
761 {
762 "NIST curve K-571",
763 "800000000000000"
764 "0000000000000000000000000000000000000000000000000000000000000000"
765 "0000000000000000000000000000000000000000000000000000000000000425",
766 "0",
767 "1",
768 "026EB7A859923FBC"
769 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
770 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
771 "0349DC807F4FBF37"
772 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
773 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
774 0,
775 "0200000000000000"
776 "00000000000000000000000000000000000000000000000000000000131850E1"
777 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
778 "4", 571
779 },
780 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
781 {
782 "NIST curve B-571",
783 "800000000000000"
784 "0000000000000000000000000000000000000000000000000000000000000000"
785 "0000000000000000000000000000000000000000000000000000000000000425",
786 "0000000000000000"
787 "0000000000000000000000000000000000000000000000000000000000000000"
788 "0000000000000000000000000000000000000000000000000000000000000001",
789 "02F40E7E2221F295"
790 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
791 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
792 "0303001D34B85629"
793 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
794 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
795 "037BF27342DA639B"
796 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
797 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
798 1,
799 "03FFFFFFFFFFFFFF"
800 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
801 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
802 "2", 571
803 }
804 };
805
806 static int char2_curve_test(int n)
807 {
808 int r = 0;
809 BN_CTX *ctx = NULL;
810 BIGNUM *p = NULL, *a = NULL, *b = NULL;
811 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
812 EC_GROUP *group = NULL, *variable = NULL;
813 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
814 const EC_POINT *points[3];
815 const BIGNUM *scalars[3];
816 struct c2_curve_test *const test = char2_curve_tests + n;
817
818 if (!TEST_ptr(ctx = BN_CTX_new())
819 || !TEST_ptr(p = BN_new())
820 || !TEST_ptr(a = BN_new())
821 || !TEST_ptr(b = BN_new())
822 || !TEST_ptr(x = BN_new())
823 || !TEST_ptr(y = BN_new())
824 || !TEST_ptr(z = BN_new())
825 || !TEST_ptr(yplusone = BN_new())
826 || !TEST_true(BN_hex2bn(&p, test->p))
827 || !TEST_true(BN_hex2bn(&a, test->a))
828 || !TEST_true(BN_hex2bn(&b, test->b))
829 || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method()))
830 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
831 || !TEST_ptr(P = EC_POINT_new(group))
832 || !TEST_ptr(Q = EC_POINT_new(group))
833 || !TEST_ptr(R = EC_POINT_new(group))
834 || !TEST_true(BN_hex2bn(&x, test->x))
835 || !TEST_true(BN_hex2bn(&y, test->y))
836 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
837 goto err;
838
839 /* Change test based on whether binary point compression is enabled or not. */
840 # ifdef OPENSSL_EC_BIN_PT_COMP
841 /*
842 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
843 * and therefore setting the coordinates should fail.
844 */
845 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
846 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
847 test->y_bit,
848 ctx))
849 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
850 || !TEST_true(BN_hex2bn(&z, test->order))
851 || !TEST_true(BN_hex2bn(&cof, test->cof))
852 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
853 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
854 goto err;
855 TEST_info("%s -- Generator", test->name);
856 test_output_bignum("x", x);
857 test_output_bignum("y", y);
858 /* G_y value taken from the standard: */
859 if (!TEST_true(BN_hex2bn(&z, test->y))
860 || !TEST_BN_eq(y, z))
861 goto err;
862 # else
863 /*
864 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
865 * and therefore setting the coordinates should fail.
866 */
867 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
868 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
869 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
870 || !TEST_true(BN_hex2bn(&z, test->order))
871 || !TEST_true(BN_hex2bn(&cof, test->cof))
872 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
873 goto err;
874 TEST_info("%s -- Generator:", test->name);
875 test_output_bignum("x", x);
876 test_output_bignum("y", y);
877 # endif
878
879 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
880 || !group_order_tests(group)
881 || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group)))
882 || !TEST_true(EC_GROUP_copy(variable, group)))
883 goto err;
884
885 /* more tests using the last curve */
886 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
887 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
888 || !TEST_true(EC_POINT_copy(Q, P))
889 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
890 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
891 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
892 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
893 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
894 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
895 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
896 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
897 goto err;
898
899 points[0] = Q;
900 points[1] = Q;
901 points[2] = Q;
902
903 if (!TEST_true(BN_add(y, z, BN_value_one()))
904 || !TEST_BN_even(y)
905 || !TEST_true(BN_rshift1(y, y)))
906 goto err;
907 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
908 scalars[1] = y;
909
910 TEST_note("combined multiplication ...");
911
912 /* z is still the group order */
913 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
914 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
915 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
916 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
917 goto err;
918
919 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
920 || !TEST_true(BN_add(z, z, y)))
921 goto err;
922 BN_set_negative(z, 1);
923 scalars[0] = y;
924 scalars[1] = z; /* z = -(order + y) */
925
926 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
927 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
928 goto err;
929
930 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
931 || !TEST_true(BN_add(z, x, y)))
932 goto err;
933 BN_set_negative(z, 1);
934 scalars[0] = x;
935 scalars[1] = y;
936 scalars[2] = z; /* z = -(x+y) */
937
938 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
939 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
940 goto err;;
941 }
942
943 r = 1;
944 err:
945 BN_CTX_free(ctx);
946 BN_free(p);
947 BN_free(a);
948 BN_free(b);
949 BN_free(x);
950 BN_free(y);
951 BN_free(z);
952 BN_free(yplusone);
953 BN_free(cof);
954 EC_POINT_free(P);
955 EC_POINT_free(Q);
956 EC_POINT_free(R);
957 EC_GROUP_free(group);
958 EC_GROUP_free(variable);
959 return r;
960 }
961
962 static int char2_field_tests(void)
963 {
964 BN_CTX *ctx = NULL;
965 BIGNUM *p = NULL, *a = NULL, *b = NULL;
966 EC_GROUP *group = NULL, *tmp = NULL;
967 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
968 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
969 unsigned char buf[100];
970 size_t len;
971 int k, r = 0;
972
973 if (!TEST_ptr(ctx = BN_CTX_new())
974 || !TEST_ptr(p = BN_new())
975 || !TEST_ptr(a = BN_new())
976 || !TEST_ptr(b = BN_new())
977 || !TEST_true(BN_hex2bn(&p, "13"))
978 || !TEST_true(BN_hex2bn(&a, "3"))
979 || !TEST_true(BN_hex2bn(&b, "1")))
980 goto err;
981
982 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
983 * EC_GROUP_new_curve_GF2m
984 * so that the library gets
985 * to choose the EC_METHOD */
986 if (!TEST_ptr(group)
987 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
988 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
989 || !TEST_true(EC_GROUP_copy(tmp, group)))
990 goto err;
991 EC_GROUP_free(group);
992 group = tmp;
993 tmp = NULL;
994
995 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
996 goto err;
997
998 TEST_info("Curve defined by Weierstrass equation");
999 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
1000 test_output_bignum("a", a);
1001 test_output_bignum("b", b);
1002 test_output_bignum("p", p);
1003
1004 if (!TEST_ptr(P = EC_POINT_new(group))
1005 || !TEST_ptr(Q = EC_POINT_new(group))
1006 || !TEST_ptr(R = EC_POINT_new(group))
1007 || !TEST_true(EC_POINT_set_to_infinity(group, P))
1008 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1009 goto err;
1010
1011 buf[0] = 0;
1012 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
1013 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
1014 || !TEST_true(EC_POINT_is_at_infinity(group, P))
1015 || !TEST_ptr(x = BN_new())
1016 || !TEST_ptr(y = BN_new())
1017 || !TEST_ptr(z = BN_new())
1018 || !TEST_ptr(cof = BN_new())
1019 || !TEST_ptr(yplusone = BN_new())
1020 || !TEST_true(BN_hex2bn(&x, "6"))
1021 /* Change test based on whether binary point compression is enabled or not. */
1022 # ifdef OPENSSL_EC_BIN_PT_COMP
1023 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
1024 # else
1025 || !TEST_true(BN_hex2bn(&y, "8"))
1026 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
1027 # endif
1028 )
1029 goto err;
1030 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
1031 /* Change test based on whether binary point compression is enabled or not. */
1032 # ifdef OPENSSL_EC_BIN_PT_COMP
1033 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
1034 goto err;
1035 # endif
1036 TEST_info("Point is not on curve");
1037 test_output_bignum("x", x);
1038 test_output_bignum("y", y);
1039 goto err;
1040 }
1041
1042 TEST_note("A cyclic subgroup:");
1043 k = 100;
1044 do {
1045 if (!TEST_int_ne(k--, 0))
1046 goto err;
1047
1048 if (EC_POINT_is_at_infinity(group, P))
1049 TEST_note(" point at infinity");
1050 else {
1051 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1052 ctx)))
1053 goto err;
1054
1055 test_output_bignum("x", x);
1056 test_output_bignum("y", y);
1057 }
1058
1059 if (!TEST_true(EC_POINT_copy(R, P))
1060 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1061 goto err;
1062 }
1063 while (!EC_POINT_is_at_infinity(group, P));
1064
1065 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1066 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1067 goto err;
1068
1069 /* Change test based on whether binary point compression is enabled or not. */
1070 # ifdef OPENSSL_EC_BIN_PT_COMP
1071 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1072 buf, sizeof(buf), ctx);
1073 if (!TEST_size_t_ne(len, 0)
1074 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1075 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1076 goto err;
1077 test_output_memory("Generator as octet string, compressed form:",
1078 buf, len);
1079 # endif
1080
1081 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1082 buf, sizeof(buf), ctx);
1083 if (!TEST_size_t_ne(len, 0)
1084 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1085 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1086 goto err;
1087 test_output_memory("Generator as octet string, uncompressed form:",
1088 buf, len);
1089
1090 /* Change test based on whether binary point compression is enabled or not. */
1091 # ifdef OPENSSL_EC_BIN_PT_COMP
1092 len =
1093 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1094 ctx);
1095 if (!TEST_size_t_ne(len, 0)
1096 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1097 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1098 goto err;
1099 test_output_memory("Generator as octet string, hybrid form:",
1100 buf, len);
1101 # endif
1102
1103 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1104 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1105 goto err;
1106
1107 TEST_note("\n");
1108
1109 r = 1;
1110 err:
1111 BN_CTX_free(ctx);
1112 BN_free(p);
1113 BN_free(a);
1114 BN_free(b);
1115 EC_GROUP_free(group);
1116 EC_GROUP_free(tmp);
1117 EC_POINT_free(P);
1118 EC_POINT_free(Q);
1119 EC_POINT_free(R);
1120 BN_free(x);
1121 BN_free(y);
1122 BN_free(z);
1123 BN_free(cof);
1124 BN_free(yplusone);
1125 return r;
1126 }
1127 # endif
1128
1129 static int internal_curve_test(int n)
1130 {
1131 EC_GROUP *group = NULL;
1132 int nid = curves[n].nid;
1133
1134 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1135 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1136 OBJ_nid2sn(nid));
1137 return 0;
1138 }
1139 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1140 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1141 EC_GROUP_free(group);
1142 return 0;
1143 }
1144 EC_GROUP_free(group);
1145 return 1;
1146 }
1147
1148 static int internal_curve_test_method(int n)
1149 {
1150 int r, nid = curves[n].nid;
1151 EC_GROUP *group;
1152
1153 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1154 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1155 return 0;
1156 }
1157 r = group_order_tests(group);
1158 EC_GROUP_free(group);
1159 return r;
1160 }
1161
1162 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1163 /*
1164 * nistp_test_params contains magic numbers for testing our optimized
1165 * implementations of several NIST curves with characteristic > 3.
1166 */
1167 struct nistp_test_params {
1168 const EC_METHOD *(*meth) (void);
1169 int degree;
1170 /*
1171 * Qx, Qy and D are taken from
1172 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1173 * Otherwise, values are standard curve parameters from FIPS 180-3
1174 */
1175 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1176 };
1177
1178 static const struct nistp_test_params nistp_tests_params[] = {
1179 {
1180 /* P-224 */
1181 EC_GFp_nistp224_method,
1182 224,
1183 /* p */
1184 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1185 /* a */
1186 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1187 /* b */
1188 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1189 /* Qx */
1190 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1191 /* Qy */
1192 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1193 /* Gx */
1194 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1195 /* Gy */
1196 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1197 /* order */
1198 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1199 /* d */
1200 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1201 },
1202 {
1203 /* P-256 */
1204 EC_GFp_nistp256_method,
1205 256,
1206 /* p */
1207 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1208 /* a */
1209 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1210 /* b */
1211 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1212 /* Qx */
1213 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1214 /* Qy */
1215 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1216 /* Gx */
1217 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1218 /* Gy */
1219 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1220 /* order */
1221 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1222 /* d */
1223 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1224 },
1225 {
1226 /* P-521 */
1227 EC_GFp_nistp521_method,
1228 521,
1229 /* p */
1230 "1ff"
1231 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1232 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1233 /* a */
1234 "1ff"
1235 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1236 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1237 /* b */
1238 "051"
1239 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1240 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1241 /* Qx */
1242 "0098"
1243 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1244 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1245 /* Qy */
1246 "0164"
1247 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1248 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1249 /* Gx */
1250 "c6"
1251 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1252 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1253 /* Gy */
1254 "118"
1255 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1256 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1257 /* order */
1258 "1ff"
1259 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1260 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1261 /* d */
1262 "0100"
1263 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1264 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1265 },
1266 };
1267
1268 static int nistp_single_test(int idx)
1269 {
1270 const struct nistp_test_params *test = nistp_tests_params + idx;
1271 BN_CTX *ctx = NULL;
1272 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1273 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1274 EC_GROUP *NISTP = NULL;
1275 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1276 int r = 0;
1277
1278 TEST_note("NIST curve P-%d (optimised implementation):",
1279 test->degree);
1280 if (!TEST_ptr(ctx = BN_CTX_new())
1281 || !TEST_ptr(p = BN_new())
1282 || !TEST_ptr(a = BN_new())
1283 || !TEST_ptr(b = BN_new())
1284 || !TEST_ptr(x = BN_new())
1285 || !TEST_ptr(y = BN_new())
1286 || !TEST_ptr(m = BN_new())
1287 || !TEST_ptr(n = BN_new())
1288 || !TEST_ptr(order = BN_new())
1289 || !TEST_ptr(yplusone = BN_new())
1290
1291 || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1292 || !TEST_true(BN_hex2bn(&p, test->p))
1293 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
1294 || !TEST_true(BN_hex2bn(&a, test->a))
1295 || !TEST_true(BN_hex2bn(&b, test->b))
1296 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1297 || !TEST_ptr(G = EC_POINT_new(NISTP))
1298 || !TEST_ptr(P = EC_POINT_new(NISTP))
1299 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1300 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1301 || !TEST_true(BN_hex2bn(&x, test->Qx))
1302 || !TEST_true(BN_hex2bn(&y, test->Qy))
1303 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1304 /*
1305 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1306 * and therefore setting the coordinates should fail.
1307 */
1308 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1309 yplusone, ctx))
1310 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1311 ctx))
1312 || !TEST_true(BN_hex2bn(&x, test->Gx))
1313 || !TEST_true(BN_hex2bn(&y, test->Gy))
1314 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1315 || !TEST_true(BN_hex2bn(&order, test->order))
1316 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1317 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1318 goto err;
1319
1320 TEST_note("NIST test vectors ... ");
1321 if (!TEST_true(BN_hex2bn(&n, test->d)))
1322 goto err;
1323 /* fixed point multiplication */
1324 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1325 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1326 goto err;
1327 /* random point multiplication */
1328 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1329 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1330
1331 /* set generator to P = 2*G, where G is the standard generator */
1332 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1333 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1334 /* set the scalar to m=n/2, where n is the NIST test scalar */
1335 || !TEST_true(BN_rshift(m, n, 1)))
1336 goto err;
1337
1338 /* test the non-standard generator */
1339 /* fixed point multiplication */
1340 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1341 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1342 goto err;
1343 /* random point multiplication */
1344 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1345 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1346
1347 /*
1348 * We have not performed precomputation so have_precompute mult should be
1349 * false
1350 */
1351 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1352
1353 /* now repeat all tests with precomputation */
1354 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1355 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
1356 goto err;
1357
1358 /* fixed point multiplication */
1359 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1360 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1361 goto err;
1362 /* random point multiplication */
1363 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1364 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1365
1366 /* reset generator */
1367 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1368 goto err;
1369 /* fixed point multiplication */
1370 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1371 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1372 goto err;
1373 /* random point multiplication */
1374 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1375 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1376 goto err;
1377
1378 /* regression test for felem_neg bug */
1379 if (!TEST_true(BN_set_word(m, 32))
1380 || !TEST_true(BN_set_word(n, 31))
1381 || !TEST_true(EC_POINT_copy(P, G))
1382 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1383 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1384 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1385 goto err;
1386
1387 r = group_order_tests(NISTP);
1388 err:
1389 EC_GROUP_free(NISTP);
1390 EC_POINT_free(G);
1391 EC_POINT_free(P);
1392 EC_POINT_free(Q);
1393 EC_POINT_free(Q_CHECK);
1394 BN_free(n);
1395 BN_free(m);
1396 BN_free(p);
1397 BN_free(a);
1398 BN_free(b);
1399 BN_free(x);
1400 BN_free(y);
1401 BN_free(order);
1402 BN_free(yplusone);
1403 BN_CTX_free(ctx);
1404 return r;
1405 }
1406
1407 /*
1408 * Tests a point known to cause an incorrect underflow in an old version of
1409 * ecp_nist521.c
1410 */
1411 static int underflow_test(void)
1412 {
1413 BN_CTX *ctx = NULL;
1414 EC_GROUP *grp = NULL;
1415 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
1416 BIGNUM *x1 = NULL, *y1 = NULL, *z1 = NULL, *x2 = NULL, *y2 = NULL;
1417 BIGNUM *k = NULL;
1418 int testresult = 0;
1419 const char *x1str =
1420 "1534f0077fffffe87e9adcfe000000000000000000003e05a21d2400002e031b1f4"
1421 "b80000c6fafa4f3c1288798d624a247b5e2ffffffffffffffefe099241900004";
1422 const char *p521m1 =
1423 "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1424 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe";
1425
1426 ctx = BN_CTX_new();
1427 if (!TEST_ptr(ctx))
1428 return 0;
1429
1430 BN_CTX_start(ctx);
1431 x1 = BN_CTX_get(ctx);
1432 y1 = BN_CTX_get(ctx);
1433 z1 = BN_CTX_get(ctx);
1434 x2 = BN_CTX_get(ctx);
1435 y2 = BN_CTX_get(ctx);
1436 k = BN_CTX_get(ctx);
1437 if (!TEST_ptr(k))
1438 goto err;
1439
1440 grp = EC_GROUP_new_by_curve_name(NID_secp521r1);
1441 P = EC_POINT_new(grp);
1442 Q = EC_POINT_new(grp);
1443 R = EC_POINT_new(grp);
1444 if (!TEST_ptr(grp) || !TEST_ptr(P) || !TEST_ptr(Q) || !TEST_ptr(R))
1445 goto err;
1446
1447 if (!TEST_int_gt(BN_hex2bn(&x1, x1str), 0)
1448 || !TEST_int_gt(BN_hex2bn(&y1, p521m1), 0)
1449 || !TEST_int_gt(BN_hex2bn(&z1, p521m1), 0)
1450 || !TEST_int_gt(BN_hex2bn(&k, "02"), 0)
1451 || !TEST_true(EC_POINT_set_Jprojective_coordinates_GFp(grp, P, x1,
1452 y1, z1, ctx))
1453 || !TEST_true(EC_POINT_mul(grp, Q, NULL, P, k, ctx))
1454 || !TEST_true(EC_POINT_get_affine_coordinates(grp, Q, x1, y1, ctx))
1455 || !TEST_true(EC_POINT_dbl(grp, R, P, ctx))
1456 || !TEST_true(EC_POINT_get_affine_coordinates(grp, R, x2, y2, ctx)))
1457 goto err;
1458
1459 if (!TEST_int_eq(BN_cmp(x1, x2), 0)
1460 || !TEST_int_eq(BN_cmp(y1, y2), 0))
1461 goto err;
1462
1463 testresult = 1;
1464
1465 err:
1466 BN_CTX_end(ctx);
1467 EC_POINT_free(P);
1468 EC_POINT_free(Q);
1469 EC_POINT_free(R);
1470 EC_GROUP_free(grp);
1471 BN_CTX_free(ctx);
1472
1473 return testresult;
1474 }
1475 # endif
1476
1477 static const unsigned char p521_named[] = {
1478 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1479 };
1480
1481 static const unsigned char p521_explicit[] = {
1482 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1483 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1484 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1485 0xff, 0xff, 0xff, 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, 0xff,
1488 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1489 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1490 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1491 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1492 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1493 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1494 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1495 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1496 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1497 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1498 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1499 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1500 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1501 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1502 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1503 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1504 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1505 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1506 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1507 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1508 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1509 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1510 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1511 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1512 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1513 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1514 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1515 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1516 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1517 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1518 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1519 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1520 };
1521
1522 /*
1523 * Sometime we cannot compare nids for equality, as the built-in curve table
1524 * includes aliases with different names for the same curve.
1525 *
1526 * This function returns TRUE (1) if the checked nids are identical, or if they
1527 * alias to the same curve. FALSE (0) otherwise.
1528 */
1529 static ossl_inline
1530 int are_ec_nids_compatible(int n1d, int n2d)
1531 {
1532 int ret = 0;
1533 switch (n1d) {
1534 # ifndef OPENSSL_NO_EC2M
1535 case NID_sect113r1:
1536 case NID_wap_wsg_idm_ecid_wtls4:
1537 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1538 break;
1539 case NID_sect163k1:
1540 case NID_wap_wsg_idm_ecid_wtls3:
1541 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1542 break;
1543 case NID_sect233k1:
1544 case NID_wap_wsg_idm_ecid_wtls10:
1545 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1546 break;
1547 case NID_sect233r1:
1548 case NID_wap_wsg_idm_ecid_wtls11:
1549 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1550 break;
1551 case NID_X9_62_c2pnb163v1:
1552 case NID_wap_wsg_idm_ecid_wtls5:
1553 ret = (n2d == NID_X9_62_c2pnb163v1
1554 || n2d == NID_wap_wsg_idm_ecid_wtls5);
1555 break;
1556 # endif /* OPENSSL_NO_EC2M */
1557 case NID_secp112r1:
1558 case NID_wap_wsg_idm_ecid_wtls6:
1559 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1560 break;
1561 case NID_secp160r2:
1562 case NID_wap_wsg_idm_ecid_wtls7:
1563 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1564 break;
1565 # ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1566 case NID_secp224r1:
1567 case NID_wap_wsg_idm_ecid_wtls12:
1568 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1569 break;
1570 # else
1571 /*
1572 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1573 * that is associated with a specialized method.
1574 */
1575 case NID_wap_wsg_idm_ecid_wtls12:
1576 ret = (n2d == NID_secp224r1);
1577 break;
1578 # endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1579
1580 default:
1581 ret = (n1d == n2d);
1582 }
1583 return ret;
1584 }
1585
1586 /*
1587 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1588 * EC_GROUP for built-in curves.
1589 *
1590 * Note that it is possible to retrieve an alternative alias that does not match
1591 * the original nid.
1592 *
1593 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1594 */
1595 static int check_named_curve_from_ecparameters(int id)
1596 {
1597 int ret = 0, nid, tnid;
1598 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1599 const EC_POINT *group_gen = NULL;
1600 EC_POINT *other_gen = NULL;
1601 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1602 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1603 const BIGNUM *group_order = NULL;
1604 BIGNUM *other_order = NULL;
1605 BN_CTX *bn_ctx = NULL;
1606 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1607 static size_t invalid_seed_len = sizeof(invalid_seed);
1608 ECPARAMETERS *params = NULL, *other_params = NULL;
1609 EC_GROUP *g_ary[8] = {NULL};
1610 EC_GROUP **g_next = &g_ary[0];
1611 ECPARAMETERS *p_ary[8] = {NULL};
1612 ECPARAMETERS **p_next = &p_ary[0];
1613
1614 /* Do some setup */
1615 nid = curves[id].nid;
1616 TEST_note("Curve %s", OBJ_nid2sn(nid));
1617 if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1618 return ret;
1619 BN_CTX_start(bn_ctx);
1620
1621 if (/* Allocations */
1622 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1623 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1624 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1625 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1626 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1627 /* Generate reference group and params */
1628 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1629 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1630 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1631 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1632 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1633 /* compute `other_*` values */
1634 || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1635 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1636 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1637 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1638 other_gen_x, other_gen_y, bn_ctx))
1639 || !TEST_true(BN_copy(other_order, group_order))
1640 || !TEST_true(BN_add_word(other_order, 1))
1641 || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1642 || !TEST_true(BN_add_word(other_cofactor, 1)))
1643 goto err;
1644
1645 EC_POINT_free(other_gen);
1646 other_gen = NULL;
1647
1648 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1649 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1650 other_gen_x, other_gen_y,
1651 bn_ctx)))
1652 goto err;
1653
1654 /*
1655 * ###########################
1656 * # Actual tests start here #
1657 * ###########################
1658 */
1659
1660 /*
1661 * Creating a group from built-in explicit parameters returns a
1662 * "named" EC_GROUP
1663 */
1664 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1665 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1666 goto err;
1667 /*
1668 * We cannot always guarantee the names match, as the built-in table
1669 * contains aliases for the same curve with different names.
1670 */
1671 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1672 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1673 goto err;
1674 }
1675 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1676 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1677 goto err;
1678
1679 /*
1680 * An invalid seed in the parameters should be ignored: expect a "named"
1681 * group.
1682 */
1683 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1684 invalid_seed_len)
1685 || !TEST_ptr(other_params = *p_next++ =
1686 EC_GROUP_get_ecparameters(tmpg, NULL))
1687 || !TEST_ptr(tgroup = *g_next++ =
1688 EC_GROUP_new_from_ecparameters(other_params))
1689 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1690 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1691 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1692 OPENSSL_EC_EXPLICIT_CURVE)) {
1693 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1694 goto err;
1695 }
1696
1697 /*
1698 * A null seed in the parameters should be ignored, as it is optional:
1699 * expect a "named" group.
1700 */
1701 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1702 || !TEST_ptr(other_params = *p_next++ =
1703 EC_GROUP_get_ecparameters(tmpg, NULL))
1704 || !TEST_ptr(tgroup = *g_next++ =
1705 EC_GROUP_new_from_ecparameters(other_params))
1706 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1707 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1708 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1709 OPENSSL_EC_EXPLICIT_CURVE)) {
1710 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1711 goto err;
1712 }
1713
1714 /*
1715 * Check that changing any of the generator parameters does not yield a
1716 * match with the built-in curves
1717 */
1718 if (/* Other gen, same group order & cofactor */
1719 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1720 group_cofactor))
1721 || !TEST_ptr(other_params = *p_next++ =
1722 EC_GROUP_get_ecparameters(tmpg, NULL))
1723 || !TEST_ptr(tgroup = *g_next++ =
1724 EC_GROUP_new_from_ecparameters(other_params))
1725 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1726 /* Same gen & cofactor, different order */
1727 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1728 group_cofactor))
1729 || !TEST_ptr(other_params = *p_next++ =
1730 EC_GROUP_get_ecparameters(tmpg, NULL))
1731 || !TEST_ptr(tgroup = *g_next++ =
1732 EC_GROUP_new_from_ecparameters(other_params))
1733 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1734 /* The order is not an optional field, so this should fail */
1735 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1736 group_cofactor))
1737 /* Check that a wrong cofactor is ignored, and we still match */
1738 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1739 other_cofactor))
1740 || !TEST_ptr(other_params = *p_next++ =
1741 EC_GROUP_get_ecparameters(tmpg, NULL))
1742 || !TEST_ptr(tgroup = *g_next++ =
1743 EC_GROUP_new_from_ecparameters(other_params))
1744 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1745 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1746 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1747 OPENSSL_EC_EXPLICIT_CURVE)
1748 /* Check that if the cofactor is not set then it still matches */
1749 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1750 NULL))
1751 || !TEST_ptr(other_params = *p_next++ =
1752 EC_GROUP_get_ecparameters(tmpg, NULL))
1753 || !TEST_ptr(tgroup = *g_next++ =
1754 EC_GROUP_new_from_ecparameters(other_params))
1755 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1756 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1757 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1758 OPENSSL_EC_EXPLICIT_CURVE)
1759 /* check that restoring the generator passes */
1760 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1761 group_cofactor))
1762 || !TEST_ptr(other_params = *p_next++ =
1763 EC_GROUP_get_ecparameters(tmpg, NULL))
1764 || !TEST_ptr(tgroup = *g_next++ =
1765 EC_GROUP_new_from_ecparameters(other_params))
1766 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1767 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1768 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1769 OPENSSL_EC_EXPLICIT_CURVE))
1770 goto err;
1771
1772 ret = 1;
1773 err:
1774 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
1775 EC_GROUP_free(*g_next);
1776 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
1777 ECPARAMETERS_free(*p_next);
1778 ECPARAMETERS_free(params);
1779 EC_POINT_free(other_gen);
1780 EC_GROUP_free(tmpg);
1781 EC_GROUP_free(group);
1782 BN_CTX_end(bn_ctx);
1783 BN_CTX_free(bn_ctx);
1784 return ret;
1785 }
1786
1787 static int parameter_test(void)
1788 {
1789 EC_GROUP *group = NULL, *group2 = NULL;
1790 ECPARAMETERS *ecparameters = NULL;
1791 unsigned char *buf = NULL;
1792 int r = 0, len;
1793
1794 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp112r1))
1795 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1796 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1797 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1798 goto err;
1799
1800 EC_GROUP_free(group);
1801 group = NULL;
1802
1803 /* Test the named curve encoding, which should be default. */
1804 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1805 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1806 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1807 goto err;
1808
1809 OPENSSL_free(buf);
1810 buf = NULL;
1811
1812 /*
1813 * Test the explicit encoding. P-521 requires correctly zero-padding the
1814 * curve coefficients.
1815 */
1816 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1817 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1818 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
1819 goto err;
1820
1821 r = 1;
1822 err:
1823 EC_GROUP_free(group);
1824 EC_GROUP_free(group2);
1825 ECPARAMETERS_free(ecparameters);
1826 OPENSSL_free(buf);
1827 return r;
1828 }
1829
1830 /*-
1831 * random 256-bit explicit parameters curve, cofactor absent
1832 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
1833 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
1834 */
1835 static const unsigned char params_cf_pass[] = {
1836 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
1837 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
1838 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
1839 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
1840 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
1841 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
1842 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
1843 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
1844 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
1845 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
1846 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
1847 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
1848 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
1849 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
1850 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
1851 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
1852 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
1853 0x14, 0xa8, 0x2f, 0x4f
1854 };
1855
1856 /*-
1857 * random 256-bit explicit parameters curve, cofactor absent
1858 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
1859 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
1860 */
1861 static const unsigned char params_cf_fail[] = {
1862 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
1863 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
1864 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
1865 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
1866 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
1867 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
1868 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
1869 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
1870 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
1871 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
1872 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
1873 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
1874 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
1875 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
1876 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
1877 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
1878 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
1879 0x34, 0xa2, 0x21, 0x01
1880 };
1881
1882 /*-
1883 * Test two random 256-bit explicit parameters curves with absent cofactor.
1884 * The two curves are chosen to roughly straddle the bounds at which the lib
1885 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
1886 *
1887 * - params_cf_pass: order is sufficiently close to p to compute cofactor
1888 * - params_cf_fail: order is too far away from p to compute cofactor
1889 *
1890 * For standards-compliant curves, cofactor is chosen as small as possible.
1891 * So you can see neither of these curves are fit for cryptographic use.
1892 *
1893 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
1894 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
1895 * will always succeed in computing the cofactor. Neither of these curves
1896 * conform to that -- this is just robustness testing.
1897 */
1898 static int cofactor_range_test(void)
1899 {
1900 EC_GROUP *group = NULL;
1901 BIGNUM *cf = NULL;
1902 int ret = 0;
1903 const unsigned char *b1 = (const unsigned char *)params_cf_fail;
1904 const unsigned char *b2 = (const unsigned char *)params_cf_pass;
1905
1906 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
1907 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
1908 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
1909 sizeof(params_cf_pass)))
1910 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
1911 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
1912 goto err;
1913 ret = 1;
1914 err:
1915 BN_free(cf);
1916 EC_GROUP_free(group);
1917 return ret;
1918 }
1919
1920 /*-
1921 * For named curves, test that:
1922 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
1923 * - a nonsensical cofactor throws an error (negative test)
1924 * - nonsensical orders throw errors (negative tests)
1925 */
1926 static int cardinality_test(int n)
1927 {
1928 int ret = 0;
1929 int nid = curves[n].nid;
1930 BN_CTX *ctx = NULL;
1931 EC_GROUP *g1 = NULL, *g2 = NULL;
1932 EC_POINT *g2_gen = NULL;
1933 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
1934 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
1935
1936 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
1937
1938 if (!TEST_ptr(ctx = BN_CTX_new())
1939 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))
1940 || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) {
1941 EC_GROUP_free(g1);
1942 EC_GROUP_free(g2);
1943 BN_CTX_free(ctx);
1944 return 0;
1945 }
1946
1947 BN_CTX_start(ctx);
1948 g1_p = BN_CTX_get(ctx);
1949 g1_a = BN_CTX_get(ctx);
1950 g1_b = BN_CTX_get(ctx);
1951 g1_x = BN_CTX_get(ctx);
1952 g1_y = BN_CTX_get(ctx);
1953 g1_order = BN_CTX_get(ctx);
1954 g1_cf = BN_CTX_get(ctx);
1955
1956 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
1957 /* pull out the explicit curve parameters */
1958 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
1959 || !TEST_true(EC_POINT_get_affine_coordinates(g1,
1960 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
1961 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
1962 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
1963 /* construct g2 manually with g1 parameters */
1964 || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx))
1965 || !TEST_ptr(g2_gen = EC_POINT_new(g2))
1966 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
1967 /* pass NULL cofactor: lib should compute it */
1968 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
1969 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
1970 || !TEST_BN_eq(g1_cf, g2_cf)
1971 /* pass zero cofactor: lib should compute it */
1972 || !TEST_true(BN_set_word(g2_cf, 0))
1973 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
1974 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
1975 || !TEST_BN_eq(g1_cf, g2_cf)
1976 /* negative test for invalid cofactor */
1977 || !TEST_true(BN_set_word(g2_cf, 0))
1978 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
1979 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
1980 /* negative test for NULL order */
1981 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
1982 /* negative test for zero order */
1983 || !TEST_true(BN_set_word(g1_order, 0))
1984 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
1985 /* negative test for negative order */
1986 || !TEST_true(BN_set_word(g2_cf, 0))
1987 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
1988 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
1989 /* negative test for too large order */
1990 || !TEST_true(BN_lshift(g1_order, g1_p, 2))
1991 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
1992 goto err;
1993 ret = 1;
1994 err:
1995 EC_POINT_free(g2_gen);
1996 EC_GROUP_free(g1);
1997 EC_GROUP_free(g2);
1998 BN_CTX_end(ctx);
1999 BN_CTX_free(ctx);
2000 return ret;
2001 }
2002
2003 /*
2004 * Helper for ec_point_hex2point_test
2005 *
2006 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2007 * (group,P) pair.
2008 *
2009 * If P is NULL use point at infinity.
2010 */
2011 static ossl_inline
2012 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2013 point_conversion_form_t form,
2014 BN_CTX *bnctx)
2015 {
2016 int ret = 0;
2017 EC_POINT *Q = NULL, *Pinf = NULL;
2018 char *hex = NULL;
2019
2020 if (P == NULL) {
2021 /* If P is NULL use point at infinity. */
2022 if (!TEST_ptr(Pinf = EC_POINT_new(group))
2023 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2024 goto err;
2025 P = Pinf;
2026 }
2027
2028 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2029 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2030 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2031 goto err;
2032
2033 /*
2034 * The next check is most likely superfluous, as EC_POINT_cmp should already
2035 * cover this.
2036 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2037 * so we include it anyway!
2038 */
2039 if (Pinf != NULL
2040 && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2041 goto err;
2042
2043 ret = 1;
2044
2045 err:
2046 EC_POINT_free(Pinf);
2047 OPENSSL_free(hex);
2048 EC_POINT_free(Q);
2049
2050 return ret;
2051 }
2052
2053 /*
2054 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2055 */
2056 static int ec_point_hex2point_test(int id)
2057 {
2058 int ret = 0, nid;
2059 EC_GROUP *group = NULL;
2060 const EC_POINT *G = NULL;
2061 EC_POINT *P = NULL;
2062 BN_CTX * bnctx = NULL;
2063
2064 /* Do some setup */
2065 nid = curves[id].nid;
2066 if (!TEST_ptr(bnctx = BN_CTX_new())
2067 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2068 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2069 || !TEST_ptr(P = EC_POINT_dup(G, group)))
2070 goto err;
2071
2072 if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2073 POINT_CONVERSION_COMPRESSED,
2074 bnctx))
2075 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2076 POINT_CONVERSION_COMPRESSED,
2077 bnctx))
2078 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2079 POINT_CONVERSION_UNCOMPRESSED,
2080 bnctx))
2081 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2082 POINT_CONVERSION_UNCOMPRESSED,
2083 bnctx))
2084 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2085 POINT_CONVERSION_HYBRID,
2086 bnctx))
2087 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2088 POINT_CONVERSION_HYBRID,
2089 bnctx)))
2090 goto err;
2091
2092 ret = 1;
2093
2094 err:
2095 EC_POINT_free(P);
2096 EC_GROUP_free(group);
2097 BN_CTX_free(bnctx);
2098
2099 return ret;
2100 }
2101
2102 #endif /* OPENSSL_NO_EC */
2103
2104 int setup_tests(void)
2105 {
2106 #ifndef OPENSSL_NO_EC
2107 crv_len = EC_get_builtin_curves(NULL, 0);
2108 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2109 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2110 return 0;
2111
2112 ADD_TEST(parameter_test);
2113 ADD_TEST(cofactor_range_test);
2114 ADD_ALL_TESTS(cardinality_test, crv_len);
2115 ADD_TEST(prime_field_tests);
2116 # ifndef OPENSSL_NO_EC2M
2117 ADD_TEST(char2_field_tests);
2118 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2119 # endif
2120 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
2121 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2122 ADD_TEST(underflow_test);
2123 # endif
2124 ADD_ALL_TESTS(internal_curve_test, crv_len);
2125 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2126
2127 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2128 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2129 #endif /* OPENSSL_NO_EC */
2130 return 1;
2131 }
2132
2133 void cleanup_tests(void)
2134 {
2135 #ifndef OPENSSL_NO_EC
2136 OPENSSL_free(curves);
2137 #endif
2138 }