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