The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / openssl / openssl / crypto / ec / ectest.c @ aa3b4b4d

History | View | Annotate | Download (50.3 KB)

1
/* crypto/ec/ectest.c */
2
/*
3
 * Originally written by Bodo Moeller for the OpenSSL project.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer. 
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    openssl-core@openssl.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com).
56
 *
57
 */
58
/* ====================================================================
59
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60
 *
61
 * Portions of the attached software ("Contribution") are developed by 
62
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63
 *
64
 * The Contribution is licensed pursuant to the OpenSSL open source
65
 * license provided above.
66
 *
67
 * The elliptic curve binary polynomial software is originally written by 
68
 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69
 *
70
 */
71

    
72
#include <stdio.h>
73
#include <stdlib.h>
74
#ifdef FLAT_INC
75
#include "e_os.h"
76
#else
77
#include "../e_os.h"
78
#endif
79
#include <string.h>
80
#include <time.h>
81

    
82

    
83
#ifdef OPENSSL_NO_EC
84
int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); return 0; }
85
#else
86

    
87

    
88
#include <openssl/ec.h>
89
#ifndef OPENSSL_NO_ENGINE
90
#include <openssl/engine.h>
91
#endif
92
#include <openssl/err.h>
93
#include <openssl/obj_mac.h>
94
#include <openssl/objects.h>
95
#include <openssl/rand.h>
96
#include <openssl/bn.h>
97
#include <openssl/opensslconf.h>
98

    
99
#if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
100
/* suppress "too big too optimize" warning */
101
#pragma warning(disable:4959)
102
#endif
103

    
104
#define ABORT do { \
105
        fflush(stdout); \
106
        fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
107
        ERR_print_errors_fp(stderr); \
108
        EXIT(1); \
109
} while (0)
110

    
111
#define TIMING_BASE_PT 0
112
#define TIMING_RAND_PT 1
113
#define TIMING_SIMUL 2
114

    
115
#if 0
116
static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
117
        {
118
        clock_t clck;
119
        int i, j;
120
        BIGNUM *s;
121
        BIGNUM *r[10], *r0[10];
122
        EC_POINT *P;
123
                
124
        s = BN_new();
125
        if (s == NULL) ABORT;
126

127
        fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
128
        if (!EC_GROUP_get_order(group, s, ctx)) ABORT;
129
        fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
130
        fflush(stdout);
131

132
        P = EC_POINT_new(group);
133
        if (P == NULL) ABORT;
134
        EC_POINT_copy(P, EC_GROUP_get0_generator(group));
135

136
        for (i = 0; i < 10; i++)
137
                {
138
                if ((r[i] = BN_new()) == NULL) ABORT;
139
                if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) ABORT;
140
                if (type != TIMING_BASE_PT)
141
                        {
142
                        if ((r0[i] = BN_new()) == NULL) ABORT;
143
                        if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) ABORT;
144
                        }
145
                }
146

147
        clck = clock();
148
        for (i = 0; i < 10; i++)
149
                {
150
                for (j = 0; j < 10; j++)
151
                        {
152
                        if (!EC_POINT_mul(group, P, (type != TIMING_RAND_PT) ? r[i] : NULL, 
153
                                (type != TIMING_BASE_PT) ? P : NULL, (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) ABORT;
154
                        }
155
                }
156
        clck = clock() - clck;
157

158
        fprintf(stdout, "\n");
159

160
#ifdef CLOCKS_PER_SEC
161
        /* "To determine the time in seconds, the value returned
162
         * by the clock function should be divided by the value
163
         * of the macro CLOCKS_PER_SEC."
164
         *                                       -- ISO/IEC 9899 */
165
#        define UNIT "s"
166
#else
167
        /* "`CLOCKS_PER_SEC' undeclared (first use this function)"
168
         *                            -- cc on NeXTstep/OpenStep */
169
#        define UNIT "units"
170
#        define CLOCKS_PER_SEC 1
171
#endif
172

    
173
        if (type == TIMING_BASE_PT) {
174
                fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
175
                        "base point multiplications", (double)clck/CLOCKS_PER_SEC);
176
        } else if (type == TIMING_RAND_PT) {
177
                fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
178
                        "random point multiplications", (double)clck/CLOCKS_PER_SEC);
179
        } else if (type == TIMING_SIMUL) {
180
                fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
181
                        "s*P+t*Q operations", (double)clck/CLOCKS_PER_SEC);
182
        }
183
        fprintf(stdout, "average: %.4f " UNIT "\n", (double)clck/(CLOCKS_PER_SEC*i*j));
184

    
185
        EC_POINT_free(P);
186
        BN_free(s);
187
        for (i = 0; i < 10; i++)
188
                {
189
                BN_free(r[i]);
190
                if (type != TIMING_BASE_PT) BN_free(r0[i]);
191
                }
192
        }
193
#endif
194

    
195
/* test multiplication with group order, long and negative scalars */
196
static void group_order_tests(EC_GROUP *group)
197
        {
198
        BIGNUM *n1, *n2, *order;
199
        EC_POINT *P = EC_POINT_new(group);
200
        EC_POINT *Q = EC_POINT_new(group);
201
        BN_CTX *ctx = BN_CTX_new();
202
        int i;
203

    
204
        n1 = BN_new(); n2 = BN_new(); order = BN_new();
205
        fprintf(stdout, "verify group order ...");
206
        fflush(stdout);
207
        if (!EC_GROUP_get_order(group, order, ctx)) ABORT;
208
        if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
209
        if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
210
        fprintf(stdout, ".");
211
        fflush(stdout);
212
        if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
213
        if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
214
        if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
215
        fprintf(stdout, " ok\n");
216
        fprintf(stdout, "long/negative scalar tests ");
217
        for (i = 1; i <= 2; i++)
218
                {
219
                const BIGNUM *scalars[6];
220
                const EC_POINT *points[6];
221

    
222
                fprintf(stdout, i == 1 ?
223
                        "allowing precomputation ... " :
224
                        "without precomputation ... ");
225
                if (!BN_set_word(n1, i)) ABORT;
226
                /* If i == 1, P will be the predefined generator for which
227
                 * EC_GROUP_precompute_mult has set up precomputation. */
228
                if (!EC_POINT_mul(group, P, n1, NULL, NULL, ctx)) ABORT;
229

    
230
                if (!BN_one(n1)) ABORT;
231
                /* n1 = 1 - order */
232
                if (!BN_sub(n1, n1, order)) ABORT;
233
                if (!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) ABORT;
234
                if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
235

    
236
                /* n2 = 1 + order */
237
                if (!BN_add(n2, order, BN_value_one())) ABORT;
238
                if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
239
                if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
240

    
241
                /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
242
                if (!BN_mul(n2, n1, n2, ctx)) ABORT;
243
                if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
244
                if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
245

    
246
                /* n2 = order^2 - 1 */
247
                BN_set_negative(n2, 0);
248
                if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
249
                /* Add P to verify the result. */
250
                if (!EC_POINT_add(group, Q, Q, P, ctx)) ABORT;
251
                if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
252

    
253
                /* Exercise EC_POINTs_mul, including corner cases. */
254
                scalars[0] = n1; points[0] = Q; /* => infinity */
255
                scalars[1] = n2; points[1] = P; /* => -P */
256
                scalars[2] = n1; points[2] = Q; /* => infinity */
257
                scalars[3] = n2; points[3] = Q; /* => infinity */
258
                scalars[4] = n1; points[4] = P; /* => P */
259
                scalars[5] = n2; points[5] = Q; /* => infinity */
260
                if (!EC_POINTs_mul(group, Q, NULL, 5, points, scalars, ctx)) ABORT;
261
                if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
262
                }
263
        fprintf(stdout, "ok\n");
264

    
265
        EC_POINT_free(P);
266
        EC_POINT_free(Q);
267
        BN_free(n1);
268
        BN_free(n2);
269
        BN_free(order);
270
        BN_CTX_free(ctx);
271
        }
272

    
273
static void prime_field_tests(void)
274
        {
275
        BN_CTX *ctx = NULL;
276
        BIGNUM *p, *a, *b;
277
        EC_GROUP *group;
278
        EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
279
        EC_POINT *P, *Q, *R;
280
        BIGNUM *x, *y, *z;
281
        unsigned char buf[100];
282
        size_t i, len;
283
        int k;
284
        
285
#if 1 /* optional */
286
        ctx = BN_CTX_new();
287
        if (!ctx) ABORT;
288
#endif
289

    
290
        p = BN_new();
291
        a = BN_new();
292
        b = BN_new();
293
        if (!p || !a || !b) ABORT;
294

    
295
        if (!BN_hex2bn(&p, "17")) ABORT;
296
        if (!BN_hex2bn(&a, "1")) ABORT;
297
        if (!BN_hex2bn(&b, "1")) ABORT;
298
        
299
        group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
300
                                                     * so that the library gets to choose the EC_METHOD */
301
        if (!group) ABORT;
302

    
303
        if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
304

    
305
        {
306
                EC_GROUP *tmp;
307
                tmp = EC_GROUP_new(EC_GROUP_method_of(group));
308
                if (!tmp) ABORT;
309
                if (!EC_GROUP_copy(tmp, group)) ABORT;
310
                EC_GROUP_free(group);
311
                group = tmp;
312
        }
313
        
314
        if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) ABORT;
315

    
316
        fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 = x^3 + a*x + b  (mod 0x");
317
        BN_print_fp(stdout, p);
318
        fprintf(stdout, ")\n     a = 0x");
319
        BN_print_fp(stdout, a);
320
        fprintf(stdout, "\n     b = 0x");
321
        BN_print_fp(stdout, b);
322
        fprintf(stdout, "\n");
323

    
324
        P = EC_POINT_new(group);
325
        Q = EC_POINT_new(group);
326
        R = EC_POINT_new(group);
327
        if (!P || !Q || !R) ABORT;
328
        
329
        if (!EC_POINT_set_to_infinity(group, P)) ABORT;
330
        if (!EC_POINT_is_at_infinity(group, P)) ABORT;
331

    
332
        buf[0] = 0;
333
        if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
334

    
335
        if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
336
        if (!EC_POINT_is_at_infinity(group, P)) ABORT;
337

    
338
        x = BN_new();
339
        y = BN_new();
340
        z = BN_new();
341
        if (!x || !y || !z) ABORT;
342

    
343
        if (!BN_hex2bn(&x, "D")) ABORT;
344
        if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
345
        if (!EC_POINT_is_on_curve(group, Q, ctx))
346
                {
347
                if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
348
                fprintf(stderr, "Point is not on curve: x = 0x");
349
                BN_print_fp(stderr, x);
350
                fprintf(stderr, ", y = 0x");
351
                BN_print_fp(stderr, y);
352
                fprintf(stderr, "\n");
353
                ABORT;
354
                }
355

    
356
        fprintf(stdout, "A cyclic subgroup:\n");
357
        k = 100;
358
        do
359
                {
360
                if (k-- == 0) ABORT;
361

    
362
                if (EC_POINT_is_at_infinity(group, P))
363
                        fprintf(stdout, "     point at infinity\n");
364
                else
365
                        {
366
                        if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
367

    
368
                        fprintf(stdout, "     x = 0x");
369
                        BN_print_fp(stdout, x);
370
                        fprintf(stdout, ", y = 0x");
371
                        BN_print_fp(stdout, y);
372
                        fprintf(stdout, "\n");
373
                        }
374
                
375
                if (!EC_POINT_copy(R, P)) ABORT;
376
                if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
377

    
378
#if 0 /* optional */
379
                {
380
                        EC_POINT *points[3];
381
                
382
                        points[0] = R;
383
                        points[1] = Q;
384
                        points[2] = P;
385
                        if (!EC_POINTs_make_affine(group, 2, points, ctx)) ABORT;
386
                }
387
#endif
388

    
389
                }
390
        while (!EC_POINT_is_at_infinity(group, P));
391

    
392
        if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
393
        if (!EC_POINT_is_at_infinity(group, P)) ABORT;
394

    
395
        len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
396
        if (len == 0) ABORT;
397
        if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
398
        if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
399
        fprintf(stdout, "Generator as octet string, compressed form:\n     ");
400
        for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
401
        
402
        len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
403
        if (len == 0) ABORT;
404
        if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
405
        if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
406
        fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
407
        for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
408
        
409
        len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
410
        if (len == 0) ABORT;
411
        if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
412
        if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
413
        fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
414
        for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
415
        
416
        if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
417
        fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n     X = 0x");
418
        BN_print_fp(stdout, x);
419
        fprintf(stdout, ", Y = 0x");
420
        BN_print_fp(stdout, y);
421
        fprintf(stdout, ", Z = 0x");
422
        BN_print_fp(stdout, z);
423
        fprintf(stdout, "\n");
424

    
425
        if (!EC_POINT_invert(group, P, ctx)) ABORT;
426
        if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
427

    
428

    
429
        /* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000)
430
         * -- not a NIST curve, but commonly used */
431
        
432
        if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) ABORT;
433
        if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
434
        if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) ABORT;
435
        if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) ABORT;
436
        if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
437

    
438
        if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
439
        if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
440
        if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
441
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
442
        if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
443
        if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
444

    
445
        if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
446
        fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n     x = 0x");
447
        BN_print_fp(stdout, x);
448
        fprintf(stdout, "\n     y = 0x");
449
        BN_print_fp(stdout, y);
450
        fprintf(stdout, "\n");
451
        /* G_y value taken from the standard: */
452
        if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
453
        if (0 != BN_cmp(y, z)) ABORT;
454

    
455
        fprintf(stdout, "verify degree ...");
456
        if (EC_GROUP_get_degree(group) != 160) ABORT;
457
        fprintf(stdout, " ok\n");
458
        
459
        group_order_tests(group);
460

    
461
        if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
462
        if (!EC_GROUP_copy(P_160, group)) ABORT;
463

    
464

    
465
        /* Curve P-192 (FIPS PUB 186-2, App. 6) */
466
        
467
        if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) ABORT;
468
        if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
469
        if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) ABORT;
470
        if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) ABORT;
471
        if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
472

    
473
        if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
474
        if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
475
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
476
        if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
477
        if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
478

    
479
        if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
480
        fprintf(stdout, "\nNIST curve P-192 -- Generator:\n     x = 0x");
481
        BN_print_fp(stdout, x);
482
        fprintf(stdout, "\n     y = 0x");
483
        BN_print_fp(stdout, y);
484
        fprintf(stdout, "\n");
485
        /* G_y value taken from the standard: */
486
        if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) ABORT;
487
        if (0 != BN_cmp(y, z)) ABORT;
488

    
489
        fprintf(stdout, "verify degree ...");
490
        if (EC_GROUP_get_degree(group) != 192) ABORT;
491
        fprintf(stdout, " ok\n");
492
        
493
        group_order_tests(group);
494

    
495
        if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
496
        if (!EC_GROUP_copy(P_192, group)) ABORT;
497

    
498

    
499
        /* Curve P-224 (FIPS PUB 186-2, App. 6) */
500
        
501
        if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
502
        if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
503
        if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
504
        if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
505
        if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
506

    
507
        if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
508
        if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
509
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
510
        if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
511
        if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
512

    
513
        if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
514
        fprintf(stdout, "\nNIST curve P-224 -- Generator:\n     x = 0x");
515
        BN_print_fp(stdout, x);
516
        fprintf(stdout, "\n     y = 0x");
517
        BN_print_fp(stdout, y);
518
        fprintf(stdout, "\n");
519
        /* G_y value taken from the standard: */
520
        if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
521
        if (0 != BN_cmp(y, z)) ABORT;
522
        
523
        fprintf(stdout, "verify degree ...");
524
        if (EC_GROUP_get_degree(group) != 224) ABORT;
525
        fprintf(stdout, " ok\n");
526
        
527
        group_order_tests(group);
528

    
529
        if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
530
        if (!EC_GROUP_copy(P_224, group)) ABORT;
531

    
532

    
533
        /* Curve P-256 (FIPS PUB 186-2, App. 6) */
534
        
535
        if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
536
        if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
537
        if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
538
        if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) ABORT;
539
        if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
540

    
541
        if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
542
        if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
543
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
544
        if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
545
                "84F3B9CAC2FC632551")) ABORT;
546
        if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
547

    
548
        if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
549
        fprintf(stdout, "\nNIST curve P-256 -- Generator:\n     x = 0x");
550
        BN_print_fp(stdout, x);
551
        fprintf(stdout, "\n     y = 0x");
552
        BN_print_fp(stdout, y);
553
        fprintf(stdout, "\n");
554
        /* G_y value taken from the standard: */
555
        if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) ABORT;
556
        if (0 != BN_cmp(y, z)) ABORT;
557
        
558
        fprintf(stdout, "verify degree ...");
559
        if (EC_GROUP_get_degree(group) != 256) ABORT;
560
        fprintf(stdout, " ok\n");
561
        
562
        group_order_tests(group);
563

    
564
        if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
565
        if (!EC_GROUP_copy(P_256, group)) ABORT;
566

    
567

    
568
        /* Curve P-384 (FIPS PUB 186-2, App. 6) */
569
        
570
        if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
571
                "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT;
572
        if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
573
        if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
574
                "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT;
575
        if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
576
                "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT;
577
        if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
578

    
579
        if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
580
                "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
581
        if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
582
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
583
        if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
584
                "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
585
        if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
586

    
587
        if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
588
        fprintf(stdout, "\nNIST curve P-384 -- Generator:\n     x = 0x");
589
        BN_print_fp(stdout, x);
590
        fprintf(stdout, "\n     y = 0x");
591
        BN_print_fp(stdout, y);
592
        fprintf(stdout, "\n");
593
        /* G_y value taken from the standard: */
594
        if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
595
                "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT;
596
        if (0 != BN_cmp(y, z)) ABORT;
597
        
598
        fprintf(stdout, "verify degree ...");
599
        if (EC_GROUP_get_degree(group) != 384) ABORT;
600
        fprintf(stdout, " ok\n");
601

    
602
        group_order_tests(group);
603

    
604
        if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
605
        if (!EC_GROUP_copy(P_384, group)) ABORT;
606

    
607

    
608
        /* Curve P-521 (FIPS PUB 186-2, App. 6) */
609
        
610
        if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
611
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
612
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
613
        if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
614
        if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
615
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
616
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
617
        if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
618
                "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
619
                "DF883D2C34F1EF451FD46B503F00")) ABORT;
620
        if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
621

    
622
        if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
623
                "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
624
                "3C1856A429BF97E7E31C2E5BD66")) ABORT;
625
        if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
626
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
627
        if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
628
                "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
629
                "C9B8899C47AEBB6FB71E91386409")) ABORT;
630
        if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
631

    
632
        if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
633
        fprintf(stdout, "\nNIST curve P-521 -- Generator:\n     x = 0x");
634
        BN_print_fp(stdout, x);
635
        fprintf(stdout, "\n     y = 0x");
636
        BN_print_fp(stdout, y);
637
        fprintf(stdout, "\n");
638
        /* G_y value taken from the standard: */
639
        if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
640
                "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
641
                "7086A272C24088BE94769FD16650")) ABORT;
642
        if (0 != BN_cmp(y, z)) ABORT;
643
        
644
        fprintf(stdout, "verify degree ...");
645
        if (EC_GROUP_get_degree(group) != 521) ABORT;
646
        fprintf(stdout, " ok\n");
647

    
648
         group_order_tests(group);
649

    
650
        if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
651
        if (!EC_GROUP_copy(P_521, group)) ABORT;
652

    
653

    
654
        /* more tests using the last curve */
655

    
656
        if (!EC_POINT_copy(Q, P)) ABORT;
657
        if (EC_POINT_is_at_infinity(group, Q)) ABORT;
658
        if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
659
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
660
        if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
661

    
662
        if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
663
        if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
664
        if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
665

    
666
        {
667
                const EC_POINT *points[4];
668
                const BIGNUM *scalars[4];
669
                BIGNUM scalar3;
670
        
671
                if (EC_POINT_is_at_infinity(group, Q)) ABORT;
672
                points[0] = Q;
673
                points[1] = Q;
674
                points[2] = Q;
675
                points[3] = Q;
676

    
677
                if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
678
                if (!BN_add(y, z, BN_value_one())) ABORT;
679
                if (BN_is_odd(y)) ABORT;
680
                if (!BN_rshift1(y, y)) ABORT;
681
                scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
682
                scalars[1] = y;
683

    
684
                fprintf(stdout, "combined multiplication ...");
685
                fflush(stdout);
686

    
687
                /* z is still the group order */
688
                if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
689
                if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
690
                if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
691
                if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
692

    
693
                fprintf(stdout, ".");
694
                fflush(stdout);
695

    
696
                if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
697
                if (!BN_add(z, z, y)) ABORT;
698
                BN_set_negative(z, 1);
699
                scalars[0] = y;
700
                scalars[1] = z; /* z = -(order + y) */
701

    
702
                if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
703
                if (!EC_POINT_is_at_infinity(group, P)) ABORT;
704

    
705
                fprintf(stdout, ".");
706
                fflush(stdout);
707

    
708
                if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
709
                if (!BN_add(z, x, y)) ABORT;
710
                BN_set_negative(z, 1);
711
                scalars[0] = x;
712
                scalars[1] = y;
713
                scalars[2] = z; /* z = -(x+y) */
714

    
715
                BN_init(&scalar3);
716
                BN_zero(&scalar3);
717
                scalars[3] = &scalar3;
718

    
719
                if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) ABORT;
720
                if (!EC_POINT_is_at_infinity(group, P)) ABORT;
721

    
722
                fprintf(stdout, " ok\n\n");
723

    
724
                BN_free(&scalar3);
725
        }
726

    
727

    
728
#if 0
729
        timings(P_160, TIMING_BASE_PT, ctx);
730
        timings(P_160, TIMING_RAND_PT, ctx);
731
        timings(P_160, TIMING_SIMUL, ctx);
732
        timings(P_192, TIMING_BASE_PT, ctx);
733
        timings(P_192, TIMING_RAND_PT, ctx);
734
        timings(P_192, TIMING_SIMUL, ctx);
735
        timings(P_224, TIMING_BASE_PT, ctx);
736
        timings(P_224, TIMING_RAND_PT, ctx);
737
        timings(P_224, TIMING_SIMUL, ctx);
738
        timings(P_256, TIMING_BASE_PT, ctx);
739
        timings(P_256, TIMING_RAND_PT, ctx);
740
        timings(P_256, TIMING_SIMUL, ctx);
741
        timings(P_384, TIMING_BASE_PT, ctx);
742
        timings(P_384, TIMING_RAND_PT, ctx);
743
        timings(P_384, TIMING_SIMUL, ctx);
744
        timings(P_521, TIMING_BASE_PT, ctx);
745
        timings(P_521, TIMING_RAND_PT, ctx);
746
        timings(P_521, TIMING_SIMUL, ctx);
747
#endif
748

    
749

    
750
        if (ctx)
751
                BN_CTX_free(ctx);
752
        BN_free(p); BN_free(a);        BN_free(b);
753
        EC_GROUP_free(group);
754
        EC_POINT_free(P);
755
        EC_POINT_free(Q);
756
        EC_POINT_free(R);
757
        BN_free(x); BN_free(y); BN_free(z);
758

    
759
        if (P_160) EC_GROUP_free(P_160);
760
        if (P_192) EC_GROUP_free(P_192);
761
        if (P_224) EC_GROUP_free(P_224);
762
        if (P_256) EC_GROUP_free(P_256);
763
        if (P_384) EC_GROUP_free(P_384);
764
        if (P_521) EC_GROUP_free(P_521);
765

    
766
        }
767

    
768
/* Change test based on whether binary point compression is enabled or not. */
769
#ifdef OPENSSL_EC_BIN_PT_COMP
770
#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
771
        if (!BN_hex2bn(&x, _x)) ABORT; \
772
        if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
773
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
774
        if (!BN_hex2bn(&z, _order)) ABORT; \
775
        if (!BN_hex2bn(&cof, _cof)) ABORT; \
776
        if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
777
        if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
778
        fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
779
        BN_print_fp(stdout, x); \
780
        fprintf(stdout, "\n     y = 0x"); \
781
        BN_print_fp(stdout, y); \
782
        fprintf(stdout, "\n"); \
783
        /* G_y value taken from the standard: */ \
784
        if (!BN_hex2bn(&z, _y)) ABORT; \
785
        if (0 != BN_cmp(y, z)) ABORT;
786
#else 
787
#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
788
        if (!BN_hex2bn(&x, _x)) ABORT; \
789
        if (!BN_hex2bn(&y, _y)) ABORT; \
790
        if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
791
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
792
        if (!BN_hex2bn(&z, _order)) ABORT; \
793
        if (!BN_hex2bn(&cof, _cof)) ABORT; \
794
        if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
795
        fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
796
        BN_print_fp(stdout, x); \
797
        fprintf(stdout, "\n     y = 0x"); \
798
        BN_print_fp(stdout, y); \
799
        fprintf(stdout, "\n");
800
#endif
801

    
802
#define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
803
        if (!BN_hex2bn(&p, _p)) ABORT; \
804
        if (!BN_hex2bn(&a, _a)) ABORT; \
805
        if (!BN_hex2bn(&b, _b)) ABORT; \
806
        if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \
807
        CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
808
        fprintf(stdout, "verify degree ..."); \
809
        if (EC_GROUP_get_degree(group) != _degree) ABORT; \
810
        fprintf(stdout, " ok\n"); \
811
        group_order_tests(group); \
812
        if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
813
        if (!EC_GROUP_copy(_variable, group)) ABORT; \
814

    
815
#ifndef OPENSSL_NO_EC2M
816

    
817
static void char2_field_tests(void)
818
        {
819
        BN_CTX *ctx = NULL;
820
        BIGNUM *p, *a, *b;
821
        EC_GROUP *group;
822
        EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = NULL, *C2_K571 = NULL;
823
        EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = NULL, *C2_B571 = NULL;
824
        EC_POINT *P, *Q, *R;
825
        BIGNUM *x, *y, *z, *cof;
826
        unsigned char buf[100];
827
        size_t i, len;
828
        int k;
829
        
830
#if 1 /* optional */
831
        ctx = BN_CTX_new();
832
        if (!ctx) ABORT;
833
#endif
834

    
835
        p = BN_new();
836
        a = BN_new();
837
        b = BN_new();
838
        if (!p || !a || !b) ABORT;
839

    
840
        if (!BN_hex2bn(&p, "13")) ABORT;
841
        if (!BN_hex2bn(&a, "3")) ABORT;
842
        if (!BN_hex2bn(&b, "1")) ABORT;
843
        
844
        group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use EC_GROUP_new_curve_GF2m
845
                                                        * so that the library gets to choose the EC_METHOD */
846
        if (!group) ABORT;
847
        if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT;
848

    
849
        {
850
                EC_GROUP *tmp;
851
                tmp = EC_GROUP_new(EC_GROUP_method_of(group));
852
                if (!tmp) ABORT;
853
                if (!EC_GROUP_copy(tmp, group)) ABORT;
854
                EC_GROUP_free(group);
855
                group = tmp;
856
        }
857
        
858
        if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) ABORT;
859

    
860
        fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 + x*y = x^3 + a*x^2 + b  (mod 0x");
861
        BN_print_fp(stdout, p);
862
        fprintf(stdout, ")\n     a = 0x");
863
        BN_print_fp(stdout, a);
864
        fprintf(stdout, "\n     b = 0x");
865
        BN_print_fp(stdout, b);
866
        fprintf(stdout, "\n(0x... means binary polynomial)\n");
867

    
868
        P = EC_POINT_new(group);
869
        Q = EC_POINT_new(group);
870
        R = EC_POINT_new(group);
871
        if (!P || !Q || !R) ABORT;
872
        
873
        if (!EC_POINT_set_to_infinity(group, P)) ABORT;
874
        if (!EC_POINT_is_at_infinity(group, P)) ABORT;
875

    
876
        buf[0] = 0;
877
        if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
878

    
879
        if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
880
        if (!EC_POINT_is_at_infinity(group, P)) ABORT;
881

    
882
        x = BN_new();
883
        y = BN_new();
884
        z = BN_new();
885
        cof = BN_new();
886
        if (!x || !y || !z || !cof) ABORT;
887

    
888
        if (!BN_hex2bn(&x, "6")) ABORT;
889
/* Change test based on whether binary point compression is enabled or not. */
890
#ifdef OPENSSL_EC_BIN_PT_COMP
891
        if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) ABORT;
892
#else
893
        if (!BN_hex2bn(&y, "8")) ABORT;
894
        if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
895
#endif
896
        if (!EC_POINT_is_on_curve(group, Q, ctx))
897
                {
898
/* Change test based on whether binary point compression is enabled or not. */
899
#ifdef OPENSSL_EC_BIN_PT_COMP
900
                if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
901
#endif
902
                fprintf(stderr, "Point is not on curve: x = 0x");
903
                BN_print_fp(stderr, x);
904
                fprintf(stderr, ", y = 0x");
905
                BN_print_fp(stderr, y);
906
                fprintf(stderr, "\n");
907
                ABORT;
908
                }
909

    
910
        fprintf(stdout, "A cyclic subgroup:\n");
911
        k = 100;
912
        do
913
                {
914
                if (k-- == 0) ABORT;
915

    
916
                if (EC_POINT_is_at_infinity(group, P))
917
                        fprintf(stdout, "     point at infinity\n");
918
                else
919
                        {
920
                        if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT;
921

    
922
                        fprintf(stdout, "     x = 0x");
923
                        BN_print_fp(stdout, x);
924
                        fprintf(stdout, ", y = 0x");
925
                        BN_print_fp(stdout, y);
926
                        fprintf(stdout, "\n");
927
                        }
928
                
929
                if (!EC_POINT_copy(R, P)) ABORT;
930
                if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
931
                }
932
        while (!EC_POINT_is_at_infinity(group, P));
933

    
934
        if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
935
        if (!EC_POINT_is_at_infinity(group, P)) ABORT;
936

    
937
/* Change test based on whether binary point compression is enabled or not. */
938
#ifdef OPENSSL_EC_BIN_PT_COMP
939
        len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
940
        if (len == 0) ABORT;
941
        if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
942
        if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
943
        fprintf(stdout, "Generator as octet string, compressed form:\n     ");
944
        for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
945
#endif
946
        
947
        len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
948
        if (len == 0) ABORT;
949
        if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
950
        if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
951
        fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
952
        for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
953
        
954
/* Change test based on whether binary point compression is enabled or not. */
955
#ifdef OPENSSL_EC_BIN_PT_COMP
956
        len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
957
        if (len == 0) ABORT;
958
        if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
959
        if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
960
        fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
961
        for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
962
#endif
963

    
964
        fprintf(stdout, "\n");
965
        
966
        if (!EC_POINT_invert(group, P, ctx)) ABORT;
967
        if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
968

    
969

    
970
        /* Curve K-163 (FIPS PUB 186-2, App. 6) */
971
        CHAR2_CURVE_TEST
972
                (
973
                "NIST curve K-163",
974
                "0800000000000000000000000000000000000000C9",
975
                "1",
976
                "1",
977
                "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
978
                "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
979
                1,
980
                "04000000000000000000020108A2E0CC0D99F8A5EF",
981
                "2",
982
                163,
983
                C2_K163
984
                );
985

    
986
        /* Curve B-163 (FIPS PUB 186-2, App. 6) */
987
        CHAR2_CURVE_TEST
988
                (
989
                "NIST curve B-163",
990
                "0800000000000000000000000000000000000000C9",
991
                "1",
992
                "020A601907B8C953CA1481EB10512F78744A3205FD",
993
                "03F0EBA16286A2D57EA0991168D4994637E8343E36",
994
                "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
995
                1,
996
                "040000000000000000000292FE77E70C12A4234C33",
997
                "2",
998
                163,
999
                C2_B163
1000
                );
1001

    
1002
        /* Curve K-233 (FIPS PUB 186-2, App. 6) */
1003
        CHAR2_CURVE_TEST
1004
                (
1005
                "NIST curve K-233",
1006
                "020000000000000000000000000000000000000004000000000000000001",
1007
                "0",
1008
                "1",
1009
                "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
1010
                "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
1011
                0,
1012
                "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
1013
                "4",
1014
                233,
1015
                C2_K233
1016
                );
1017

    
1018
        /* Curve B-233 (FIPS PUB 186-2, App. 6) */
1019
        CHAR2_CURVE_TEST
1020
                (
1021
                "NIST curve B-233",
1022
                "020000000000000000000000000000000000000004000000000000000001",
1023
                "000000000000000000000000000000000000000000000000000000000001",
1024
                "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
1025
                "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
1026
                "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
1027
                1,
1028
                "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
1029
                "2",
1030
                233,
1031
                C2_B233
1032
                );
1033

    
1034
        /* Curve K-283 (FIPS PUB 186-2, App. 6) */
1035
        CHAR2_CURVE_TEST
1036
                (
1037
                "NIST curve K-283",
1038
                "0800000000000000000000000000000000000000000000000000000000000000000010A1",
1039
                "0",
1040
                "1",
1041
                "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
1042
                "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
1043
                0,
1044
                "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
1045
                "4",
1046
                283,
1047
                C2_K283
1048
                );
1049

    
1050
        /* Curve B-283 (FIPS PUB 186-2, App. 6) */
1051
        CHAR2_CURVE_TEST
1052
                (
1053
                "NIST curve B-283",
1054
                "0800000000000000000000000000000000000000000000000000000000000000000010A1",
1055
                "000000000000000000000000000000000000000000000000000000000000000000000001",
1056
                "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
1057
                "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
1058
                "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
1059
                1,
1060
                "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
1061
                "2",
1062
                283,
1063
                C2_B283
1064
                );
1065

    
1066
        /* Curve K-409 (FIPS PUB 186-2, App. 6) */
1067
        CHAR2_CURVE_TEST
1068
                (
1069
                "NIST curve K-409",
1070
                "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
1071
                "0",
1072
                "1",
1073
                "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
1074
                "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
1075
                1,
1076
                "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
1077
                "4",
1078
                409,
1079
                C2_K409
1080
                );
1081

    
1082
        /* Curve B-409 (FIPS PUB 186-2, App. 6) */
1083
        CHAR2_CURVE_TEST
1084
                (
1085
                "NIST curve B-409",
1086
                "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
1087
                "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
1088
                "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
1089
                "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
1090
                "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
1091
                1,
1092
                "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
1093
                "2",
1094
                409,
1095
                C2_B409
1096
                );
1097

    
1098
        /* Curve K-571 (FIPS PUB 186-2, App. 6) */
1099
        CHAR2_CURVE_TEST
1100
                (
1101
                "NIST curve K-571",
1102
                "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
1103
                "0",
1104
                "1",
1105
                "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
1106
                "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
1107
                0,
1108
                "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
1109
                "4",
1110
                571,
1111
                C2_K571
1112
                );
1113

    
1114
        /* Curve B-571 (FIPS PUB 186-2, App. 6) */
1115
        CHAR2_CURVE_TEST
1116
                (
1117
                "NIST curve B-571",
1118
                "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
1119
                "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
1120
                "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
1121
                "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
1122
                "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
1123
                1,
1124
                "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
1125
                "2",
1126
                571,
1127
                C2_B571
1128
                );
1129

    
1130
        /* more tests using the last curve */
1131

    
1132
        if (!EC_POINT_copy(Q, P)) ABORT;
1133
        if (EC_POINT_is_at_infinity(group, Q)) ABORT;
1134
        if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
1135
        if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
1136
        if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
1137

    
1138
        if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
1139
        if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
1140
        if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
1141

    
1142
        {
1143
                const EC_POINT *points[3];
1144
                const BIGNUM *scalars[3];
1145
        
1146
                if (EC_POINT_is_at_infinity(group, Q)) ABORT;
1147
                points[0] = Q;
1148
                points[1] = Q;
1149
                points[2] = Q;
1150

    
1151
                if (!BN_add(y, z, BN_value_one())) ABORT;
1152
                if (BN_is_odd(y)) ABORT;
1153
                if (!BN_rshift1(y, y)) ABORT;
1154
                scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
1155
                scalars[1] = y;
1156

    
1157
                fprintf(stdout, "combined multiplication ...");
1158
                fflush(stdout);
1159

    
1160
                /* z is still the group order */
1161
                if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
1162
                if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
1163
                if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
1164
                if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
1165

    
1166
                fprintf(stdout, ".");
1167
                fflush(stdout);
1168

    
1169
                if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
1170
                if (!BN_add(z, z, y)) ABORT;
1171
                BN_set_negative(z, 1);
1172
                scalars[0] = y;
1173
                scalars[1] = z; /* z = -(order + y) */
1174

    
1175
                if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
1176
                if (!EC_POINT_is_at_infinity(group, P)) ABORT;
1177

    
1178
                fprintf(stdout, ".");
1179
                fflush(stdout);
1180

    
1181
                if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
1182
                if (!BN_add(z, x, y)) ABORT;
1183
                BN_set_negative(z, 1);
1184
                scalars[0] = x;
1185
                scalars[1] = y;
1186
                scalars[2] = z; /* z = -(x+y) */
1187

    
1188
                if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
1189
                if (!EC_POINT_is_at_infinity(group, P)) ABORT;
1190

    
1191
                fprintf(stdout, " ok\n\n");
1192
        }
1193

    
1194

    
1195
#if 0
1196
        timings(C2_K163, TIMING_BASE_PT, ctx);
1197
        timings(C2_K163, TIMING_RAND_PT, ctx);
1198
        timings(C2_K163, TIMING_SIMUL, ctx);
1199
        timings(C2_B163, TIMING_BASE_PT, ctx);
1200
        timings(C2_B163, TIMING_RAND_PT, ctx);
1201
        timings(C2_B163, TIMING_SIMUL, ctx);
1202
        timings(C2_K233, TIMING_BASE_PT, ctx);
1203
        timings(C2_K233, TIMING_RAND_PT, ctx);
1204
        timings(C2_K233, TIMING_SIMUL, ctx);
1205
        timings(C2_B233, TIMING_BASE_PT, ctx);
1206
        timings(C2_B233, TIMING_RAND_PT, ctx);
1207
        timings(C2_B233, TIMING_SIMUL, ctx);
1208
        timings(C2_K283, TIMING_BASE_PT, ctx);
1209
        timings(C2_K283, TIMING_RAND_PT, ctx);
1210
        timings(C2_K283, TIMING_SIMUL, ctx);
1211
        timings(C2_B283, TIMING_BASE_PT, ctx);
1212
        timings(C2_B283, TIMING_RAND_PT, ctx);
1213
        timings(C2_B283, TIMING_SIMUL, ctx);
1214
        timings(C2_K409, TIMING_BASE_PT, ctx);
1215
        timings(C2_K409, TIMING_RAND_PT, ctx);
1216
        timings(C2_K409, TIMING_SIMUL, ctx);
1217
        timings(C2_B409, TIMING_BASE_PT, ctx);
1218
        timings(C2_B409, TIMING_RAND_PT, ctx);
1219
        timings(C2_B409, TIMING_SIMUL, ctx);
1220
        timings(C2_K571, TIMING_BASE_PT, ctx);
1221
        timings(C2_K571, TIMING_RAND_PT, ctx);
1222
        timings(C2_K571, TIMING_SIMUL, ctx);
1223
        timings(C2_B571, TIMING_BASE_PT, ctx);
1224
        timings(C2_B571, TIMING_RAND_PT, ctx);
1225
        timings(C2_B571, TIMING_SIMUL, ctx);
1226
#endif
1227

    
1228

    
1229
        if (ctx)
1230
                BN_CTX_free(ctx);
1231
        BN_free(p); BN_free(a);        BN_free(b);
1232
        EC_GROUP_free(group);
1233
        EC_POINT_free(P);
1234
        EC_POINT_free(Q);
1235
        EC_POINT_free(R);
1236
        BN_free(x); BN_free(y); BN_free(z); BN_free(cof);
1237

    
1238
        if (C2_K163) EC_GROUP_free(C2_K163);
1239
        if (C2_B163) EC_GROUP_free(C2_B163);
1240
        if (C2_K233) EC_GROUP_free(C2_K233);
1241
        if (C2_B233) EC_GROUP_free(C2_B233);
1242
        if (C2_K283) EC_GROUP_free(C2_K283);
1243
        if (C2_B283) EC_GROUP_free(C2_B283);
1244
        if (C2_K409) EC_GROUP_free(C2_K409);
1245
        if (C2_B409) EC_GROUP_free(C2_B409);
1246
        if (C2_K571) EC_GROUP_free(C2_K571);
1247
        if (C2_B571) EC_GROUP_free(C2_B571);
1248

    
1249
        }
1250
#endif
1251

    
1252
static void internal_curve_test(void)
1253
        {
1254
        EC_builtin_curve *curves = NULL;
1255
        size_t crv_len = 0, n = 0;
1256
        int    ok = 1;
1257

    
1258
        crv_len = EC_get_builtin_curves(NULL, 0);
1259

    
1260
        curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
1261

    
1262
        if (curves == NULL)
1263
                return;
1264

    
1265
        if (!EC_get_builtin_curves(curves, crv_len))
1266
                {
1267
                OPENSSL_free(curves);
1268
                return;
1269
                }
1270

    
1271
        fprintf(stdout, "testing internal curves: ");
1272
                
1273
        for (n = 0; n < crv_len; n++)
1274
                {
1275
                EC_GROUP *group = NULL;
1276
                int nid = curves[n].nid;
1277
                if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
1278
                        {
1279
                        ok = 0;
1280
                        fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with"
1281
                                " curve %s\n", OBJ_nid2sn(nid));
1282
                        /* try next curve */
1283
                        continue;
1284
                        }
1285
                if (!EC_GROUP_check(group, NULL))
1286
                        {
1287
                        ok = 0;
1288
                        fprintf(stdout, "\nEC_GROUP_check() failed with"
1289
                                " curve %s\n", OBJ_nid2sn(nid));
1290
                        EC_GROUP_free(group);
1291
                        /* try the next curve */
1292
                        continue;
1293
                        }
1294
                fprintf(stdout, ".");
1295
                fflush(stdout);
1296
                EC_GROUP_free(group);
1297
                }
1298
        if (ok)
1299
                fprintf(stdout, " ok\n\n");
1300
        else
1301
                {
1302
                fprintf(stdout, " failed\n\n");
1303
                ABORT;
1304
                }
1305
        OPENSSL_free(curves);
1306
        return;
1307
        }
1308

    
1309
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1310
/* nistp_test_params contains magic numbers for testing our optimized
1311
 * implementations of several NIST curves with characteristic > 3. */
1312
struct nistp_test_params
1313
        {
1314
        const EC_METHOD* (*meth) ();
1315
        int degree;
1316
        /* Qx, Qy and D are taken from
1317
         * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1318
         * Otherwise, values are standard curve parameters from FIPS 180-3 */
1319
        const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1320
        };
1321

    
1322
static const struct nistp_test_params nistp_tests_params[] =
1323
        {
1324
                {
1325
                /* P-224 */
1326
                EC_GFp_nistp224_method,
1327
                224,
1328
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* p */
1329
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* a */
1330
                "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* b */
1331
                "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", /* Qx */
1332
                "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", /* Qy */
1333
                "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */
1334
                "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */
1335
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */
1336
                "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", /* d */
1337
                },
1338
                {
1339
                /* P-256 */
1340
                EC_GFp_nistp256_method,
1341
                256,
1342
                "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", /* p */
1343
                "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", /* a */
1344
                "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", /* b */
1345
                "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", /* Qx */
1346
                "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", /* Qy */
1347
                "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", /* Gx */
1348
                "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", /* Gy */
1349
                "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", /* order */
1350
                "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", /* d */
1351
                },
1352
                {
1353
                /* P-521 */
1354
                EC_GFp_nistp521_method,
1355
                521,
1356
                "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", /* p */
1357
                "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", /* a */
1358
                "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", /* b */
1359
                "0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", /* Qx */
1360
                "0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", /* Qy */
1361
                "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", /* Gx */
1362
                "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", /* Gy */
1363
                "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", /* order */
1364
                "0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", /* d */
1365
                },
1366
        };
1367

    
1368
void nistp_single_test(const struct nistp_test_params *test)
1369
        {
1370
        BN_CTX *ctx;
1371
        BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
1372
        EC_GROUP *NISTP;
1373
        EC_POINT *G, *P, *Q, *Q_CHECK;
1374

    
1375
        fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", test->degree);
1376
        ctx = BN_CTX_new();
1377
        p = BN_new();
1378
        a = BN_new();
1379
        b = BN_new();
1380
        x = BN_new(); y = BN_new();
1381
        m = BN_new(); n = BN_new(); order = BN_new();
1382

    
1383
        NISTP = EC_GROUP_new(test->meth());
1384
        if(!NISTP) ABORT;
1385
        if (!BN_hex2bn(&p, test->p)) ABORT;
1386
        if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
1387
        if (!BN_hex2bn(&a, test->a)) ABORT;
1388
        if (!BN_hex2bn(&b, test->b)) ABORT;
1389
        if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) ABORT;
1390
        G = EC_POINT_new(NISTP);
1391
        P = EC_POINT_new(NISTP);
1392
        Q = EC_POINT_new(NISTP);
1393
        Q_CHECK = EC_POINT_new(NISTP);
1394
        if(!BN_hex2bn(&x, test->Qx)) ABORT;
1395
        if(!BN_hex2bn(&y, test->Qy)) ABORT;
1396
        if(!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) ABORT;
1397
        if (!BN_hex2bn(&x, test->Gx)) ABORT;
1398
        if (!BN_hex2bn(&y, test->Gy)) ABORT;
1399
        if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) ABORT;
1400
        if (!BN_hex2bn(&order, test->order)) ABORT;
1401
        if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
1402

    
1403
        fprintf(stdout, "verify degree ... ");
1404
        if (EC_GROUP_get_degree(NISTP) != test->degree) ABORT;
1405
        fprintf(stdout, "ok\n");
1406

    
1407
        fprintf(stdout, "NIST test vectors ... ");
1408
        if (!BN_hex2bn(&n, test->d)) ABORT;
1409
        /* fixed point multiplication */
1410
        EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1411
        if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
1412
        /* random point multiplication */
1413
        EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1414
        if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
1415

    
1416
        /* set generator to P = 2*G, where G is the standard generator */
1417
        if (!EC_POINT_dbl(NISTP, P, G, ctx)) ABORT;
1418
        if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) ABORT;
1419
        /* set the scalar to m=n/2, where n is the NIST test scalar */
1420
        if (!BN_rshift(m, n, 1)) ABORT;
1421

    
1422
        /* test the non-standard generator */
1423
        /* fixed point multiplication */
1424
        EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1425
        if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
1426
        /* random point multiplication */
1427
        EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1428
        if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
1429

    
1430
        /* now repeat all tests with precomputation */
1431
        if (!EC_GROUP_precompute_mult(NISTP, ctx)) ABORT;
1432

    
1433
        /* fixed point multiplication */
1434
        EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1435
        if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
1436
        /* random point multiplication */
1437
        EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1438
        if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
1439

    
1440
        /* reset generator */
1441
        if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
1442
        /* fixed point multiplication */
1443
        EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1444
        if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
1445
        /* random point multiplication */
1446
        EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1447
        if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
1448

    
1449
        fprintf(stdout, "ok\n");
1450
        group_order_tests(NISTP);
1451
#if 0
1452
        timings(NISTP, TIMING_BASE_PT, ctx);
1453
        timings(NISTP, TIMING_RAND_PT, ctx);
1454
#endif
1455
        EC_GROUP_free(NISTP);
1456
        EC_POINT_free(G);
1457
        EC_POINT_free(P);
1458
        EC_POINT_free(Q);
1459
        EC_POINT_free(Q_CHECK);
1460
        BN_free(n);
1461
        BN_free(m);
1462
        BN_free(p);
1463
        BN_free(a);
1464
        BN_free(b);
1465
        BN_free(x);
1466
        BN_free(y);
1467
        BN_free(order);
1468
        BN_CTX_free(ctx);
1469
        }
1470

    
1471
void nistp_tests()
1472
        {
1473
        unsigned i;
1474

    
1475
        for (i = 0; i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); i++)
1476
                {
1477
                nistp_single_test(&nistp_tests_params[i]);
1478
                }
1479
        }
1480
#endif
1481

    
1482
static const char rnd_seed[] = "string to make the random number generator think it has entropy";
1483

    
1484
int main(int argc, char *argv[])
1485
        {        
1486
        
1487
        /* enable memory leak checking unless explicitly disabled */
1488
        if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
1489
                {
1490
                CRYPTO_malloc_debug_init();
1491
                CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
1492
                }
1493
        else
1494
                {
1495
                /* OPENSSL_DEBUG_MEMORY=off */
1496
                CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
1497
                }
1498
        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
1499
        ERR_load_crypto_strings();
1500

    
1501
        RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
1502

    
1503
        prime_field_tests();
1504
        puts("");
1505
#ifndef OPENSSL_NO_EC2M
1506
        char2_field_tests();
1507
#endif
1508
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1509
        nistp_tests();
1510
#endif
1511
        /* test the internal curves */
1512
        internal_curve_test();
1513

    
1514
#ifndef OPENSSL_NO_ENGINE
1515
        ENGINE_cleanup();
1516
#endif
1517
        CRYPTO_cleanup_all_ex_data();
1518
        ERR_free_strings();
1519
        ERR_remove_thread_state(NULL);
1520
        CRYPTO_mem_leaks_fp(stderr);
1521
        
1522
        return 0;
1523
        }
1524
#endif