ectest.c revision 296465
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#ifdef OPENSSL_NO_EC
83int main(int argc, char *argv[])
84{
85    puts("Elliptic curves are disabled.");
86    return 0;
87}
88#else
89
90# include <openssl/ec.h>
91# ifndef OPENSSL_NO_ENGINE
92#  include <openssl/engine.h>
93# endif
94# include <openssl/err.h>
95# include <openssl/obj_mac.h>
96# include <openssl/objects.h>
97# include <openssl/rand.h>
98# include <openssl/bn.h>
99
100# if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
101/* suppress "too big too optimize" warning */
102#  pragma warning(disable:4959)
103# endif
104
105# define ABORT do { \
106        fflush(stdout); \
107        fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
108        ERR_print_errors_fp(stderr); \
109        EXIT(1); \
110} while (0)
111
112void prime_field_tests(void);
113void char2_field_tests(void);
114void internal_curve_test(void);
115
116# define TIMING_BASE_PT 0
117# define TIMING_RAND_PT 1
118# define TIMING_SIMUL 2
119
120# if 0
121static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
122{
123    clock_t clck;
124    int i, j;
125    BIGNUM *s;
126    BIGNUM *r[10], *r0[10];
127    EC_POINT *P;
128
129    s = BN_new();
130    if (s == NULL)
131        ABORT;
132
133    fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
134    if (!EC_GROUP_get_order(group, s, ctx))
135        ABORT;
136    fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
137    fflush(stdout);
138
139    P = EC_POINT_new(group);
140    if (P == NULL)
141        ABORT;
142    EC_POINT_copy(P, EC_GROUP_get0_generator(group));
143
144    for (i = 0; i < 10; i++) {
145        if ((r[i] = BN_new()) == NULL)
146            ABORT;
147        if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0))
148            ABORT;
149        if (type != TIMING_BASE_PT) {
150            if ((r0[i] = BN_new()) == NULL)
151                ABORT;
152            if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0))
153                ABORT;
154        }
155    }
156
157    clck = clock();
158    for (i = 0; i < 10; i++) {
159        for (j = 0; j < 10; j++) {
160            if (!EC_POINT_mul
161                (group, P, (type != TIMING_RAND_PT) ? r[i] : NULL,
162                 (type != TIMING_BASE_PT) ? P : NULL,
163                 (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx))
164                ABORT;
165        }
166    }
167    clck = clock() - clck;
168
169    fprintf(stdout, "\n");
170
171#  ifdef CLOCKS_PER_SEC
172    /*
173     * "To determine the time in seconds, the value returned by the clock
174     * function should be divided by the value of the macro CLOCKS_PER_SEC."
175     * -- ISO/IEC 9899
176     */
177#   define UNIT "s"
178#  else
179    /*
180     * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on
181     * NeXTstep/OpenStep
182     */
183#   define UNIT "units"
184#   define CLOCKS_PER_SEC 1
185#  endif
186
187    if (type == TIMING_BASE_PT) {
188        fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j,
189                "base point multiplications", (double)clck / CLOCKS_PER_SEC);
190    } else if (type == TIMING_RAND_PT) {
191        fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j,
192                "random point multiplications",
193                (double)clck / CLOCKS_PER_SEC);
194    } else if (type == TIMING_SIMUL) {
195        fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j,
196                "s*P+t*Q operations", (double)clck / CLOCKS_PER_SEC);
197    }
198    fprintf(stdout, "average: %.4f " UNIT "\n",
199            (double)clck / (CLOCKS_PER_SEC * i * j));
200
201    EC_POINT_free(P);
202    BN_free(s);
203    for (i = 0; i < 10; i++) {
204        BN_free(r[i]);
205        if (type != TIMING_BASE_PT)
206            BN_free(r0[i]);
207    }
208}
209# endif
210
211void prime_field_tests()
212{
213    BN_CTX *ctx = NULL;
214    BIGNUM *p, *a, *b;
215    EC_GROUP *group;
216    EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 =
217        NULL, *P_384 = NULL, *P_521 = NULL;
218    EC_POINT *P, *Q, *R;
219    BIGNUM *x, *y, *z;
220    unsigned char buf[100];
221    size_t i, len;
222    int k;
223
224# if 1                          /* optional */
225    ctx = BN_CTX_new();
226    if (!ctx)
227        ABORT;
228# endif
229
230    p = BN_new();
231    a = BN_new();
232    b = BN_new();
233    if (!p || !a || !b)
234        ABORT;
235
236    if (!BN_hex2bn(&p, "17"))
237        ABORT;
238    if (!BN_hex2bn(&a, "1"))
239        ABORT;
240    if (!BN_hex2bn(&b, "1"))
241        ABORT;
242
243    group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use
244                                                 * EC_GROUP_new_curve_GFp so
245                                                 * that the library gets to
246                                                 * choose the EC_METHOD */
247    if (!group)
248        ABORT;
249
250    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
251        ABORT;
252
253    {
254        EC_GROUP *tmp;
255        tmp = EC_GROUP_new(EC_GROUP_method_of(group));
256        if (!tmp)
257            ABORT;
258        if (!EC_GROUP_copy(tmp, group))
259            ABORT;
260        EC_GROUP_free(group);
261        group = tmp;
262    }
263
264    if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx))
265        ABORT;
266
267    fprintf(stdout,
268            "Curve defined by Weierstrass equation\n     y^2 = x^3 + a*x + b  (mod 0x");
269    BN_print_fp(stdout, p);
270    fprintf(stdout, ")\n     a = 0x");
271    BN_print_fp(stdout, a);
272    fprintf(stdout, "\n     b = 0x");
273    BN_print_fp(stdout, b);
274    fprintf(stdout, "\n");
275
276    P = EC_POINT_new(group);
277    Q = EC_POINT_new(group);
278    R = EC_POINT_new(group);
279    if (!P || !Q || !R)
280        ABORT;
281
282    if (!EC_POINT_set_to_infinity(group, P))
283        ABORT;
284    if (!EC_POINT_is_at_infinity(group, P))
285        ABORT;
286
287    buf[0] = 0;
288    if (!EC_POINT_oct2point(group, Q, buf, 1, ctx))
289        ABORT;
290
291    if (!EC_POINT_add(group, P, P, Q, ctx))
292        ABORT;
293    if (!EC_POINT_is_at_infinity(group, P))
294        ABORT;
295
296    x = BN_new();
297    y = BN_new();
298    z = BN_new();
299    if (!x || !y || !z)
300        ABORT;
301
302    if (!BN_hex2bn(&x, "D"))
303        ABORT;
304    if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx))
305        ABORT;
306    if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) {
307        if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx))
308            ABORT;
309        fprintf(stderr, "Point is not on curve: x = 0x");
310        BN_print_fp(stderr, x);
311        fprintf(stderr, ", y = 0x");
312        BN_print_fp(stderr, y);
313        fprintf(stderr, "\n");
314        ABORT;
315    }
316
317    fprintf(stdout, "A cyclic subgroup:\n");
318    k = 100;
319    do {
320        if (k-- == 0)
321            ABORT;
322
323        if (EC_POINT_is_at_infinity(group, P))
324            fprintf(stdout, "     point at infinity\n");
325        else {
326            if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
327                ABORT;
328
329            fprintf(stdout, "     x = 0x");
330            BN_print_fp(stdout, x);
331            fprintf(stdout, ", y = 0x");
332            BN_print_fp(stdout, y);
333            fprintf(stdout, "\n");
334        }
335
336        if (!EC_POINT_copy(R, P))
337            ABORT;
338        if (!EC_POINT_add(group, P, P, Q, ctx))
339            ABORT;
340
341# if 0                          /* optional */
342        {
343            EC_POINT *points[3];
344
345            points[0] = R;
346            points[1] = Q;
347            points[2] = P;
348            if (!EC_POINTs_make_affine(group, 2, points, ctx))
349                ABORT;
350        }
351# endif
352
353    }
354    while (!EC_POINT_is_at_infinity(group, P));
355
356    if (!EC_POINT_add(group, P, Q, R, ctx))
357        ABORT;
358    if (!EC_POINT_is_at_infinity(group, P))
359        ABORT;
360
361    len =
362        EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
363                           sizeof buf, ctx);
364    if (len == 0)
365        ABORT;
366    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
367        ABORT;
368    if (0 != EC_POINT_cmp(group, P, Q, ctx))
369        ABORT;
370    fprintf(stdout, "Generator as octect string, compressed form:\n     ");
371    for (i = 0; i < len; i++)
372        fprintf(stdout, "%02X", buf[i]);
373
374    len =
375        EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf,
376                           sizeof buf, ctx);
377    if (len == 0)
378        ABORT;
379    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
380        ABORT;
381    if (0 != EC_POINT_cmp(group, P, Q, ctx))
382        ABORT;
383    fprintf(stdout,
384            "\nGenerator as octect string, uncompressed form:\n     ");
385    for (i = 0; i < len; i++)
386        fprintf(stdout, "%02X", buf[i]);
387
388    len =
389        EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf,
390                           ctx);
391    if (len == 0)
392        ABORT;
393    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
394        ABORT;
395    if (0 != EC_POINT_cmp(group, P, Q, ctx))
396        ABORT;
397    fprintf(stdout, "\nGenerator as octect string, hybrid form:\n     ");
398    for (i = 0; i < len; i++)
399        fprintf(stdout, "%02X", buf[i]);
400
401    if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx))
402        ABORT;
403    fprintf(stdout,
404            "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n     X = 0x");
405    BN_print_fp(stdout, x);
406    fprintf(stdout, ", Y = 0x");
407    BN_print_fp(stdout, y);
408    fprintf(stdout, ", Z = 0x");
409    BN_print_fp(stdout, z);
410    fprintf(stdout, "\n");
411
412    if (!EC_POINT_invert(group, P, ctx))
413        ABORT;
414    if (0 != EC_POINT_cmp(group, P, R, ctx))
415        ABORT;
416
417    /*
418     * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
419     * 2000) -- not a NIST curve, but commonly used
420     */
421
422    if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
423        ABORT;
424    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
425        ABORT;
426    if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
427        ABORT;
428    if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"))
429        ABORT;
430    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
431        ABORT;
432
433    if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82"))
434        ABORT;
435    if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32"))
436        ABORT;
437    if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
438        ABORT;
439    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
440        ABORT;
441    if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257"))
442        ABORT;
443    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
444        ABORT;
445
446    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
447        ABORT;
448    fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n     x = 0x");
449    BN_print_fp(stdout, x);
450    fprintf(stdout, "\n     y = 0x");
451    BN_print_fp(stdout, y);
452    fprintf(stdout, "\n");
453    /* G_y value taken from the standard: */
454    if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32"))
455        ABORT;
456    if (0 != BN_cmp(y, z))
457        ABORT;
458
459    fprintf(stdout, "verify degree ...");
460    if (EC_GROUP_get_degree(group) != 160)
461        ABORT;
462    fprintf(stdout, " ok\n");
463
464    fprintf(stdout, "verify group order ...");
465    fflush(stdout);
466    if (!EC_GROUP_get_order(group, z, ctx))
467        ABORT;
468    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
469        ABORT;
470    if (!EC_POINT_is_at_infinity(group, Q))
471        ABORT;
472    fprintf(stdout, ".");
473    fflush(stdout);
474    if (!EC_GROUP_precompute_mult(group, ctx))
475        ABORT;
476    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
477        ABORT;
478    if (!EC_POINT_is_at_infinity(group, Q))
479        ABORT;
480    fprintf(stdout, " ok\n");
481
482    if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group))))
483        ABORT;
484    if (!EC_GROUP_copy(P_160, group))
485        ABORT;
486
487    /* Curve P-192 (FIPS PUB 186-2, App. 6) */
488
489    if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
490        ABORT;
491    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
492        ABORT;
493    if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
494        ABORT;
495    if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"))
496        ABORT;
497    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
498        ABORT;
499
500    if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"))
501        ABORT;
502    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx))
503        ABORT;
504    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
505        ABORT;
506    if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"))
507        ABORT;
508    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
509        ABORT;
510
511    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
512        ABORT;
513    fprintf(stdout, "\nNIST curve P-192 -- Generator:\n     x = 0x");
514    BN_print_fp(stdout, x);
515    fprintf(stdout, "\n     y = 0x");
516    BN_print_fp(stdout, y);
517    fprintf(stdout, "\n");
518    /* G_y value taken from the standard: */
519    if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"))
520        ABORT;
521    if (0 != BN_cmp(y, z))
522        ABORT;
523
524    fprintf(stdout, "verify degree ...");
525    if (EC_GROUP_get_degree(group) != 192)
526        ABORT;
527    fprintf(stdout, " ok\n");
528
529    fprintf(stdout, "verify group order ...");
530    fflush(stdout);
531    if (!EC_GROUP_get_order(group, z, ctx))
532        ABORT;
533    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
534        ABORT;
535    if (!EC_POINT_is_at_infinity(group, Q))
536        ABORT;
537    fprintf(stdout, ".");
538    fflush(stdout);
539# if 0
540    if (!EC_GROUP_precompute_mult(group, ctx))
541        ABORT;
542# endif
543    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
544        ABORT;
545    if (!EC_POINT_is_at_infinity(group, Q))
546        ABORT;
547    fprintf(stdout, " ok\n");
548
549    if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group))))
550        ABORT;
551    if (!EC_GROUP_copy(P_192, group))
552        ABORT;
553
554    /* Curve P-224 (FIPS PUB 186-2, App. 6) */
555
556    if (!BN_hex2bn
557        (&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"))
558        ABORT;
559    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
560        ABORT;
561    if (!BN_hex2bn
562        (&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
563        ABORT;
564    if (!BN_hex2bn
565        (&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"))
566        ABORT;
567    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
568        ABORT;
569
570    if (!BN_hex2bn
571        (&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"))
572        ABORT;
573    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx))
574        ABORT;
575    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
576        ABORT;
577    if (!BN_hex2bn
578        (&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"))
579        ABORT;
580    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
581        ABORT;
582
583    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
584        ABORT;
585    fprintf(stdout, "\nNIST curve P-224 -- Generator:\n     x = 0x");
586    BN_print_fp(stdout, x);
587    fprintf(stdout, "\n     y = 0x");
588    BN_print_fp(stdout, y);
589    fprintf(stdout, "\n");
590    /* G_y value taken from the standard: */
591    if (!BN_hex2bn
592        (&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"))
593        ABORT;
594    if (0 != BN_cmp(y, z))
595        ABORT;
596
597    fprintf(stdout, "verify degree ...");
598    if (EC_GROUP_get_degree(group) != 224)
599        ABORT;
600    fprintf(stdout, " ok\n");
601
602    fprintf(stdout, "verify group order ...");
603    fflush(stdout);
604    if (!EC_GROUP_get_order(group, z, ctx))
605        ABORT;
606    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
607        ABORT;
608    if (!EC_POINT_is_at_infinity(group, Q))
609        ABORT;
610    fprintf(stdout, ".");
611    fflush(stdout);
612# if 0
613    if (!EC_GROUP_precompute_mult(group, ctx))
614        ABORT;
615# endif
616    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
617        ABORT;
618    if (!EC_POINT_is_at_infinity(group, Q))
619        ABORT;
620    fprintf(stdout, " ok\n");
621
622    if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group))))
623        ABORT;
624    if (!EC_GROUP_copy(P_224, group))
625        ABORT;
626
627    /* Curve P-256 (FIPS PUB 186-2, App. 6) */
628
629    if (!BN_hex2bn
630        (&p,
631         "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"))
632        ABORT;
633    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
634        ABORT;
635    if (!BN_hex2bn
636        (&a,
637         "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"))
638        ABORT;
639    if (!BN_hex2bn
640        (&b,
641         "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"))
642        ABORT;
643    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
644        ABORT;
645
646    if (!BN_hex2bn
647        (&x,
648         "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"))
649        ABORT;
650    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx))
651        ABORT;
652    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
653        ABORT;
654    if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
655                   "84F3B9CAC2FC632551"))
656        ABORT;
657    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
658        ABORT;
659
660    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
661        ABORT;
662    fprintf(stdout, "\nNIST curve P-256 -- Generator:\n     x = 0x");
663    BN_print_fp(stdout, x);
664    fprintf(stdout, "\n     y = 0x");
665    BN_print_fp(stdout, y);
666    fprintf(stdout, "\n");
667    /* G_y value taken from the standard: */
668    if (!BN_hex2bn
669        (&z,
670         "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"))
671        ABORT;
672    if (0 != BN_cmp(y, z))
673        ABORT;
674
675    fprintf(stdout, "verify degree ...");
676    if (EC_GROUP_get_degree(group) != 256)
677        ABORT;
678    fprintf(stdout, " ok\n");
679
680    fprintf(stdout, "verify group order ...");
681    fflush(stdout);
682    if (!EC_GROUP_get_order(group, z, ctx))
683        ABORT;
684    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
685        ABORT;
686    if (!EC_POINT_is_at_infinity(group, Q))
687        ABORT;
688    fprintf(stdout, ".");
689    fflush(stdout);
690# if 0
691    if (!EC_GROUP_precompute_mult(group, ctx))
692        ABORT;
693# endif
694    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
695        ABORT;
696    if (!EC_POINT_is_at_infinity(group, Q))
697        ABORT;
698    fprintf(stdout, " ok\n");
699
700    if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group))))
701        ABORT;
702    if (!EC_GROUP_copy(P_256, group))
703        ABORT;
704
705    /* Curve P-384 (FIPS PUB 186-2, App. 6) */
706
707    if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
708                   "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"))
709        ABORT;
710    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
711        ABORT;
712    if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
713                   "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC"))
714        ABORT;
715    if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
716                   "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"))
717        ABORT;
718    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
719        ABORT;
720
721    if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
722                   "9859F741E082542A385502F25DBF55296C3A545E3872760AB7"))
723        ABORT;
724    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx))
725        ABORT;
726    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
727        ABORT;
728    if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
729                   "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"))
730        ABORT;
731    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
732        ABORT;
733
734    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
735        ABORT;
736    fprintf(stdout, "\nNIST curve P-384 -- Generator:\n     x = 0x");
737    BN_print_fp(stdout, x);
738    fprintf(stdout, "\n     y = 0x");
739    BN_print_fp(stdout, y);
740    fprintf(stdout, "\n");
741    /* G_y value taken from the standard: */
742    if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
743                   "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"))
744        ABORT;
745    if (0 != BN_cmp(y, z))
746        ABORT;
747
748    fprintf(stdout, "verify degree ...");
749    if (EC_GROUP_get_degree(group) != 384)
750        ABORT;
751    fprintf(stdout, " ok\n");
752
753    fprintf(stdout, "verify group order ...");
754    fflush(stdout);
755    if (!EC_GROUP_get_order(group, z, ctx))
756        ABORT;
757    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
758        ABORT;
759    if (!EC_POINT_is_at_infinity(group, Q))
760        ABORT;
761    fprintf(stdout, ".");
762    fflush(stdout);
763# if 0
764    if (!EC_GROUP_precompute_mult(group, ctx))
765        ABORT;
766# endif
767    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
768        ABORT;
769    if (!EC_POINT_is_at_infinity(group, Q))
770        ABORT;
771    fprintf(stdout, " ok\n");
772
773    if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group))))
774        ABORT;
775    if (!EC_GROUP_copy(P_384, group))
776        ABORT;
777
778    /* Curve P-521 (FIPS PUB 186-2, App. 6) */
779
780    if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
781                   "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
782                   "FFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
783        ABORT;
784    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
785        ABORT;
786    if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
787                   "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
788                   "FFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
789        ABORT;
790    if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
791                   "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
792                   "DF883D2C34F1EF451FD46B503F00"))
793        ABORT;
794    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
795        ABORT;
796
797    if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
798                   "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
799                   "3C1856A429BF97E7E31C2E5BD66"))
800        ABORT;
801    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx))
802        ABORT;
803    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
804        ABORT;
805    if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
806                   "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
807                   "C9B8899C47AEBB6FB71E91386409"))
808        ABORT;
809    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
810        ABORT;
811
812    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
813        ABORT;
814    fprintf(stdout, "\nNIST curve P-521 -- Generator:\n     x = 0x");
815    BN_print_fp(stdout, x);
816    fprintf(stdout, "\n     y = 0x");
817    BN_print_fp(stdout, y);
818    fprintf(stdout, "\n");
819    /* G_y value taken from the standard: */
820    if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
821                   "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
822                   "7086A272C24088BE94769FD16650"))
823        ABORT;
824    if (0 != BN_cmp(y, z))
825        ABORT;
826
827    fprintf(stdout, "verify degree ...");
828    if (EC_GROUP_get_degree(group) != 521)
829        ABORT;
830    fprintf(stdout, " ok\n");
831
832    fprintf(stdout, "verify group order ...");
833    fflush(stdout);
834    if (!EC_GROUP_get_order(group, z, ctx))
835        ABORT;
836    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
837        ABORT;
838    if (!EC_POINT_is_at_infinity(group, Q))
839        ABORT;
840    fprintf(stdout, ".");
841    fflush(stdout);
842# if 0
843    if (!EC_GROUP_precompute_mult(group, ctx))
844        ABORT;
845# endif
846    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
847        ABORT;
848    if (!EC_POINT_is_at_infinity(group, Q))
849        ABORT;
850    fprintf(stdout, " ok\n");
851
852    if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group))))
853        ABORT;
854    if (!EC_GROUP_copy(P_521, group))
855        ABORT;
856
857    /* more tests using the last curve */
858
859    if (!EC_POINT_copy(Q, P))
860        ABORT;
861    if (EC_POINT_is_at_infinity(group, Q))
862        ABORT;
863    if (!EC_POINT_dbl(group, P, P, ctx))
864        ABORT;
865    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
866        ABORT;
867    if (!EC_POINT_invert(group, Q, ctx))
868        ABORT;                  /* P = -2Q */
869
870    if (!EC_POINT_add(group, R, P, Q, ctx))
871        ABORT;
872    if (!EC_POINT_add(group, R, R, Q, ctx))
873        ABORT;
874    if (!EC_POINT_is_at_infinity(group, R))
875        ABORT;                  /* R = P + 2Q */
876
877    {
878        const EC_POINT *points[4];
879        const BIGNUM *scalars[4];
880        BIGNUM scalar3;
881
882        if (EC_POINT_is_at_infinity(group, Q))
883            ABORT;
884        points[0] = Q;
885        points[1] = Q;
886        points[2] = Q;
887        points[3] = Q;
888
889        if (!BN_add(y, z, BN_value_one()))
890            ABORT;
891        if (BN_is_odd(y))
892            ABORT;
893        if (!BN_rshift1(y, y))
894            ABORT;
895        scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
896        scalars[1] = y;
897
898        fprintf(stdout, "combined multiplication ...");
899        fflush(stdout);
900
901        /* z is still the group order */
902        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
903            ABORT;
904        if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
905            ABORT;
906        if (0 != EC_POINT_cmp(group, P, R, ctx))
907            ABORT;
908        if (0 != EC_POINT_cmp(group, R, Q, ctx))
909            ABORT;
910
911        fprintf(stdout, ".");
912        fflush(stdout);
913
914        if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0))
915            ABORT;
916        if (!BN_add(z, z, y))
917            ABORT;
918        BN_set_negative(z, 1);
919        scalars[0] = y;
920        scalars[1] = z;         /* z = -(order + y) */
921
922        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
923            ABORT;
924        if (!EC_POINT_is_at_infinity(group, P))
925            ABORT;
926
927        fprintf(stdout, ".");
928        fflush(stdout);
929
930        if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0))
931            ABORT;
932        if (!BN_add(z, x, y))
933            ABORT;
934        BN_set_negative(z, 1);
935        scalars[0] = x;
936        scalars[1] = y;
937        scalars[2] = z;         /* z = -(x+y) */
938
939        BN_init(&scalar3);
940        BN_zero(&scalar3);
941        scalars[3] = &scalar3;
942
943        if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
944            ABORT;
945        if (!EC_POINT_is_at_infinity(group, P))
946            ABORT;
947
948        fprintf(stdout, " ok\n\n");
949
950        BN_free(&scalar3);
951    }
952
953# if 0
954    timings(P_160, TIMING_BASE_PT, ctx);
955    timings(P_160, TIMING_RAND_PT, ctx);
956    timings(P_160, TIMING_SIMUL, ctx);
957    timings(P_192, TIMING_BASE_PT, ctx);
958    timings(P_192, TIMING_RAND_PT, ctx);
959    timings(P_192, TIMING_SIMUL, ctx);
960    timings(P_224, TIMING_BASE_PT, ctx);
961    timings(P_224, TIMING_RAND_PT, ctx);
962    timings(P_224, TIMING_SIMUL, ctx);
963    timings(P_256, TIMING_BASE_PT, ctx);
964    timings(P_256, TIMING_RAND_PT, ctx);
965    timings(P_256, TIMING_SIMUL, ctx);
966    timings(P_384, TIMING_BASE_PT, ctx);
967    timings(P_384, TIMING_RAND_PT, ctx);
968    timings(P_384, TIMING_SIMUL, ctx);
969    timings(P_521, TIMING_BASE_PT, ctx);
970    timings(P_521, TIMING_RAND_PT, ctx);
971    timings(P_521, TIMING_SIMUL, ctx);
972# endif
973
974    if (ctx)
975        BN_CTX_free(ctx);
976    BN_free(p);
977    BN_free(a);
978    BN_free(b);
979    EC_GROUP_free(group);
980    EC_POINT_free(P);
981    EC_POINT_free(Q);
982    EC_POINT_free(R);
983    BN_free(x);
984    BN_free(y);
985    BN_free(z);
986
987    if (P_160)
988        EC_GROUP_free(P_160);
989    if (P_192)
990        EC_GROUP_free(P_192);
991    if (P_224)
992        EC_GROUP_free(P_224);
993    if (P_256)
994        EC_GROUP_free(P_256);
995    if (P_384)
996        EC_GROUP_free(P_384);
997    if (P_521)
998        EC_GROUP_free(P_521);
999
1000}
1001
1002/* Change test based on whether binary point compression is enabled or not. */
1003# ifdef OPENSSL_EC_BIN_PT_COMP
1004#  define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
1005        if (!BN_hex2bn(&x, _x)) ABORT; \
1006        if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
1007        if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
1008        if (!BN_hex2bn(&z, _order)) ABORT; \
1009        if (!BN_hex2bn(&cof, _cof)) ABORT; \
1010        if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
1011        if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
1012        fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
1013        BN_print_fp(stdout, x); \
1014        fprintf(stdout, "\n     y = 0x"); \
1015        BN_print_fp(stdout, y); \
1016        fprintf(stdout, "\n"); \
1017        /* G_y value taken from the standard: */ \
1018        if (!BN_hex2bn(&z, _y)) ABORT; \
1019        if (0 != BN_cmp(y, z)) ABORT;
1020# else
1021#  define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
1022        if (!BN_hex2bn(&x, _x)) ABORT; \
1023        if (!BN_hex2bn(&y, _y)) ABORT; \
1024        if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
1025        if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
1026        if (!BN_hex2bn(&z, _order)) ABORT; \
1027        if (!BN_hex2bn(&cof, _cof)) ABORT; \
1028        if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
1029        fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
1030        BN_print_fp(stdout, x); \
1031        fprintf(stdout, "\n     y = 0x"); \
1032        BN_print_fp(stdout, y); \
1033        fprintf(stdout, "\n");
1034# endif
1035
1036# define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
1037        if (!BN_hex2bn(&p, _p)) ABORT; \
1038        if (!BN_hex2bn(&a, _a)) ABORT; \
1039        if (!BN_hex2bn(&b, _b)) ABORT; \
1040        if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \
1041        CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
1042        fprintf(stdout, "verify degree ..."); \
1043        if (EC_GROUP_get_degree(group) != _degree) ABORT; \
1044        fprintf(stdout, " ok\n"); \
1045        fprintf(stdout, "verify group order ..."); \
1046        fflush(stdout); \
1047        if (!EC_GROUP_get_order(group, z, ctx)) ABORT; \
1048        if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
1049        if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
1050        fprintf(stdout, "."); \
1051        fflush(stdout); \
1052        /* if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; */ \
1053        if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
1054        if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
1055        fprintf(stdout, " ok\n"); \
1056        if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
1057        if (!EC_GROUP_copy(_variable, group)) ABORT;
1058
1059void char2_field_tests()
1060{
1061    BN_CTX *ctx = NULL;
1062    BIGNUM *p, *a, *b;
1063    EC_GROUP *group;
1064    EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 =
1065        NULL, *C2_K571 = NULL;
1066    EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 =
1067        NULL, *C2_B571 = NULL;
1068    EC_POINT *P, *Q, *R;
1069    BIGNUM *x, *y, *z, *cof;
1070    unsigned char buf[100];
1071    size_t i, len;
1072    int k;
1073
1074# if 1                          /* optional */
1075    ctx = BN_CTX_new();
1076    if (!ctx)
1077        ABORT;
1078# endif
1079
1080    p = BN_new();
1081    a = BN_new();
1082    b = BN_new();
1083    if (!p || !a || !b)
1084        ABORT;
1085
1086    if (!BN_hex2bn(&p, "13"))
1087        ABORT;
1088    if (!BN_hex2bn(&a, "3"))
1089        ABORT;
1090    if (!BN_hex2bn(&b, "1"))
1091        ABORT;
1092
1093    group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
1094                                                    * EC_GROUP_new_curve_GF2m
1095                                                    * so that the library gets
1096                                                    * to choose the EC_METHOD */
1097    if (!group)
1098        ABORT;
1099    if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx))
1100        ABORT;
1101
1102    {
1103        EC_GROUP *tmp;
1104        tmp = EC_GROUP_new(EC_GROUP_method_of(group));
1105        if (!tmp)
1106            ABORT;
1107        if (!EC_GROUP_copy(tmp, group))
1108            ABORT;
1109        EC_GROUP_free(group);
1110        group = tmp;
1111    }
1112
1113    if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx))
1114        ABORT;
1115
1116    fprintf(stdout,
1117            "Curve defined by Weierstrass equation\n     y^2 + x*y = x^3 + a*x^2 + b  (mod 0x");
1118    BN_print_fp(stdout, p);
1119    fprintf(stdout, ")\n     a = 0x");
1120    BN_print_fp(stdout, a);
1121    fprintf(stdout, "\n     b = 0x");
1122    BN_print_fp(stdout, b);
1123    fprintf(stdout, "\n(0x... means binary polynomial)\n");
1124
1125    P = EC_POINT_new(group);
1126    Q = EC_POINT_new(group);
1127    R = EC_POINT_new(group);
1128    if (!P || !Q || !R)
1129        ABORT;
1130
1131    if (!EC_POINT_set_to_infinity(group, P))
1132        ABORT;
1133    if (!EC_POINT_is_at_infinity(group, P))
1134        ABORT;
1135
1136    buf[0] = 0;
1137    if (!EC_POINT_oct2point(group, Q, buf, 1, ctx))
1138        ABORT;
1139
1140    if (!EC_POINT_add(group, P, P, Q, ctx))
1141        ABORT;
1142    if (!EC_POINT_is_at_infinity(group, P))
1143        ABORT;
1144
1145    x = BN_new();
1146    y = BN_new();
1147    z = BN_new();
1148    cof = BN_new();
1149    if (!x || !y || !z || !cof)
1150        ABORT;
1151
1152    if (!BN_hex2bn(&x, "6"))
1153        ABORT;
1154/* Change test based on whether binary point compression is enabled or not. */
1155# ifdef OPENSSL_EC_BIN_PT_COMP
1156    if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx))
1157        ABORT;
1158# else
1159    if (!BN_hex2bn(&y, "8"))
1160        ABORT;
1161    if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx))
1162        ABORT;
1163# endif
1164    if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) {
1165/* Change test based on whether binary point compression is enabled or not. */
1166# ifdef OPENSSL_EC_BIN_PT_COMP
1167        if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx))
1168            ABORT;
1169# endif
1170        fprintf(stderr, "Point is not on curve: x = 0x");
1171        BN_print_fp(stderr, x);
1172        fprintf(stderr, ", y = 0x");
1173        BN_print_fp(stderr, y);
1174        fprintf(stderr, "\n");
1175        ABORT;
1176    }
1177
1178    fprintf(stdout, "A cyclic subgroup:\n");
1179    k = 100;
1180    do {
1181        if (k-- == 0)
1182            ABORT;
1183
1184        if (EC_POINT_is_at_infinity(group, P))
1185            fprintf(stdout, "     point at infinity\n");
1186        else {
1187            if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx))
1188                ABORT;
1189
1190            fprintf(stdout, "     x = 0x");
1191            BN_print_fp(stdout, x);
1192            fprintf(stdout, ", y = 0x");
1193            BN_print_fp(stdout, y);
1194            fprintf(stdout, "\n");
1195        }
1196
1197        if (!EC_POINT_copy(R, P))
1198            ABORT;
1199        if (!EC_POINT_add(group, P, P, Q, ctx))
1200            ABORT;
1201    }
1202    while (!EC_POINT_is_at_infinity(group, P));
1203
1204    if (!EC_POINT_add(group, P, Q, R, ctx))
1205        ABORT;
1206    if (!EC_POINT_is_at_infinity(group, P))
1207        ABORT;
1208
1209/* Change test based on whether binary point compression is enabled or not. */
1210# ifdef OPENSSL_EC_BIN_PT_COMP
1211    len =
1212        EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
1213                           sizeof buf, ctx);
1214    if (len == 0)
1215        ABORT;
1216    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
1217        ABORT;
1218    if (0 != EC_POINT_cmp(group, P, Q, ctx))
1219        ABORT;
1220    fprintf(stdout, "Generator as octet string, compressed form:\n     ");
1221    for (i = 0; i < len; i++)
1222        fprintf(stdout, "%02X", buf[i]);
1223# endif
1224
1225    len =
1226        EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf,
1227                           sizeof buf, ctx);
1228    if (len == 0)
1229        ABORT;
1230    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
1231        ABORT;
1232    if (0 != EC_POINT_cmp(group, P, Q, ctx))
1233        ABORT;
1234    fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
1235    for (i = 0; i < len; i++)
1236        fprintf(stdout, "%02X", buf[i]);
1237
1238/* Change test based on whether binary point compression is enabled or not. */
1239# ifdef OPENSSL_EC_BIN_PT_COMP
1240    len =
1241        EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf,
1242                           ctx);
1243    if (len == 0)
1244        ABORT;
1245    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
1246        ABORT;
1247    if (0 != EC_POINT_cmp(group, P, Q, ctx))
1248        ABORT;
1249    fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
1250    for (i = 0; i < len; i++)
1251        fprintf(stdout, "%02X", buf[i]);
1252# endif
1253
1254    fprintf(stdout, "\n");
1255
1256    if (!EC_POINT_invert(group, P, ctx))
1257        ABORT;
1258    if (0 != EC_POINT_cmp(group, P, R, ctx))
1259        ABORT;
1260
1261    /* Curve K-163 (FIPS PUB 186-2, App. 6) */
1262    CHAR2_CURVE_TEST
1263        ("NIST curve K-163",
1264         "0800000000000000000000000000000000000000C9",
1265         "1",
1266         "1",
1267         "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
1268         "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
1269         1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163, C2_K163);
1270
1271    /* Curve B-163 (FIPS PUB 186-2, App. 6) */
1272    CHAR2_CURVE_TEST
1273        ("NIST curve B-163",
1274         "0800000000000000000000000000000000000000C9",
1275         "1",
1276         "020A601907B8C953CA1481EB10512F78744A3205FD",
1277         "03F0EBA16286A2D57EA0991168D4994637E8343E36",
1278         "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
1279         1, "040000000000000000000292FE77E70C12A4234C33", "2", 163, C2_B163);
1280
1281    /* Curve K-233 (FIPS PUB 186-2, App. 6) */
1282    CHAR2_CURVE_TEST
1283        ("NIST curve K-233",
1284         "020000000000000000000000000000000000000004000000000000000001",
1285         "0",
1286         "1",
1287         "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
1288         "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
1289         0,
1290         "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
1291         "4", 233, C2_K233);
1292
1293    /* Curve B-233 (FIPS PUB 186-2, App. 6) */
1294    CHAR2_CURVE_TEST
1295        ("NIST curve B-233",
1296         "020000000000000000000000000000000000000004000000000000000001",
1297         "000000000000000000000000000000000000000000000000000000000001",
1298         "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
1299         "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
1300         "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
1301         1,
1302         "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
1303         "2", 233, C2_B233);
1304
1305    /* Curve K-283 (FIPS PUB 186-2, App. 6) */
1306    CHAR2_CURVE_TEST
1307        ("NIST curve K-283",
1308         "0800000000000000000000000000000000000000000000000000000000000000000010A1",
1309         "0",
1310         "1",
1311         "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
1312         "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
1313         0,
1314         "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
1315         "4", 283, C2_K283);
1316
1317    /* Curve B-283 (FIPS PUB 186-2, App. 6) */
1318    CHAR2_CURVE_TEST
1319        ("NIST curve B-283",
1320         "0800000000000000000000000000000000000000000000000000000000000000000010A1",
1321         "000000000000000000000000000000000000000000000000000000000000000000000001",
1322         "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
1323         "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
1324         "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
1325         1,
1326         "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
1327         "2", 283, C2_B283);
1328
1329    /* Curve K-409 (FIPS PUB 186-2, App. 6) */
1330    CHAR2_CURVE_TEST
1331        ("NIST curve K-409",
1332         "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
1333         "0",
1334         "1",
1335         "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
1336         "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
1337         1,
1338         "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
1339         "4", 409, C2_K409);
1340
1341    /* Curve B-409 (FIPS PUB 186-2, App. 6) */
1342    CHAR2_CURVE_TEST
1343        ("NIST curve B-409",
1344         "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
1345         "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
1346         "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
1347         "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
1348         "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
1349         1,
1350         "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
1351         "2", 409, C2_B409);
1352
1353    /* Curve K-571 (FIPS PUB 186-2, App. 6) */
1354    CHAR2_CURVE_TEST
1355        ("NIST curve K-571",
1356         "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
1357         "0",
1358         "1",
1359         "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
1360         "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
1361         0,
1362         "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
1363         "4", 571, C2_K571);
1364
1365    /* Curve B-571 (FIPS PUB 186-2, App. 6) */
1366    CHAR2_CURVE_TEST
1367        ("NIST curve B-571",
1368         "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
1369         "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
1370         "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
1371         "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
1372         "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
1373         1,
1374         "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
1375         "2", 571, C2_B571);
1376
1377    /* more tests using the last curve */
1378
1379    if (!EC_POINT_copy(Q, P))
1380        ABORT;
1381    if (EC_POINT_is_at_infinity(group, Q))
1382        ABORT;
1383    if (!EC_POINT_dbl(group, P, P, ctx))
1384        ABORT;
1385    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
1386        ABORT;
1387    if (!EC_POINT_invert(group, Q, ctx))
1388        ABORT;                  /* P = -2Q */
1389
1390    if (!EC_POINT_add(group, R, P, Q, ctx))
1391        ABORT;
1392    if (!EC_POINT_add(group, R, R, Q, ctx))
1393        ABORT;
1394    if (!EC_POINT_is_at_infinity(group, R))
1395        ABORT;                  /* R = P + 2Q */
1396
1397    {
1398        const EC_POINT *points[3];
1399        const BIGNUM *scalars[3];
1400
1401        if (EC_POINT_is_at_infinity(group, Q))
1402            ABORT;
1403        points[0] = Q;
1404        points[1] = Q;
1405        points[2] = Q;
1406
1407        if (!BN_add(y, z, BN_value_one()))
1408            ABORT;
1409        if (BN_is_odd(y))
1410            ABORT;
1411        if (!BN_rshift1(y, y))
1412            ABORT;
1413        scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
1414        scalars[1] = y;
1415
1416        fprintf(stdout, "combined multiplication ...");
1417        fflush(stdout);
1418
1419        /* z is still the group order */
1420        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
1421            ABORT;
1422        if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
1423            ABORT;
1424        if (0 != EC_POINT_cmp(group, P, R, ctx))
1425            ABORT;
1426        if (0 != EC_POINT_cmp(group, R, Q, ctx))
1427            ABORT;
1428
1429        fprintf(stdout, ".");
1430        fflush(stdout);
1431
1432        if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0))
1433            ABORT;
1434        if (!BN_add(z, z, y))
1435            ABORT;
1436        BN_set_negative(z, 1);
1437        scalars[0] = y;
1438        scalars[1] = z;         /* z = -(order + y) */
1439
1440        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
1441            ABORT;
1442        if (!EC_POINT_is_at_infinity(group, P))
1443            ABORT;
1444
1445        fprintf(stdout, ".");
1446        fflush(stdout);
1447
1448        if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0))
1449            ABORT;
1450        if (!BN_add(z, x, y))
1451            ABORT;
1452        BN_set_negative(z, 1);
1453        scalars[0] = x;
1454        scalars[1] = y;
1455        scalars[2] = z;         /* z = -(x+y) */
1456
1457        if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
1458            ABORT;
1459        if (!EC_POINT_is_at_infinity(group, P))
1460            ABORT;
1461
1462        fprintf(stdout, " ok\n\n");
1463    }
1464
1465# if 0
1466    timings(C2_K163, TIMING_BASE_PT, ctx);
1467    timings(C2_K163, TIMING_RAND_PT, ctx);
1468    timings(C2_K163, TIMING_SIMUL, ctx);
1469    timings(C2_B163, TIMING_BASE_PT, ctx);
1470    timings(C2_B163, TIMING_RAND_PT, ctx);
1471    timings(C2_B163, TIMING_SIMUL, ctx);
1472    timings(C2_K233, TIMING_BASE_PT, ctx);
1473    timings(C2_K233, TIMING_RAND_PT, ctx);
1474    timings(C2_K233, TIMING_SIMUL, ctx);
1475    timings(C2_B233, TIMING_BASE_PT, ctx);
1476    timings(C2_B233, TIMING_RAND_PT, ctx);
1477    timings(C2_B233, TIMING_SIMUL, ctx);
1478    timings(C2_K283, TIMING_BASE_PT, ctx);
1479    timings(C2_K283, TIMING_RAND_PT, ctx);
1480    timings(C2_K283, TIMING_SIMUL, ctx);
1481    timings(C2_B283, TIMING_BASE_PT, ctx);
1482    timings(C2_B283, TIMING_RAND_PT, ctx);
1483    timings(C2_B283, TIMING_SIMUL, ctx);
1484    timings(C2_K409, TIMING_BASE_PT, ctx);
1485    timings(C2_K409, TIMING_RAND_PT, ctx);
1486    timings(C2_K409, TIMING_SIMUL, ctx);
1487    timings(C2_B409, TIMING_BASE_PT, ctx);
1488    timings(C2_B409, TIMING_RAND_PT, ctx);
1489    timings(C2_B409, TIMING_SIMUL, ctx);
1490    timings(C2_K571, TIMING_BASE_PT, ctx);
1491    timings(C2_K571, TIMING_RAND_PT, ctx);
1492    timings(C2_K571, TIMING_SIMUL, ctx);
1493    timings(C2_B571, TIMING_BASE_PT, ctx);
1494    timings(C2_B571, TIMING_RAND_PT, ctx);
1495    timings(C2_B571, TIMING_SIMUL, ctx);
1496# endif
1497
1498    if (ctx)
1499        BN_CTX_free(ctx);
1500    BN_free(p);
1501    BN_free(a);
1502    BN_free(b);
1503    EC_GROUP_free(group);
1504    EC_POINT_free(P);
1505    EC_POINT_free(Q);
1506    EC_POINT_free(R);
1507    BN_free(x);
1508    BN_free(y);
1509    BN_free(z);
1510    BN_free(cof);
1511
1512    if (C2_K163)
1513        EC_GROUP_free(C2_K163);
1514    if (C2_B163)
1515        EC_GROUP_free(C2_B163);
1516    if (C2_K233)
1517        EC_GROUP_free(C2_K233);
1518    if (C2_B233)
1519        EC_GROUP_free(C2_B233);
1520    if (C2_K283)
1521        EC_GROUP_free(C2_K283);
1522    if (C2_B283)
1523        EC_GROUP_free(C2_B283);
1524    if (C2_K409)
1525        EC_GROUP_free(C2_K409);
1526    if (C2_B409)
1527        EC_GROUP_free(C2_B409);
1528    if (C2_K571)
1529        EC_GROUP_free(C2_K571);
1530    if (C2_B571)
1531        EC_GROUP_free(C2_B571);
1532
1533}
1534
1535void internal_curve_test(void)
1536{
1537    EC_builtin_curve *curves = NULL;
1538    size_t crv_len = 0, n = 0;
1539    int ok = 1;
1540
1541    crv_len = EC_get_builtin_curves(NULL, 0);
1542
1543    curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
1544
1545    if (curves == NULL)
1546        return;
1547
1548    if (!EC_get_builtin_curves(curves, crv_len)) {
1549        OPENSSL_free(curves);
1550        return;
1551    }
1552
1553    fprintf(stdout, "testing internal curves: ");
1554
1555    for (n = 0; n < crv_len; n++) {
1556        EC_GROUP *group = NULL;
1557        int nid = curves[n].nid;
1558        if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
1559            ok = 0;
1560            fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with"
1561                    " curve %s\n", OBJ_nid2sn(nid));
1562            /* try next curve */
1563            continue;
1564        }
1565        if (!EC_GROUP_check(group, NULL)) {
1566            ok = 0;
1567            fprintf(stdout, "\nEC_GROUP_check() failed with"
1568                    " curve %s\n", OBJ_nid2sn(nid));
1569            EC_GROUP_free(group);
1570            /* try the next curve */
1571            continue;
1572        }
1573        fprintf(stdout, ".");
1574        fflush(stdout);
1575        EC_GROUP_free(group);
1576    }
1577    if (ok)
1578        fprintf(stdout, " ok\n");
1579    else
1580        fprintf(stdout, " failed\n");
1581    OPENSSL_free(curves);
1582    return;
1583}
1584
1585static const char rnd_seed[] =
1586    "string to make the random number generator think it has entropy";
1587
1588int main(int argc, char *argv[])
1589{
1590
1591    /* enable memory leak checking unless explicitly disabled */
1592    if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL)
1593          && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) {
1594        CRYPTO_malloc_debug_init();
1595        CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
1596    } else {
1597        /* OPENSSL_DEBUG_MEMORY=off */
1598        CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
1599    }
1600    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
1601    ERR_load_crypto_strings();
1602
1603    RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
1604
1605    prime_field_tests();
1606    puts("");
1607    char2_field_tests();
1608    /* test the internal curves */
1609    internal_curve_test();
1610
1611# ifndef OPENSSL_NO_ENGINE
1612    ENGINE_cleanup();
1613# endif
1614    CRYPTO_cleanup_all_ex_data();
1615    ERR_free_strings();
1616    ERR_remove_state(0);
1617    CRYPTO_mem_leaks_fp(stderr);
1618
1619    return 0;
1620}
1621#endif
1622