1 /* crypto/ec/ectest.c */ 2 /* 3 * Originally written by Bodo Moeller for the OpenSSL project. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * openssl-core@openssl.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 /* ==================================================================== 59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60 * 61 * Portions of the attached software ("Contribution") are developed by 62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 63 * 64 * The Contribution is licensed pursuant to the OpenSSL open source 65 * license provided above. 66 * 67 * The elliptic curve binary polynomial software is originally written by 68 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. 69 * 70 */ 71 72 #include <stdio.h> 73 #include <stdlib.h> 74 #include <string.h> 75 #include <time.h> 76 77 #include <openssl/ec.h> 78 #ifndef OPENSSL_NO_ENGINE 79 #include <openssl/engine.h> 80 #endif 81 #include <openssl/err.h> 82 #include <openssl/obj_mac.h> 83 #include <openssl/objects.h> 84 #include <openssl/bn.h> 85 #include <openssl/opensslconf.h> 86 87 #define ABORT do { \ 88 fflush(stdout); \ 89 fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \ 90 ERR_print_errors_fp(stderr); \ 91 exit(1); \ 92 } while (0) 93 94 #define TIMING_BASE_PT 0 95 #define TIMING_RAND_PT 1 96 #define TIMING_SIMUL 2 97 98 /* test multiplication with group order, long and negative scalars */ 99 static void 100 group_order_tests(EC_GROUP *group) 101 { 102 BIGNUM *n1, *n2, *order; 103 EC_POINT *P = EC_POINT_new(group); 104 EC_POINT *Q = EC_POINT_new(group); 105 BN_CTX *ctx = BN_CTX_new(); 106 107 n1 = BN_new(); 108 n2 = BN_new(); 109 order = BN_new(); 110 fprintf(stdout, "verify group order ..."); 111 fflush(stdout); 112 if (!EC_GROUP_get_order(group, order, ctx)) 113 ABORT; 114 if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) 115 ABORT; 116 if (!EC_POINT_is_at_infinity(group, Q)) 117 ABORT; 118 fprintf(stdout, "."); 119 fflush(stdout); 120 if (!EC_GROUP_precompute_mult(group, ctx)) 121 ABORT; 122 if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) 123 ABORT; 124 if (!EC_POINT_is_at_infinity(group, Q)) 125 ABORT; 126 fprintf(stdout, " ok\n"); 127 fprintf(stdout, "long/negative scalar tests ... "); 128 if (!BN_one(n1)) 129 ABORT; 130 /* n1 = 1 - order */ 131 if (!BN_sub(n1, n1, order)) 132 ABORT; 133 if (!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) 134 ABORT; 135 if (0 != EC_POINT_cmp(group, Q, P, ctx)) 136 ABORT; 137 /* n2 = 1 + order */ 138 if (!BN_add(n2, order, BN_value_one())) 139 ABORT; 140 if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 141 ABORT; 142 if (0 != EC_POINT_cmp(group, Q, P, ctx)) 143 ABORT; 144 /* n2 = (1 - order) * (1 + order) */ 145 if (!BN_mul(n2, n1, n2, ctx)) 146 ABORT; 147 if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 148 ABORT; 149 if (0 != EC_POINT_cmp(group, Q, P, ctx)) 150 ABORT; 151 fprintf(stdout, "ok\n"); 152 EC_POINT_free(P); 153 EC_POINT_free(Q); 154 BN_free(n1); 155 BN_free(n2); 156 BN_free(order); 157 BN_CTX_free(ctx); 158 } 159 160 static void 161 prime_field_tests(void) 162 { 163 BN_CTX *ctx = NULL; 164 BIGNUM *p, *a, *b; 165 EC_GROUP *group; 166 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL; 167 EC_POINT *P, *Q, *R; 168 BIGNUM *x, *y, *z; 169 unsigned char buf[100]; 170 size_t i, len; 171 int k; 172 173 #if 1 /* optional */ 174 ctx = BN_CTX_new(); 175 if (!ctx) 176 ABORT; 177 #endif 178 179 p = BN_new(); 180 a = BN_new(); 181 b = BN_new(); 182 if (!p || !a || !b) 183 ABORT; 184 185 if (!BN_hex2bn(&p, "17")) 186 ABORT; 187 if (!BN_hex2bn(&a, "1")) 188 ABORT; 189 if (!BN_hex2bn(&b, "1")) 190 ABORT; 191 192 group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp 193 * so that the library gets to choose the EC_METHOD */ 194 if (!group) 195 ABORT; 196 197 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 198 ABORT; 199 200 { 201 EC_GROUP *tmp; 202 tmp = EC_GROUP_new(EC_GROUP_method_of(group)); 203 if (!tmp) 204 ABORT; 205 if (!EC_GROUP_copy(tmp, group)) 206 ABORT; 207 EC_GROUP_free(group); 208 group = tmp; 209 } 210 211 if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) 212 ABORT; 213 214 fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x"); 215 BN_print_fp(stdout, p); 216 fprintf(stdout, ")\n a = 0x"); 217 BN_print_fp(stdout, a); 218 fprintf(stdout, "\n b = 0x"); 219 BN_print_fp(stdout, b); 220 fprintf(stdout, "\n"); 221 222 P = EC_POINT_new(group); 223 Q = EC_POINT_new(group); 224 R = EC_POINT_new(group); 225 if (!P || !Q || !R) 226 ABORT; 227 228 if (!EC_POINT_set_to_infinity(group, P)) 229 ABORT; 230 if (!EC_POINT_is_at_infinity(group, P)) 231 ABORT; 232 233 buf[0] = 0; 234 if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) 235 ABORT; 236 237 if (!EC_POINT_add(group, P, P, Q, ctx)) 238 ABORT; 239 if (!EC_POINT_is_at_infinity(group, P)) 240 ABORT; 241 242 x = BN_new(); 243 y = BN_new(); 244 z = BN_new(); 245 if (!x || !y || !z) 246 ABORT; 247 248 if (!BN_hex2bn(&x, "D")) 249 ABORT; 250 if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) 251 ABORT; 252 if (!EC_POINT_is_on_curve(group, Q, ctx)) { 253 if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) 254 ABORT; 255 fprintf(stderr, "Point is not on curve: x = 0x"); 256 BN_print_fp(stderr, x); 257 fprintf(stderr, ", y = 0x"); 258 BN_print_fp(stderr, y); 259 fprintf(stderr, "\n"); 260 ABORT; 261 } 262 263 fprintf(stdout, "A cyclic subgroup:\n"); 264 k = 100; 265 do 266 { 267 if (k-- == 0) 268 ABORT; 269 270 if (EC_POINT_is_at_infinity(group, P)) 271 fprintf(stdout, " point at infinity\n"); 272 else { 273 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 274 ABORT; 275 276 fprintf(stdout, " x = 0x"); 277 BN_print_fp(stdout, x); 278 fprintf(stdout, ", y = 0x"); 279 BN_print_fp(stdout, y); 280 fprintf(stdout, "\n"); 281 } 282 283 if (!EC_POINT_copy(R, P)) 284 ABORT; 285 if (!EC_POINT_add(group, P, P, Q, ctx)) 286 ABORT; 287 288 #if 0 /* optional */ 289 { 290 EC_POINT *points[3]; 291 292 points[0] = R; 293 points[1] = Q; 294 points[2] = P; 295 if (!EC_POINTs_make_affine(group, 2, points, ctx)) 296 ABORT; 297 } 298 #endif 299 300 } 301 while (!EC_POINT_is_at_infinity(group, P)); 302 303 if (!EC_POINT_add(group, P, Q, R, ctx)) 304 ABORT; 305 if (!EC_POINT_is_at_infinity(group, P)) 306 ABORT; 307 308 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx); 309 if (len == 0) 310 ABORT; 311 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 312 ABORT; 313 if (0 != EC_POINT_cmp(group, P, Q, ctx)) 314 ABORT; 315 fprintf(stdout, "Generator as octet string, compressed form:\n "); 316 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); 317 318 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx); 319 if (len == 0) 320 ABORT; 321 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 322 ABORT; 323 if (0 != EC_POINT_cmp(group, P, Q, ctx)) 324 ABORT; 325 fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); 326 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); 327 328 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx); 329 if (len == 0) 330 ABORT; 331 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 332 ABORT; 333 if (0 != EC_POINT_cmp(group, P, Q, ctx)) 334 ABORT; 335 fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); 336 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); 337 338 if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) 339 ABORT; 340 fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n X = 0x"); 341 BN_print_fp(stdout, x); 342 fprintf(stdout, ", Y = 0x"); 343 BN_print_fp(stdout, y); 344 fprintf(stdout, ", Z = 0x"); 345 BN_print_fp(stdout, z); 346 fprintf(stdout, "\n"); 347 348 if (!EC_POINT_invert(group, P, ctx)) 349 ABORT; 350 if (0 != EC_POINT_cmp(group, P, R, ctx)) 351 ABORT; 352 353 354 /* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000) 355 * -- not a NIST curve, but commonly used */ 356 357 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) 358 ABORT; 359 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 360 ABORT; 361 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) 362 ABORT; 363 if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) 364 ABORT; 365 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 366 ABORT; 367 368 if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) 369 ABORT; 370 if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) 371 ABORT; 372 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) 373 ABORT; 374 if (!EC_POINT_is_on_curve(group, P, ctx)) 375 ABORT; 376 if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) 377 ABORT; 378 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 379 ABORT; 380 381 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 382 ABORT; 383 fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n x = 0x"); 384 BN_print_fp(stdout, x); 385 fprintf(stdout, "\n y = 0x"); 386 BN_print_fp(stdout, y); 387 fprintf(stdout, "\n"); 388 /* G_y value taken from the standard: */ 389 if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) 390 ABORT; 391 if (0 != BN_cmp(y, z)) 392 ABORT; 393 394 fprintf(stdout, "verify degree ..."); 395 if (EC_GROUP_get_degree(group) != 160) 396 ABORT; 397 fprintf(stdout, " ok\n"); 398 399 group_order_tests(group); 400 401 if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) 402 ABORT; 403 if (!EC_GROUP_copy(P_160, group)) 404 ABORT; 405 406 407 /* Curve P-192 (FIPS PUB 186-2, App. 6) */ 408 409 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) 410 ABORT; 411 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 412 ABORT; 413 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) 414 ABORT; 415 if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) 416 ABORT; 417 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 418 ABORT; 419 420 if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) 421 ABORT; 422 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) 423 ABORT; 424 if (!EC_POINT_is_on_curve(group, P, ctx)) 425 ABORT; 426 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) 427 ABORT; 428 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 429 ABORT; 430 431 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 432 ABORT; 433 fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x"); 434 BN_print_fp(stdout, x); 435 fprintf(stdout, "\n y = 0x"); 436 BN_print_fp(stdout, y); 437 fprintf(stdout, "\n"); 438 /* G_y value taken from the standard: */ 439 if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) 440 ABORT; 441 if (0 != BN_cmp(y, z)) 442 ABORT; 443 444 fprintf(stdout, "verify degree ..."); 445 if (EC_GROUP_get_degree(group) != 192) 446 ABORT; 447 fprintf(stdout, " ok\n"); 448 449 group_order_tests(group); 450 451 if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) 452 ABORT; 453 if (!EC_GROUP_copy(P_192, group)) 454 ABORT; 455 456 457 /* Curve P-224 (FIPS PUB 186-2, App. 6) */ 458 459 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) 460 ABORT; 461 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 462 ABORT; 463 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) 464 ABORT; 465 if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) 466 ABORT; 467 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 468 ABORT; 469 470 if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) 471 ABORT; 472 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) 473 ABORT; 474 if (!EC_POINT_is_on_curve(group, P, ctx)) 475 ABORT; 476 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) 477 ABORT; 478 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 479 ABORT; 480 481 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 482 ABORT; 483 fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x"); 484 BN_print_fp(stdout, x); 485 fprintf(stdout, "\n y = 0x"); 486 BN_print_fp(stdout, y); 487 fprintf(stdout, "\n"); 488 /* G_y value taken from the standard: */ 489 if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) 490 ABORT; 491 if (0 != BN_cmp(y, z)) 492 ABORT; 493 494 fprintf(stdout, "verify degree ..."); 495 if (EC_GROUP_get_degree(group) != 224) 496 ABORT; 497 fprintf(stdout, " ok\n"); 498 499 group_order_tests(group); 500 501 if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) 502 ABORT; 503 if (!EC_GROUP_copy(P_224, group)) 504 ABORT; 505 506 507 /* Curve P-256 (FIPS PUB 186-2, App. 6) */ 508 509 if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) 510 ABORT; 511 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 512 ABORT; 513 if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) 514 ABORT; 515 if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) 516 ABORT; 517 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 518 ABORT; 519 520 if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) 521 ABORT; 522 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) 523 ABORT; 524 if (!EC_POINT_is_on_curve(group, P, ctx)) 525 ABORT; 526 if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E" 527 "84F3B9CAC2FC632551")) ABORT; 528 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 529 ABORT; 530 531 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 532 ABORT; 533 fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x"); 534 BN_print_fp(stdout, x); 535 fprintf(stdout, "\n y = 0x"); 536 BN_print_fp(stdout, y); 537 fprintf(stdout, "\n"); 538 /* G_y value taken from the standard: */ 539 if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) 540 ABORT; 541 if (0 != BN_cmp(y, z)) 542 ABORT; 543 544 fprintf(stdout, "verify degree ..."); 545 if (EC_GROUP_get_degree(group) != 256) 546 ABORT; 547 fprintf(stdout, " ok\n"); 548 549 group_order_tests(group); 550 551 if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) 552 ABORT; 553 if (!EC_GROUP_copy(P_256, group)) 554 ABORT; 555 556 557 /* Curve P-384 (FIPS PUB 186-2, App. 6) */ 558 559 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 560 "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT; 561 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 562 ABORT; 563 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 564 "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT; 565 if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141" 566 "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT; 567 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 568 ABORT; 569 570 if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B" 571 "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT; 572 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) 573 ABORT; 574 if (!EC_POINT_is_on_curve(group, P, ctx)) 575 ABORT; 576 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 577 "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT; 578 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 579 ABORT; 580 581 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 582 ABORT; 583 fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x"); 584 BN_print_fp(stdout, x); 585 fprintf(stdout, "\n y = 0x"); 586 BN_print_fp(stdout, y); 587 fprintf(stdout, "\n"); 588 /* G_y value taken from the standard: */ 589 if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14" 590 "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT; 591 if (0 != BN_cmp(y, z)) 592 ABORT; 593 594 fprintf(stdout, "verify degree ..."); 595 if (EC_GROUP_get_degree(group) != 384) 596 ABORT; 597 fprintf(stdout, " ok\n"); 598 599 group_order_tests(group); 600 601 if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) 602 ABORT; 603 if (!EC_GROUP_copy(P_384, group)) 604 ABORT; 605 606 607 /* Curve P-521 (FIPS PUB 186-2, App. 6) */ 608 609 if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 610 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 611 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT; 612 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 613 ABORT; 614 if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 615 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 616 "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT; 617 if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B" 618 "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573" 619 "DF883D2C34F1EF451FD46B503F00")) ABORT; 620 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 621 ABORT; 622 623 if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F" 624 "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B" 625 "3C1856A429BF97E7E31C2E5BD66")) ABORT; 626 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) 627 ABORT; 628 if (!EC_POINT_is_on_curve(group, P, ctx)) 629 ABORT; 630 if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 631 "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5" 632 "C9B8899C47AEBB6FB71E91386409")) ABORT; 633 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 634 ABORT; 635 636 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 637 ABORT; 638 fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x"); 639 BN_print_fp(stdout, x); 640 fprintf(stdout, "\n y = 0x"); 641 BN_print_fp(stdout, y); 642 fprintf(stdout, "\n"); 643 /* G_y value taken from the standard: */ 644 if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579" 645 "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C" 646 "7086A272C24088BE94769FD16650")) ABORT; 647 if (0 != BN_cmp(y, z)) 648 ABORT; 649 650 fprintf(stdout, "verify degree ..."); 651 if (EC_GROUP_get_degree(group) != 521) 652 ABORT; 653 fprintf(stdout, " ok\n"); 654 655 group_order_tests(group); 656 657 if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) 658 ABORT; 659 if (!EC_GROUP_copy(P_521, group)) 660 ABORT; 661 662 663 /* more tests using the last curve */ 664 665 if (!EC_POINT_copy(Q, P)) 666 ABORT; 667 if (EC_POINT_is_at_infinity(group, Q)) 668 ABORT; 669 if (!EC_POINT_dbl(group, P, P, ctx)) 670 ABORT; 671 if (!EC_POINT_is_on_curve(group, P, ctx)) 672 ABORT; 673 if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */ 674 675 if (!EC_POINT_add(group, R, P, Q, ctx)) 676 ABORT; 677 if (!EC_POINT_add(group, R, R, Q, ctx)) 678 ABORT; 679 if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */ 680 681 { 682 const EC_POINT *points[4]; 683 const BIGNUM *scalars[4]; 684 BIGNUM scalar3; 685 686 if (EC_POINT_is_at_infinity(group, Q)) 687 ABORT; 688 points[0] = Q; 689 points[1] = Q; 690 points[2] = Q; 691 points[3] = Q; 692 693 if (!EC_GROUP_get_order(group, z, ctx)) 694 ABORT; 695 if (!BN_add(y, z, BN_value_one())) 696 ABORT; 697 if (BN_is_odd(y)) 698 ABORT; 699 if (!BN_rshift1(y, y)) 700 ABORT; 701 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */ 702 scalars[1] = y; 703 704 fprintf(stdout, "combined multiplication ..."); 705 fflush(stdout); 706 707 /* z is still the group order */ 708 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 709 ABORT; 710 if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) 711 ABORT; 712 if (0 != EC_POINT_cmp(group, P, R, ctx)) 713 ABORT; 714 if (0 != EC_POINT_cmp(group, R, Q, ctx)) 715 ABORT; 716 717 fprintf(stdout, "."); 718 fflush(stdout); 719 720 if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) 721 ABORT; 722 if (!BN_add(z, z, y)) 723 ABORT; 724 BN_set_negative(z, 1); 725 scalars[0] = y; 726 scalars[1] = z; /* z = -(order + y) */ 727 728 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 729 ABORT; 730 if (!EC_POINT_is_at_infinity(group, P)) 731 ABORT; 732 733 fprintf(stdout, "."); 734 fflush(stdout); 735 736 if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) 737 ABORT; 738 if (!BN_add(z, x, y)) 739 ABORT; 740 BN_set_negative(z, 1); 741 scalars[0] = x; 742 scalars[1] = y; 743 scalars[2] = z; /* z = -(x+y) */ 744 745 BN_init(&scalar3); 746 BN_zero(&scalar3); 747 scalars[3] = &scalar3; 748 749 if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) 750 ABORT; 751 if (!EC_POINT_is_at_infinity(group, P)) 752 ABORT; 753 754 fprintf(stdout, " ok\n\n"); 755 756 BN_free(&scalar3); 757 } 758 759 760 if (ctx) 761 BN_CTX_free(ctx); 762 BN_free(p); 763 BN_free(a); 764 BN_free(b); 765 EC_GROUP_free(group); 766 EC_POINT_free(P); 767 EC_POINT_free(Q); 768 EC_POINT_free(R); 769 BN_free(x); 770 BN_free(y); 771 BN_free(z); 772 773 if (P_160) 774 EC_GROUP_free(P_160); 775 if (P_192) 776 EC_GROUP_free(P_192); 777 if (P_224) 778 EC_GROUP_free(P_224); 779 if (P_256) 780 EC_GROUP_free(P_256); 781 if (P_384) 782 EC_GROUP_free(P_384); 783 if (P_521) 784 EC_GROUP_free(P_521); 785 786 } 787 788 /* Change test based on whether binary point compression is enabled or not. */ 789 #ifdef OPENSSL_EC_BIN_PT_COMP 790 #define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ 791 if (!BN_hex2bn(&x, _x)) ABORT; \ 792 if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \ 793 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \ 794 if (!BN_hex2bn(&z, _order)) ABORT; \ 795 if (!BN_hex2bn(&cof, _cof)) ABORT; \ 796 if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ 797 if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \ 798 fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \ 799 BN_print_fp(stdout, x); \ 800 fprintf(stdout, "\n y = 0x"); \ 801 BN_print_fp(stdout, y); \ 802 fprintf(stdout, "\n"); \ 803 /* G_y value taken from the standard: */ \ 804 if (!BN_hex2bn(&z, _y)) ABORT; \ 805 if (0 != BN_cmp(y, z)) ABORT; 806 #else 807 #define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ 808 if (!BN_hex2bn(&x, _x)) ABORT; \ 809 if (!BN_hex2bn(&y, _y)) ABORT; \ 810 if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \ 811 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \ 812 if (!BN_hex2bn(&z, _order)) ABORT; \ 813 if (!BN_hex2bn(&cof, _cof)) ABORT; \ 814 if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ 815 fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \ 816 BN_print_fp(stdout, x); \ 817 fprintf(stdout, "\n y = 0x"); \ 818 BN_print_fp(stdout, y); \ 819 fprintf(stdout, "\n"); 820 #endif 821 822 #define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ 823 if (!BN_hex2bn(&p, _p)) ABORT; \ 824 if (!BN_hex2bn(&a, _a)) ABORT; \ 825 if (!BN_hex2bn(&b, _b)) ABORT; \ 826 if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \ 827 CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ 828 fprintf(stdout, "verify degree ..."); \ 829 if (EC_GROUP_get_degree(group) != _degree) ABORT; \ 830 fprintf(stdout, " ok\n"); \ 831 group_order_tests(group); \ 832 if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \ 833 if (!EC_GROUP_copy(_variable, group)) ABORT; \ 834 835 #ifndef OPENSSL_NO_EC2M 836 837 static void char2_field_tests(void) 838 { 839 BN_CTX *ctx = NULL; 840 BIGNUM *p, *a, *b; 841 EC_GROUP *group; 842 EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = NULL, *C2_K571 = NULL; 843 EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = NULL, *C2_B571 = NULL; 844 EC_POINT *P, *Q, *R; 845 BIGNUM *x, *y, *z, *cof; 846 unsigned char buf[100]; 847 size_t i, len; 848 int k; 849 850 #if 1 /* optional */ 851 ctx = BN_CTX_new(); 852 if (!ctx) 853 ABORT; 854 #endif 855 856 p = BN_new(); 857 a = BN_new(); 858 b = BN_new(); 859 if (!p || !a || !b) 860 ABORT; 861 862 if (!BN_hex2bn(&p, "13")) 863 ABORT; 864 if (!BN_hex2bn(&a, "3")) 865 ABORT; 866 if (!BN_hex2bn(&b, "1")) 867 ABORT; 868 869 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use EC_GROUP_new_curve_GF2m 870 * so that the library gets to choose the EC_METHOD */ 871 if (!group) 872 ABORT; 873 if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) 874 ABORT; 875 876 { 877 EC_GROUP *tmp; 878 tmp = EC_GROUP_new(EC_GROUP_method_of(group)); 879 if (!tmp) 880 ABORT; 881 if (!EC_GROUP_copy(tmp, group)) 882 ABORT; 883 EC_GROUP_free(group); 884 group = tmp; 885 } 886 887 if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) 888 ABORT; 889 890 fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 + x*y = x^3 + a*x^2 + b (mod 0x"); 891 BN_print_fp(stdout, p); 892 fprintf(stdout, ")\n a = 0x"); 893 BN_print_fp(stdout, a); 894 fprintf(stdout, "\n b = 0x"); 895 BN_print_fp(stdout, b); 896 fprintf(stdout, "\n(0x... means binary polynomial)\n"); 897 898 P = EC_POINT_new(group); 899 Q = EC_POINT_new(group); 900 R = EC_POINT_new(group); 901 if (!P || !Q || !R) 902 ABORT; 903 904 if (!EC_POINT_set_to_infinity(group, P)) 905 ABORT; 906 if (!EC_POINT_is_at_infinity(group, P)) 907 ABORT; 908 909 buf[0] = 0; 910 if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) 911 ABORT; 912 913 if (!EC_POINT_add(group, P, P, Q, ctx)) 914 ABORT; 915 if (!EC_POINT_is_at_infinity(group, P)) 916 ABORT; 917 918 x = BN_new(); 919 y = BN_new(); 920 z = BN_new(); 921 cof = BN_new(); 922 if (!x || !y || !z || !cof) 923 ABORT; 924 925 if (!BN_hex2bn(&x, "6")) 926 ABORT; 927 /* Change test based on whether binary point compression is enabled or not. */ 928 #ifdef OPENSSL_EC_BIN_PT_COMP 929 if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) 930 ABORT; 931 #else 932 if (!BN_hex2bn(&y, "8")) 933 ABORT; 934 if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) 935 ABORT; 936 #endif 937 if (!EC_POINT_is_on_curve(group, Q, ctx)) { 938 /* Change test based on whether binary point compression is enabled or not. */ 939 #ifdef OPENSSL_EC_BIN_PT_COMP 940 if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) 941 ABORT; 942 #endif 943 fprintf(stderr, "Point is not on curve: x = 0x"); 944 BN_print_fp(stderr, x); 945 fprintf(stderr, ", y = 0x"); 946 BN_print_fp(stderr, y); 947 fprintf(stderr, "\n"); 948 ABORT; 949 } 950 951 fprintf(stdout, "A cyclic subgroup:\n"); 952 k = 100; 953 do 954 { 955 if (k-- == 0) 956 ABORT; 957 958 if (EC_POINT_is_at_infinity(group, P)) 959 fprintf(stdout, " point at infinity\n"); 960 else { 961 if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) 962 ABORT; 963 964 fprintf(stdout, " x = 0x"); 965 BN_print_fp(stdout, x); 966 fprintf(stdout, ", y = 0x"); 967 BN_print_fp(stdout, y); 968 fprintf(stdout, "\n"); 969 } 970 971 if (!EC_POINT_copy(R, P)) 972 ABORT; 973 if (!EC_POINT_add(group, P, P, Q, ctx)) 974 ABORT; 975 } 976 while (!EC_POINT_is_at_infinity(group, P)); 977 978 if (!EC_POINT_add(group, P, Q, R, ctx)) 979 ABORT; 980 if (!EC_POINT_is_at_infinity(group, P)) 981 ABORT; 982 983 /* Change test based on whether binary point compression is enabled or not. */ 984 #ifdef OPENSSL_EC_BIN_PT_COMP 985 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx); 986 if (len == 0) 987 ABORT; 988 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 989 ABORT; 990 if (0 != EC_POINT_cmp(group, P, Q, ctx)) 991 ABORT; 992 fprintf(stdout, "Generator as octet string, compressed form:\n "); 993 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); 994 #endif 995 996 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx); 997 if (len == 0) 998 ABORT; 999 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 1000 ABORT; 1001 if (0 != EC_POINT_cmp(group, P, Q, ctx)) 1002 ABORT; 1003 fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); 1004 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); 1005 1006 /* Change test based on whether binary point compression is enabled or not. */ 1007 #ifdef OPENSSL_EC_BIN_PT_COMP 1008 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx); 1009 if (len == 0) 1010 ABORT; 1011 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 1012 ABORT; 1013 if (0 != EC_POINT_cmp(group, P, Q, ctx)) 1014 ABORT; 1015 fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); 1016 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); 1017 #endif 1018 1019 fprintf(stdout, "\n"); 1020 1021 if (!EC_POINT_invert(group, P, ctx)) 1022 ABORT; 1023 if (0 != EC_POINT_cmp(group, P, R, ctx)) 1024 ABORT; 1025 1026 1027 /* Curve K-163 (FIPS PUB 186-2, App. 6) */ 1028 CHAR2_CURVE_TEST 1029 ( 1030 "NIST curve K-163", 1031 "0800000000000000000000000000000000000000C9", 1032 "1", 1033 "1", 1034 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", 1035 "0289070FB05D38FF58321F2E800536D538CCDAA3D9", 1036 1, 1037 "04000000000000000000020108A2E0CC0D99F8A5EF", 1038 "2", 1039 163, 1040 C2_K163 1041 ); 1042 1043 /* Curve B-163 (FIPS PUB 186-2, App. 6) */ 1044 CHAR2_CURVE_TEST 1045 ( 1046 "NIST curve B-163", 1047 "0800000000000000000000000000000000000000C9", 1048 "1", 1049 "020A601907B8C953CA1481EB10512F78744A3205FD", 1050 "03F0EBA16286A2D57EA0991168D4994637E8343E36", 1051 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", 1052 1, 1053 "040000000000000000000292FE77E70C12A4234C33", 1054 "2", 1055 163, 1056 C2_B163 1057 ); 1058 1059 /* Curve K-233 (FIPS PUB 186-2, App. 6) */ 1060 CHAR2_CURVE_TEST 1061 ( 1062 "NIST curve K-233", 1063 "020000000000000000000000000000000000000004000000000000000001", 1064 "0", 1065 "1", 1066 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", 1067 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", 1068 0, 1069 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 1070 "4", 1071 233, 1072 C2_K233 1073 ); 1074 1075 /* Curve B-233 (FIPS PUB 186-2, App. 6) */ 1076 CHAR2_CURVE_TEST 1077 ( 1078 "NIST curve B-233", 1079 "020000000000000000000000000000000000000004000000000000000001", 1080 "000000000000000000000000000000000000000000000000000000000001", 1081 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", 1082 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", 1083 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", 1084 1, 1085 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 1086 "2", 1087 233, 1088 C2_B233 1089 ); 1090 1091 /* Curve K-283 (FIPS PUB 186-2, App. 6) */ 1092 CHAR2_CURVE_TEST 1093 ( 1094 "NIST curve K-283", 1095 "0800000000000000000000000000000000000000000000000000000000000000000010A1", 1096 "0", 1097 "1", 1098 "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836", 1099 "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", 1100 0, 1101 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", 1102 "4", 1103 283, 1104 C2_K283 1105 ); 1106 1107 /* Curve B-283 (FIPS PUB 186-2, App. 6) */ 1108 CHAR2_CURVE_TEST 1109 ( 1110 "NIST curve B-283", 1111 "0800000000000000000000000000000000000000000000000000000000000000000010A1", 1112 "000000000000000000000000000000000000000000000000000000000000000000000001", 1113 "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", 1114 "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", 1115 "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", 1116 1, 1117 "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 1118 "2", 1119 283, 1120 C2_B283 1121 ); 1122 1123 /* Curve K-409 (FIPS PUB 186-2, App. 6) */ 1124 CHAR2_CURVE_TEST 1125 ( 1126 "NIST curve K-409", 1127 "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", 1128 "0", 1129 "1", 1130 "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", 1131 "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", 1132 1, 1133 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 1134 "4", 1135 409, 1136 C2_K409 1137 ); 1138 1139 /* Curve B-409 (FIPS PUB 186-2, App. 6) */ 1140 CHAR2_CURVE_TEST 1141 ( 1142 "NIST curve B-409", 1143 "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", 1144 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 1145 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", 1146 "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7", 1147 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", 1148 1, 1149 "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", 1150 "2", 1151 409, 1152 C2_B409 1153 ); 1154 1155 /* Curve K-571 (FIPS PUB 186-2, App. 6) */ 1156 CHAR2_CURVE_TEST 1157 ( 1158 "NIST curve K-571", 1159 "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", 1160 "0", 1161 "1", 1162 "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972", 1163 "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", 1164 0, 1165 "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", 1166 "4", 1167 571, 1168 C2_K571 1169 ); 1170 1171 /* Curve B-571 (FIPS PUB 186-2, App. 6) */ 1172 CHAR2_CURVE_TEST 1173 ( 1174 "NIST curve B-571", 1175 "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", 1176 "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 1177 "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", 1178 "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19", 1179 "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", 1180 1, 1181 "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", 1182 "2", 1183 571, 1184 C2_B571 1185 ); 1186 1187 /* more tests using the last curve */ 1188 1189 if (!EC_POINT_copy(Q, P)) 1190 ABORT; 1191 if (EC_POINT_is_at_infinity(group, Q)) 1192 ABORT; 1193 if (!EC_POINT_dbl(group, P, P, ctx)) 1194 ABORT; 1195 if (!EC_POINT_is_on_curve(group, P, ctx)) 1196 ABORT; 1197 if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */ 1198 1199 if (!EC_POINT_add(group, R, P, Q, ctx)) 1200 ABORT; 1201 if (!EC_POINT_add(group, R, R, Q, ctx)) 1202 ABORT; 1203 if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */ 1204 1205 { 1206 const EC_POINT *points[3]; 1207 const BIGNUM *scalars[3]; 1208 1209 if (EC_POINT_is_at_infinity(group, Q)) 1210 ABORT; 1211 points[0] = Q; 1212 points[1] = Q; 1213 points[2] = Q; 1214 1215 if (!BN_add(y, z, BN_value_one())) 1216 ABORT; 1217 if (BN_is_odd(y)) 1218 ABORT; 1219 if (!BN_rshift1(y, y)) 1220 ABORT; 1221 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */ 1222 scalars[1] = y; 1223 1224 fprintf(stdout, "combined multiplication ..."); 1225 fflush(stdout); 1226 1227 /* z is still the group order */ 1228 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 1229 ABORT; 1230 if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) 1231 ABORT; 1232 if (0 != EC_POINT_cmp(group, P, R, ctx)) 1233 ABORT; 1234 if (0 != EC_POINT_cmp(group, R, Q, ctx)) 1235 ABORT; 1236 1237 fprintf(stdout, "."); 1238 fflush(stdout); 1239 1240 if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) 1241 ABORT; 1242 if (!BN_add(z, z, y)) 1243 ABORT; 1244 BN_set_negative(z, 1); 1245 scalars[0] = y; 1246 scalars[1] = z; /* z = -(order + y) */ 1247 1248 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 1249 ABORT; 1250 if (!EC_POINT_is_at_infinity(group, P)) 1251 ABORT; 1252 1253 fprintf(stdout, "."); 1254 fflush(stdout); 1255 1256 if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) 1257 ABORT; 1258 if (!BN_add(z, x, y)) 1259 ABORT; 1260 BN_set_negative(z, 1); 1261 scalars[0] = x; 1262 scalars[1] = y; 1263 scalars[2] = z; /* z = -(x+y) */ 1264 1265 if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) 1266 ABORT; 1267 if (!EC_POINT_is_at_infinity(group, P)) 1268 ABORT; 1269 1270 fprintf(stdout, " ok\n\n"); 1271 } 1272 1273 1274 if (ctx) 1275 BN_CTX_free(ctx); 1276 BN_free(p); 1277 BN_free(a); 1278 BN_free(b); 1279 EC_GROUP_free(group); 1280 EC_POINT_free(P); 1281 EC_POINT_free(Q); 1282 EC_POINT_free(R); 1283 BN_free(x); 1284 BN_free(y); 1285 BN_free(z); 1286 BN_free(cof); 1287 1288 if (C2_K163) 1289 EC_GROUP_free(C2_K163); 1290 if (C2_B163) 1291 EC_GROUP_free(C2_B163); 1292 if (C2_K233) 1293 EC_GROUP_free(C2_K233); 1294 if (C2_B233) 1295 EC_GROUP_free(C2_B233); 1296 if (C2_K283) 1297 EC_GROUP_free(C2_K283); 1298 if (C2_B283) 1299 EC_GROUP_free(C2_B283); 1300 if (C2_K409) 1301 EC_GROUP_free(C2_K409); 1302 if (C2_B409) 1303 EC_GROUP_free(C2_B409); 1304 if (C2_K571) 1305 EC_GROUP_free(C2_K571); 1306 if (C2_B571) 1307 EC_GROUP_free(C2_B571); 1308 1309 } 1310 #endif 1311 1312 static void 1313 internal_curve_test(void) 1314 { 1315 EC_builtin_curve *curves = NULL; 1316 size_t crv_len = 0, n = 0; 1317 int ok = 1; 1318 1319 crv_len = EC_get_builtin_curves(NULL, 0); 1320 1321 curves = reallocarray(NULL, sizeof(EC_builtin_curve), crv_len); 1322 1323 if (curves == NULL) 1324 return; 1325 1326 if (!EC_get_builtin_curves(curves, crv_len)) { 1327 free(curves); 1328 return; 1329 } 1330 1331 fprintf(stdout, "testing internal curves: "); 1332 1333 for (n = 0; n < crv_len; n++) { 1334 EC_GROUP *group = NULL; 1335 int nid = curves[n].nid; 1336 if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) { 1337 ok = 0; 1338 fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with" 1339 " curve %s\n", OBJ_nid2sn(nid)); 1340 /* try next curve */ 1341 continue; 1342 } 1343 if (!EC_GROUP_check(group, NULL)) { 1344 ok = 0; 1345 fprintf(stdout, "\nEC_GROUP_check() failed with" 1346 " curve %s\n", OBJ_nid2sn(nid)); 1347 EC_GROUP_free(group); 1348 /* try the next curve */ 1349 continue; 1350 } 1351 fprintf(stdout, "."); 1352 fflush(stdout); 1353 EC_GROUP_free(group); 1354 } 1355 if (ok) 1356 fprintf(stdout, " ok\n\n"); 1357 else { 1358 fprintf(stdout, " failed\n\n"); 1359 ABORT; 1360 } 1361 free(curves); 1362 return; 1363 } 1364 1365 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 1366 /* nistp_test_params contains magic numbers for testing our optimized 1367 * implementations of several NIST curves with characteristic > 3. */ 1368 struct nistp_test_params { 1369 const EC_METHOD* (*meth) (); 1370 int degree; 1371 /* Qx, Qy and D are taken from 1372 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf 1373 * Otherwise, values are standard curve parameters from FIPS 180-3 */ 1374 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d; 1375 }; 1376 1377 static const struct nistp_test_params nistp_tests_params[] = { { 1378 /* P-224 */ 1379 EC_GFp_nistp224_method, 1380 224, 1381 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* p */ 1382 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* a */ 1383 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* b */ 1384 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", /* Qx */ 1385 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", /* Qy */ 1386 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */ 1387 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */ 1388 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */ 1389 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", /* d */ 1390 }, 1391 { 1392 /* P-256 */ 1393 EC_GFp_nistp256_method, 1394 256, 1395 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", /* p */ 1396 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", /* a */ 1397 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", /* b */ 1398 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", /* Qx */ 1399 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", /* Qy */ 1400 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", /* Gx */ 1401 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", /* Gy */ 1402 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", /* order */ 1403 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", /* d */ 1404 }, 1405 { 1406 /* P-521 */ 1407 EC_GFp_nistp521_method, 1408 521, 1409 "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", /* p */ 1410 "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", /* a */ 1411 "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", /* b */ 1412 "0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", /* Qx */ 1413 "0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", /* Qy */ 1414 "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", /* Gx */ 1415 "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", /* Gy */ 1416 "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", /* order */ 1417 "0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", /* d */ 1418 }, 1419 }; 1420 1421 void 1422 nistp_single_test(const struct nistp_test_params *test) 1423 { 1424 BN_CTX *ctx; 1425 BIGNUM *p, *a, *b, *x, *y, *n, *m, *order; 1426 EC_GROUP *NISTP; 1427 EC_POINT *G, *P, *Q, *Q_CHECK; 1428 1429 fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", test->degree); 1430 ctx = BN_CTX_new(); 1431 p = BN_new(); 1432 a = BN_new(); 1433 b = BN_new(); 1434 x = BN_new(); 1435 y = BN_new(); 1436 m = BN_new(); 1437 n = BN_new(); 1438 order = BN_new(); 1439 1440 NISTP = EC_GROUP_new(test->meth()); 1441 if (!NISTP) 1442 ABORT; 1443 if (!BN_hex2bn(&p, test->p)) 1444 ABORT; 1445 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 1446 ABORT; 1447 if (!BN_hex2bn(&a, test->a)) 1448 ABORT; 1449 if (!BN_hex2bn(&b, test->b)) 1450 ABORT; 1451 if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) 1452 ABORT; 1453 G = EC_POINT_new(NISTP); 1454 P = EC_POINT_new(NISTP); 1455 Q = EC_POINT_new(NISTP); 1456 Q_CHECK = EC_POINT_new(NISTP); 1457 if (!BN_hex2bn(&x, test->Qx)) 1458 ABORT; 1459 if (!BN_hex2bn(&y, test->Qy)) 1460 ABORT; 1461 if (!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) 1462 ABORT; 1463 if (!BN_hex2bn(&x, test->Gx)) 1464 ABORT; 1465 if (!BN_hex2bn(&y, test->Gy)) 1466 ABORT; 1467 if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) 1468 ABORT; 1469 if (!BN_hex2bn(&order, test->order)) 1470 ABORT; 1471 if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) 1472 ABORT; 1473 1474 fprintf(stdout, "verify degree ... "); 1475 if (EC_GROUP_get_degree(NISTP) != test->degree) 1476 ABORT; 1477 fprintf(stdout, "ok\n"); 1478 1479 fprintf(stdout, "NIST test vectors ... "); 1480 if (!BN_hex2bn(&n, test->d)) 1481 ABORT; 1482 /* fixed point multiplication */ 1483 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); 1484 if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1485 ABORT; 1486 /* random point multiplication */ 1487 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); 1488 if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1489 ABORT; 1490 1491 /* set generator to P = 2*G, where G is the standard generator */ 1492 if (!EC_POINT_dbl(NISTP, P, G, ctx)) 1493 ABORT; 1494 if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) 1495 ABORT; 1496 /* set the scalar to m=n/2, where n is the NIST test scalar */ 1497 if (!BN_rshift(m, n, 1)) 1498 ABORT; 1499 1500 /* test the non-standard generator */ 1501 /* fixed point multiplication */ 1502 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); 1503 if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1504 ABORT; 1505 /* random point multiplication */ 1506 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); 1507 if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1508 ABORT; 1509 1510 /* now repeat all tests with precomputation */ 1511 if (!EC_GROUP_precompute_mult(NISTP, ctx)) 1512 ABORT; 1513 1514 /* fixed point multiplication */ 1515 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); 1516 if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1517 ABORT; 1518 /* random point multiplication */ 1519 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); 1520 if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1521 ABORT; 1522 1523 /* reset generator */ 1524 if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) 1525 ABORT; 1526 /* fixed point multiplication */ 1527 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); 1528 if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1529 ABORT; 1530 /* random point multiplication */ 1531 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); 1532 if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1533 ABORT; 1534 1535 fprintf(stdout, "ok\n"); 1536 group_order_tests(NISTP); 1537 EC_GROUP_free(NISTP); 1538 EC_POINT_free(G); 1539 EC_POINT_free(P); 1540 EC_POINT_free(Q); 1541 EC_POINT_free(Q_CHECK); 1542 BN_free(n); 1543 BN_free(m); 1544 BN_free(p); 1545 BN_free(a); 1546 BN_free(b); 1547 BN_free(x); 1548 BN_free(y); 1549 BN_free(order); 1550 BN_CTX_free(ctx); 1551 } 1552 1553 void 1554 nistp_tests() 1555 { 1556 unsigned i; 1557 1558 for (i = 0; i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); i++) { 1559 nistp_single_test(&nistp_tests_params[i]); 1560 } 1561 } 1562 #endif 1563 1564 int 1565 main(int argc, char *argv[]) 1566 { 1567 ERR_load_crypto_strings(); 1568 1569 prime_field_tests(); 1570 puts(""); 1571 #ifndef OPENSSL_NO_EC2M 1572 char2_field_tests(); 1573 #endif 1574 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 1575 nistp_tests(); 1576 #endif 1577 /* test the internal curves */ 1578 internal_curve_test(); 1579 1580 #ifndef OPENSSL_NO_ENGINE 1581 ENGINE_cleanup(); 1582 #endif 1583 CRYPTO_cleanup_all_ex_data(); 1584 ERR_free_strings(); 1585 ERR_remove_thread_state(NULL); 1586 CRYPTO_mem_leaks_fp(stderr); 1587 1588 return 0; 1589 } 1590