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