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