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