]> git.ipfire.org Git - thirdparty/openssl.git/blob - test/ectest.c
Rename the PROVIDER_CONF trace to CONF
[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 "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 static int group_field_test(void)
1163 {
1164 int r = 1;
1165 BIGNUM *secp521r1_field = NULL;
1166 BIGNUM *sect163r2_field = NULL;
1167 EC_GROUP *secp521r1_group = NULL;
1168 EC_GROUP *sect163r2_group = NULL;
1169
1170 BN_hex2bn(&secp521r1_field,
1171 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1172 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1173 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1174 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1175 "FFFF");
1176
1177
1178 BN_hex2bn(&sect163r2_field,
1179 "08000000000000000000000000000000"
1180 "00000000C9");
1181
1182 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1183 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1184 r = 0;
1185
1186 # ifndef OPENSSL_NO_EC2M
1187 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1188 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1189 r = 0;
1190 # endif
1191
1192 EC_GROUP_free(secp521r1_group);
1193 EC_GROUP_free(sect163r2_group);
1194 BN_free(secp521r1_field);
1195 BN_free(sect163r2_field);
1196 return r;
1197 }
1198
1199 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1200 /*
1201 * nistp_test_params contains magic numbers for testing our optimized
1202 * implementations of several NIST curves with characteristic > 3.
1203 */
1204 struct nistp_test_params {
1205 const EC_METHOD *(*meth) (void);
1206 int degree;
1207 /*
1208 * Qx, Qy and D are taken from
1209 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1210 * Otherwise, values are standard curve parameters from FIPS 180-3
1211 */
1212 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1213 };
1214
1215 static const struct nistp_test_params nistp_tests_params[] = {
1216 {
1217 /* P-224 */
1218 EC_GFp_nistp224_method,
1219 224,
1220 /* p */
1221 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1222 /* a */
1223 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1224 /* b */
1225 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1226 /* Qx */
1227 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1228 /* Qy */
1229 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1230 /* Gx */
1231 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1232 /* Gy */
1233 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1234 /* order */
1235 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1236 /* d */
1237 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1238 },
1239 {
1240 /* P-256 */
1241 EC_GFp_nistp256_method,
1242 256,
1243 /* p */
1244 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1245 /* a */
1246 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1247 /* b */
1248 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1249 /* Qx */
1250 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1251 /* Qy */
1252 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1253 /* Gx */
1254 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1255 /* Gy */
1256 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1257 /* order */
1258 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1259 /* d */
1260 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1261 },
1262 {
1263 /* P-521 */
1264 EC_GFp_nistp521_method,
1265 521,
1266 /* p */
1267 "1ff"
1268 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1269 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1270 /* a */
1271 "1ff"
1272 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1273 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1274 /* b */
1275 "051"
1276 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1277 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1278 /* Qx */
1279 "0098"
1280 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1281 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1282 /* Qy */
1283 "0164"
1284 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1285 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1286 /* Gx */
1287 "c6"
1288 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1289 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1290 /* Gy */
1291 "118"
1292 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1293 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1294 /* order */
1295 "1ff"
1296 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1297 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1298 /* d */
1299 "0100"
1300 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1301 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1302 },
1303 };
1304
1305 static int nistp_single_test(int idx)
1306 {
1307 const struct nistp_test_params *test = nistp_tests_params + idx;
1308 BN_CTX *ctx = NULL;
1309 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1310 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1311 EC_GROUP *NISTP = NULL;
1312 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1313 int r = 0;
1314
1315 TEST_note("NIST curve P-%d (optimised implementation):",
1316 test->degree);
1317 if (!TEST_ptr(ctx = BN_CTX_new())
1318 || !TEST_ptr(p = BN_new())
1319 || !TEST_ptr(a = BN_new())
1320 || !TEST_ptr(b = BN_new())
1321 || !TEST_ptr(x = BN_new())
1322 || !TEST_ptr(y = BN_new())
1323 || !TEST_ptr(m = BN_new())
1324 || !TEST_ptr(n = BN_new())
1325 || !TEST_ptr(order = BN_new())
1326 || !TEST_ptr(yplusone = BN_new())
1327
1328 || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1329 || !TEST_true(BN_hex2bn(&p, test->p))
1330 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
1331 || !TEST_true(BN_hex2bn(&a, test->a))
1332 || !TEST_true(BN_hex2bn(&b, test->b))
1333 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1334 || !TEST_ptr(G = EC_POINT_new(NISTP))
1335 || !TEST_ptr(P = EC_POINT_new(NISTP))
1336 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1337 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1338 || !TEST_true(BN_hex2bn(&x, test->Qx))
1339 || !TEST_true(BN_hex2bn(&y, test->Qy))
1340 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1341 /*
1342 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1343 * and therefore setting the coordinates should fail.
1344 */
1345 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1346 yplusone, ctx))
1347 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1348 ctx))
1349 || !TEST_true(BN_hex2bn(&x, test->Gx))
1350 || !TEST_true(BN_hex2bn(&y, test->Gy))
1351 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1352 || !TEST_true(BN_hex2bn(&order, test->order))
1353 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1354 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1355 goto err;
1356
1357 TEST_note("NIST test vectors ... ");
1358 if (!TEST_true(BN_hex2bn(&n, test->d)))
1359 goto err;
1360 /* fixed point multiplication */
1361 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1362 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1363 goto err;
1364 /* random point multiplication */
1365 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1366 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1367
1368 /* set generator to P = 2*G, where G is the standard generator */
1369 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1370 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1371 /* set the scalar to m=n/2, where n is the NIST test scalar */
1372 || !TEST_true(BN_rshift(m, n, 1)))
1373 goto err;
1374
1375 /* test the non-standard generator */
1376 /* fixed point multiplication */
1377 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1378 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1379 goto err;
1380 /* random point multiplication */
1381 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1382 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1383
1384 /*
1385 * We have not performed precomputation so have_precompute mult should be
1386 * false
1387 */
1388 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1389
1390 /* now repeat all tests with precomputation */
1391 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1392 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
1393 goto err;
1394
1395 /* fixed point multiplication */
1396 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1397 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1398 goto err;
1399 /* random point multiplication */
1400 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1401 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1402
1403 /* reset generator */
1404 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1405 goto err;
1406 /* fixed point multiplication */
1407 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1408 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1409 goto err;
1410 /* random point multiplication */
1411 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1412 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1413 goto err;
1414
1415 /* regression test for felem_neg bug */
1416 if (!TEST_true(BN_set_word(m, 32))
1417 || !TEST_true(BN_set_word(n, 31))
1418 || !TEST_true(EC_POINT_copy(P, G))
1419 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1420 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1421 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1422 goto err;
1423
1424 r = group_order_tests(NISTP);
1425 err:
1426 EC_GROUP_free(NISTP);
1427 EC_POINT_free(G);
1428 EC_POINT_free(P);
1429 EC_POINT_free(Q);
1430 EC_POINT_free(Q_CHECK);
1431 BN_free(n);
1432 BN_free(m);
1433 BN_free(p);
1434 BN_free(a);
1435 BN_free(b);
1436 BN_free(x);
1437 BN_free(y);
1438 BN_free(order);
1439 BN_free(yplusone);
1440 BN_CTX_free(ctx);
1441 return r;
1442 }
1443
1444 /*
1445 * Tests a point known to cause an incorrect underflow in an old version of
1446 * ecp_nist521.c
1447 */
1448 static int underflow_test(void)
1449 {
1450 BN_CTX *ctx = NULL;
1451 EC_GROUP *grp = NULL;
1452 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
1453 BIGNUM *x1 = NULL, *y1 = NULL, *z1 = NULL, *x2 = NULL, *y2 = NULL;
1454 BIGNUM *k = NULL;
1455 int testresult = 0;
1456 const char *x1str =
1457 "1534f0077fffffe87e9adcfe000000000000000000003e05a21d2400002e031b1f4"
1458 "b80000c6fafa4f3c1288798d624a247b5e2ffffffffffffffefe099241900004";
1459 const char *p521m1 =
1460 "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1461 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe";
1462
1463 ctx = BN_CTX_new();
1464 if (!TEST_ptr(ctx))
1465 return 0;
1466
1467 BN_CTX_start(ctx);
1468 x1 = BN_CTX_get(ctx);
1469 y1 = BN_CTX_get(ctx);
1470 z1 = BN_CTX_get(ctx);
1471 x2 = BN_CTX_get(ctx);
1472 y2 = BN_CTX_get(ctx);
1473 k = BN_CTX_get(ctx);
1474 if (!TEST_ptr(k))
1475 goto err;
1476
1477 grp = EC_GROUP_new_by_curve_name(NID_secp521r1);
1478 P = EC_POINT_new(grp);
1479 Q = EC_POINT_new(grp);
1480 R = EC_POINT_new(grp);
1481 if (!TEST_ptr(grp) || !TEST_ptr(P) || !TEST_ptr(Q) || !TEST_ptr(R))
1482 goto err;
1483
1484 if (!TEST_int_gt(BN_hex2bn(&x1, x1str), 0)
1485 || !TEST_int_gt(BN_hex2bn(&y1, p521m1), 0)
1486 || !TEST_int_gt(BN_hex2bn(&z1, p521m1), 0)
1487 || !TEST_int_gt(BN_hex2bn(&k, "02"), 0)
1488 || !TEST_true(EC_POINT_set_Jprojective_coordinates_GFp(grp, P, x1,
1489 y1, z1, ctx))
1490 || !TEST_true(EC_POINT_mul(grp, Q, NULL, P, k, ctx))
1491 || !TEST_true(EC_POINT_get_affine_coordinates(grp, Q, x1, y1, ctx))
1492 || !TEST_true(EC_POINT_dbl(grp, R, P, ctx))
1493 || !TEST_true(EC_POINT_get_affine_coordinates(grp, R, x2, y2, ctx)))
1494 goto err;
1495
1496 if (!TEST_int_eq(BN_cmp(x1, x2), 0)
1497 || !TEST_int_eq(BN_cmp(y1, y2), 0))
1498 goto err;
1499
1500 testresult = 1;
1501
1502 err:
1503 BN_CTX_end(ctx);
1504 EC_POINT_free(P);
1505 EC_POINT_free(Q);
1506 EC_POINT_free(R);
1507 EC_GROUP_free(grp);
1508 BN_CTX_free(ctx);
1509
1510 return testresult;
1511 }
1512 # endif
1513
1514 static const unsigned char p521_named[] = {
1515 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1516 };
1517
1518 static const unsigned char p521_explicit[] = {
1519 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1520 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1521 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1527 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1533 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1534 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1535 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1536 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1537 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1538 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1539 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1540 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1541 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1542 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1543 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1544 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1545 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1546 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1547 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1548 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1549 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1550 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1551 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1552 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1553 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1554 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1555 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1556 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1557 };
1558
1559 static int parameter_test(void)
1560 {
1561 EC_GROUP *group = NULL, *group2 = NULL;
1562 ECPARAMETERS *ecparameters = NULL;
1563 unsigned char *buf = NULL;
1564 int r = 0, len;
1565
1566 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp112r1))
1567 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1568 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1569 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1570 goto err;
1571
1572 EC_GROUP_free(group);
1573 group = NULL;
1574
1575 /* Test the named curve encoding, which should be default. */
1576 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1577 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1578 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1579 goto err;
1580
1581 OPENSSL_free(buf);
1582 buf = NULL;
1583
1584 /*
1585 * Test the explicit encoding. P-521 requires correctly zero-padding the
1586 * curve coefficients.
1587 */
1588 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1589 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1590 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
1591 goto err;
1592
1593 r = 1;
1594 err:
1595 EC_GROUP_free(group);
1596 EC_GROUP_free(group2);
1597 ECPARAMETERS_free(ecparameters);
1598 OPENSSL_free(buf);
1599 return r;
1600 }
1601 #endif
1602
1603 int setup_tests(void)
1604 {
1605 #ifndef OPENSSL_NO_EC
1606 crv_len = EC_get_builtin_curves(NULL, 0);
1607 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
1608 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
1609 return 0;
1610
1611 ADD_TEST(parameter_test);
1612 ADD_TEST(prime_field_tests);
1613 # ifndef OPENSSL_NO_EC2M
1614 ADD_TEST(char2_field_tests);
1615 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
1616 # endif
1617 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1618 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
1619 ADD_TEST(underflow_test);
1620 # endif
1621 ADD_ALL_TESTS(internal_curve_test, crv_len);
1622 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
1623 ADD_TEST(group_field_test);
1624 #endif
1625 return 1;
1626 }
1627
1628 void cleanup_tests(void)
1629 {
1630 #ifndef OPENSSL_NO_EC
1631 OPENSSL_free(curves);
1632 #endif
1633 }