1 /* $OpenBSD: ectest.c,v 1.35 2025/01/24 11:49:13 tb Exp $ */ 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 #include <openssl/err.h> 79 #include <openssl/obj_mac.h> 80 #include <openssl/objects.h> 81 #include <openssl/bn.h> 82 #include <openssl/opensslconf.h> 83 84 #define ABORT do { \ 85 fflush(stdout); \ 86 fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \ 87 ERR_print_errors_fp(stderr); \ 88 exit(1); \ 89 } while (0) 90 91 /* test multiplication with group order, long and negative scalars */ 92 static void 93 group_order_tests(EC_GROUP *group, BN_CTX *ctx) 94 { 95 BIGNUM *n1, *n2, *order; 96 EC_POINT *P = EC_POINT_new(group); 97 EC_POINT *Q = EC_POINT_new(group); 98 99 if (P == NULL || Q == NULL) 100 ABORT; 101 102 BN_CTX_start(ctx); 103 104 if ((n1 = BN_CTX_get(ctx)) == NULL) 105 ABORT; 106 if ((n2 = BN_CTX_get(ctx)) == NULL) 107 ABORT; 108 if ((order = BN_CTX_get(ctx)) == NULL) 109 ABORT; 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_POINT_mul(group, Q, order, NULL, NULL, ctx)) 121 ABORT; 122 if (!EC_POINT_is_at_infinity(group, Q)) 123 ABORT; 124 fprintf(stdout, " ok\n"); 125 fprintf(stdout, "long/negative scalar tests ... "); 126 if (!BN_one(n1)) 127 ABORT; 128 /* n1 = 1 - order */ 129 if (!BN_sub(n1, n1, order)) 130 ABORT; 131 if (!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) 132 ABORT; 133 if (0 != EC_POINT_cmp(group, Q, P, ctx)) 134 ABORT; 135 /* n2 = 1 + order */ 136 if (!BN_add(n2, order, BN_value_one())) 137 ABORT; 138 if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 139 ABORT; 140 if (0 != EC_POINT_cmp(group, Q, P, ctx)) 141 ABORT; 142 /* n2 = (1 - order) * (1 + order) */ 143 if (!BN_mul(n2, n1, n2, ctx)) 144 ABORT; 145 if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 146 ABORT; 147 if (0 != EC_POINT_cmp(group, Q, P, ctx)) 148 ABORT; 149 fprintf(stdout, "ok\n"); 150 EC_POINT_free(P); 151 EC_POINT_free(Q); 152 BN_CTX_end(ctx); 153 } 154 155 static void 156 prime_field_tests(void) 157 { 158 BN_CTX *ctx = NULL; 159 BIGNUM *p, *a, *b; 160 EC_GROUP *group; 161 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL; 162 EC_POINT *P, *Q, *R; 163 BIGNUM *x, *y, *z; 164 unsigned char buf[100]; 165 size_t i, len; 166 int k; 167 168 ctx = BN_CTX_new(); 169 if (!ctx) 170 ABORT; 171 172 p = BN_new(); 173 a = BN_new(); 174 b = BN_new(); 175 if (!p || !a || !b) 176 ABORT; 177 178 if (!BN_hex2bn(&p, "17")) 179 ABORT; 180 if (!BN_hex2bn(&a, "1")) 181 ABORT; 182 if (!BN_hex2bn(&b, "1")) 183 ABORT; 184 185 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) 186 ABORT; 187 188 { 189 EC_GROUP *tmp; 190 191 if ((tmp = EC_GROUP_dup(group)) == NULL) 192 ABORT; 193 EC_GROUP_free(group); 194 group = tmp; 195 } 196 197 if (!EC_GROUP_get_curve(group, p, a, b, ctx)) 198 ABORT; 199 200 fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x"); 201 BN_print_fp(stdout, p); 202 fprintf(stdout, ")\n a = 0x"); 203 BN_print_fp(stdout, a); 204 fprintf(stdout, "\n b = 0x"); 205 BN_print_fp(stdout, b); 206 fprintf(stdout, "\n"); 207 208 P = EC_POINT_new(group); 209 Q = EC_POINT_new(group); 210 R = EC_POINT_new(group); 211 if (!P || !Q || !R) 212 ABORT; 213 214 if (!EC_POINT_set_to_infinity(group, P)) 215 ABORT; 216 if (!EC_POINT_is_at_infinity(group, P)) 217 ABORT; 218 219 buf[0] = 0; 220 if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) 221 ABORT; 222 223 if (!EC_POINT_add(group, P, P, Q, ctx)) 224 ABORT; 225 if (!EC_POINT_is_at_infinity(group, P)) 226 ABORT; 227 228 x = BN_new(); 229 y = BN_new(); 230 z = BN_new(); 231 if (!x || !y || !z) 232 ABORT; 233 234 if (!BN_hex2bn(&x, "D")) 235 ABORT; 236 if (!EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)) 237 ABORT; 238 if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) { 239 if (!EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)) 240 ABORT; 241 fprintf(stderr, "Point is not on curve: x = 0x"); 242 BN_print_fp(stderr, x); 243 fprintf(stderr, ", y = 0x"); 244 BN_print_fp(stderr, y); 245 fprintf(stderr, "\n"); 246 ABORT; 247 } 248 249 fprintf(stdout, "A cyclic subgroup:\n"); 250 k = 0; 251 do { 252 fprintf(stderr, " %d - ", k); 253 if (EC_POINT_is_at_infinity(group, P)) 254 fprintf(stdout, "point at infinity\n"); 255 else { 256 if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 257 ABORT; 258 259 fprintf(stdout, "x = 0x"); 260 BN_print_fp(stdout, x); 261 fprintf(stdout, ", y = 0x"); 262 BN_print_fp(stdout, y); 263 fprintf(stdout, "\n"); 264 } 265 266 if (!EC_POINT_copy(R, P)) 267 ABORT; 268 if (!EC_POINT_add(group, P, P, Q, ctx)) 269 ABORT; 270 if (k++ > 99) 271 ABORT; 272 } while (!EC_POINT_is_at_infinity(group, P)); 273 274 if (k != 7) { 275 fprintf(stderr, "cycled in %d iterations, want 7\n", k); 276 ABORT; 277 } 278 279 if (!EC_POINT_add(group, P, Q, R, ctx)) 280 ABORT; 281 if (!EC_POINT_is_at_infinity(group, P)) 282 ABORT; 283 284 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx); 285 if (len == 0) 286 ABORT; 287 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 288 ABORT; 289 if (0 != EC_POINT_cmp(group, P, Q, ctx)) 290 ABORT; 291 fprintf(stdout, "Generator as octet string, compressed form:\n "); 292 for (i = 0; i < len; i++) 293 fprintf(stdout, "%02X", buf[i]); 294 295 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx); 296 if (len == 0) 297 ABORT; 298 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 299 ABORT; 300 if (0 != EC_POINT_cmp(group, P, Q, ctx)) 301 ABORT; 302 fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); 303 for (i = 0; i < len; i++) 304 fprintf(stdout, "%02X", buf[i]); 305 306 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx); 307 if (len == 0) 308 ABORT; 309 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 310 ABORT; 311 if (0 != EC_POINT_cmp(group, P, Q, ctx)) 312 ABORT; 313 fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); 314 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); 315 316 if (!EC_POINT_get_affine_coordinates(group, R, x, y, ctx)) 317 ABORT; 318 fprintf(stdout, "\nThe inverse of that generator:\n X = 0x"); 319 BN_print_fp(stdout, x); 320 fprintf(stdout, ", Y = 0x"); 321 BN_print_fp(stdout, y); 322 fprintf(stdout, "\n"); 323 324 if (!EC_POINT_invert(group, P, ctx)) 325 ABORT; 326 if (0 != EC_POINT_cmp(group, P, R, ctx)) 327 ABORT; 328 329 330 /* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000) 331 * -- not a NIST curve, but commonly used */ 332 333 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) 334 ABORT; 335 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 336 ABORT; 337 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) 338 ABORT; 339 if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) 340 ABORT; 341 if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 342 ABORT; 343 344 if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) 345 ABORT; 346 if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) 347 ABORT; 348 if (!EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) 349 ABORT; 350 if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 351 ABORT; 352 if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) 353 ABORT; 354 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 355 ABORT; 356 357 if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 358 ABORT; 359 fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n x = 0x"); 360 BN_print_fp(stdout, x); 361 fprintf(stdout, "\n y = 0x"); 362 BN_print_fp(stdout, y); 363 fprintf(stdout, "\n"); 364 /* G_y value taken from the standard: */ 365 if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) 366 ABORT; 367 if (0 != BN_cmp(y, z)) 368 ABORT; 369 370 fprintf(stdout, "verify degree ..."); 371 if (EC_GROUP_get_degree(group) != 160) 372 ABORT; 373 fprintf(stdout, " ok\n"); 374 375 group_order_tests(group, ctx); 376 377 if ((P_160 = EC_GROUP_dup(group)) == NULL) 378 ABORT; 379 380 /* Curve P-192 (FIPS PUB 186-2, App. 6) */ 381 382 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) 383 ABORT; 384 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 385 ABORT; 386 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) 387 ABORT; 388 if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) 389 ABORT; 390 if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 391 ABORT; 392 393 if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) 394 ABORT; 395 if (!EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) 396 ABORT; 397 if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 398 ABORT; 399 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) 400 ABORT; 401 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 402 ABORT; 403 404 if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 405 ABORT; 406 fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x"); 407 BN_print_fp(stdout, x); 408 fprintf(stdout, "\n y = 0x"); 409 BN_print_fp(stdout, y); 410 fprintf(stdout, "\n"); 411 /* G_y value taken from the standard: */ 412 if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) 413 ABORT; 414 if (0 != BN_cmp(y, z)) 415 ABORT; 416 417 fprintf(stdout, "verify degree ..."); 418 if (EC_GROUP_get_degree(group) != 192) 419 ABORT; 420 fprintf(stdout, " ok\n"); 421 422 group_order_tests(group, ctx); 423 424 if ((P_192 = EC_GROUP_dup(group)) == NULL) 425 ABORT; 426 427 /* Curve P-224 (FIPS PUB 186-2, App. 6) */ 428 429 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) 430 ABORT; 431 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 432 ABORT; 433 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) 434 ABORT; 435 if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) 436 ABORT; 437 if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 438 ABORT; 439 440 if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) 441 ABORT; 442 if (!EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx)) 443 ABORT; 444 if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 445 ABORT; 446 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) 447 ABORT; 448 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 449 ABORT; 450 451 if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 452 ABORT; 453 fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x"); 454 BN_print_fp(stdout, x); 455 fprintf(stdout, "\n y = 0x"); 456 BN_print_fp(stdout, y); 457 fprintf(stdout, "\n"); 458 /* G_y value taken from the standard: */ 459 if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) 460 ABORT; 461 if (0 != BN_cmp(y, z)) 462 ABORT; 463 464 fprintf(stdout, "verify degree ..."); 465 if (EC_GROUP_get_degree(group) != 224) 466 ABORT; 467 fprintf(stdout, " ok\n"); 468 469 group_order_tests(group, ctx); 470 471 if ((P_224 = EC_GROUP_dup(group)) == NULL) 472 ABORT; 473 474 /* Curve P-256 (FIPS PUB 186-2, App. 6) */ 475 476 if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) 477 ABORT; 478 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 479 ABORT; 480 if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) 481 ABORT; 482 if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) 483 ABORT; 484 if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 485 ABORT; 486 487 if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) 488 ABORT; 489 if (!EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) 490 ABORT; 491 if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 492 ABORT; 493 if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E" 494 "84F3B9CAC2FC632551")) ABORT; 495 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 496 ABORT; 497 498 if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 499 ABORT; 500 fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x"); 501 BN_print_fp(stdout, x); 502 fprintf(stdout, "\n y = 0x"); 503 BN_print_fp(stdout, y); 504 fprintf(stdout, "\n"); 505 /* G_y value taken from the standard: */ 506 if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) 507 ABORT; 508 if (0 != BN_cmp(y, z)) 509 ABORT; 510 511 fprintf(stdout, "verify degree ..."); 512 if (EC_GROUP_get_degree(group) != 256) 513 ABORT; 514 fprintf(stdout, " ok\n"); 515 516 group_order_tests(group, ctx); 517 518 if ((P_256 = EC_GROUP_dup(group)) == NULL) 519 ABORT; 520 521 /* Curve P-384 (FIPS PUB 186-2, App. 6) */ 522 523 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 524 "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT; 525 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 526 ABORT; 527 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 528 "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT; 529 if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141" 530 "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT; 531 if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 532 ABORT; 533 534 if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B" 535 "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT; 536 if (!EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) 537 ABORT; 538 if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 539 ABORT; 540 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 541 "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT; 542 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 543 ABORT; 544 545 if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 546 ABORT; 547 fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x"); 548 BN_print_fp(stdout, x); 549 fprintf(stdout, "\n y = 0x"); 550 BN_print_fp(stdout, y); 551 fprintf(stdout, "\n"); 552 /* G_y value taken from the standard: */ 553 if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14" 554 "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT; 555 if (0 != BN_cmp(y, z)) 556 ABORT; 557 558 fprintf(stdout, "verify degree ..."); 559 if (EC_GROUP_get_degree(group) != 384) 560 ABORT; 561 fprintf(stdout, " ok\n"); 562 563 group_order_tests(group, ctx); 564 565 if ((P_384 = EC_GROUP_dup(group)) == NULL) 566 ABORT; 567 568 /* Curve P-521 (FIPS PUB 186-2, App. 6) */ 569 570 if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 571 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 572 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT; 573 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 574 ABORT; 575 if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 576 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 577 "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT; 578 if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B" 579 "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573" 580 "DF883D2C34F1EF451FD46B503F00")) ABORT; 581 if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 582 ABORT; 583 584 if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F" 585 "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B" 586 "3C1856A429BF97E7E31C2E5BD66")) ABORT; 587 if (!EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx)) 588 ABORT; 589 if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 590 ABORT; 591 if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 592 "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5" 593 "C9B8899C47AEBB6FB71E91386409")) ABORT; 594 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 595 ABORT; 596 597 if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 598 ABORT; 599 fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x"); 600 BN_print_fp(stdout, x); 601 fprintf(stdout, "\n y = 0x"); 602 BN_print_fp(stdout, y); 603 fprintf(stdout, "\n"); 604 /* G_y value taken from the standard: */ 605 if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579" 606 "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C" 607 "7086A272C24088BE94769FD16650")) ABORT; 608 if (0 != BN_cmp(y, z)) 609 ABORT; 610 611 fprintf(stdout, "verify degree ..."); 612 if (EC_GROUP_get_degree(group) != 521) 613 ABORT; 614 fprintf(stdout, " ok\n"); 615 616 group_order_tests(group, ctx); 617 618 if ((P_521 = EC_GROUP_dup(group)) == NULL) 619 ABORT; 620 621 /* more tests using the last curve */ 622 fprintf(stdout, "infinity tests ..."); 623 fflush(stdout); 624 if (!EC_POINT_copy(Q, P)) 625 ABORT; 626 if (EC_POINT_is_at_infinity(group, Q)) 627 ABORT; 628 /* P := 2P */ 629 if (!EC_POINT_dbl(group, P, P, ctx)) 630 ABORT; 631 if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 632 ABORT; 633 /* Q := -P */ 634 if (!EC_POINT_invert(group, Q, ctx)) 635 ABORT; 636 /* R := 2P - P = P */ 637 if (!EC_POINT_add(group, R, P, Q, ctx)) 638 ABORT; 639 /* R := R + Q = P - P = infty */ 640 if (!EC_POINT_add(group, R, R, Q, ctx)) 641 ABORT; 642 if (!EC_POINT_is_at_infinity(group, R)) 643 ABORT; 644 fprintf(stdout, " ok\n\n"); 645 646 if (ctx) 647 BN_CTX_free(ctx); 648 BN_free(p); 649 BN_free(a); 650 BN_free(b); 651 EC_GROUP_free(group); 652 EC_POINT_free(P); 653 EC_POINT_free(Q); 654 EC_POINT_free(R); 655 BN_free(x); 656 BN_free(y); 657 BN_free(z); 658 659 EC_GROUP_free(P_160); 660 EC_GROUP_free(P_192); 661 EC_GROUP_free(P_224); 662 EC_GROUP_free(P_256); 663 EC_GROUP_free(P_384); 664 EC_GROUP_free(P_521); 665 } 666 667 int 668 main(int argc, char *argv[]) 669 { 670 ERR_load_crypto_strings(); 671 672 prime_field_tests(); 673 674 CRYPTO_cleanup_all_ex_data(); 675 ERR_free_strings(); 676 ERR_remove_thread_state(NULL); 677 678 return 0; 679 } 680