(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/test/ectest.c

    1: /* crypto/ec/ectest.c */
    2: /*
    3:  * Originally written by Bodo Moeller for the OpenSSL project.
    4:  */
    5: /* ====================================================================
    6:  * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
    7:  *
    8:  * Redistribution and use in source and binary forms, with or without
    9:  * modification, are permitted provided that the following conditions
   10:  * are met:
   11:  *
   12:  * 1. Redistributions of source code must retain the above copyright
   13:  *    notice, this list of conditions and the following disclaimer. 
   14:  *
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in
   17:  *    the documentation and/or other materials provided with the
   18:  *    distribution.
   19:  *
   20:  * 3. All advertising materials mentioning features or use of this
   21:  *    software must display the following acknowledgment:
   22:  *    "This product includes software developed by the OpenSSL Project
   23:  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
   24:  *
   25:  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
   26:  *    endorse or promote products derived from this software without
   27:  *    prior written permission. For written permission, please contact
   28:  *    openssl-core@openssl.org.
   29:  *
   30:  * 5. Products derived from this software may not be called "OpenSSL"
   31:  *    nor may "OpenSSL" appear in their names without prior written
   32:  *    permission of the OpenSSL Project.
   33:  *
   34:  * 6. Redistributions of any form whatsoever must retain the following
   35:  *    acknowledgment:
   36:  *    "This product includes software developed by the OpenSSL Project
   37:  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
   38:  *
   39:  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
   40:  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   41:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   42:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
   43:  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   44:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   45:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   46:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   47:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   48:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   49:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   50:  * OF THE POSSIBILITY OF SUCH DAMAGE.
   51:  * ====================================================================
   52:  *
   53:  * This product includes cryptographic software written by Eric Young
   54:  * (eay@cryptsoft.com).  This product includes software written by Tim
   55:  * Hudson (tjh@cryptsoft.com).
   56:  *
   57:  */
   58: /* ====================================================================
   59:  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
   60:  *
   61:  * Portions of the attached software ("Contribution") are developed by 
   62:  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
   63:  *
   64:  * The Contribution is licensed pursuant to the OpenSSL open source
   65:  * license provided above.
   66:  *
   67:  * The elliptic curve binary polynomial software is originally written by 
   68:  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
   69:  *
   70:  */
   71: 
   72: #include <stdio.h>
   73: #include <stdlib.h>
   74: #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 0
  436:         if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
  437: #endif
  438:         if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
  439:         if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
  440:         fprintf(stdout, " ok\n");
  441: 
  442:         if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
  443:         if (!EC_GROUP_copy(P_192, group)) ABORT;
  444: 
  445: 
  446:         /* Curve P-224 (FIPS PUB 186-2, App. 6) */
  447:         
  448:         if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
  449:         if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
  450:         if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
  451:         if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
  452:         if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
  453: 
  454:         if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
  455:         if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
  456:         if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
  457:         if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
  458:         if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
  459: 
  460:         if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
  461:         fprintf(stdout, "\nNIST curve P-224 -- Generator:\n     x = 0x");
  462:         BN_print_fp(stdout, x);
  463:         fprintf(stdout, "\n     y = 0x");
  464:         BN_print_fp(stdout, y);
  465:         fprintf(stdout, "\n");
  466:         /* G_y value taken from the standard: */
  467:         if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
  468:         if (0 != BN_cmp(y, z)) ABORT;
  469:         
  470:         fprintf(stdout, "verify degree ...");
  471:         if (EC_GROUP_get_degree(group) != 224) ABORT;
  472:         fprintf(stdout, " ok\n");
  473:         
  474:         fprintf(stdout, "verify group order ...");
  475:         fflush(stdout);
  476:         if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
  477:         if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
  478:         if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
  479:         fprintf(stdout, ".");
  480:         fflush(stdout);
  481: #if 0
  482:         if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
  483: #endif
  484:         if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
  485:         if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
  486:         fprintf(stdout, " ok\n");
  487: 
  488:         if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
  489:         if (!EC_GROUP_copy(P_224, group)) ABORT;
  490: 
  491: 
  492:         /* Curve P-256 (FIPS PUB 186-2, App. 6) */
  493:         
  494:         if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
  495:         if (1 != BN_is_prime_ex(p, BN_prime_checks,