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