]> git.ipfire.org Git - thirdparty/openssl.git/blob - test/ectest.c
doc fixups
[thirdparty/openssl.git] / test / ectest.c
1 /*
2 * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4 *
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
9 */
10
11 #include <string.h>
12 #include "internal/nelem.h"
13 #include "testutil.h"
14
15 #ifndef OPENSSL_NO_EC
16 # include <openssl/ec.h>
17 # ifndef OPENSSL_NO_ENGINE
18 # include <openssl/engine.h>
19 # endif
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>
26
27 static size_t crv_len = 0;
28 static EC_builtin_curve *curves = NULL;
29
30 /* test multiplication with group order, long and negative scalars */
31 static int group_order_tests(EC_GROUP *group)
32 {
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;
36 BN_CTX *ctx = NULL;
37 int i = 0, r = 0;
38
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)))
48 goto err;
49
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)))
64 goto err;
65
66 for (i = 1; i <= 2; i++) {
67 const BIGNUM *scalars[6];
68 const EC_POINT *points[6];
69
70 if (!TEST_true(BN_set_word(n1, i))
71 /*
72 * If i == 1, P will be the predefined generator for which
73 * EC_GROUP_precompute_mult has set up precomputation.
74 */
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))
78 /* n1 = 1 - order */
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))
82
83 /* n2 = 1 + order */
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))
87
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)))
92 goto err;
93
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))
100
101 /* Exercise EC_POINTs_mul, including corner cases. */
102 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
103 goto err;
104
105 scalars[0] = scalars[1] = BN_value_one();
106 points[0] = points[1] = P;
107
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)))
111 goto err;
112
113 scalars[0] = n1;
114 points[0] = Q; /* => infinity */
115 scalars[1] = n2;
116 points[1] = P; /* => -P */
117 scalars[2] = n1;
118 points[2] = Q; /* => infinity */
119 scalars[3] = n2;
120 points[3] = Q; /* => infinity */
121 scalars[4] = n1;
122 points[4] = P; /* => P */
123 scalars[5] = n2;
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)))
127 goto err;
128 }
129
130 r = 1;
131 err:
132 if (r == 0 && i != 0)
133 TEST_info(i == 1 ? "allowing precomputation" :
134 "without precomputation");
135 EC_POINT_free(P);
136 EC_POINT_free(Q);
137 EC_POINT_free(R);
138 EC_POINT_free(S);
139 BN_free(n1);
140 BN_free(n2);
141 BN_free(order);
142 BN_CTX_free(ctx);
143 return r;
144 }
145
146 static int prime_field_tests(void)
147 {
148 BN_CTX *ctx = NULL;
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];
158 size_t len, r = 0;
159 int k;
160
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"))
168 /*
169 * applications should use EC_GROUP_new_curve_GFp so
170 * that the library gets to choose the EC_METHOD
171 */
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)))
176 goto err;
177 EC_GROUP_free(group);
178 group = tmp;
179 tmp = NULL;
180
181 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
182 goto err;
183
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);
189
190 buf[0] = 0;
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)))
205 goto err;
206
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)))
209 goto err;
210 TEST_info("Point is not on curve");
211 test_output_bignum("x", x);
212 test_output_bignum("y", y);
213 goto err;
214 }
215
216 TEST_note("A cyclic subgroup:");
217 k = 100;
218 do {
219 if (!TEST_int_ne(k--, 0))
220 goto err;
221
222 if (EC_POINT_is_at_infinity(group, P)) {
223 TEST_note(" point at infinity");
224 } else {
225 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
226 ctx)))
227 goto err;
228
229 test_output_bignum("x", x);
230 test_output_bignum("y", y);
231 }
232
233 if (!TEST_true(EC_POINT_copy(R, P))
234 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
235 goto err;
236
237 } while (!EC_POINT_is_at_infinity(group, P));
238
239 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
240 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
241 goto err;
242
243 len =
244 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
245 sizeof(buf), ctx);
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)))
249 goto err;
250 test_output_memory("Generator as octet string, compressed form:",
251 buf, len);
252
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)))
258 goto err;
259 test_output_memory("Generator as octet string, uncompressed form:",
260 buf, len);
261
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)))
267 goto err;
268 test_output_memory("Generator as octet string, hybrid form:",
269 buf, len);
270
271 if (!TEST_true(EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z,
272 ctx)))
273 goto err;
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);
279
280 if (!TEST_true(EC_POINT_invert(group, P, ctx))
281 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
282
283 /*
284 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
285 * 2000) -- not a NIST curve, but commonly used
286 */
287
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()))
301 /*
302 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
303 * and therefore setting the coordinates should fail.
304 */
305 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
306 ctx))
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)))
313 goto err;
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"))
320 || !TEST_BN_eq(y, z)
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))
325
326 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
327
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)))
344 goto err;
345
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"))
352 || !TEST_BN_eq(y, z)
353 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
354 /*
355 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
356 * and therefore setting the coordinates should fail.
357 */
358 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
359 ctx))
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))
364
365 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
366
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)))
383 goto err;
384
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"))
391 || !TEST_BN_eq(y, z)
392 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
393 /*
394 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
395 * and therefore setting the coordinates should fail.
396 */
397 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
398 ctx))
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))
403
404 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
405
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))
414
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)))
423 goto err;
424
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"))
431 || !TEST_BN_eq(y, z)
432 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
433 /*
434 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
435 * and therefore setting the coordinates should fail.
436 */
437 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
438 ctx))
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))
443
444 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
445
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))
457
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)))
468 goto err;
469
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"))
477 || !TEST_BN_eq(y, z)
478 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
479 /*
480 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
481 * and therefore setting the coordinates should fail.
482 */
483 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
484 ctx))
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))
489
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)))
522 goto err;
523
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"))
533 || !TEST_BN_eq(y, z)
534 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
535 /*
536 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
537 * and therefore setting the coordinates should fail.
538 */
539 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
540 ctx))
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))
545
546 /* more tests using the last curve */
547
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)))
559 goto err;
560 points[0] = Q;
561 points[1] = Q;
562 points[2] = Q;
563 points[3] = Q;
564
565 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
566 || !TEST_true(BN_add(y, z, BN_value_one()))
567 || !TEST_BN_even(y)
568 || !TEST_true(BN_rshift1(y, y)))
569 goto err;
570 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
571 scalars[1] = y;
572
573 TEST_note("combined multiplication ...");
574
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)))
582 goto err;
583 BN_set_negative(z, 1);
584 scalars[0] = y;
585 scalars[1] = z; /* z = -(order + y) */
586
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)))
591 goto err;
592 BN_set_negative(z, 1);
593 scalars[0] = x;
594 scalars[1] = y;
595 scalars[2] = z; /* z = -(x+y) */
596
597 if (!TEST_ptr(scalar3 = BN_new()))
598 goto err;
599 BN_zero(scalar3);
600 scalars[3] = scalar3;
601
602 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
603 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
604 goto err;
605
606 TEST_note(" ok\n");
607
608
609 r = 1;
610 err:
611 BN_CTX_free(ctx);
612 BN_free(p);
613 BN_free(a);
614 BN_free(b);
615 EC_GROUP_free(group);
616 EC_GROUP_free(tmp);
617 EC_POINT_free(P);
618 EC_POINT_free(Q);
619 EC_POINT_free(R);
620 BN_free(x);
621 BN_free(y);
622 BN_free(z);
623 BN_free(yplusone);
624 BN_free(scalar3);
625
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);
632 return r;
633 }
634
635 # ifndef OPENSSL_NO_EC2M
636
637 static struct c2_curve_test {
638 const char *name;
639 const char *p;
640 const char *a;
641 const char *b;
642 const char *x;
643 const char *y;
644 int ybit;
645 const char *order;
646 const char *cof;
647 int degree;
648 } char2_curve_tests[] = {
649 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
650 {
651 "NIST curve K-163",
652 "0800000000000000000000000000000000000000C9",
653 "1",
654 "1",
655 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
656 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
657 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
658 },
659 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
660 {
661 "NIST curve B-163",
662 "0800000000000000000000000000000000000000C9",
663 "1",
664 "020A601907B8C953CA1481EB10512F78744A3205FD",
665 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
666 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
667 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
668 },
669 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
670 {
671 "NIST curve K-233",
672 "020000000000000000000000000000000000000004000000000000000001",
673 "0",
674 "1",
675 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
676 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
677 0,
678 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
679 "4", 233
680 },
681 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
682 {
683 "NIST curve B-233",
684 "020000000000000000000000000000000000000004000000000000000001",
685 "000000000000000000000000000000000000000000000000000000000001",
686 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
687 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
688 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
689 1,
690 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
691 "2", 233
692 },
693 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
694 {
695 "NIST curve K-283",
696 "08000000"
697 "00000000000000000000000000000000000000000000000000000000000010A1",
698 "0",
699 "1",
700 "0503213F"
701 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
702 "01CCDA38"
703 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
704 0,
705 "01FFFFFF"
706 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
707 "4", 283
708 },
709 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
710 {
711 "NIST curve B-283",
712 "08000000"
713 "00000000000000000000000000000000000000000000000000000000000010A1",
714 "00000000"
715 "0000000000000000000000000000000000000000000000000000000000000001",
716 "027B680A"
717 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
718 "05F93925"
719 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
720 "03676854"
721 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
722 1,
723 "03FFFFFF"
724 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
725 "2", 283
726 },
727 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
728 {
729 "NIST curve K-409",
730 "0200000000000000000000000000000000000000"
731 "0000000000000000000000000000000000000000008000000000000000000001",
732 "0",
733 "1",
734 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
735 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
736 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
737 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
738 1,
739 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
740 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
741 "4", 409
742 },
743 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
744 {
745 "NIST curve B-409",
746 "0200000000000000000000000000000000000000"
747 "0000000000000000000000000000000000000000008000000000000000000001",
748 "0000000000000000000000000000000000000000"
749 "0000000000000000000000000000000000000000000000000000000000000001",
750 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
751 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
752 "015D4860D088DDB3496B0C6064756260441CDE4A"
753 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
754 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
755 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
756 1,
757 "0100000000000000000000000000000000000000"
758 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
759 "2", 409
760 },
761 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
762 {
763 "NIST curve K-571",
764 "800000000000000"
765 "0000000000000000000000000000000000000000000000000000000000000000"
766 "0000000000000000000000000000000000000000000000000000000000000425",
767 "0",
768 "1",
769 "026EB7A859923FBC"
770 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
771 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
772 "0349DC807F4FBF37"
773 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
774 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
775 0,
776 "0200000000000000"
777 "00000000000000000000000000000000000000000000000000000000131850E1"
778 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
779 "4", 571
780 },
781 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
782 {
783 "NIST curve B-571",
784 "800000000000000"
785 "0000000000000000000000000000000000000000000000000000000000000000"
786 "0000000000000000000000000000000000000000000000000000000000000425",
787 "0000000000000000"
788 "0000000000000000000000000000000000000000000000000000000000000000"
789 "0000000000000000000000000000000000000000000000000000000000000001",
790 "02F40E7E2221F295"
791 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
792 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
793 "0303001D34B85629"
794 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
795 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
796 "037BF27342DA639B"
797 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
798 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
799 1,
800 "03FFFFFFFFFFFFFF"
801 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
802 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
803 "2", 571
804 }
805 };
806
807 static int char2_curve_test(int n)
808 {
809 int r = 0;
810 BN_CTX *ctx = NULL;
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;
818
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())))
838 goto err;
839
840 /* Change test based on whether binary point compression is enabled or not. */
841 # ifdef OPENSSL_EC_BIN_PT_COMP
842 /*
843 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
844 * and therefore setting the coordinates should fail.
845 */
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,
848 test->y_bit,
849 ctx))
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)))
855 goto err;
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))
862 goto err;
863 # else
864 /*
865 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
866 * and therefore setting the coordinates should fail.
867 */
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)))
874 goto err;
875 TEST_info("%s -- Generator:", test->name);
876 test_output_bignum("x", x);
877 test_output_bignum("y", y);
878 # endif
879
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)))
884 goto err;
885
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)))
898 goto err;
899
900 points[0] = Q;
901 points[1] = Q;
902 points[2] = Q;
903
904 if (!TEST_true(BN_add(y, z, BN_value_one()))
905 || !TEST_BN_even(y)
906 || !TEST_true(BN_rshift1(y, y)))
907 goto err;
908 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
909 scalars[1] = y;
910
911 TEST_note("combined multiplication ...");
912
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)))
918 goto err;
919
920 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
921 || !TEST_true(BN_add(z, z, y)))
922 goto err;
923 BN_set_negative(z, 1);
924 scalars[0] = y;
925 scalars[1] = z; /* z = -(order + y) */
926
927 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
928 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
929 goto err;
930
931 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
932 || !TEST_true(BN_add(z, x, y)))
933 goto err;
934 BN_set_negative(z, 1);
935 scalars[0] = x;
936 scalars[1] = y;
937 scalars[2] = z; /* z = -(x+y) */
938
939 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
940 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
941 goto err;;
942 }
943
944 r = 1;
945 err:
946 BN_CTX_free(ctx);
947 BN_free(p);
948 BN_free(a);
949 BN_free(b);
950 BN_free(x);
951 BN_free(y);
952 BN_free(z);
953 BN_free(yplusone);
954 BN_free(cof);
955 EC_POINT_free(P);
956 EC_POINT_free(Q);
957 EC_POINT_free(R);
958 EC_GROUP_free(group);
959 EC_GROUP_free(variable);
960 return r;
961 }
962
963 static int char2_field_tests(void)
964 {
965 BN_CTX *ctx = NULL;
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];
971 size_t len;
972 int k, r = 0;
973
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")))
981 goto err;
982
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 */
987 if (!TEST_ptr(group)
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)))
991 goto err;
992 EC_GROUP_free(group);
993 group = tmp;
994 tmp = NULL;
995
996 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
997 goto err;
998
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);
1004
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)))
1010 goto err;
1011
1012 buf[0] = 0;
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))
1025 # else
1026 || !TEST_true(BN_hex2bn(&y, "8"))
1027 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
1028 # endif
1029 )
1030 goto err;
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)))
1035 goto err;
1036 # endif
1037 TEST_info("Point is not on curve");
1038 test_output_bignum("x", x);
1039 test_output_bignum("y", y);
1040 goto err;
1041 }
1042
1043 TEST_note("A cyclic subgroup:");
1044 k = 100;
1045 do {
1046 if (!TEST_int_ne(k--, 0))
1047 goto err;
1048
1049 if (EC_POINT_is_at_infinity(group, P))
1050 TEST_note(" point at infinity");
1051 else {
1052 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1053 ctx)))
1054 goto err;
1055
1056 test_output_bignum("x", x);
1057 test_output_bignum("y", y);
1058 }
1059
1060 if (!TEST_true(EC_POINT_copy(R, P))
1061 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1062 goto err;
1063 }
1064 while (!EC_POINT_is_at_infinity(group, P));
1065
1066 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1067 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1068 goto err;
1069
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)))
1077 goto err;
1078 test_output_memory("Generator as octet string, compressed form:",
1079 buf, len);
1080 # endif
1081
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)))
1087 goto err;
1088 test_output_memory("Generator as octet string, uncompressed form:",
1089 buf, len);
1090
1091 /* Change test based on whether binary point compression is enabled or not. */
1092 # ifdef OPENSSL_EC_BIN_PT_COMP
1093 len =
1094 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1095 ctx);
1096 if (!TEST_size_t_ne(len, 0)
1097 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1098 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1099 goto err;
1100 test_output_memory("Generator as octet string, hybrid form:",
1101 buf, len);
1102 # endif
1103
1104 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1105 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1106 goto err;
1107
1108 TEST_note("\n");
1109
1110 r = 1;
1111 err:
1112 BN_CTX_free(ctx);
1113 BN_free(p);
1114 BN_free(a);
1115 BN_free(b);
1116 EC_GROUP_free(group);
1117 EC_GROUP_free(tmp);
1118 EC_POINT_free(P);
1119 EC_POINT_free(Q);
1120 EC_POINT_free(R);
1121 BN_free(x);
1122 BN_free(y);
1123 BN_free(z);
1124 BN_free(cof);
1125 BN_free(yplusone);
1126 return r;
1127 }
1128 # endif
1129
1130 static int internal_curve_test(int n)
1131 {
1132 EC_GROUP *group = NULL;
1133 int nid = curves[n].nid;
1134
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",
1137 OBJ_nid2sn(nid));
1138 return 0;
1139 }
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);
1143 return 0;
1144 }
1145 EC_GROUP_free(group);
1146 return 1;
1147 }
1148
1149 static int internal_curve_test_method(int n)
1150 {
1151 int r, nid = curves[n].nid;
1152 EC_GROUP *group;
1153
1154 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1155 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1156 return 0;
1157 }
1158 r = group_order_tests(group);
1159 EC_GROUP_free(group);
1160 return r;
1161 }
1162
1163 static int group_field_test(void)
1164 {
1165 int r = 1;
1166 BIGNUM *secp521r1_field = NULL;
1167 BIGNUM *sect163r2_field = NULL;
1168 EC_GROUP *secp521r1_group = NULL;
1169 EC_GROUP *sect163r2_group = NULL;
1170
1171 BN_hex2bn(&secp521r1_field,
1172 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1173 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1174 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1175 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1176 "FFFF");
1177
1178
1179 BN_hex2bn(&sect163r2_field,
1180 "08000000000000000000000000000000"
1181 "00000000C9");
1182
1183 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1184 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1185 r = 0;
1186
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)))
1190 r = 0;
1191 # endif
1192
1193 EC_GROUP_free(secp521r1_group);
1194 EC_GROUP_free(sect163r2_group);
1195 BN_free(secp521r1_field);
1196 BN_free(sect163r2_field);
1197 return r;
1198 }
1199
1200 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1201 /*
1202 * nistp_test_params contains magic numbers for testing our optimized
1203 * implementations of several NIST curves with characteristic > 3.
1204 */
1205 struct nistp_test_params {
1206 const EC_METHOD *(*meth) (void);
1207 int degree;
1208 /*
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
1212 */
1213 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1214 };
1215
1216 static const struct nistp_test_params nistp_tests_params[] = {
1217 {
1218 /* P-224 */
1219 EC_GFp_nistp224_method,
1220 224,
1221 /* p */
1222 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1223 /* a */
1224 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1225 /* b */
1226 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1227 /* Qx */
1228 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1229 /* Qy */
1230 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1231 /* Gx */
1232 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1233 /* Gy */
1234 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1235 /* order */
1236 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1237 /* d */
1238 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1239 },
1240 {
1241 /* P-256 */
1242 EC_GFp_nistp256_method,
1243 256,
1244 /* p */
1245 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1246 /* a */
1247 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1248 /* b */
1249 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1250 /* Qx */
1251 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1252 /* Qy */
1253 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1254 /* Gx */
1255 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1256 /* Gy */
1257 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1258 /* order */
1259 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1260 /* d */
1261 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1262 },
1263 {
1264 /* P-521 */
1265 EC_GFp_nistp521_method,
1266 521,
1267 /* p */
1268 "1ff"
1269 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1270 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1271 /* a */
1272 "1ff"
1273 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1274 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1275 /* b */
1276 "051"
1277 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1278 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1279 /* Qx */
1280 "0098"
1281 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1282 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1283 /* Qy */
1284 "0164"
1285 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1286 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1287 /* Gx */
1288 "c6"
1289 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1290 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1291 /* Gy */
1292 "118"
1293 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1294 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1295 /* order */
1296 "1ff"
1297 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1298 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1299 /* d */
1300 "0100"
1301 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1302 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1303 },
1304 };
1305
1306 static int nistp_single_test(int idx)
1307 {
1308 const struct nistp_test_params *test = nistp_tests_params + idx;
1309 BN_CTX *ctx = NULL;
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;
1314 int r = 0;
1315
1316 TEST_note("NIST curve P-%d (optimised implementation):",
1317 test->degree);
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())
1328
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()))
1342 /*
1343 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1344 * and therefore setting the coordinates should fail.
1345 */
1346 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1347 yplusone, ctx))
1348 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1349 ctx))
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))
1356 goto err;
1357
1358 TEST_note("NIST test vectors ... ");
1359 if (!TEST_true(BN_hex2bn(&n, test->d)))
1360 goto err;
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)))
1364 goto err;
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))
1368
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)))
1374 goto err;
1375
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)))
1380 goto err;
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))
1384
1385 /*
1386 * We have not performed precomputation so have_precompute mult should be
1387 * false
1388 */
1389 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1390
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)))
1394 goto err;
1395
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)))
1399 goto err;
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))
1403
1404 /* reset generator */
1405 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1406 goto err;
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)))
1410 goto err;
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)))
1414 goto err;
1415
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)))
1423 goto err;
1424
1425 r = group_order_tests(NISTP);
1426 err:
1427 EC_GROUP_free(NISTP);
1428 EC_POINT_free(G);
1429 EC_POINT_free(P);
1430 EC_POINT_free(Q);
1431 EC_POINT_free(Q_CHECK);
1432 BN_free(n);
1433 BN_free(m);
1434 BN_free(p);
1435 BN_free(a);
1436 BN_free(b);
1437 BN_free(x);
1438 BN_free(y);
1439 BN_free(order);
1440 BN_free(yplusone);
1441 BN_CTX_free(ctx);
1442 return r;
1443 }
1444
1445 /*
1446 * Tests a point known to cause an incorrect underflow in an old version of
1447 * ecp_nist521.c
1448 */
1449 static int underflow_test(void)
1450 {
1451 BN_CTX *ctx = NULL;
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;
1455 BIGNUM *k = NULL;
1456 int testresult = 0;
1457 const char *x1str =
1458 "1534f0077fffffe87e9adcfe000000000000000000003e05a21d2400002e031b1f4"
1459 "b80000c6fafa4f3c1288798d624a247b5e2ffffffffffffffefe099241900004";
1460 const char *p521m1 =
1461 "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1462 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe";
1463
1464 ctx = BN_CTX_new();
1465 if (!TEST_ptr(ctx))
1466 return 0;
1467
1468 BN_CTX_start(ctx);
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);
1475 if (!TEST_ptr(k))
1476 goto err;
1477
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))
1483 goto err;
1484
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,
1490 y1, z1, ctx))
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)))
1495 goto err;
1496
1497 if (!TEST_int_eq(BN_cmp(x1, x2), 0)
1498 || !TEST_int_eq(BN_cmp(y1, y2), 0))
1499 goto err;
1500
1501 testresult = 1;
1502
1503 err:
1504 BN_CTX_end(ctx);
1505 EC_POINT_free(P);
1506 EC_POINT_free(Q);
1507 EC_POINT_free(R);
1508 EC_GROUP_free(grp);
1509 BN_CTX_free(ctx);
1510
1511 return testresult;
1512 }
1513 # endif
1514
1515 static const unsigned char p521_named[] = {
1516 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1517 };
1518
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,
1558 };
1559
1560 /*
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.
1564 */
1565 static int check_named_curve_test(int id)
1566 {
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);
1579
1580 /* Do some setup */
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)))
1603 goto err;
1604
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)))
1611 goto err;
1612 } else {
1613 if (!TEST_ptr(other_p = BN_dup(group_p)))
1614 goto err;
1615 /*
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.
1619 */
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())))
1624 goto err;
1625 }
1626
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))
1632 goto err;
1633
1634 /* Fail if the curve name doesn't match the parameters */
1635 EC_GROUP_set_curve_name(group, nid + 1);
1636 ERR_set_mark();
1637 if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0), 0))
1638 goto err;
1639 ERR_pop_to_mark();
1640
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))
1644 goto err;
1645
1646 if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len),
1647 invalid_seed_len))
1648 goto err;
1649
1650 if (has_seed) {
1651 /*
1652 * If the built-in curve has a seed and we set the seed to another value
1653 * then it will fail the check.
1654 */
1655 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0), 0))
1656 goto err;
1657 } else {
1658 /*
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).
1661 */
1662 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0), nid))
1663 goto err;
1664 }
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))
1668 goto err;
1669
1670 /* Check that a duped group passes */
1671 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0), nid))
1672 goto err;
1673
1674 /* check that changing any generator parameter fails */
1675 if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order,
1676 group_cofactor))
1677 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0), 0)
1678 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order,
1679 group_cofactor))
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,
1683 group_cofactor))
1684 || !TEST_int_le(EC_GROUP_check_named_curve(gtest, 0), 0)
1685 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1686 other_cofactor))
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,
1690 NULL))
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,
1694 group_cofactor))
1695 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0), nid))
1696 goto err;
1697
1698 /*
1699 * check that changing any curve parameter fails
1700 *
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().
1704 */
1705 ERR_set_mark();
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))
1708 goto err;
1709 } else {
1710 /* clear the error stack if EC_GROUP_set_curve() failed */
1711 ERR_pop_to_mark();
1712 ERR_set_mark();
1713 }
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))
1716 goto err;
1717 } else {
1718 /* clear the error stack if EC_GROUP_set_curve() failed */
1719 ERR_pop_to_mark();
1720 ERR_set_mark();
1721 }
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))
1724 goto err;
1725 } else {
1726 /* clear the error stack if EC_GROUP_set_curve() failed */
1727 ERR_pop_to_mark();
1728 ERR_set_mark();
1729 }
1730 ERR_pop_to_mark();
1731
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))
1735 goto err;
1736
1737 ret = 1;
1738 err:
1739 BN_free(group_p);
1740 BN_free(other_p);
1741 BN_free(group_a);
1742 BN_free(other_a);
1743 BN_free(group_b);
1744 BN_free(other_b);
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);
1752 return ret;
1753 }
1754
1755 /*
1756 * This checks the lookup capability of EC_GROUP_check_named_curve()
1757 * when the given group was created with explicit parameters.
1758 *
1759 * It is possible to retrieve an alternative alias that does not match
1760 * the original nid in this case.
1761 */
1762 static int check_named_curve_lookup_test(int id)
1763 {
1764 int ret = 0, nid, rv = 0;
1765 EC_GROUP *g = NULL , *ga = NULL;
1766 ECPARAMETERS *p = NULL, *pa = NULL;
1767 BN_CTX *ctx = NULL;
1768
1769 /* Do some setup */
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)))
1774 goto err;
1775
1776 /* replace with group from explicit parameters */
1777 EC_GROUP_free(g);
1778 if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p)))
1779 goto err;
1780
1781 if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0), 0))
1782 goto err;
1783 if (rv != nid) {
1784 /*
1785 * Found an alias:
1786 * fail if the returned nid is not an alias of the original group.
1787 *
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
1791 * EC_METHODs.
1792 */
1793 if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv))
1794 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL)))
1795 goto err;
1796
1797 /* replace with group from explicit parameters, then compare */
1798 EC_GROUP_free(ga);
1799 if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa))
1800 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0))
1801 goto err;
1802 }
1803
1804 ret = 1;
1805
1806 err:
1807 EC_GROUP_free(g);
1808 EC_GROUP_free(ga);
1809 ECPARAMETERS_free(p);
1810 ECPARAMETERS_free(pa);
1811 BN_CTX_free(ctx);
1812
1813 return ret;
1814 }
1815
1816 static int parameter_test(void)
1817 {
1818 EC_GROUP *group = NULL, *group2 = NULL;
1819 ECPARAMETERS *ecparameters = NULL;
1820 unsigned char *buf = NULL;
1821 int r = 0, len;
1822
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))
1827 goto err;
1828
1829 EC_GROUP_free(group);
1830 group = NULL;
1831
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)))
1836 goto err;
1837
1838 OPENSSL_free(buf);
1839 buf = NULL;
1840
1841 /*
1842 * Test the explicit encoding. P-521 requires correctly zero-padding the
1843 * curve coefficients.
1844 */
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)))
1848 goto err;
1849
1850 r = 1;
1851 err:
1852 EC_GROUP_free(group);
1853 EC_GROUP_free(group2);
1854 ECPARAMETERS_free(ecparameters);
1855 OPENSSL_free(buf);
1856 return r;
1857 }
1858 #endif
1859
1860 int setup_tests(void)
1861 {
1862 #ifndef OPENSSL_NO_EC
1863 crv_len = EC_get_builtin_curves(NULL, 0);
1864 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
1865 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
1866 return 0;
1867
1868 ADD_TEST(parameter_test);
1869 ADD_TEST(prime_field_tests);
1870 # ifndef OPENSSL_NO_EC2M
1871 ADD_TEST(char2_field_tests);
1872 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
1873 # endif
1874 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1875 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
1876 ADD_TEST(underflow_test);
1877 # endif
1878 ADD_ALL_TESTS(internal_curve_test, crv_len);
1879 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
1880 ADD_TEST(group_field_test);
1881 ADD_ALL_TESTS(check_named_curve_test, crv_len);
1882 ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
1883 #endif
1884 return 1;
1885 }
1886
1887 void cleanup_tests(void)
1888 {
1889 #ifndef OPENSSL_NO_EC
1890 OPENSSL_free(curves);
1891 #endif
1892 }