1109998Smarkm/* crypto/ec/ectest.c */ 2160814Ssimon/* 3160814Ssimon * Originally written by Bodo Moeller for the OpenSSL project. 4160814Ssimon */ 5109998Smarkm/* ==================================================================== 6109998Smarkm * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 7109998Smarkm * 8109998Smarkm * Redistribution and use in source and binary forms, with or without 9109998Smarkm * modification, are permitted provided that the following conditions 10109998Smarkm * are met: 11109998Smarkm * 12109998Smarkm * 1. Redistributions of source code must retain the above copyright 13280304Sjkim * notice, this list of conditions and the following disclaimer. 14109998Smarkm * 15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 16109998Smarkm * notice, this list of conditions and the following disclaimer in 17109998Smarkm * the documentation and/or other materials provided with the 18109998Smarkm * distribution. 19109998Smarkm * 20109998Smarkm * 3. All advertising materials mentioning features or use of this 21109998Smarkm * software must display the following acknowledgment: 22109998Smarkm * "This product includes software developed by the OpenSSL Project 23109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24109998Smarkm * 25109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26109998Smarkm * endorse or promote products derived from this software without 27109998Smarkm * prior written permission. For written permission, please contact 28109998Smarkm * openssl-core@openssl.org. 29109998Smarkm * 30109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 31109998Smarkm * nor may "OpenSSL" appear in their names without prior written 32109998Smarkm * permission of the OpenSSL Project. 33109998Smarkm * 34109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 35109998Smarkm * acknowledgment: 36109998Smarkm * "This product includes software developed by the OpenSSL Project 37109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38109998Smarkm * 39109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 51109998Smarkm * ==================================================================== 52109998Smarkm * 53109998Smarkm * This product includes cryptographic software written by Eric Young 54109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 55109998Smarkm * Hudson (tjh@cryptsoft.com). 56109998Smarkm * 57109998Smarkm */ 58160814Ssimon/* ==================================================================== 59160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60160814Ssimon * 61280304Sjkim * Portions of the attached software ("Contribution") are developed by 62160814Ssimon * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 63160814Ssimon * 64160814Ssimon * The Contribution is licensed pursuant to the OpenSSL open source 65160814Ssimon * license provided above. 66160814Ssimon * 67280304Sjkim * The elliptic curve binary polynomial software is originally written by 68160814Ssimon * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. 69160814Ssimon * 70160814Ssimon */ 71109998Smarkm 72109998Smarkm#include <stdio.h> 73109998Smarkm#include <stdlib.h> 74109998Smarkm#ifdef FLAT_INC 75280304Sjkim# include "e_os.h" 76109998Smarkm#else 77280304Sjkim# include "../e_os.h" 78109998Smarkm#endif 79109998Smarkm#include <string.h> 80109998Smarkm#include <time.h> 81109998Smarkm 82109998Smarkm#ifdef OPENSSL_NO_EC 83280304Sjkimint main(int argc, char *argv[]) 84280304Sjkim{ 85280304Sjkim puts("Elliptic curves are disabled."); 86280304Sjkim return 0; 87280304Sjkim} 88109998Smarkm#else 89109998Smarkm 90280304Sjkim# include <openssl/ec.h> 91280304Sjkim# ifndef OPENSSL_NO_ENGINE 92280304Sjkim# include <openssl/engine.h> 93280304Sjkim# endif 94280304Sjkim# include <openssl/err.h> 95280304Sjkim# include <openssl/obj_mac.h> 96280304Sjkim# include <openssl/objects.h> 97280304Sjkim# include <openssl/rand.h> 98280304Sjkim# include <openssl/bn.h> 99280304Sjkim# include <openssl/opensslconf.h> 100109998Smarkm 101280304Sjkim# if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12) 102160814Ssimon/* suppress "too big too optimize" warning */ 103280304Sjkim# pragma warning(disable:4959) 104280304Sjkim# endif 105160814Ssimon 106280304Sjkim# define ABORT do { \ 107280304Sjkim fflush(stdout); \ 108280304Sjkim fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \ 109280304Sjkim ERR_print_errors_fp(stderr); \ 110280304Sjkim EXIT(1); \ 111109998Smarkm} while (0) 112109998Smarkm 113280304Sjkim# define TIMING_BASE_PT 0 114280304Sjkim# define TIMING_RAND_PT 1 115280304Sjkim# define TIMING_SIMUL 2 116160814Ssimon 117280304Sjkim# if 0 118160814Ssimonstatic void timings(EC_GROUP *group, int type, BN_CTX *ctx) 119280304Sjkim{ 120280304Sjkim clock_t clck; 121280304Sjkim int i, j; 122280304Sjkim BIGNUM *s; 123280304Sjkim BIGNUM *r[10], *r0[10]; 124280304Sjkim EC_POINT *P; 125109998Smarkm 126280304Sjkim s = BN_new(); 127280304Sjkim if (s == NULL) 128280304Sjkim ABORT; 129109998Smarkm 130280304Sjkim fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group)); 131280304Sjkim if (!EC_GROUP_get_order(group, s, ctx)) 132280304Sjkim ABORT; 133280304Sjkim fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s)); 134280304Sjkim fflush(stdout); 135109998Smarkm 136280304Sjkim P = EC_POINT_new(group); 137280304Sjkim if (P == NULL) 138280304Sjkim ABORT; 139280304Sjkim EC_POINT_copy(P, EC_GROUP_get0_generator(group)); 140160814Ssimon 141280304Sjkim for (i = 0; i < 10; i++) { 142280304Sjkim if ((r[i] = BN_new()) == NULL) 143280304Sjkim ABORT; 144280304Sjkim if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) 145280304Sjkim ABORT; 146280304Sjkim if (type != TIMING_BASE_PT) { 147280304Sjkim if ((r0[i] = BN_new()) == NULL) 148280304Sjkim ABORT; 149280304Sjkim if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) 150280304Sjkim ABORT; 151280304Sjkim } 152280304Sjkim } 153109998Smarkm 154280304Sjkim clck = clock(); 155280304Sjkim for (i = 0; i < 10; i++) { 156280304Sjkim for (j = 0; j < 10; j++) { 157280304Sjkim if (!EC_POINT_mul 158280304Sjkim (group, P, (type != TIMING_RAND_PT) ? r[i] : NULL, 159280304Sjkim (type != TIMING_BASE_PT) ? P : NULL, 160280304Sjkim (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) 161280304Sjkim ABORT; 162280304Sjkim } 163280304Sjkim } 164280304Sjkim clck = clock() - clck; 165160814Ssimon 166280304Sjkim fprintf(stdout, "\n"); 167109998Smarkm 168280304Sjkim# ifdef CLOCKS_PER_SEC 169280304Sjkim /* 170280304Sjkim * "To determine the time in seconds, the value returned by the clock 171280304Sjkim * function should be divided by the value of the macro CLOCKS_PER_SEC." 172280304Sjkim * -- ISO/IEC 9899 173280304Sjkim */ 174280304Sjkim# define UNIT "s" 175280304Sjkim# else 176280304Sjkim /* 177280304Sjkim * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on 178280304Sjkim * NeXTstep/OpenStep 179280304Sjkim */ 180280304Sjkim# define UNIT "units" 181280304Sjkim# define CLOCKS_PER_SEC 1 182280304Sjkim# endif 183109998Smarkm 184280304Sjkim if (type == TIMING_BASE_PT) { 185280304Sjkim fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j, 186280304Sjkim "base point multiplications", (double)clck / CLOCKS_PER_SEC); 187280304Sjkim } else if (type == TIMING_RAND_PT) { 188280304Sjkim fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j, 189280304Sjkim "random point multiplications", 190280304Sjkim (double)clck / CLOCKS_PER_SEC); 191280304Sjkim } else if (type == TIMING_SIMUL) { 192280304Sjkim fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j, 193280304Sjkim "s*P+t*Q operations", (double)clck / CLOCKS_PER_SEC); 194280304Sjkim } 195280304Sjkim fprintf(stdout, "average: %.4f " UNIT "\n", 196280304Sjkim (double)clck / (CLOCKS_PER_SEC * i * j)); 197109998Smarkm 198280304Sjkim EC_POINT_free(P); 199280304Sjkim BN_free(s); 200280304Sjkim for (i = 0; i < 10; i++) { 201280304Sjkim BN_free(r[i]); 202280304Sjkim if (type != TIMING_BASE_PT) 203280304Sjkim BN_free(r0[i]); 204280304Sjkim } 205280304Sjkim} 206280304Sjkim# endif 207280304Sjkim 208238405Sjkim/* test multiplication with group order, long and negative scalars */ 209238405Sjkimstatic void group_order_tests(EC_GROUP *group) 210280304Sjkim{ 211280304Sjkim BIGNUM *n1, *n2, *order; 212280304Sjkim EC_POINT *P = EC_POINT_new(group); 213280304Sjkim EC_POINT *Q = EC_POINT_new(group); 214280304Sjkim BN_CTX *ctx = BN_CTX_new(); 215280304Sjkim int i; 216238405Sjkim 217280304Sjkim n1 = BN_new(); 218280304Sjkim n2 = BN_new(); 219280304Sjkim order = BN_new(); 220280304Sjkim fprintf(stdout, "verify group order ..."); 221280304Sjkim fflush(stdout); 222280304Sjkim if (!EC_GROUP_get_order(group, order, ctx)) 223280304Sjkim ABORT; 224280304Sjkim if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) 225280304Sjkim ABORT; 226280304Sjkim if (!EC_POINT_is_at_infinity(group, Q)) 227280304Sjkim ABORT; 228280304Sjkim fprintf(stdout, "."); 229280304Sjkim fflush(stdout); 230280304Sjkim if (!EC_GROUP_precompute_mult(group, ctx)) 231280304Sjkim ABORT; 232280304Sjkim if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) 233280304Sjkim ABORT; 234280304Sjkim if (!EC_POINT_is_at_infinity(group, Q)) 235280304Sjkim ABORT; 236280304Sjkim fprintf(stdout, " ok\n"); 237280304Sjkim fprintf(stdout, "long/negative scalar tests "); 238280304Sjkim for (i = 1; i <= 2; i++) { 239280304Sjkim const BIGNUM *scalars[6]; 240280304Sjkim const EC_POINT *points[6]; 241269686Sjkim 242280304Sjkim fprintf(stdout, i == 1 ? 243280304Sjkim "allowing precomputation ... " : 244280304Sjkim "without precomputation ... "); 245280304Sjkim if (!BN_set_word(n1, i)) 246280304Sjkim ABORT; 247280304Sjkim /* 248280304Sjkim * If i == 1, P will be the predefined generator for which 249280304Sjkim * EC_GROUP_precompute_mult has set up precomputation. 250280304Sjkim */ 251280304Sjkim if (!EC_POINT_mul(group, P, n1, NULL, NULL, ctx)) 252280304Sjkim ABORT; 253269686Sjkim 254280304Sjkim if (!BN_one(n1)) 255280304Sjkim ABORT; 256280304Sjkim /* n1 = 1 - order */ 257280304Sjkim if (!BN_sub(n1, n1, order)) 258280304Sjkim ABORT; 259280304Sjkim if (!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) 260280304Sjkim ABORT; 261280304Sjkim if (0 != EC_POINT_cmp(group, Q, P, ctx)) 262280304Sjkim ABORT; 263269686Sjkim 264280304Sjkim /* n2 = 1 + order */ 265280304Sjkim if (!BN_add(n2, order, BN_value_one())) 266280304Sjkim ABORT; 267280304Sjkim if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 268280304Sjkim ABORT; 269280304Sjkim if (0 != EC_POINT_cmp(group, Q, P, ctx)) 270280304Sjkim ABORT; 271269686Sjkim 272280304Sjkim /* n2 = (1 - order) * (1 + order) = 1 - order^2 */ 273280304Sjkim if (!BN_mul(n2, n1, n2, ctx)) 274280304Sjkim ABORT; 275280304Sjkim if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 276280304Sjkim ABORT; 277280304Sjkim if (0 != EC_POINT_cmp(group, Q, P, ctx)) 278280304Sjkim ABORT; 279269686Sjkim 280280304Sjkim /* n2 = order^2 - 1 */ 281280304Sjkim BN_set_negative(n2, 0); 282280304Sjkim if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 283280304Sjkim ABORT; 284280304Sjkim /* Add P to verify the result. */ 285280304Sjkim if (!EC_POINT_add(group, Q, Q, P, ctx)) 286280304Sjkim ABORT; 287280304Sjkim if (!EC_POINT_is_at_infinity(group, Q)) 288280304Sjkim ABORT; 289269686Sjkim 290280304Sjkim /* Exercise EC_POINTs_mul, including corner cases. */ 291280304Sjkim if (EC_POINT_is_at_infinity(group, P)) 292280304Sjkim ABORT; 293280304Sjkim scalars[0] = n1; 294280304Sjkim points[0] = Q; /* => infinity */ 295280304Sjkim scalars[1] = n2; 296280304Sjkim points[1] = P; /* => -P */ 297280304Sjkim scalars[2] = n1; 298280304Sjkim points[2] = Q; /* => infinity */ 299280304Sjkim scalars[3] = n2; 300280304Sjkim points[3] = Q; /* => infinity */ 301280304Sjkim scalars[4] = n1; 302280304Sjkim points[4] = P; /* => P */ 303280304Sjkim scalars[5] = n2; 304280304Sjkim points[5] = Q; /* => infinity */ 305280304Sjkim if (!EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx)) 306280304Sjkim ABORT; 307280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 308280304Sjkim ABORT; 309280304Sjkim } 310280304Sjkim fprintf(stdout, "ok\n"); 311269686Sjkim 312280304Sjkim EC_POINT_free(P); 313280304Sjkim EC_POINT_free(Q); 314280304Sjkim BN_free(n1); 315280304Sjkim BN_free(n2); 316280304Sjkim BN_free(order); 317280304Sjkim BN_CTX_free(ctx); 318280304Sjkim} 319238405Sjkim 320238405Sjkimstatic void prime_field_tests(void) 321280304Sjkim{ 322280304Sjkim BN_CTX *ctx = NULL; 323280304Sjkim BIGNUM *p, *a, *b; 324280304Sjkim EC_GROUP *group; 325280304Sjkim EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = 326280304Sjkim NULL, *P_384 = NULL, *P_521 = NULL; 327280304Sjkim EC_POINT *P, *Q, *R; 328280304Sjkim BIGNUM *x, *y, *z; 329280304Sjkim unsigned char buf[100]; 330280304Sjkim size_t i, len; 331280304Sjkim int k; 332109998Smarkm 333280304Sjkim# if 1 /* optional */ 334280304Sjkim ctx = BN_CTX_new(); 335280304Sjkim if (!ctx) 336280304Sjkim ABORT; 337280304Sjkim# endif 338109998Smarkm 339280304Sjkim p = BN_new(); 340280304Sjkim a = BN_new(); 341280304Sjkim b = BN_new(); 342280304Sjkim if (!p || !a || !b) 343280304Sjkim ABORT; 344109998Smarkm 345280304Sjkim if (!BN_hex2bn(&p, "17")) 346280304Sjkim ABORT; 347280304Sjkim if (!BN_hex2bn(&a, "1")) 348280304Sjkim ABORT; 349280304Sjkim if (!BN_hex2bn(&b, "1")) 350280304Sjkim ABORT; 351109998Smarkm 352280304Sjkim group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use 353280304Sjkim * EC_GROUP_new_curve_GFp so 354280304Sjkim * that the library gets to 355280304Sjkim * choose the EC_METHOD */ 356280304Sjkim if (!group) 357280304Sjkim ABORT; 358109998Smarkm 359280304Sjkim if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 360280304Sjkim ABORT; 361109998Smarkm 362280304Sjkim { 363280304Sjkim EC_GROUP *tmp; 364280304Sjkim tmp = EC_GROUP_new(EC_GROUP_method_of(group)); 365280304Sjkim if (!tmp) 366280304Sjkim ABORT; 367280304Sjkim if (!EC_GROUP_copy(tmp, group)) 368280304Sjkim ABORT; 369280304Sjkim EC_GROUP_free(group); 370280304Sjkim group = tmp; 371280304Sjkim } 372109998Smarkm 373280304Sjkim if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) 374280304Sjkim ABORT; 375109998Smarkm 376280304Sjkim fprintf(stdout, 377280304Sjkim "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x"); 378280304Sjkim BN_print_fp(stdout, p); 379280304Sjkim fprintf(stdout, ")\n a = 0x"); 380280304Sjkim BN_print_fp(stdout, a); 381280304Sjkim fprintf(stdout, "\n b = 0x"); 382280304Sjkim BN_print_fp(stdout, b); 383280304Sjkim fprintf(stdout, "\n"); 384109998Smarkm 385280304Sjkim P = EC_POINT_new(group); 386280304Sjkim Q = EC_POINT_new(group); 387280304Sjkim R = EC_POINT_new(group); 388280304Sjkim if (!P || !Q || !R) 389280304Sjkim ABORT; 390109998Smarkm 391280304Sjkim if (!EC_POINT_set_to_infinity(group, P)) 392280304Sjkim ABORT; 393280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 394280304Sjkim ABORT; 395109998Smarkm 396280304Sjkim buf[0] = 0; 397280304Sjkim if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) 398280304Sjkim ABORT; 399109998Smarkm 400280304Sjkim if (!EC_POINT_add(group, P, P, Q, ctx)) 401280304Sjkim ABORT; 402280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 403280304Sjkim ABORT; 404109998Smarkm 405280304Sjkim x = BN_new(); 406280304Sjkim y = BN_new(); 407280304Sjkim z = BN_new(); 408280304Sjkim if (!x || !y || !z) 409280304Sjkim ABORT; 410109998Smarkm 411280304Sjkim if (!BN_hex2bn(&x, "D")) 412280304Sjkim ABORT; 413280304Sjkim if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) 414280304Sjkim ABORT; 415284285Sjkim if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) { 416280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) 417280304Sjkim ABORT; 418280304Sjkim fprintf(stderr, "Point is not on curve: x = 0x"); 419280304Sjkim BN_print_fp(stderr, x); 420280304Sjkim fprintf(stderr, ", y = 0x"); 421280304Sjkim BN_print_fp(stderr, y); 422280304Sjkim fprintf(stderr, "\n"); 423280304Sjkim ABORT; 424280304Sjkim } 425109998Smarkm 426280304Sjkim fprintf(stdout, "A cyclic subgroup:\n"); 427280304Sjkim k = 100; 428280304Sjkim do { 429280304Sjkim if (k-- == 0) 430280304Sjkim ABORT; 431109998Smarkm 432280304Sjkim if (EC_POINT_is_at_infinity(group, P)) 433280304Sjkim fprintf(stdout, " point at infinity\n"); 434280304Sjkim else { 435280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 436280304Sjkim ABORT; 437109998Smarkm 438280304Sjkim fprintf(stdout, " x = 0x"); 439280304Sjkim BN_print_fp(stdout, x); 440280304Sjkim fprintf(stdout, ", y = 0x"); 441280304Sjkim BN_print_fp(stdout, y); 442280304Sjkim fprintf(stdout, "\n"); 443280304Sjkim } 444109998Smarkm 445280304Sjkim if (!EC_POINT_copy(R, P)) 446280304Sjkim ABORT; 447280304Sjkim if (!EC_POINT_add(group, P, P, Q, ctx)) 448280304Sjkim ABORT; 449109998Smarkm 450280304Sjkim# if 0 /* optional */ 451280304Sjkim { 452280304Sjkim EC_POINT *points[3]; 453109998Smarkm 454280304Sjkim points[0] = R; 455280304Sjkim points[1] = Q; 456280304Sjkim points[2] = P; 457280304Sjkim if (!EC_POINTs_make_affine(group, 2, points, ctx)) 458280304Sjkim ABORT; 459280304Sjkim } 460280304Sjkim# endif 461160814Ssimon 462280304Sjkim } 463280304Sjkim while (!EC_POINT_is_at_infinity(group, P)); 464160814Ssimon 465280304Sjkim if (!EC_POINT_add(group, P, Q, R, ctx)) 466280304Sjkim ABORT; 467280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 468280304Sjkim ABORT; 469160814Ssimon 470280304Sjkim len = 471280304Sjkim EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, 472280304Sjkim sizeof buf, ctx); 473280304Sjkim if (len == 0) 474280304Sjkim ABORT; 475280304Sjkim if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 476280304Sjkim ABORT; 477280304Sjkim if (0 != EC_POINT_cmp(group, P, Q, ctx)) 478280304Sjkim ABORT; 479280304Sjkim fprintf(stdout, "Generator as octet string, compressed form:\n "); 480280304Sjkim for (i = 0; i < len; i++) 481280304Sjkim fprintf(stdout, "%02X", buf[i]); 482160814Ssimon 483280304Sjkim len = 484280304Sjkim EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, 485280304Sjkim sizeof buf, ctx); 486280304Sjkim if (len == 0) 487280304Sjkim ABORT; 488280304Sjkim if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 489280304Sjkim ABORT; 490280304Sjkim if (0 != EC_POINT_cmp(group, P, Q, ctx)) 491280304Sjkim ABORT; 492280304Sjkim fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); 493280304Sjkim for (i = 0; i < len; i++) 494280304Sjkim fprintf(stdout, "%02X", buf[i]); 495160814Ssimon 496280304Sjkim len = 497280304Sjkim EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, 498280304Sjkim ctx); 499280304Sjkim if (len == 0) 500280304Sjkim ABORT; 501280304Sjkim if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 502280304Sjkim ABORT; 503280304Sjkim if (0 != EC_POINT_cmp(group, P, Q, ctx)) 504280304Sjkim ABORT; 505280304Sjkim fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); 506280304Sjkim for (i = 0; i < len; i++) 507280304Sjkim fprintf(stdout, "%02X", buf[i]); 508160814Ssimon 509280304Sjkim if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) 510280304Sjkim ABORT; 511280304Sjkim fprintf(stdout, 512280304Sjkim "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n X = 0x"); 513280304Sjkim BN_print_fp(stdout, x); 514280304Sjkim fprintf(stdout, ", Y = 0x"); 515280304Sjkim BN_print_fp(stdout, y); 516280304Sjkim fprintf(stdout, ", Z = 0x"); 517280304Sjkim BN_print_fp(stdout, z); 518280304Sjkim fprintf(stdout, "\n"); 519109998Smarkm 520280304Sjkim if (!EC_POINT_invert(group, P, ctx)) 521280304Sjkim ABORT; 522280304Sjkim if (0 != EC_POINT_cmp(group, P, R, ctx)) 523280304Sjkim ABORT; 524109998Smarkm 525280304Sjkim /* 526280304Sjkim * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 527280304Sjkim * 2000) -- not a NIST curve, but commonly used 528280304Sjkim */ 529160814Ssimon 530280304Sjkim if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) 531280304Sjkim ABORT; 532280304Sjkim if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 533280304Sjkim ABORT; 534280304Sjkim if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) 535280304Sjkim ABORT; 536280304Sjkim if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) 537280304Sjkim ABORT; 538280304Sjkim if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 539280304Sjkim ABORT; 540109998Smarkm 541280304Sjkim if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) 542280304Sjkim ABORT; 543280304Sjkim if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) 544280304Sjkim ABORT; 545280304Sjkim if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) 546280304Sjkim ABORT; 547284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 548280304Sjkim ABORT; 549280304Sjkim if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) 550280304Sjkim ABORT; 551280304Sjkim if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 552280304Sjkim ABORT; 553109998Smarkm 554280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 555280304Sjkim ABORT; 556280304Sjkim fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n x = 0x"); 557280304Sjkim BN_print_fp(stdout, x); 558280304Sjkim fprintf(stdout, "\n y = 0x"); 559280304Sjkim BN_print_fp(stdout, y); 560280304Sjkim fprintf(stdout, "\n"); 561280304Sjkim /* G_y value taken from the standard: */ 562280304Sjkim if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) 563280304Sjkim ABORT; 564280304Sjkim if (0 != BN_cmp(y, z)) 565280304Sjkim ABORT; 566109998Smarkm 567280304Sjkim fprintf(stdout, "verify degree ..."); 568280304Sjkim if (EC_GROUP_get_degree(group) != 160) 569280304Sjkim ABORT; 570280304Sjkim fprintf(stdout, " ok\n"); 571109998Smarkm 572280304Sjkim group_order_tests(group); 573109998Smarkm 574280304Sjkim if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) 575280304Sjkim ABORT; 576280304Sjkim if (!EC_GROUP_copy(P_160, group)) 577280304Sjkim ABORT; 578109998Smarkm 579280304Sjkim /* Curve P-192 (FIPS PUB 186-2, App. 6) */ 580109998Smarkm 581280304Sjkim if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) 582280304Sjkim ABORT; 583280304Sjkim if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 584280304Sjkim ABORT; 585280304Sjkim if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) 586280304Sjkim ABORT; 587280304Sjkim if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) 588280304Sjkim ABORT; 589280304Sjkim if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 590280304Sjkim ABORT; 591109998Smarkm 592280304Sjkim if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) 593280304Sjkim ABORT; 594280304Sjkim if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) 595280304Sjkim ABORT; 596284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 597280304Sjkim ABORT; 598280304Sjkim if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) 599280304Sjkim ABORT; 600280304Sjkim if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 601280304Sjkim ABORT; 602109998Smarkm 603280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 604280304Sjkim ABORT; 605280304Sjkim fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x"); 606280304Sjkim BN_print_fp(stdout, x); 607280304Sjkim fprintf(stdout, "\n y = 0x"); 608280304Sjkim BN_print_fp(stdout, y); 609280304Sjkim fprintf(stdout, "\n"); 610280304Sjkim /* G_y value taken from the standard: */ 611280304Sjkim if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) 612280304Sjkim ABORT; 613280304Sjkim if (0 != BN_cmp(y, z)) 614280304Sjkim ABORT; 615109998Smarkm 616280304Sjkim fprintf(stdout, "verify degree ..."); 617280304Sjkim if (EC_GROUP_get_degree(group) != 192) 618280304Sjkim ABORT; 619280304Sjkim fprintf(stdout, " ok\n"); 620109998Smarkm 621280304Sjkim group_order_tests(group); 622109998Smarkm 623280304Sjkim if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) 624280304Sjkim ABORT; 625280304Sjkim if (!EC_GROUP_copy(P_192, group)) 626280304Sjkim ABORT; 627109998Smarkm 628280304Sjkim /* Curve P-224 (FIPS PUB 186-2, App. 6) */ 629109998Smarkm 630280304Sjkim if (!BN_hex2bn 631280304Sjkim (&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) 632280304Sjkim ABORT; 633280304Sjkim if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 634280304Sjkim ABORT; 635280304Sjkim if (!BN_hex2bn 636280304Sjkim (&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) 637280304Sjkim ABORT; 638280304Sjkim if (!BN_hex2bn 639280304Sjkim (&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) 640280304Sjkim ABORT; 641280304Sjkim if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 642280304Sjkim ABORT; 643109998Smarkm 644280304Sjkim if (!BN_hex2bn 645280304Sjkim (&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) 646280304Sjkim ABORT; 647280304Sjkim if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) 648280304Sjkim ABORT; 649284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 650280304Sjkim ABORT; 651280304Sjkim if (!BN_hex2bn 652280304Sjkim (&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) 653280304Sjkim ABORT; 654280304Sjkim if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 655280304Sjkim ABORT; 656109998Smarkm 657280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 658280304Sjkim ABORT; 659280304Sjkim fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x"); 660280304Sjkim BN_print_fp(stdout, x); 661280304Sjkim fprintf(stdout, "\n y = 0x"); 662280304Sjkim BN_print_fp(stdout, y); 663280304Sjkim fprintf(stdout, "\n"); 664280304Sjkim /* G_y value taken from the standard: */ 665280304Sjkim if (!BN_hex2bn 666280304Sjkim (&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) 667280304Sjkim ABORT; 668280304Sjkim if (0 != BN_cmp(y, z)) 669280304Sjkim ABORT; 670238405Sjkim 671280304Sjkim fprintf(stdout, "verify degree ..."); 672280304Sjkim if (EC_GROUP_get_degree(group) != 224) 673280304Sjkim ABORT; 674280304Sjkim fprintf(stdout, " ok\n"); 675109998Smarkm 676280304Sjkim group_order_tests(group); 677109998Smarkm 678280304Sjkim if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) 679280304Sjkim ABORT; 680280304Sjkim if (!EC_GROUP_copy(P_224, group)) 681280304Sjkim ABORT; 682109998Smarkm 683280304Sjkim /* Curve P-256 (FIPS PUB 186-2, App. 6) */ 684109998Smarkm 685280304Sjkim if (!BN_hex2bn 686280304Sjkim (&p, 687280304Sjkim "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) 688280304Sjkim ABORT; 689280304Sjkim if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 690280304Sjkim ABORT; 691280304Sjkim if (!BN_hex2bn 692280304Sjkim (&a, 693280304Sjkim "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) 694280304Sjkim ABORT; 695280304Sjkim if (!BN_hex2bn 696280304Sjkim (&b, 697280304Sjkim "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) 698280304Sjkim ABORT; 699280304Sjkim if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 700280304Sjkim ABORT; 701109998Smarkm 702280304Sjkim if (!BN_hex2bn 703280304Sjkim (&x, 704280304Sjkim "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) 705280304Sjkim ABORT; 706280304Sjkim if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) 707280304Sjkim ABORT; 708284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 709280304Sjkim ABORT; 710280304Sjkim if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E" 711280304Sjkim "84F3B9CAC2FC632551")) 712280304Sjkim ABORT; 713280304Sjkim if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 714280304Sjkim ABORT; 715238405Sjkim 716280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 717280304Sjkim ABORT; 718280304Sjkim fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x"); 719280304Sjkim BN_print_fp(stdout, x); 720280304Sjkim fprintf(stdout, "\n y = 0x"); 721280304Sjkim BN_print_fp(stdout, y); 722280304Sjkim fprintf(stdout, "\n"); 723280304Sjkim /* G_y value taken from the standard: */ 724280304Sjkim if (!BN_hex2bn 725280304Sjkim (&z, 726280304Sjkim "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) 727280304Sjkim ABORT; 728280304Sjkim if (0 != BN_cmp(y, z)) 729280304Sjkim ABORT; 730109998Smarkm 731280304Sjkim fprintf(stdout, "verify degree ..."); 732280304Sjkim if (EC_GROUP_get_degree(group) != 256) 733280304Sjkim ABORT; 734280304Sjkim fprintf(stdout, " ok\n"); 735109998Smarkm 736280304Sjkim group_order_tests(group); 737109998Smarkm 738280304Sjkim if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) 739280304Sjkim ABORT; 740280304Sjkim if (!EC_GROUP_copy(P_256, group)) 741280304Sjkim ABORT; 742109998Smarkm 743280304Sjkim /* Curve P-384 (FIPS PUB 186-2, App. 6) */ 744109998Smarkm 745280304Sjkim if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 746280304Sjkim "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) 747280304Sjkim ABORT; 748280304Sjkim if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 749280304Sjkim ABORT; 750280304Sjkim if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 751280304Sjkim "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) 752280304Sjkim ABORT; 753280304Sjkim if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141" 754280304Sjkim "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) 755280304Sjkim ABORT; 756280304Sjkim if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 757280304Sjkim ABORT; 758109998Smarkm 759280304Sjkim if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B" 760280304Sjkim "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) 761280304Sjkim ABORT; 762280304Sjkim if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) 763280304Sjkim ABORT; 764284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 765280304Sjkim ABORT; 766280304Sjkim if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 767280304Sjkim "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) 768280304Sjkim ABORT; 769280304Sjkim if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 770280304Sjkim ABORT; 771109998Smarkm 772280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 773280304Sjkim ABORT; 774280304Sjkim fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x"); 775280304Sjkim BN_print_fp(stdout, x); 776280304Sjkim fprintf(stdout, "\n y = 0x"); 777280304Sjkim BN_print_fp(stdout, y); 778280304Sjkim fprintf(stdout, "\n"); 779280304Sjkim /* G_y value taken from the standard: */ 780280304Sjkim if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14" 781280304Sjkim "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) 782280304Sjkim ABORT; 783280304Sjkim if (0 != BN_cmp(y, z)) 784280304Sjkim ABORT; 785109998Smarkm 786280304Sjkim fprintf(stdout, "verify degree ..."); 787280304Sjkim if (EC_GROUP_get_degree(group) != 384) 788280304Sjkim ABORT; 789280304Sjkim fprintf(stdout, " ok\n"); 790109998Smarkm 791280304Sjkim group_order_tests(group); 792109998Smarkm 793280304Sjkim if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) 794280304Sjkim ABORT; 795280304Sjkim if (!EC_GROUP_copy(P_384, group)) 796280304Sjkim ABORT; 797109998Smarkm 798280304Sjkim /* Curve P-521 (FIPS PUB 186-2, App. 6) */ 799109998Smarkm 800280304Sjkim if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 801280304Sjkim "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 802280304Sjkim "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) 803280304Sjkim ABORT; 804280304Sjkim if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 805280304Sjkim ABORT; 806280304Sjkim if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 807280304Sjkim "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 808280304Sjkim "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) 809280304Sjkim ABORT; 810280304Sjkim if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B" 811280304Sjkim "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573" 812280304Sjkim "DF883D2C34F1EF451FD46B503F00")) 813280304Sjkim ABORT; 814280304Sjkim if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) 815280304Sjkim ABORT; 816109998Smarkm 817280304Sjkim if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F" 818280304Sjkim "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B" 819280304Sjkim "3C1856A429BF97E7E31C2E5BD66")) 820280304Sjkim ABORT; 821280304Sjkim if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) 822280304Sjkim ABORT; 823284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 824280304Sjkim ABORT; 825280304Sjkim if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 826280304Sjkim "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5" 827280304Sjkim "C9B8899C47AEBB6FB71E91386409")) 828280304Sjkim ABORT; 829280304Sjkim if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) 830280304Sjkim ABORT; 831109998Smarkm 832280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 833280304Sjkim ABORT; 834280304Sjkim fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x"); 835280304Sjkim BN_print_fp(stdout, x); 836280304Sjkim fprintf(stdout, "\n y = 0x"); 837280304Sjkim BN_print_fp(stdout, y); 838280304Sjkim fprintf(stdout, "\n"); 839280304Sjkim /* G_y value taken from the standard: */ 840280304Sjkim if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579" 841280304Sjkim "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C" 842280304Sjkim "7086A272C24088BE94769FD16650")) 843280304Sjkim ABORT; 844280304Sjkim if (0 != BN_cmp(y, z)) 845280304Sjkim ABORT; 846194206Ssimon 847280304Sjkim fprintf(stdout, "verify degree ..."); 848280304Sjkim if (EC_GROUP_get_degree(group) != 521) 849280304Sjkim ABORT; 850280304Sjkim fprintf(stdout, " ok\n"); 851109998Smarkm 852280304Sjkim group_order_tests(group); 853194206Ssimon 854280304Sjkim if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) 855280304Sjkim ABORT; 856280304Sjkim if (!EC_GROUP_copy(P_521, group)) 857280304Sjkim ABORT; 858109998Smarkm 859280304Sjkim /* more tests using the last curve */ 860109998Smarkm 861280304Sjkim if (!EC_POINT_copy(Q, P)) 862280304Sjkim ABORT; 863280304Sjkim if (EC_POINT_is_at_infinity(group, Q)) 864280304Sjkim ABORT; 865280304Sjkim if (!EC_POINT_dbl(group, P, P, ctx)) 866280304Sjkim ABORT; 867284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 868280304Sjkim ABORT; 869280304Sjkim if (!EC_POINT_invert(group, Q, ctx)) 870280304Sjkim ABORT; /* P = -2Q */ 871109998Smarkm 872280304Sjkim if (!EC_POINT_add(group, R, P, Q, ctx)) 873280304Sjkim ABORT; 874280304Sjkim if (!EC_POINT_add(group, R, R, Q, ctx)) 875280304Sjkim ABORT; 876280304Sjkim if (!EC_POINT_is_at_infinity(group, R)) 877280304Sjkim ABORT; /* R = P + 2Q */ 878109998Smarkm 879280304Sjkim { 880280304Sjkim const EC_POINT *points[4]; 881280304Sjkim const BIGNUM *scalars[4]; 882280304Sjkim BIGNUM scalar3; 883109998Smarkm 884280304Sjkim if (EC_POINT_is_at_infinity(group, Q)) 885280304Sjkim ABORT; 886280304Sjkim points[0] = Q; 887280304Sjkim points[1] = Q; 888280304Sjkim points[2] = Q; 889280304Sjkim points[3] = Q; 890109998Smarkm 891280304Sjkim if (!EC_GROUP_get_order(group, z, ctx)) 892280304Sjkim ABORT; 893280304Sjkim if (!BN_add(y, z, BN_value_one())) 894280304Sjkim ABORT; 895280304Sjkim if (BN_is_odd(y)) 896280304Sjkim ABORT; 897280304Sjkim if (!BN_rshift1(y, y)) 898280304Sjkim ABORT; 899280304Sjkim scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */ 900280304Sjkim scalars[1] = y; 901160814Ssimon 902280304Sjkim fprintf(stdout, "combined multiplication ..."); 903280304Sjkim fflush(stdout); 904280304Sjkim 905280304Sjkim /* z is still the group order */ 906280304Sjkim if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 907280304Sjkim ABORT; 908280304Sjkim if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) 909280304Sjkim ABORT; 910280304Sjkim if (0 != EC_POINT_cmp(group, P, R, ctx)) 911280304Sjkim ABORT; 912280304Sjkim if (0 != EC_POINT_cmp(group, R, Q, ctx)) 913280304Sjkim ABORT; 914280304Sjkim 915280304Sjkim fprintf(stdout, "."); 916280304Sjkim fflush(stdout); 917280304Sjkim 918280304Sjkim if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) 919280304Sjkim ABORT; 920280304Sjkim if (!BN_add(z, z, y)) 921280304Sjkim ABORT; 922280304Sjkim BN_set_negative(z, 1); 923280304Sjkim scalars[0] = y; 924280304Sjkim scalars[1] = z; /* z = -(order + y) */ 925280304Sjkim 926280304Sjkim if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 927280304Sjkim ABORT; 928280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 929280304Sjkim ABORT; 930280304Sjkim 931280304Sjkim fprintf(stdout, "."); 932280304Sjkim fflush(stdout); 933280304Sjkim 934280304Sjkim if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) 935280304Sjkim ABORT; 936280304Sjkim if (!BN_add(z, x, y)) 937280304Sjkim ABORT; 938280304Sjkim BN_set_negative(z, 1); 939280304Sjkim scalars[0] = x; 940280304Sjkim scalars[1] = y; 941280304Sjkim scalars[2] = z; /* z = -(x+y) */ 942280304Sjkim 943280304Sjkim BN_init(&scalar3); 944280304Sjkim BN_zero(&scalar3); 945280304Sjkim scalars[3] = &scalar3; 946280304Sjkim 947280304Sjkim if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) 948280304Sjkim ABORT; 949280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 950280304Sjkim ABORT; 951280304Sjkim 952280304Sjkim fprintf(stdout, " ok\n\n"); 953280304Sjkim 954280304Sjkim BN_free(&scalar3); 955280304Sjkim } 956280304Sjkim 957280304Sjkim# if 0 958280304Sjkim timings(P_160, TIMING_BASE_PT, ctx); 959280304Sjkim timings(P_160, TIMING_RAND_PT, ctx); 960280304Sjkim timings(P_160, TIMING_SIMUL, ctx); 961280304Sjkim timings(P_192, TIMING_BASE_PT, ctx); 962280304Sjkim timings(P_192, TIMING_RAND_PT, ctx); 963280304Sjkim timings(P_192, TIMING_SIMUL, ctx); 964280304Sjkim timings(P_224, TIMING_BASE_PT, ctx); 965280304Sjkim timings(P_224, TIMING_RAND_PT, ctx); 966280304Sjkim timings(P_224, TIMING_SIMUL, ctx); 967280304Sjkim timings(P_256, TIMING_BASE_PT, ctx); 968280304Sjkim timings(P_256, TIMING_RAND_PT, ctx); 969280304Sjkim timings(P_256, TIMING_SIMUL, ctx); 970280304Sjkim timings(P_384, TIMING_BASE_PT, ctx); 971280304Sjkim timings(P_384, TIMING_RAND_PT, ctx); 972280304Sjkim timings(P_384, TIMING_SIMUL, ctx); 973280304Sjkim timings(P_521, TIMING_BASE_PT, ctx); 974280304Sjkim timings(P_521, TIMING_RAND_PT, ctx); 975280304Sjkim timings(P_521, TIMING_SIMUL, ctx); 976280304Sjkim# endif 977280304Sjkim 978280304Sjkim if (ctx) 979280304Sjkim BN_CTX_free(ctx); 980280304Sjkim BN_free(p); 981280304Sjkim BN_free(a); 982280304Sjkim BN_free(b); 983280304Sjkim EC_GROUP_free(group); 984280304Sjkim EC_POINT_free(P); 985280304Sjkim EC_POINT_free(Q); 986280304Sjkim EC_POINT_free(R); 987280304Sjkim BN_free(x); 988280304Sjkim BN_free(y); 989280304Sjkim BN_free(z); 990280304Sjkim 991280304Sjkim if (P_160) 992280304Sjkim EC_GROUP_free(P_160); 993280304Sjkim if (P_192) 994280304Sjkim EC_GROUP_free(P_192); 995280304Sjkim if (P_224) 996280304Sjkim EC_GROUP_free(P_224); 997280304Sjkim if (P_256) 998280304Sjkim EC_GROUP_free(P_256); 999280304Sjkim if (P_384) 1000280304Sjkim EC_GROUP_free(P_384); 1001280304Sjkim if (P_521) 1002280304Sjkim EC_GROUP_free(P_521); 1003280304Sjkim 1004280304Sjkim} 1005280304Sjkim 1006160814Ssimon/* Change test based on whether binary point compression is enabled or not. */ 1007280304Sjkim# ifdef OPENSSL_EC_BIN_PT_COMP 1008280304Sjkim# define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ 1009280304Sjkim if (!BN_hex2bn(&x, _x)) ABORT; \ 1010280304Sjkim if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \ 1011284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \ 1012280304Sjkim if (!BN_hex2bn(&z, _order)) ABORT; \ 1013280304Sjkim if (!BN_hex2bn(&cof, _cof)) ABORT; \ 1014280304Sjkim if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ 1015280304Sjkim if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \ 1016280304Sjkim fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \ 1017280304Sjkim BN_print_fp(stdout, x); \ 1018280304Sjkim fprintf(stdout, "\n y = 0x"); \ 1019280304Sjkim BN_print_fp(stdout, y); \ 1020280304Sjkim fprintf(stdout, "\n"); \ 1021280304Sjkim /* G_y value taken from the standard: */ \ 1022280304Sjkim if (!BN_hex2bn(&z, _y)) ABORT; \ 1023280304Sjkim if (0 != BN_cmp(y, z)) ABORT; 1024280304Sjkim# else 1025280304Sjkim# define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ 1026280304Sjkim if (!BN_hex2bn(&x, _x)) ABORT; \ 1027280304Sjkim if (!BN_hex2bn(&y, _y)) ABORT; \ 1028280304Sjkim if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \ 1029284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \ 1030280304Sjkim if (!BN_hex2bn(&z, _order)) ABORT; \ 1031280304Sjkim if (!BN_hex2bn(&cof, _cof)) ABORT; \ 1032280304Sjkim if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ 1033280304Sjkim fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \ 1034280304Sjkim BN_print_fp(stdout, x); \ 1035280304Sjkim fprintf(stdout, "\n y = 0x"); \ 1036280304Sjkim BN_print_fp(stdout, y); \ 1037280304Sjkim fprintf(stdout, "\n"); 1038280304Sjkim# endif 1039160814Ssimon 1040280304Sjkim# define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ 1041280304Sjkim if (!BN_hex2bn(&p, _p)) ABORT; \ 1042280304Sjkim if (!BN_hex2bn(&a, _a)) ABORT; \ 1043280304Sjkim if (!BN_hex2bn(&b, _b)) ABORT; \ 1044280304Sjkim if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \ 1045280304Sjkim CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ 1046280304Sjkim fprintf(stdout, "verify degree ..."); \ 1047280304Sjkim if (EC_GROUP_get_degree(group) != _degree) ABORT; \ 1048280304Sjkim fprintf(stdout, " ok\n"); \ 1049280304Sjkim group_order_tests(group); \ 1050280304Sjkim if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \ 1051280304Sjkim if (!EC_GROUP_copy(_variable, group)) ABORT; \ 1052160814Ssimon 1053280304Sjkim# ifndef OPENSSL_NO_EC2M 1054238405Sjkim 1055238405Sjkimstatic void char2_field_tests(void) 1056280304Sjkim{ 1057280304Sjkim BN_CTX *ctx = NULL; 1058280304Sjkim BIGNUM *p, *a, *b; 1059280304Sjkim EC_GROUP *group; 1060280304Sjkim EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = 1061280304Sjkim NULL, *C2_K571 = NULL; 1062280304Sjkim EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = 1063280304Sjkim NULL, *C2_B571 = NULL; 1064280304Sjkim EC_POINT *P, *Q, *R; 1065280304Sjkim BIGNUM *x, *y, *z, *cof; 1066280304Sjkim unsigned char buf[100]; 1067280304Sjkim size_t i, len; 1068280304Sjkim int k; 1069160814Ssimon 1070280304Sjkim# if 1 /* optional */ 1071280304Sjkim ctx = BN_CTX_new(); 1072280304Sjkim if (!ctx) 1073280304Sjkim ABORT; 1074280304Sjkim# endif 1075160814Ssimon 1076280304Sjkim p = BN_new(); 1077280304Sjkim a = BN_new(); 1078280304Sjkim b = BN_new(); 1079280304Sjkim if (!p || !a || !b) 1080280304Sjkim ABORT; 1081160814Ssimon 1082280304Sjkim if (!BN_hex2bn(&p, "13")) 1083280304Sjkim ABORT; 1084280304Sjkim if (!BN_hex2bn(&a, "3")) 1085280304Sjkim ABORT; 1086280304Sjkim if (!BN_hex2bn(&b, "1")) 1087280304Sjkim ABORT; 1088160814Ssimon 1089280304Sjkim group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use 1090280304Sjkim * EC_GROUP_new_curve_GF2m 1091280304Sjkim * so that the library gets 1092280304Sjkim * to choose the EC_METHOD */ 1093280304Sjkim if (!group) 1094280304Sjkim ABORT; 1095280304Sjkim if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) 1096280304Sjkim ABORT; 1097160814Ssimon 1098280304Sjkim { 1099280304Sjkim EC_GROUP *tmp; 1100280304Sjkim tmp = EC_GROUP_new(EC_GROUP_method_of(group)); 1101280304Sjkim if (!tmp) 1102280304Sjkim ABORT; 1103280304Sjkim if (!EC_GROUP_copy(tmp, group)) 1104280304Sjkim ABORT; 1105280304Sjkim EC_GROUP_free(group); 1106280304Sjkim group = tmp; 1107280304Sjkim } 1108160814Ssimon 1109280304Sjkim if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) 1110280304Sjkim ABORT; 1111160814Ssimon 1112280304Sjkim fprintf(stdout, 1113280304Sjkim "Curve defined by Weierstrass equation\n y^2 + x*y = x^3 + a*x^2 + b (mod 0x"); 1114280304Sjkim BN_print_fp(stdout, p); 1115280304Sjkim fprintf(stdout, ")\n a = 0x"); 1116280304Sjkim BN_print_fp(stdout, a); 1117280304Sjkim fprintf(stdout, "\n b = 0x"); 1118280304Sjkim BN_print_fp(stdout, b); 1119280304Sjkim fprintf(stdout, "\n(0x... means binary polynomial)\n"); 1120160814Ssimon 1121280304Sjkim P = EC_POINT_new(group); 1122280304Sjkim Q = EC_POINT_new(group); 1123280304Sjkim R = EC_POINT_new(group); 1124280304Sjkim if (!P || !Q || !R) 1125280304Sjkim ABORT; 1126160814Ssimon 1127280304Sjkim if (!EC_POINT_set_to_infinity(group, P)) 1128280304Sjkim ABORT; 1129280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 1130280304Sjkim ABORT; 1131280304Sjkim 1132280304Sjkim buf[0] = 0; 1133280304Sjkim if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) 1134280304Sjkim ABORT; 1135280304Sjkim 1136280304Sjkim if (!EC_POINT_add(group, P, P, Q, ctx)) 1137280304Sjkim ABORT; 1138280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 1139280304Sjkim ABORT; 1140280304Sjkim 1141280304Sjkim x = BN_new(); 1142280304Sjkim y = BN_new(); 1143280304Sjkim z = BN_new(); 1144280304Sjkim cof = BN_new(); 1145280304Sjkim if (!x || !y || !z || !cof) 1146280304Sjkim ABORT; 1147280304Sjkim 1148280304Sjkim if (!BN_hex2bn(&x, "6")) 1149280304Sjkim ABORT; 1150160814Ssimon/* Change test based on whether binary point compression is enabled or not. */ 1151280304Sjkim# ifdef OPENSSL_EC_BIN_PT_COMP 1152280304Sjkim if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) 1153280304Sjkim ABORT; 1154280304Sjkim# else 1155280304Sjkim if (!BN_hex2bn(&y, "8")) 1156280304Sjkim ABORT; 1157280304Sjkim if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) 1158280304Sjkim ABORT; 1159280304Sjkim# endif 1160284285Sjkim if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) { 1161160814Ssimon/* Change test based on whether binary point compression is enabled or not. */ 1162280304Sjkim# ifdef OPENSSL_EC_BIN_PT_COMP 1163280304Sjkim if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) 1164280304Sjkim ABORT; 1165280304Sjkim# endif 1166280304Sjkim fprintf(stderr, "Point is not on curve: x = 0x"); 1167280304Sjkim BN_print_fp(stderr, x); 1168280304Sjkim fprintf(stderr, ", y = 0x"); 1169280304Sjkim BN_print_fp(stderr, y); 1170280304Sjkim fprintf(stderr, "\n"); 1171280304Sjkim ABORT; 1172280304Sjkim } 1173160814Ssimon 1174280304Sjkim fprintf(stdout, "A cyclic subgroup:\n"); 1175280304Sjkim k = 100; 1176280304Sjkim do { 1177280304Sjkim if (k-- == 0) 1178280304Sjkim ABORT; 1179160814Ssimon 1180280304Sjkim if (EC_POINT_is_at_infinity(group, P)) 1181280304Sjkim fprintf(stdout, " point at infinity\n"); 1182280304Sjkim else { 1183280304Sjkim if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) 1184280304Sjkim ABORT; 1185160814Ssimon 1186280304Sjkim fprintf(stdout, " x = 0x"); 1187280304Sjkim BN_print_fp(stdout, x); 1188280304Sjkim fprintf(stdout, ", y = 0x"); 1189280304Sjkim BN_print_fp(stdout, y); 1190280304Sjkim fprintf(stdout, "\n"); 1191280304Sjkim } 1192160814Ssimon 1193280304Sjkim if (!EC_POINT_copy(R, P)) 1194280304Sjkim ABORT; 1195280304Sjkim if (!EC_POINT_add(group, P, P, Q, ctx)) 1196280304Sjkim ABORT; 1197280304Sjkim } 1198280304Sjkim while (!EC_POINT_is_at_infinity(group, P)); 1199160814Ssimon 1200280304Sjkim if (!EC_POINT_add(group, P, Q, R, ctx)) 1201280304Sjkim ABORT; 1202280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 1203280304Sjkim ABORT; 1204280304Sjkim 1205160814Ssimon/* Change test based on whether binary point compression is enabled or not. */ 1206280304Sjkim# ifdef OPENSSL_EC_BIN_PT_COMP 1207280304Sjkim len = 1208280304Sjkim EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, 1209280304Sjkim sizeof buf, ctx); 1210280304Sjkim if (len == 0) 1211280304Sjkim ABORT; 1212280304Sjkim if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 1213280304Sjkim ABORT; 1214280304Sjkim if (0 != EC_POINT_cmp(group, P, Q, ctx)) 1215280304Sjkim ABORT; 1216280304Sjkim fprintf(stdout, "Generator as octet string, compressed form:\n "); 1217280304Sjkim for (i = 0; i < len; i++) 1218280304Sjkim fprintf(stdout, "%02X", buf[i]); 1219280304Sjkim# endif 1220280304Sjkim 1221280304Sjkim len = 1222280304Sjkim EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, 1223280304Sjkim sizeof buf, ctx); 1224280304Sjkim if (len == 0) 1225280304Sjkim ABORT; 1226280304Sjkim if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 1227280304Sjkim ABORT; 1228280304Sjkim if (0 != EC_POINT_cmp(group, P, Q, ctx)) 1229280304Sjkim ABORT; 1230280304Sjkim fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); 1231280304Sjkim for (i = 0; i < len; i++) 1232280304Sjkim fprintf(stdout, "%02X", buf[i]); 1233280304Sjkim 1234160814Ssimon/* Change test based on whether binary point compression is enabled or not. */ 1235280304Sjkim# ifdef OPENSSL_EC_BIN_PT_COMP 1236280304Sjkim len = 1237280304Sjkim EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, 1238280304Sjkim ctx); 1239280304Sjkim if (len == 0) 1240280304Sjkim ABORT; 1241280304Sjkim if (!EC_POINT_oct2point(group, P, buf, len, ctx)) 1242280304Sjkim ABORT; 1243280304Sjkim if (0 != EC_POINT_cmp(group, P, Q, ctx)) 1244280304Sjkim ABORT; 1245280304Sjkim fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); 1246280304Sjkim for (i = 0; i < len; i++) 1247280304Sjkim fprintf(stdout, "%02X", buf[i]); 1248280304Sjkim# endif 1249160814Ssimon 1250280304Sjkim fprintf(stdout, "\n"); 1251160814Ssimon 1252280304Sjkim if (!EC_POINT_invert(group, P, ctx)) 1253280304Sjkim ABORT; 1254280304Sjkim if (0 != EC_POINT_cmp(group, P, R, ctx)) 1255280304Sjkim ABORT; 1256160814Ssimon 1257280304Sjkim /* Curve K-163 (FIPS PUB 186-2, App. 6) */ 1258280304Sjkim CHAR2_CURVE_TEST 1259280304Sjkim ("NIST curve K-163", 1260280304Sjkim "0800000000000000000000000000000000000000C9", 1261280304Sjkim "1", 1262280304Sjkim "1", 1263280304Sjkim "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", 1264280304Sjkim "0289070FB05D38FF58321F2E800536D538CCDAA3D9", 1265280304Sjkim 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163, C2_K163); 1266160814Ssimon 1267280304Sjkim /* Curve B-163 (FIPS PUB 186-2, App. 6) */ 1268280304Sjkim CHAR2_CURVE_TEST 1269280304Sjkim ("NIST curve B-163", 1270280304Sjkim "0800000000000000000000000000000000000000C9", 1271280304Sjkim "1", 1272280304Sjkim "020A601907B8C953CA1481EB10512F78744A3205FD", 1273280304Sjkim "03F0EBA16286A2D57EA0991168D4994637E8343E36", 1274280304Sjkim "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", 1275280304Sjkim 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163, C2_B163); 1276160814Ssimon 1277280304Sjkim /* Curve K-233 (FIPS PUB 186-2, App. 6) */ 1278280304Sjkim CHAR2_CURVE_TEST 1279280304Sjkim ("NIST curve K-233", 1280280304Sjkim "020000000000000000000000000000000000000004000000000000000001", 1281280304Sjkim "0", 1282280304Sjkim "1", 1283280304Sjkim "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", 1284280304Sjkim "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", 1285280304Sjkim 0, 1286280304Sjkim "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 1287280304Sjkim "4", 233, C2_K233); 1288160814Ssimon 1289280304Sjkim /* Curve B-233 (FIPS PUB 186-2, App. 6) */ 1290280304Sjkim CHAR2_CURVE_TEST 1291280304Sjkim ("NIST curve B-233", 1292280304Sjkim "020000000000000000000000000000000000000004000000000000000001", 1293280304Sjkim "000000000000000000000000000000000000000000000000000000000001", 1294280304Sjkim "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", 1295280304Sjkim "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", 1296280304Sjkim "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", 1297280304Sjkim 1, 1298280304Sjkim "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 1299280304Sjkim "2", 233, C2_B233); 1300160814Ssimon 1301280304Sjkim /* Curve K-283 (FIPS PUB 186-2, App. 6) */ 1302280304Sjkim CHAR2_CURVE_TEST 1303280304Sjkim ("NIST curve K-283", 1304280304Sjkim "0800000000000000000000000000000000000000000000000000000000000000000010A1", 1305280304Sjkim "0", 1306280304Sjkim "1", 1307280304Sjkim "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836", 1308280304Sjkim "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", 1309280304Sjkim 0, 1310280304Sjkim "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", 1311280304Sjkim "4", 283, C2_K283); 1312160814Ssimon 1313280304Sjkim /* Curve B-283 (FIPS PUB 186-2, App. 6) */ 1314280304Sjkim CHAR2_CURVE_TEST 1315280304Sjkim ("NIST curve B-283", 1316280304Sjkim "0800000000000000000000000000000000000000000000000000000000000000000010A1", 1317280304Sjkim "000000000000000000000000000000000000000000000000000000000000000000000001", 1318280304Sjkim "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", 1319280304Sjkim "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", 1320280304Sjkim "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", 1321280304Sjkim 1, 1322280304Sjkim "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 1323280304Sjkim "2", 283, C2_B283); 1324160814Ssimon 1325280304Sjkim /* Curve K-409 (FIPS PUB 186-2, App. 6) */ 1326280304Sjkim CHAR2_CURVE_TEST 1327280304Sjkim ("NIST curve K-409", 1328280304Sjkim "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", 1329280304Sjkim "0", 1330280304Sjkim "1", 1331280304Sjkim "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", 1332280304Sjkim "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", 1333280304Sjkim 1, 1334280304Sjkim "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 1335280304Sjkim "4", 409, C2_K409); 1336160814Ssimon 1337280304Sjkim /* Curve B-409 (FIPS PUB 186-2, App. 6) */ 1338280304Sjkim CHAR2_CURVE_TEST 1339280304Sjkim ("NIST curve B-409", 1340280304Sjkim "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", 1341280304Sjkim "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 1342280304Sjkim "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", 1343280304Sjkim "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7", 1344280304Sjkim "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", 1345280304Sjkim 1, 1346280304Sjkim "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", 1347280304Sjkim "2", 409, C2_B409); 1348160814Ssimon 1349280304Sjkim /* Curve K-571 (FIPS PUB 186-2, App. 6) */ 1350280304Sjkim CHAR2_CURVE_TEST 1351280304Sjkim ("NIST curve K-571", 1352280304Sjkim "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", 1353280304Sjkim "0", 1354280304Sjkim "1", 1355280304Sjkim "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972", 1356280304Sjkim "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", 1357280304Sjkim 0, 1358280304Sjkim "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", 1359280304Sjkim "4", 571, C2_K571); 1360160814Ssimon 1361280304Sjkim /* Curve B-571 (FIPS PUB 186-2, App. 6) */ 1362280304Sjkim CHAR2_CURVE_TEST 1363280304Sjkim ("NIST curve B-571", 1364280304Sjkim "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", 1365280304Sjkim "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 1366280304Sjkim "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", 1367280304Sjkim "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19", 1368280304Sjkim "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", 1369280304Sjkim 1, 1370280304Sjkim "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", 1371280304Sjkim "2", 571, C2_B571); 1372160814Ssimon 1373280304Sjkim /* more tests using the last curve */ 1374160814Ssimon 1375280304Sjkim if (!EC_POINT_copy(Q, P)) 1376280304Sjkim ABORT; 1377280304Sjkim if (EC_POINT_is_at_infinity(group, Q)) 1378280304Sjkim ABORT; 1379280304Sjkim if (!EC_POINT_dbl(group, P, P, ctx)) 1380280304Sjkim ABORT; 1381284285Sjkim if (EC_POINT_is_on_curve(group, P, ctx) <= 0) 1382280304Sjkim ABORT; 1383280304Sjkim if (!EC_POINT_invert(group, Q, ctx)) 1384280304Sjkim ABORT; /* P = -2Q */ 1385160814Ssimon 1386280304Sjkim if (!EC_POINT_add(group, R, P, Q, ctx)) 1387280304Sjkim ABORT; 1388280304Sjkim if (!EC_POINT_add(group, R, R, Q, ctx)) 1389280304Sjkim ABORT; 1390280304Sjkim if (!EC_POINT_is_at_infinity(group, R)) 1391280304Sjkim ABORT; /* R = P + 2Q */ 1392160814Ssimon 1393280304Sjkim { 1394280304Sjkim const EC_POINT *points[3]; 1395280304Sjkim const BIGNUM *scalars[3]; 1396160814Ssimon 1397280304Sjkim if (EC_POINT_is_at_infinity(group, Q)) 1398280304Sjkim ABORT; 1399280304Sjkim points[0] = Q; 1400280304Sjkim points[1] = Q; 1401280304Sjkim points[2] = Q; 1402160814Ssimon 1403280304Sjkim if (!BN_add(y, z, BN_value_one())) 1404280304Sjkim ABORT; 1405280304Sjkim if (BN_is_odd(y)) 1406280304Sjkim ABORT; 1407280304Sjkim if (!BN_rshift1(y, y)) 1408280304Sjkim ABORT; 1409280304Sjkim scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */ 1410280304Sjkim scalars[1] = y; 1411160814Ssimon 1412280304Sjkim fprintf(stdout, "combined multiplication ..."); 1413280304Sjkim fflush(stdout); 1414160814Ssimon 1415280304Sjkim /* z is still the group order */ 1416280304Sjkim if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 1417280304Sjkim ABORT; 1418280304Sjkim if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) 1419280304Sjkim ABORT; 1420280304Sjkim if (0 != EC_POINT_cmp(group, P, R, ctx)) 1421280304Sjkim ABORT; 1422280304Sjkim if (0 != EC_POINT_cmp(group, R, Q, ctx)) 1423280304Sjkim ABORT; 1424160814Ssimon 1425280304Sjkim fprintf(stdout, "."); 1426280304Sjkim fflush(stdout); 1427160814Ssimon 1428280304Sjkim if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) 1429280304Sjkim ABORT; 1430280304Sjkim if (!BN_add(z, z, y)) 1431280304Sjkim ABORT; 1432280304Sjkim BN_set_negative(z, 1); 1433280304Sjkim scalars[0] = y; 1434280304Sjkim scalars[1] = z; /* z = -(order + y) */ 1435160814Ssimon 1436280304Sjkim if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 1437280304Sjkim ABORT; 1438280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 1439280304Sjkim ABORT; 1440160814Ssimon 1441280304Sjkim fprintf(stdout, "."); 1442280304Sjkim fflush(stdout); 1443160814Ssimon 1444280304Sjkim if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) 1445280304Sjkim ABORT; 1446280304Sjkim if (!BN_add(z, x, y)) 1447280304Sjkim ABORT; 1448280304Sjkim BN_set_negative(z, 1); 1449280304Sjkim scalars[0] = x; 1450280304Sjkim scalars[1] = y; 1451280304Sjkim scalars[2] = z; /* z = -(x+y) */ 1452160814Ssimon 1453280304Sjkim if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) 1454280304Sjkim ABORT; 1455280304Sjkim if (!EC_POINT_is_at_infinity(group, P)) 1456280304Sjkim ABORT; 1457160814Ssimon 1458280304Sjkim fprintf(stdout, " ok\n\n"); 1459280304Sjkim } 1460160814Ssimon 1461280304Sjkim# if 0 1462280304Sjkim timings(C2_K163, TIMING_BASE_PT, ctx); 1463280304Sjkim timings(C2_K163, TIMING_RAND_PT, ctx); 1464280304Sjkim timings(C2_K163, TIMING_SIMUL, ctx); 1465280304Sjkim timings(C2_B163, TIMING_BASE_PT, ctx); 1466280304Sjkim timings(C2_B163, TIMING_RAND_PT, ctx); 1467280304Sjkim timings(C2_B163, TIMING_SIMUL, ctx); 1468280304Sjkim timings(C2_K233, TIMING_BASE_PT, ctx); 1469280304Sjkim timings(C2_K233, TIMING_RAND_PT, ctx); 1470280304Sjkim timings(C2_K233, TIMING_SIMUL, ctx); 1471280304Sjkim timings(C2_B233, TIMING_BASE_PT, ctx); 1472280304Sjkim timings(C2_B233, TIMING_RAND_PT, ctx); 1473280304Sjkim timings(C2_B233, TIMING_SIMUL, ctx); 1474280304Sjkim timings(C2_K283, TIMING_BASE_PT, ctx); 1475280304Sjkim timings(C2_K283, TIMING_RAND_PT, ctx); 1476280304Sjkim timings(C2_K283, TIMING_SIMUL, ctx); 1477280304Sjkim timings(C2_B283, TIMING_BASE_PT, ctx); 1478280304Sjkim timings(C2_B283, TIMING_RAND_PT, ctx); 1479280304Sjkim timings(C2_B283, TIMING_SIMUL, ctx); 1480280304Sjkim timings(C2_K409, TIMING_BASE_PT, ctx); 1481280304Sjkim timings(C2_K409, TIMING_RAND_PT, ctx); 1482280304Sjkim timings(C2_K409, TIMING_SIMUL, ctx); 1483280304Sjkim timings(C2_B409, TIMING_BASE_PT, ctx); 1484280304Sjkim timings(C2_B409, TIMING_RAND_PT, ctx); 1485280304Sjkim timings(C2_B409, TIMING_SIMUL, ctx); 1486280304Sjkim timings(C2_K571, TIMING_BASE_PT, ctx); 1487280304Sjkim timings(C2_K571, TIMING_RAND_PT, ctx); 1488280304Sjkim timings(C2_K571, TIMING_SIMUL, ctx); 1489280304Sjkim timings(C2_B571, TIMING_BASE_PT, ctx); 1490280304Sjkim timings(C2_B571, TIMING_RAND_PT, ctx); 1491280304Sjkim timings(C2_B571, TIMING_SIMUL, ctx); 1492280304Sjkim# endif 1493160814Ssimon 1494280304Sjkim if (ctx) 1495280304Sjkim BN_CTX_free(ctx); 1496280304Sjkim BN_free(p); 1497280304Sjkim BN_free(a); 1498280304Sjkim BN_free(b); 1499280304Sjkim EC_GROUP_free(group); 1500280304Sjkim EC_POINT_free(P); 1501280304Sjkim EC_POINT_free(Q); 1502280304Sjkim EC_POINT_free(R); 1503280304Sjkim BN_free(x); 1504280304Sjkim BN_free(y); 1505280304Sjkim BN_free(z); 1506280304Sjkim BN_free(cof); 1507160814Ssimon 1508280304Sjkim if (C2_K163) 1509280304Sjkim EC_GROUP_free(C2_K163); 1510280304Sjkim if (C2_B163) 1511280304Sjkim EC_GROUP_free(C2_B163); 1512280304Sjkim if (C2_K233) 1513280304Sjkim EC_GROUP_free(C2_K233); 1514280304Sjkim if (C2_B233) 1515280304Sjkim EC_GROUP_free(C2_B233); 1516280304Sjkim if (C2_K283) 1517280304Sjkim EC_GROUP_free(C2_K283); 1518280304Sjkim if (C2_B283) 1519280304Sjkim EC_GROUP_free(C2_B283); 1520280304Sjkim if (C2_K409) 1521280304Sjkim EC_GROUP_free(C2_K409); 1522280304Sjkim if (C2_B409) 1523280304Sjkim EC_GROUP_free(C2_B409); 1524280304Sjkim if (C2_K571) 1525280304Sjkim EC_GROUP_free(C2_K571); 1526280304Sjkim if (C2_B571) 1527280304Sjkim EC_GROUP_free(C2_B571); 1528160814Ssimon 1529280304Sjkim} 1530280304Sjkim# endif 1531160814Ssimon 1532238405Sjkimstatic void internal_curve_test(void) 1533280304Sjkim{ 1534280304Sjkim EC_builtin_curve *curves = NULL; 1535280304Sjkim size_t crv_len = 0, n = 0; 1536280304Sjkim int ok = 1; 1537160814Ssimon 1538280304Sjkim crv_len = EC_get_builtin_curves(NULL, 0); 1539160814Ssimon 1540280304Sjkim curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); 1541160814Ssimon 1542280304Sjkim if (curves == NULL) 1543280304Sjkim return; 1544160814Ssimon 1545280304Sjkim if (!EC_get_builtin_curves(curves, crv_len)) { 1546280304Sjkim OPENSSL_free(curves); 1547280304Sjkim return; 1548280304Sjkim } 1549160814Ssimon 1550280304Sjkim fprintf(stdout, "testing internal curves: "); 1551160814Ssimon 1552280304Sjkim for (n = 0; n < crv_len; n++) { 1553280304Sjkim EC_GROUP *group = NULL; 1554280304Sjkim int nid = curves[n].nid; 1555280304Sjkim if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) { 1556280304Sjkim ok = 0; 1557280304Sjkim fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with" 1558280304Sjkim " curve %s\n", OBJ_nid2sn(nid)); 1559280304Sjkim /* try next curve */ 1560280304Sjkim continue; 1561280304Sjkim } 1562280304Sjkim if (!EC_GROUP_check(group, NULL)) { 1563280304Sjkim ok = 0; 1564280304Sjkim fprintf(stdout, "\nEC_GROUP_check() failed with" 1565280304Sjkim " curve %s\n", OBJ_nid2sn(nid)); 1566280304Sjkim EC_GROUP_free(group); 1567280304Sjkim /* try the next curve */ 1568280304Sjkim continue; 1569280304Sjkim } 1570280304Sjkim fprintf(stdout, "."); 1571280304Sjkim fflush(stdout); 1572280304Sjkim EC_GROUP_free(group); 1573280304Sjkim } 1574280304Sjkim if (ok) 1575280304Sjkim fprintf(stdout, " ok\n\n"); 1576280304Sjkim else { 1577280304Sjkim fprintf(stdout, " failed\n\n"); 1578280304Sjkim ABORT; 1579280304Sjkim } 1580280304Sjkim OPENSSL_free(curves); 1581280304Sjkim return; 1582280304Sjkim} 1583238405Sjkim 1584280304Sjkim# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 1585280304Sjkim/* 1586280304Sjkim * nistp_test_params contains magic numbers for testing our optimized 1587280304Sjkim * implementations of several NIST curves with characteristic > 3. 1588280304Sjkim */ 1589280304Sjkimstruct nistp_test_params { 1590280304Sjkim const EC_METHOD *(*meth) (); 1591280304Sjkim int degree; 1592280304Sjkim /* 1593280304Sjkim * Qx, Qy and D are taken from 1594295016Sjkim * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf 1595280304Sjkim * Otherwise, values are standard curve parameters from FIPS 180-3 1596280304Sjkim */ 1597280304Sjkim const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d; 1598280304Sjkim}; 1599238405Sjkim 1600280304Sjkimstatic const struct nistp_test_params nistp_tests_params[] = { 1601280304Sjkim { 1602280304Sjkim /* P-224 */ 1603280304Sjkim EC_GFp_nistp224_method, 1604280304Sjkim 224, 1605280304Sjkim /* p */ 1606280304Sjkim "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", 1607280304Sjkim /* a */ 1608280304Sjkim "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", 1609280304Sjkim /* b */ 1610280304Sjkim "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", 1611280304Sjkim /* Qx */ 1612280304Sjkim "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", 1613280304Sjkim /* Qy */ 1614280304Sjkim "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", 1615280304Sjkim /* Gx */ 1616280304Sjkim "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", 1617280304Sjkim /* Gy */ 1618280304Sjkim "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", 1619280304Sjkim /* order */ 1620280304Sjkim "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1621280304Sjkim /* d */ 1622280304Sjkim "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", 1623280304Sjkim }, 1624280304Sjkim { 1625280304Sjkim /* P-256 */ 1626280304Sjkim EC_GFp_nistp256_method, 1627280304Sjkim 256, 1628280304Sjkim /* p */ 1629280304Sjkim "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 1630280304Sjkim /* a */ 1631280304Sjkim "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 1632280304Sjkim /* b */ 1633280304Sjkim "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 1634280304Sjkim /* Qx */ 1635280304Sjkim "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", 1636280304Sjkim /* Qy */ 1637280304Sjkim "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", 1638280304Sjkim /* Gx */ 1639280304Sjkim "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 1640280304Sjkim /* Gy */ 1641280304Sjkim "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 1642280304Sjkim /* order */ 1643280304Sjkim "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 1644280304Sjkim /* d */ 1645280304Sjkim "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", 1646280304Sjkim }, 1647280304Sjkim { 1648280304Sjkim /* P-521 */ 1649280304Sjkim EC_GFp_nistp521_method, 1650280304Sjkim 521, 1651280304Sjkim /* p */ 1652280304Sjkim "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 1653280304Sjkim /* a */ 1654280304Sjkim "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", 1655280304Sjkim /* b */ 1656280304Sjkim "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 1657280304Sjkim /* Qx */ 1658280304Sjkim "0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", 1659280304Sjkim /* Qy */ 1660280304Sjkim "0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", 1661280304Sjkim /* Gx */ 1662280304Sjkim "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 1663280304Sjkim /* Gy */ 1664280304Sjkim "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 1665280304Sjkim /* order */ 1666280304Sjkim "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", 1667280304Sjkim /* d */ 1668280304Sjkim "0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", 1669280304Sjkim }, 1670280304Sjkim}; 1671280304Sjkim 1672276864Sjkimstatic void nistp_single_test(const struct nistp_test_params *test) 1673280304Sjkim{ 1674280304Sjkim BN_CTX *ctx; 1675280304Sjkim BIGNUM *p, *a, *b, *x, *y, *n, *m, *order; 1676280304Sjkim EC_GROUP *NISTP; 1677280304Sjkim EC_POINT *G, *P, *Q, *Q_CHECK; 1678238405Sjkim 1679280304Sjkim fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", 1680280304Sjkim test->degree); 1681280304Sjkim ctx = BN_CTX_new(); 1682280304Sjkim p = BN_new(); 1683280304Sjkim a = BN_new(); 1684280304Sjkim b = BN_new(); 1685280304Sjkim x = BN_new(); 1686280304Sjkim y = BN_new(); 1687280304Sjkim m = BN_new(); 1688280304Sjkim n = BN_new(); 1689280304Sjkim order = BN_new(); 1690238405Sjkim 1691280304Sjkim NISTP = EC_GROUP_new(test->meth()); 1692280304Sjkim if (!NISTP) 1693280304Sjkim ABORT; 1694280304Sjkim if (!BN_hex2bn(&p, test->p)) 1695280304Sjkim ABORT; 1696280304Sjkim if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) 1697280304Sjkim ABORT; 1698280304Sjkim if (!BN_hex2bn(&a, test->a)) 1699280304Sjkim ABORT; 1700280304Sjkim if (!BN_hex2bn(&b, test->b)) 1701280304Sjkim ABORT; 1702280304Sjkim if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) 1703280304Sjkim ABORT; 1704280304Sjkim G = EC_POINT_new(NISTP); 1705280304Sjkim P = EC_POINT_new(NISTP); 1706280304Sjkim Q = EC_POINT_new(NISTP); 1707280304Sjkim Q_CHECK = EC_POINT_new(NISTP); 1708280304Sjkim if (!BN_hex2bn(&x, test->Qx)) 1709280304Sjkim ABORT; 1710280304Sjkim if (!BN_hex2bn(&y, test->Qy)) 1711280304Sjkim ABORT; 1712280304Sjkim if (!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) 1713280304Sjkim ABORT; 1714280304Sjkim if (!BN_hex2bn(&x, test->Gx)) 1715280304Sjkim ABORT; 1716280304Sjkim if (!BN_hex2bn(&y, test->Gy)) 1717280304Sjkim ABORT; 1718280304Sjkim if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) 1719280304Sjkim ABORT; 1720280304Sjkim if (!BN_hex2bn(&order, test->order)) 1721280304Sjkim ABORT; 1722280304Sjkim if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) 1723280304Sjkim ABORT; 1724238405Sjkim 1725280304Sjkim fprintf(stdout, "verify degree ... "); 1726280304Sjkim if (EC_GROUP_get_degree(NISTP) != test->degree) 1727280304Sjkim ABORT; 1728280304Sjkim fprintf(stdout, "ok\n"); 1729238405Sjkim 1730280304Sjkim fprintf(stdout, "NIST test vectors ... "); 1731280304Sjkim if (!BN_hex2bn(&n, test->d)) 1732280304Sjkim ABORT; 1733280304Sjkim /* fixed point multiplication */ 1734280304Sjkim EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); 1735280304Sjkim if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1736280304Sjkim ABORT; 1737280304Sjkim /* random point multiplication */ 1738280304Sjkim EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); 1739280304Sjkim if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1740280304Sjkim ABORT; 1741238405Sjkim 1742280304Sjkim /* set generator to P = 2*G, where G is the standard generator */ 1743280304Sjkim if (!EC_POINT_dbl(NISTP, P, G, ctx)) 1744280304Sjkim ABORT; 1745280304Sjkim if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) 1746280304Sjkim ABORT; 1747280304Sjkim /* set the scalar to m=n/2, where n is the NIST test scalar */ 1748280304Sjkim if (!BN_rshift(m, n, 1)) 1749280304Sjkim ABORT; 1750238405Sjkim 1751280304Sjkim /* test the non-standard generator */ 1752280304Sjkim /* fixed point multiplication */ 1753280304Sjkim EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); 1754280304Sjkim if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1755280304Sjkim ABORT; 1756280304Sjkim /* random point multiplication */ 1757280304Sjkim EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); 1758280304Sjkim if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1759280304Sjkim ABORT; 1760238405Sjkim 1761280304Sjkim /* now repeat all tests with precomputation */ 1762280304Sjkim if (!EC_GROUP_precompute_mult(NISTP, ctx)) 1763280304Sjkim ABORT; 1764238405Sjkim 1765280304Sjkim /* fixed point multiplication */ 1766280304Sjkim EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); 1767280304Sjkim if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1768280304Sjkim ABORT; 1769280304Sjkim /* random point multiplication */ 1770280304Sjkim EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); 1771280304Sjkim if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1772280304Sjkim ABORT; 1773238405Sjkim 1774280304Sjkim /* reset generator */ 1775280304Sjkim if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) 1776280304Sjkim ABORT; 1777280304Sjkim /* fixed point multiplication */ 1778280304Sjkim EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); 1779280304Sjkim if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1780280304Sjkim ABORT; 1781280304Sjkim /* random point multiplication */ 1782280304Sjkim EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); 1783280304Sjkim if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1784280304Sjkim ABORT; 1785238405Sjkim 1786280304Sjkim fprintf(stdout, "ok\n"); 1787280304Sjkim group_order_tests(NISTP); 1788280304Sjkim# if 0 1789280304Sjkim timings(NISTP, TIMING_BASE_PT, ctx); 1790280304Sjkim timings(NISTP, TIMING_RAND_PT, ctx); 1791280304Sjkim# endif 1792280304Sjkim EC_GROUP_free(NISTP); 1793280304Sjkim EC_POINT_free(G); 1794280304Sjkim EC_POINT_free(P); 1795280304Sjkim EC_POINT_free(Q); 1796280304Sjkim EC_POINT_free(Q_CHECK); 1797280304Sjkim BN_free(n); 1798280304Sjkim BN_free(m); 1799280304Sjkim BN_free(p); 1800280304Sjkim BN_free(a); 1801280304Sjkim BN_free(b); 1802280304Sjkim BN_free(x); 1803280304Sjkim BN_free(y); 1804280304Sjkim BN_free(order); 1805280304Sjkim BN_CTX_free(ctx); 1806280304Sjkim} 1807238405Sjkim 1808276864Sjkimstatic void nistp_tests() 1809280304Sjkim{ 1810280304Sjkim unsigned i; 1811238405Sjkim 1812280304Sjkim for (i = 0; 1813280304Sjkim i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); 1814280304Sjkim i++) { 1815280304Sjkim nistp_single_test(&nistp_tests_params[i]); 1816280304Sjkim } 1817280304Sjkim} 1818280304Sjkim# endif 1819238405Sjkim 1820280304Sjkimstatic const char rnd_seed[] = 1821280304Sjkim "string to make the random number generator think it has entropy"; 1822160814Ssimon 1823160814Ssimonint main(int argc, char *argv[]) 1824280304Sjkim{ 1825160814Ssimon 1826280304Sjkim /* enable memory leak checking unless explicitly disabled */ 1827280304Sjkim if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) 1828280304Sjkim && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { 1829280304Sjkim CRYPTO_malloc_debug_init(); 1830280304Sjkim CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 1831280304Sjkim } else { 1832280304Sjkim /* OPENSSL_DEBUG_MEMORY=off */ 1833280304Sjkim CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); 1834280304Sjkim } 1835280304Sjkim CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 1836280304Sjkim ERR_load_crypto_strings(); 1837160814Ssimon 1838280304Sjkim RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */ 1839160814Ssimon 1840280304Sjkim prime_field_tests(); 1841280304Sjkim puts(""); 1842280304Sjkim# ifndef OPENSSL_NO_EC2M 1843280304Sjkim char2_field_tests(); 1844280304Sjkim# endif 1845280304Sjkim# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 1846280304Sjkim nistp_tests(); 1847280304Sjkim# endif 1848280304Sjkim /* test the internal curves */ 1849280304Sjkim internal_curve_test(); 1850280304Sjkim 1851280304Sjkim# ifndef OPENSSL_NO_ENGINE 1852280304Sjkim ENGINE_cleanup(); 1853280304Sjkim# endif 1854280304Sjkim CRYPTO_cleanup_all_ex_data(); 1855280304Sjkim ERR_free_strings(); 1856280304Sjkim ERR_remove_thread_state(NULL); 1857280304Sjkim CRYPTO_mem_leaks_fp(stderr); 1858280304Sjkim 1859280304Sjkim return 0; 1860280304Sjkim} 1861111147Snectar#endif 1862