1*3370674dStb /* $OpenBSD: ectest.c,v 1.35 2025/01/24 11:49:13 tb Exp $ */ 23c6bd008Smiod /* 33c6bd008Smiod * Originally written by Bodo Moeller for the OpenSSL project. 43c6bd008Smiod */ 53c6bd008Smiod /* ==================================================================== 63c6bd008Smiod * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 73c6bd008Smiod * 83c6bd008Smiod * Redistribution and use in source and binary forms, with or without 93c6bd008Smiod * modification, are permitted provided that the following conditions 103c6bd008Smiod * are met: 113c6bd008Smiod * 123c6bd008Smiod * 1. Redistributions of source code must retain the above copyright 133c6bd008Smiod * notice, this list of conditions and the following disclaimer. 143c6bd008Smiod * 153c6bd008Smiod * 2. Redistributions in binary form must reproduce the above copyright 163c6bd008Smiod * notice, this list of conditions and the following disclaimer in 173c6bd008Smiod * the documentation and/or other materials provided with the 183c6bd008Smiod * distribution. 193c6bd008Smiod * 203c6bd008Smiod * 3. All advertising materials mentioning features or use of this 213c6bd008Smiod * software must display the following acknowledgment: 223c6bd008Smiod * "This product includes software developed by the OpenSSL Project 233c6bd008Smiod * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 243c6bd008Smiod * 253c6bd008Smiod * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 263c6bd008Smiod * endorse or promote products derived from this software without 273c6bd008Smiod * prior written permission. For written permission, please contact 283c6bd008Smiod * openssl-core@openssl.org. 293c6bd008Smiod * 303c6bd008Smiod * 5. Products derived from this software may not be called "OpenSSL" 313c6bd008Smiod * nor may "OpenSSL" appear in their names without prior written 323c6bd008Smiod * permission of the OpenSSL Project. 333c6bd008Smiod * 343c6bd008Smiod * 6. Redistributions of any form whatsoever must retain the following 353c6bd008Smiod * acknowledgment: 363c6bd008Smiod * "This product includes software developed by the OpenSSL Project 373c6bd008Smiod * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 383c6bd008Smiod * 393c6bd008Smiod * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 403c6bd008Smiod * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 413c6bd008Smiod * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 423c6bd008Smiod * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 433c6bd008Smiod * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 443c6bd008Smiod * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 453c6bd008Smiod * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 463c6bd008Smiod * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 473c6bd008Smiod * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 483c6bd008Smiod * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 493c6bd008Smiod * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 503c6bd008Smiod * OF THE POSSIBILITY OF SUCH DAMAGE. 513c6bd008Smiod * ==================================================================== 523c6bd008Smiod * 533c6bd008Smiod * This product includes cryptographic software written by Eric Young 543c6bd008Smiod * (eay@cryptsoft.com). This product includes software written by Tim 553c6bd008Smiod * Hudson (tjh@cryptsoft.com). 563c6bd008Smiod * 573c6bd008Smiod */ 583c6bd008Smiod /* ==================================================================== 593c6bd008Smiod * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 603c6bd008Smiod * 613c6bd008Smiod * Portions of the attached software ("Contribution") are developed by 623c6bd008Smiod * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 633c6bd008Smiod * 643c6bd008Smiod * The Contribution is licensed pursuant to the OpenSSL open source 653c6bd008Smiod * license provided above. 663c6bd008Smiod * 673c6bd008Smiod * The elliptic curve binary polynomial software is originally written by 683c6bd008Smiod * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. 693c6bd008Smiod * 703c6bd008Smiod */ 713c6bd008Smiod 723c6bd008Smiod #include <stdio.h> 733c6bd008Smiod #include <stdlib.h> 743c6bd008Smiod #include <string.h> 753c6bd008Smiod #include <time.h> 763c6bd008Smiod 773c6bd008Smiod #include <openssl/ec.h> 783c6bd008Smiod #include <openssl/err.h> 793c6bd008Smiod #include <openssl/obj_mac.h> 803c6bd008Smiod #include <openssl/objects.h> 813c6bd008Smiod #include <openssl/bn.h> 823c6bd008Smiod #include <openssl/opensslconf.h> 833c6bd008Smiod 843c6bd008Smiod #define ABORT do { \ 853c6bd008Smiod fflush(stdout); \ 863c6bd008Smiod fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \ 873c6bd008Smiod ERR_print_errors_fp(stderr); \ 883c6bd008Smiod exit(1); \ 893c6bd008Smiod } while (0) 903c6bd008Smiod 913c6bd008Smiod /* test multiplication with group order, long and negative scalars */ 92bb8ec7f4Sjsing static void 936f11255eStb group_order_tests(EC_GROUP *group, BN_CTX *ctx) 943c6bd008Smiod { 953c6bd008Smiod BIGNUM *n1, *n2, *order; 963c6bd008Smiod EC_POINT *P = EC_POINT_new(group); 973c6bd008Smiod EC_POINT *Q = EC_POINT_new(group); 983c6bd008Smiod 996f11255eStb if (P == NULL || Q == NULL) 1009ec92463Stb ABORT; 1019ec92463Stb 1026f11255eStb BN_CTX_start(ctx); 1036f11255eStb 1046f11255eStb if ((n1 = BN_CTX_get(ctx)) == NULL) 1059ec92463Stb ABORT; 1066f11255eStb if ((n2 = BN_CTX_get(ctx)) == NULL) 1079ec92463Stb ABORT; 1086f11255eStb if ((order = BN_CTX_get(ctx)) == NULL) 1099ec92463Stb ABORT; 1103c6bd008Smiod fprintf(stdout, "verify group order ..."); 1113c6bd008Smiod fflush(stdout); 112bb8ec7f4Sjsing if (!EC_GROUP_get_order(group, order, ctx)) 113bb8ec7f4Sjsing ABORT; 114bb8ec7f4Sjsing if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) 115bb8ec7f4Sjsing ABORT; 116bb8ec7f4Sjsing if (!EC_POINT_is_at_infinity(group, Q)) 117bb8ec7f4Sjsing ABORT; 1183c6bd008Smiod fprintf(stdout, "."); 1193c6bd008Smiod fflush(stdout); 120bb8ec7f4Sjsing if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) 121bb8ec7f4Sjsing ABORT; 122bb8ec7f4Sjsing if (!EC_POINT_is_at_infinity(group, Q)) 123bb8ec7f4Sjsing ABORT; 1243c6bd008Smiod fprintf(stdout, " ok\n"); 1253c6bd008Smiod fprintf(stdout, "long/negative scalar tests ... "); 126717b1211Stb if (!BN_one(n1)) 127bb8ec7f4Sjsing ABORT; 1283c6bd008Smiod /* n1 = 1 - order */ 129bb8ec7f4Sjsing if (!BN_sub(n1, n1, order)) 130bb8ec7f4Sjsing ABORT; 131bb8ec7f4Sjsing if (!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) 132bb8ec7f4Sjsing ABORT; 133bb8ec7f4Sjsing if (0 != EC_POINT_cmp(group, Q, P, ctx)) 134bb8ec7f4Sjsing ABORT; 1353c6bd008Smiod /* n2 = 1 + order */ 136bb8ec7f4Sjsing if (!BN_add(n2, order, BN_value_one())) 137bb8ec7f4Sjsing ABORT; 138bb8ec7f4Sjsing if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 139bb8ec7f4Sjsing ABORT; 140bb8ec7f4Sjsing if (0 != EC_POINT_cmp(group, Q, P, ctx)) 141bb8ec7f4Sjsing ABORT; 1423c6bd008Smiod /* n2 = (1 - order) * (1 + order) */ 143bb8ec7f4Sjsing if (!BN_mul(n2, n1, n2, ctx)) 144bb8ec7f4Sjsing ABORT; 145bb8ec7f4Sjsing if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 146bb8ec7f4Sjsing ABORT; 147bb8ec7f4Sjsing if (0 != EC_POINT_cmp(group, Q, P, ctx)) 148bb8ec7f4Sjsing ABORT; 1493c6bd008Smiod fprintf(stdout, "ok\n"); 1503c6bd008Smiod EC_POINT_free(P); 1513c6bd008Smiod EC_POINT_free(Q); 1526f11255eStb BN_CTX_end(ctx); 1533c6bd008Smiod } 1543c6bd008Smiod 155bb8ec7f4Sjsing static void 156bb8ec7f4Sjsing prime_field_tests(void) 1573c6bd008Smiod { 1583c6bd008Smiod BN_CTX *ctx = NULL; 1593c6bd008Smiod BIGNUM *p, *a, *b; 1603c6bd008Smiod EC_GROUP *group; 1613c6bd008Smiod EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL; 1623c6bd008Smiod EC_POINT *P, *Q, *R; 1633c6bd008Smiod BIGNUM *x, *y, *z; 1643c6bd008Smiod unsigned char buf[100]; 1653c6bd008Smiod size_t i, len; 1663c6bd008Smiod int k; 1673c6bd008Smiod 1683c6bd008Smiod ctx = BN_CTX_new(); 169bb8ec7f4Sjsing if (!ctx) 170bb8ec7f4Sjsing ABORT; 1713c6bd008Smiod 1723c6bd008Smiod p = BN_new(); 1733c6bd008Smiod a = BN_new(); 1743c6bd008Smiod b = BN_new(); 175bb8ec7f4Sjsing if (!p || !a || !b) 176bb8ec7f4Sjsing ABORT; 1773c6bd008Smiod 178bb8ec7f4Sjsing if (!BN_hex2bn(&p, "17")) 179bb8ec7f4Sjsing ABORT; 180bb8ec7f4Sjsing if (!BN_hex2bn(&a, "1")) 181bb8ec7f4Sjsing ABORT; 182bb8ec7f4Sjsing if (!BN_hex2bn(&b, "1")) 183bb8ec7f4Sjsing ABORT; 1843c6bd008Smiod 1858b9e009eStb if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) 186bb8ec7f4Sjsing ABORT; 1873c6bd008Smiod 1883c6bd008Smiod { 1893c6bd008Smiod EC_GROUP *tmp; 1901e6310a2Stb 1911e6310a2Stb if ((tmp = EC_GROUP_dup(group)) == NULL) 192bb8ec7f4Sjsing ABORT; 1933c6bd008Smiod EC_GROUP_free(group); 1943c6bd008Smiod group = tmp; 1953c6bd008Smiod } 1963c6bd008Smiod 1970318edf0Stb if (!EC_GROUP_get_curve(group, p, a, b, ctx)) 198bb8ec7f4Sjsing ABORT; 1993c6bd008Smiod 2003c6bd008Smiod fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x"); 2013c6bd008Smiod BN_print_fp(stdout, p); 2023c6bd008Smiod fprintf(stdout, ")\n a = 0x"); 2033c6bd008Smiod BN_print_fp(stdout, a); 2043c6bd008Smiod fprintf(stdout, "\n b = 0x"); 2053c6bd008Smiod BN_print_fp(stdout, b); 2063c6bd008Smiod fprintf(stdout, "\n"); 2073c6bd008Smiod 2083c6bd008Smiod P = EC_POINT_new(group); 2093c6bd008Smiod Q = EC_POINT_new(group); 2103c6bd008Smiod R = EC_POINT_new(group); 211bb8ec7f4Sjsing if (!P || !Q || !R) 212bb8ec7f4Sjsing ABORT; 2133c6bd008Smiod 214bb8ec7f4Sjsing if (!EC_POINT_set_to_infinity(group, P)) 215bb8ec7f4Sjsing ABORT; 216bb8ec7f4Sjsing if (!EC_POINT_is_at_infinity(group, P)) 217bb8ec7f4Sjsing ABORT; 2183c6bd008Smiod 2193c6bd008Smiod buf[0] = 0; 220bb8ec7f4Sjsing if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) 221bb8ec7f4Sjsing ABORT; 2223c6bd008Smiod 223bb8ec7f4Sjsing if (!EC_POINT_add(group, P, P, Q, ctx)) 224bb8ec7f4Sjsing ABORT; 225bb8ec7f4Sjsing if (!EC_POINT_is_at_infinity(group, P)) 226bb8ec7f4Sjsing ABORT; 2273c6bd008Smiod 2283c6bd008Smiod x = BN_new(); 2293c6bd008Smiod y = BN_new(); 2303c6bd008Smiod z = BN_new(); 231bb8ec7f4Sjsing if (!x || !y || !z) 232bb8ec7f4Sjsing ABORT; 2333c6bd008Smiod 234bb8ec7f4Sjsing if (!BN_hex2bn(&x, "D")) 235bb8ec7f4Sjsing ABORT; 236a20a87c2Stb if (!EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)) 237bb8ec7f4Sjsing ABORT; 238a267e192Stb if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) { 239b425ed70Stb if (!EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)) 240bb8ec7f4Sjsing ABORT; 2413c6bd008Smiod fprintf(stderr, "Point is not on curve: x = 0x"); 2423c6bd008Smiod BN_print_fp(stderr, x); 2433c6bd008Smiod fprintf(stderr, ", y = 0x"); 2443c6bd008Smiod BN_print_fp(stderr, y); 2453c6bd008Smiod fprintf(stderr, "\n"); 2463c6bd008Smiod ABORT; 2473c6bd008Smiod } 2483c6bd008Smiod 2493c6bd008Smiod fprintf(stdout, "A cyclic subgroup:\n"); 2507cccfedaSjsing k = 0; 2514bd67212Stb do { 2527cccfedaSjsing fprintf(stderr, " %d - ", k); 2533c6bd008Smiod if (EC_POINT_is_at_infinity(group, P)) 2543c6bd008Smiod fprintf(stdout, "point at infinity\n"); 255bb8ec7f4Sjsing else { 256b425ed70Stb if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 257bb8ec7f4Sjsing ABORT; 2583c6bd008Smiod 2593c6bd008Smiod fprintf(stdout, "x = 0x"); 2603c6bd008Smiod BN_print_fp(stdout, x); 2613c6bd008Smiod fprintf(stdout, ", y = 0x"); 2623c6bd008Smiod BN_print_fp(stdout, y); 2633c6bd008Smiod fprintf(stdout, "\n"); 2643c6bd008Smiod } 2653c6bd008Smiod 266bb8ec7f4Sjsing if (!EC_POINT_copy(R, P)) 267bb8ec7f4Sjsing ABORT; 268bb8ec7f4Sjsing if (!EC_POINT_add(group, P, P, Q, ctx)) 269bb8ec7f4Sjsing ABORT; 2707cccfedaSjsing if (k++ > 99) 2717cccfedaSjsing ABORT; 2724bd67212Stb } while (!EC_POINT_is_at_infinity(group, P)); 2733c6bd008Smiod 2747cccfedaSjsing if (k != 7) { 2757cccfedaSjsing fprintf(stderr, "cycled in %d iterations, want 7\n", k); 2767cccfedaSjsing ABORT; 2777cccfedaSjsing } 2787cccfedaSjsing 279bb8ec7f4Sjsing if (!EC_POINT_add(group, P, Q, R, ctx)) 280bb8ec7f4Sjsing ABORT; 281bb8ec7f4Sjsing if (!EC_POINT_is_at_infinity(group, P)) 282bb8ec7f4Sjsing ABORT; 2833c6bd008Smiod 2843c6bd008Smiod len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx); 285bb8ec7f4Sjsing if (len == 0) 286bb8ec7f4Sjsing ABORT; 287bb8ec7f4Sjsing if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 288bb8ec7f4Sjsing ABORT; 289bb8ec7f4Sjsing if (0 != EC_POINT_cmp(group, P, Q, ctx)) 290bb8ec7f4Sjsing ABORT; 2913c6bd008Smiod fprintf(stdout, "Generator as octet string, compressed form:\n "); 2925fc787e0Stb for (i = 0; i < len; i++) 2935fc787e0Stb fprintf(stdout, "%02X", buf[i]); 2943c6bd008Smiod 2953c6bd008Smiod len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx); 296bb8ec7f4Sjsing if (len == 0) 297bb8ec7f4Sjsing ABORT; 298bb8ec7f4Sjsing if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 299bb8ec7f4Sjsing ABORT; 300bb8ec7f4Sjsing if (0 != EC_POINT_cmp(group, P, Q, ctx)) 301bb8ec7f4Sjsing ABORT; 3023c6bd008Smiod fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); 3035fc787e0Stb for (i = 0; i < len; i++) 3045fc787e0Stb fprintf(stdout, "%02X", buf[i]); 3053c6bd008Smiod 3063c6bd008Smiod len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx); 307bb8ec7f4Sjsing if (len == 0) 308bb8ec7f4Sjsing ABORT; 309bb8ec7f4Sjsing if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 310bb8ec7f4Sjsing ABORT; 311bb8ec7f4Sjsing if (0 != EC_POINT_cmp(group, P, Q, ctx)) 312bb8ec7f4Sjsing ABORT; 3133c6bd008Smiod fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); 3143c6bd008Smiod for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); 3153c6bd008Smiod 316ca071fc0Stb if (!EC_POINT_get_affine_coordinates(group, R, x, y, ctx)) 317bb8ec7f4Sjsing ABORT; 3185e713ac6Stb fprintf(stdout, "\nThe inverse of that generator:\n X = 0x"); 3193c6bd008Smiod BN_print_fp(stdout, x); 3203c6bd008Smiod fprintf(stdout, ", Y = 0x"); 3213c6bd008Smiod BN_print_fp(stdout, y); 3223c6bd008Smiod fprintf(stdout, "\n"); 3233c6bd008Smiod 324bb8ec7f4Sjsing if (!EC_POINT_invert(group, P, ctx)) 325bb8ec7f4Sjsing ABORT; 326bb8ec7f4Sjsing if (0 != EC_POINT_cmp(group, P, R, ctx)) 327bb8ec7f4Sjsing ABORT; 3283c6bd008Smiod 3293c6bd008Smiod 3303c6bd008Smiod /* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000) 3313c6bd008Smiod * -- not a NIST curve, but commonly used */ 3323c6bd008Smiod 333bb8ec7f4Sjsing if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) 334bb8ec7f4Sjsing ABORT; 335bb8ec7f4Sjsing if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 336bb8ec7f4Sjsing ABORT; 337bb8ec7f4Sjsing if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) 338bb8ec7f4Sjsing ABORT; 339bb8ec7f4Sjsing if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) 340bb8ec7f4Sjsing ABORT; 3410318edf0Stb if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 342bb8ec7f4Sjsing ABORT; 3433c6bd008Smiod 344bb8ec7f4Sjsing if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) 345bb8ec7f4Sjsing ABORT; 346bb8ec7f4Sjsing if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) 347bb8ec7f4Sjsing ABORT; 348b425ed70Stb if (!EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) 349bb8ec7f4Sjsing ABORT; 350a267e192Stb if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 351bb8ec7f4Sjsing ABORT; 352bb8ec7f4Sjsing if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) 353bb8ec7f4Sjsing ABORT; 354bb8ec7f4Sjsing if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 355bb8ec7f4Sjsing ABORT; 3563c6bd008Smiod 357b425ed70Stb if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 358bb8ec7f4Sjsing ABORT; 3593c6bd008Smiod fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n x = 0x"); 3603c6bd008Smiod BN_print_fp(stdout, x); 3613c6bd008Smiod fprintf(stdout, "\n y = 0x"); 3623c6bd008Smiod BN_print_fp(stdout, y); 3633c6bd008Smiod fprintf(stdout, "\n"); 3643c6bd008Smiod /* G_y value taken from the standard: */ 365bb8ec7f4Sjsing if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) 366bb8ec7f4Sjsing ABORT; 367bb8ec7f4Sjsing if (0 != BN_cmp(y, z)) 368bb8ec7f4Sjsing ABORT; 3693c6bd008Smiod 3703c6bd008Smiod fprintf(stdout, "verify degree ..."); 371bb8ec7f4Sjsing if (EC_GROUP_get_degree(group) != 160) 372bb8ec7f4Sjsing ABORT; 3733c6bd008Smiod fprintf(stdout, " ok\n"); 3743c6bd008Smiod 3756f11255eStb group_order_tests(group, ctx); 3763c6bd008Smiod 3771e6310a2Stb if ((P_160 = EC_GROUP_dup(group)) == NULL) 378bb8ec7f4Sjsing ABORT; 3793c6bd008Smiod 3803c6bd008Smiod /* Curve P-192 (FIPS PUB 186-2, App. 6) */ 3813c6bd008Smiod 382bb8ec7f4Sjsing if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) 383bb8ec7f4Sjsing ABORT; 384bb8ec7f4Sjsing if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 385bb8ec7f4Sjsing ABORT; 386bb8ec7f4Sjsing if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) 387bb8ec7f4Sjsing ABORT; 388bb8ec7f4Sjsing if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) 389bb8ec7f4Sjsing ABORT; 3900318edf0Stb if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 391bb8ec7f4Sjsing ABORT; 3923c6bd008Smiod 393bb8ec7f4Sjsing if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) 394bb8ec7f4Sjsing ABORT; 395a20a87c2Stb if (!EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) 396bb8ec7f4Sjsing ABORT; 397a267e192Stb if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 398bb8ec7f4Sjsing ABORT; 399bb8ec7f4Sjsing if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) 400bb8ec7f4Sjsing ABORT; 401bb8ec7f4Sjsing if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 402bb8ec7f4Sjsing ABORT; 4033c6bd008Smiod 404b425ed70Stb if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 405bb8ec7f4Sjsing ABORT; 4063c6bd008Smiod fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x"); 4073c6bd008Smiod BN_print_fp(stdout, x); 4083c6bd008Smiod fprintf(stdout, "\n y = 0x"); 4093c6bd008Smiod BN_print_fp(stdout, y); 4103c6bd008Smiod fprintf(stdout, "\n"); 4113c6bd008Smiod /* G_y value taken from the standard: */ 412bb8ec7f4Sjsing if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) 413bb8ec7f4Sjsing ABORT; 414bb8ec7f4Sjsing if (0 != BN_cmp(y, z)) 415bb8ec7f4Sjsing ABORT; 4163c6bd008Smiod 4173c6bd008Smiod fprintf(stdout, "verify degree ..."); 418bb8ec7f4Sjsing if (EC_GROUP_get_degree(group) != 192) 419bb8ec7f4Sjsing ABORT; 4203c6bd008Smiod fprintf(stdout, " ok\n"); 4213c6bd008Smiod 4226f11255eStb group_order_tests(group, ctx); 4233c6bd008Smiod 4241e6310a2Stb if ((P_192 = EC_GROUP_dup(group)) == NULL) 425bb8ec7f4Sjsing ABORT; 4263c6bd008Smiod 4273c6bd008Smiod /* Curve P-224 (FIPS PUB 186-2, App. 6) */ 4283c6bd008Smiod 429bb8ec7f4Sjsing if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) 430bb8ec7f4Sjsing ABORT; 431bb8ec7f4Sjsing if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 432bb8ec7f4Sjsing ABORT; 433bb8ec7f4Sjsing if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) 434bb8ec7f4Sjsing ABORT; 435bb8ec7f4Sjsing if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) 436bb8ec7f4Sjsing ABORT; 4370318edf0Stb if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 438bb8ec7f4Sjsing ABORT; 4393c6bd008Smiod 440bb8ec7f4Sjsing if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) 441bb8ec7f4Sjsing ABORT; 442a20a87c2Stb if (!EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx)) 443bb8ec7f4Sjsing ABORT; 444a267e192Stb if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 445bb8ec7f4Sjsing ABORT; 446bb8ec7f4Sjsing if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) 447bb8ec7f4Sjsing ABORT; 448bb8ec7f4Sjsing if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 449bb8ec7f4Sjsing ABORT; 4503c6bd008Smiod 451b425ed70Stb if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 452bb8ec7f4Sjsing ABORT; 4533c6bd008Smiod fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x"); 4543c6bd008Smiod BN_print_fp(stdout, x); 4553c6bd008Smiod fprintf(stdout, "\n y = 0x"); 4563c6bd008Smiod BN_print_fp(stdout, y); 4573c6bd008Smiod fprintf(stdout, "\n"); 4583c6bd008Smiod /* G_y value taken from the standard: */ 459bb8ec7f4Sjsing if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) 460bb8ec7f4Sjsing ABORT; 461bb8ec7f4Sjsing if (0 != BN_cmp(y, z)) 462bb8ec7f4Sjsing ABORT; 4633c6bd008Smiod 4643c6bd008Smiod fprintf(stdout, "verify degree ..."); 465bb8ec7f4Sjsing if (EC_GROUP_get_degree(group) != 224) 466bb8ec7f4Sjsing ABORT; 4673c6bd008Smiod fprintf(stdout, " ok\n"); 4683c6bd008Smiod 4696f11255eStb group_order_tests(group, ctx); 4703c6bd008Smiod 4711e6310a2Stb if ((P_224 = EC_GROUP_dup(group)) == NULL) 472bb8ec7f4Sjsing ABORT; 4733c6bd008Smiod 4743c6bd008Smiod /* Curve P-256 (FIPS PUB 186-2, App. 6) */ 4753c6bd008Smiod 476bb8ec7f4Sjsing if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) 477bb8ec7f4Sjsing ABORT; 478bb8ec7f4Sjsing if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 479bb8ec7f4Sjsing ABORT; 480bb8ec7f4Sjsing if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) 481bb8ec7f4Sjsing ABORT; 482bb8ec7f4Sjsing if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) 483bb8ec7f4Sjsing ABORT; 4840318edf0Stb if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 485bb8ec7f4Sjsing ABORT; 4863c6bd008Smiod 487bb8ec7f4Sjsing if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) 488bb8ec7f4Sjsing ABORT; 489a20a87c2Stb if (!EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) 490bb8ec7f4Sjsing ABORT; 491a267e192Stb if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 492bb8ec7f4Sjsing ABORT; 4933c6bd008Smiod if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E" 4943c6bd008Smiod "84F3B9CAC2FC632551")) ABORT; 495bb8ec7f4Sjsing if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 496bb8ec7f4Sjsing ABORT; 4973c6bd008Smiod 498b425ed70Stb if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 499bb8ec7f4Sjsing ABORT; 5003c6bd008Smiod fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x"); 5013c6bd008Smiod BN_print_fp(stdout, x); 5023c6bd008Smiod fprintf(stdout, "\n y = 0x"); 5033c6bd008Smiod BN_print_fp(stdout, y); 5043c6bd008Smiod fprintf(stdout, "\n"); 5053c6bd008Smiod /* G_y value taken from the standard: */ 506bb8ec7f4Sjsing if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) 507bb8ec7f4Sjsing ABORT; 508bb8ec7f4Sjsing if (0 != BN_cmp(y, z)) 509bb8ec7f4Sjsing ABORT; 5103c6bd008Smiod 5113c6bd008Smiod fprintf(stdout, "verify degree ..."); 512bb8ec7f4Sjsing if (EC_GROUP_get_degree(group) != 256) 513bb8ec7f4Sjsing ABORT; 5143c6bd008Smiod fprintf(stdout, " ok\n"); 5153c6bd008Smiod 5166f11255eStb group_order_tests(group, ctx); 5173c6bd008Smiod 5188b9e009eStb if ((P_256 = EC_GROUP_dup(group)) == NULL) 519bb8ec7f4Sjsing ABORT; 5203c6bd008Smiod 5213c6bd008Smiod /* Curve P-384 (FIPS PUB 186-2, App. 6) */ 5223c6bd008Smiod 5233c6bd008Smiod if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 5243c6bd008Smiod "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT; 525bb8ec7f4Sjsing if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 526bb8ec7f4Sjsing ABORT; 5273c6bd008Smiod if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 5283c6bd008Smiod "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT; 5293c6bd008Smiod if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141" 5303c6bd008Smiod "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT; 5310318edf0Stb if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 532bb8ec7f4Sjsing ABORT; 5333c6bd008Smiod 5343c6bd008Smiod if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B" 5353c6bd008Smiod "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT; 536a20a87c2Stb if (!EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) 537bb8ec7f4Sjsing ABORT; 538a267e192Stb if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 539bb8ec7f4Sjsing ABORT; 5403c6bd008Smiod if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 5413c6bd008Smiod "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT; 542bb8ec7f4Sjsing if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 543bb8ec7f4Sjsing ABORT; 5443c6bd008Smiod 545b425ed70Stb if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 546bb8ec7f4Sjsing ABORT; 5473c6bd008Smiod fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x"); 5483c6bd008Smiod BN_print_fp(stdout, x); 5493c6bd008Smiod fprintf(stdout, "\n y = 0x"); 5503c6bd008Smiod BN_print_fp(stdout, y); 5513c6bd008Smiod fprintf(stdout, "\n"); 5523c6bd008Smiod /* G_y value taken from the standard: */ 5533c6bd008Smiod if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14" 5543c6bd008Smiod "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT; 555bb8ec7f4Sjsing if (0 != BN_cmp(y, z)) 556bb8ec7f4Sjsing ABORT; 5573c6bd008Smiod 5583c6bd008Smiod fprintf(stdout, "verify degree ..."); 559bb8ec7f4Sjsing if (EC_GROUP_get_degree(group) != 384) 560bb8ec7f4Sjsing ABORT; 5613c6bd008Smiod fprintf(stdout, " ok\n"); 5623c6bd008Smiod 5636f11255eStb group_order_tests(group, ctx); 5643c6bd008Smiod 5651e6310a2Stb if ((P_384 = EC_GROUP_dup(group)) == NULL) 566bb8ec7f4Sjsing ABORT; 5673c6bd008Smiod 5683c6bd008Smiod /* Curve P-521 (FIPS PUB 186-2, App. 6) */ 5693c6bd008Smiod 5703c6bd008Smiod if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 5713c6bd008Smiod "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 5723c6bd008Smiod "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT; 573bb8ec7f4Sjsing if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 574bb8ec7f4Sjsing ABORT; 5753c6bd008Smiod if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 5763c6bd008Smiod "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 5773c6bd008Smiod "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT; 5783c6bd008Smiod if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B" 5793c6bd008Smiod "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573" 5803c6bd008Smiod "DF883D2C34F1EF451FD46B503F00")) ABORT; 5810318edf0Stb if (!EC_GROUP_set_curve(group, p, a, b, ctx)) 582bb8ec7f4Sjsing ABORT; 5833c6bd008Smiod 5843c6bd008Smiod if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F" 5853c6bd008Smiod "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B" 5863c6bd008Smiod "3C1856A429BF97E7E31C2E5BD66")) ABORT; 587a20a87c2Stb if (!EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx)) 588bb8ec7f4Sjsing ABORT; 589a267e192Stb if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 590bb8ec7f4Sjsing ABORT; 5913c6bd008Smiod if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 5923c6bd008Smiod "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5" 5933c6bd008Smiod "C9B8899C47AEBB6FB71E91386409")) ABORT; 594bb8ec7f4Sjsing if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 595bb8ec7f4Sjsing ABORT; 5963c6bd008Smiod 597b425ed70Stb if (!EC_POINT_get_affine_coordinates(group, P, x, y, ctx)) 598bb8ec7f4Sjsing ABORT; 5993c6bd008Smiod fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x"); 6003c6bd008Smiod BN_print_fp(stdout, x); 6013c6bd008Smiod fprintf(stdout, "\n y = 0x"); 6023c6bd008Smiod BN_print_fp(stdout, y); 6033c6bd008Smiod fprintf(stdout, "\n"); 6043c6bd008Smiod /* G_y value taken from the standard: */ 6053c6bd008Smiod if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579" 6063c6bd008Smiod "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C" 6073c6bd008Smiod "7086A272C24088BE94769FD16650")) ABORT; 608bb8ec7f4Sjsing if (0 != BN_cmp(y, z)) 609bb8ec7f4Sjsing ABORT; 6103c6bd008Smiod 6113c6bd008Smiod fprintf(stdout, "verify degree ..."); 612bb8ec7f4Sjsing if (EC_GROUP_get_degree(group) != 521) 613bb8ec7f4Sjsing ABORT; 6143c6bd008Smiod fprintf(stdout, " ok\n"); 6153c6bd008Smiod 6166f11255eStb group_order_tests(group, ctx); 6173c6bd008Smiod 6181e6310a2Stb if ((P_521 = EC_GROUP_dup(group)) == NULL) 619bb8ec7f4Sjsing ABORT; 6203c6bd008Smiod 6213c6bd008Smiod /* more tests using the last curve */ 622089cda23Stb fprintf(stdout, "infinity tests ..."); 623089cda23Stb fflush(stdout); 624bb8ec7f4Sjsing if (!EC_POINT_copy(Q, P)) 625bb8ec7f4Sjsing ABORT; 626bb8ec7f4Sjsing if (EC_POINT_is_at_infinity(group, Q)) 627bb8ec7f4Sjsing ABORT; 628089cda23Stb /* P := 2P */ 629bb8ec7f4Sjsing if (!EC_POINT_dbl(group, P, P, ctx)) 630bb8ec7f4Sjsing ABORT; 631a267e192Stb if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 632bb8ec7f4Sjsing ABORT; 633089cda23Stb /* Q := -P */ 634089cda23Stb if (!EC_POINT_invert(group, Q, ctx)) 635089cda23Stb ABORT; 636089cda23Stb /* R := 2P - P = P */ 637bb8ec7f4Sjsing if (!EC_POINT_add(group, R, P, Q, ctx)) 638bb8ec7f4Sjsing ABORT; 639089cda23Stb /* R := R + Q = P - P = infty */ 640bb8ec7f4Sjsing if (!EC_POINT_add(group, R, R, Q, ctx)) 641bb8ec7f4Sjsing ABORT; 642089cda23Stb if (!EC_POINT_is_at_infinity(group, R)) 643bb8ec7f4Sjsing ABORT; 6443c6bd008Smiod fprintf(stdout, " ok\n\n"); 6453c6bd008Smiod 6463c6bd008Smiod if (ctx) 6473c6bd008Smiod BN_CTX_free(ctx); 648bb8ec7f4Sjsing BN_free(p); 649bb8ec7f4Sjsing BN_free(a); 650bb8ec7f4Sjsing BN_free(b); 6513c6bd008Smiod EC_GROUP_free(group); 6523c6bd008Smiod EC_POINT_free(P); 6533c6bd008Smiod EC_POINT_free(Q); 6543c6bd008Smiod EC_POINT_free(R); 655bb8ec7f4Sjsing BN_free(x); 656bb8ec7f4Sjsing BN_free(y); 657bb8ec7f4Sjsing BN_free(z); 6583c6bd008Smiod 659bb8ec7f4Sjsing EC_GROUP_free(P_160); 660bb8ec7f4Sjsing EC_GROUP_free(P_192); 661bb8ec7f4Sjsing EC_GROUP_free(P_224); 662bb8ec7f4Sjsing EC_GROUP_free(P_256); 663bb8ec7f4Sjsing EC_GROUP_free(P_384); 664bb8ec7f4Sjsing EC_GROUP_free(P_521); 6653c6bd008Smiod } 6663c6bd008Smiod 667bb8ec7f4Sjsing int 668bb8ec7f4Sjsing main(int argc, char *argv[]) 6693c6bd008Smiod { 6703c6bd008Smiod ERR_load_crypto_strings(); 6713c6bd008Smiod 6723c6bd008Smiod prime_field_tests(); 6733c6bd008Smiod 6743c6bd008Smiod CRYPTO_cleanup_all_ex_data(); 6753c6bd008Smiod ERR_free_strings(); 6763c6bd008Smiod ERR_remove_thread_state(NULL); 6773c6bd008Smiod 6783c6bd008Smiod return 0; 6793c6bd008Smiod } 680