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