1109998Smarkm/* crypto/ec/ectest.c */
2160814Ssimon/*
3160814Ssimon * Originally written by Bodo Moeller for the OpenSSL project.
4160814Ssimon */
5109998Smarkm/* ====================================================================
6109998Smarkm * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
7109998Smarkm *
8109998Smarkm * Redistribution and use in source and binary forms, with or without
9109998Smarkm * modification, are permitted provided that the following conditions
10109998Smarkm * are met:
11109998Smarkm *
12109998Smarkm * 1. Redistributions of source code must retain the above copyright
13296465Sdelphij *    notice, this list of conditions and the following disclaimer.
14109998Smarkm *
15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
16109998Smarkm *    notice, this list of conditions and the following disclaimer in
17109998Smarkm *    the documentation and/or other materials provided with the
18109998Smarkm *    distribution.
19109998Smarkm *
20109998Smarkm * 3. All advertising materials mentioning features or use of this
21109998Smarkm *    software must display the following acknowledgment:
22109998Smarkm *    "This product includes software developed by the OpenSSL Project
23109998Smarkm *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24109998Smarkm *
25109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26109998Smarkm *    endorse or promote products derived from this software without
27109998Smarkm *    prior written permission. For written permission, please contact
28109998Smarkm *    openssl-core@openssl.org.
29109998Smarkm *
30109998Smarkm * 5. Products derived from this software may not be called "OpenSSL"
31109998Smarkm *    nor may "OpenSSL" appear in their names without prior written
32109998Smarkm *    permission of the OpenSSL Project.
33109998Smarkm *
34109998Smarkm * 6. Redistributions of any form whatsoever must retain the following
35109998Smarkm *    acknowledgment:
36109998Smarkm *    "This product includes software developed by the OpenSSL Project
37109998Smarkm *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38109998Smarkm *
39109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42109998Smarkm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE.
51109998Smarkm * ====================================================================
52109998Smarkm *
53109998Smarkm * This product includes cryptographic software written by Eric Young
54109998Smarkm * (eay@cryptsoft.com).  This product includes software written by Tim
55109998Smarkm * Hudson (tjh@cryptsoft.com).
56109998Smarkm *
57109998Smarkm */
58160814Ssimon/* ====================================================================
59160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60160814Ssimon *
61296465Sdelphij * Portions of the attached software ("Contribution") are developed by
62160814Ssimon * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63160814Ssimon *
64160814Ssimon * The Contribution is licensed pursuant to the OpenSSL open source
65160814Ssimon * license provided above.
66160814Ssimon *
67296465Sdelphij * The elliptic curve binary polynomial software is originally written by
68160814Ssimon * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69160814Ssimon *
70160814Ssimon */
71109998Smarkm
72109998Smarkm#include <stdio.h>
73109998Smarkm#include <stdlib.h>
74109998Smarkm#ifdef FLAT_INC
75296465Sdelphij# include "e_os.h"
76109998Smarkm#else
77296465Sdelphij# include "../e_os.h"
78109998Smarkm#endif
79109998Smarkm#include <string.h>
80109998Smarkm#include <time.h>
81109998Smarkm
82109998Smarkm#ifdef OPENSSL_NO_EC
83296465Sdelphijint main(int argc, char *argv[])
84296465Sdelphij{
85296465Sdelphij    puts("Elliptic curves are disabled.");
86296465Sdelphij    return 0;
87296465Sdelphij}
88109998Smarkm#else
89109998Smarkm
90296465Sdelphij# include <openssl/ec.h>
91296465Sdelphij# ifndef OPENSSL_NO_ENGINE
92296465Sdelphij#  include <openssl/engine.h>
93296465Sdelphij# endif
94296465Sdelphij# include <openssl/err.h>
95296465Sdelphij# include <openssl/obj_mac.h>
96296465Sdelphij# include <openssl/objects.h>
97296465Sdelphij# include <openssl/rand.h>
98296465Sdelphij# include <openssl/bn.h>
99109998Smarkm
100296465Sdelphij# if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
101160814Ssimon/* suppress "too big too optimize" warning */
102296465Sdelphij#  pragma warning(disable:4959)
103296465Sdelphij# endif
104160814Ssimon
105296465Sdelphij# define ABORT do { \
106296465Sdelphij        fflush(stdout); \
107296465Sdelphij        fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
108296465Sdelphij        ERR_print_errors_fp(stderr); \
109296465Sdelphij        EXIT(1); \
110109998Smarkm} while (0)
111109998Smarkm
112160814Ssimonvoid prime_field_tests(void);
113160814Ssimonvoid char2_field_tests(void);
114160814Ssimonvoid internal_curve_test(void);
115160814Ssimon
116296465Sdelphij# define TIMING_BASE_PT 0
117296465Sdelphij# define TIMING_RAND_PT 1
118296465Sdelphij# define TIMING_SIMUL 2
119160814Ssimon
120296465Sdelphij# if 0
121160814Ssimonstatic void timings(EC_GROUP *group, int type, BN_CTX *ctx)
122296465Sdelphij{
123296465Sdelphij    clock_t clck;
124296465Sdelphij    int i, j;
125296465Sdelphij    BIGNUM *s;
126296465Sdelphij    BIGNUM *r[10], *r0[10];
127296465Sdelphij    EC_POINT *P;
128109998Smarkm
129296465Sdelphij    s = BN_new();
130296465Sdelphij    if (s == NULL)
131296465Sdelphij        ABORT;
132109998Smarkm
133296465Sdelphij    fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
134296465Sdelphij    if (!EC_GROUP_get_order(group, s, ctx))
135296465Sdelphij        ABORT;
136296465Sdelphij    fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
137296465Sdelphij    fflush(stdout);
138109998Smarkm
139296465Sdelphij    P = EC_POINT_new(group);
140296465Sdelphij    if (P == NULL)
141296465Sdelphij        ABORT;
142296465Sdelphij    EC_POINT_copy(P, EC_GROUP_get0_generator(group));
143160814Ssimon
144296465Sdelphij    for (i = 0; i < 10; i++) {
145296465Sdelphij        if ((r[i] = BN_new()) == NULL)
146296465Sdelphij            ABORT;
147296465Sdelphij        if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0))
148296465Sdelphij            ABORT;
149296465Sdelphij        if (type != TIMING_BASE_PT) {
150296465Sdelphij            if ((r0[i] = BN_new()) == NULL)
151296465Sdelphij                ABORT;
152296465Sdelphij            if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0))
153296465Sdelphij                ABORT;
154296465Sdelphij        }
155296465Sdelphij    }
156109998Smarkm
157296465Sdelphij    clck = clock();
158296465Sdelphij    for (i = 0; i < 10; i++) {
159296465Sdelphij        for (j = 0; j < 10; j++) {
160296465Sdelphij            if (!EC_POINT_mul
161296465Sdelphij                (group, P, (type != TIMING_RAND_PT) ? r[i] : NULL,
162296465Sdelphij                 (type != TIMING_BASE_PT) ? P : NULL,
163296465Sdelphij                 (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx))
164296465Sdelphij                ABORT;
165296465Sdelphij        }
166296465Sdelphij    }
167296465Sdelphij    clck = clock() - clck;
168160814Ssimon
169296465Sdelphij    fprintf(stdout, "\n");
170109998Smarkm
171296465Sdelphij#  ifdef CLOCKS_PER_SEC
172296465Sdelphij    /*
173296465Sdelphij     * "To determine the time in seconds, the value returned by the clock
174296465Sdelphij     * function should be divided by the value of the macro CLOCKS_PER_SEC."
175296465Sdelphij     * -- ISO/IEC 9899
176296465Sdelphij     */
177296465Sdelphij#   define UNIT "s"
178296465Sdelphij#  else
179296465Sdelphij    /*
180296465Sdelphij     * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on
181296465Sdelphij     * NeXTstep/OpenStep
182296465Sdelphij     */
183296465Sdelphij#   define UNIT "units"
184296465Sdelphij#   define CLOCKS_PER_SEC 1
185296465Sdelphij#  endif
186109998Smarkm
187296465Sdelphij    if (type == TIMING_BASE_PT) {
188296465Sdelphij        fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j,
189296465Sdelphij                "base point multiplications", (double)clck / CLOCKS_PER_SEC);
190296465Sdelphij    } else if (type == TIMING_RAND_PT) {
191296465Sdelphij        fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j,
192296465Sdelphij                "random point multiplications",
193296465Sdelphij                (double)clck / CLOCKS_PER_SEC);
194296465Sdelphij    } else if (type == TIMING_SIMUL) {
195296465Sdelphij        fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j,
196296465Sdelphij                "s*P+t*Q operations", (double)clck / CLOCKS_PER_SEC);
197296465Sdelphij    }
198296465Sdelphij    fprintf(stdout, "average: %.4f " UNIT "\n",
199296465Sdelphij            (double)clck / (CLOCKS_PER_SEC * i * j));
200109998Smarkm
201296465Sdelphij    EC_POINT_free(P);
202296465Sdelphij    BN_free(s);
203296465Sdelphij    for (i = 0; i < 10; i++) {
204296465Sdelphij        BN_free(r[i]);
205296465Sdelphij        if (type != TIMING_BASE_PT)
206296465Sdelphij            BN_free(r0[i]);
207296465Sdelphij    }
208296465Sdelphij}
209296465Sdelphij# endif
210296465Sdelphij
211160814Ssimonvoid prime_field_tests()
212296465Sdelphij{
213296465Sdelphij    BN_CTX *ctx = NULL;
214296465Sdelphij    BIGNUM *p, *a, *b;
215296465Sdelphij    EC_GROUP *group;
216296465Sdelphij    EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 =
217296465Sdelphij        NULL, *P_384 = NULL, *P_521 = NULL;
218296465Sdelphij    EC_POINT *P, *Q, *R;
219296465Sdelphij    BIGNUM *x, *y, *z;
220296465Sdelphij    unsigned char buf[100];
221296465Sdelphij    size_t i, len;
222296465Sdelphij    int k;
223109998Smarkm
224296465Sdelphij# if 1                          /* optional */
225296465Sdelphij    ctx = BN_CTX_new();
226296465Sdelphij    if (!ctx)
227296465Sdelphij        ABORT;
228296465Sdelphij# endif
229109998Smarkm
230296465Sdelphij    p = BN_new();
231296465Sdelphij    a = BN_new();
232296465Sdelphij    b = BN_new();
233296465Sdelphij    if (!p || !a || !b)
234296465Sdelphij        ABORT;
235109998Smarkm
236296465Sdelphij    if (!BN_hex2bn(&p, "17"))
237296465Sdelphij        ABORT;
238296465Sdelphij    if (!BN_hex2bn(&a, "1"))
239296465Sdelphij        ABORT;
240296465Sdelphij    if (!BN_hex2bn(&b, "1"))
241296465Sdelphij        ABORT;
242109998Smarkm
243296465Sdelphij    group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use
244296465Sdelphij                                                 * EC_GROUP_new_curve_GFp so
245296465Sdelphij                                                 * that the library gets to
246296465Sdelphij                                                 * choose the EC_METHOD */
247296465Sdelphij    if (!group)
248296465Sdelphij        ABORT;
249109998Smarkm
250296465Sdelphij    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
251296465Sdelphij        ABORT;
252109998Smarkm
253296465Sdelphij    {
254296465Sdelphij        EC_GROUP *tmp;
255296465Sdelphij        tmp = EC_GROUP_new(EC_GROUP_method_of(group));
256296465Sdelphij        if (!tmp)
257296465Sdelphij            ABORT;
258296465Sdelphij        if (!EC_GROUP_copy(tmp, group))
259296465Sdelphij            ABORT;
260296465Sdelphij        EC_GROUP_free(group);
261296465Sdelphij        group = tmp;
262296465Sdelphij    }
263109998Smarkm
264296465Sdelphij    if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx))
265296465Sdelphij        ABORT;
266109998Smarkm
267296465Sdelphij    fprintf(stdout,
268296465Sdelphij            "Curve defined by Weierstrass equation\n     y^2 = x^3 + a*x + b  (mod 0x");
269296465Sdelphij    BN_print_fp(stdout, p);
270296465Sdelphij    fprintf(stdout, ")\n     a = 0x");
271296465Sdelphij    BN_print_fp(stdout, a);
272296465Sdelphij    fprintf(stdout, "\n     b = 0x");
273296465Sdelphij    BN_print_fp(stdout, b);
274296465Sdelphij    fprintf(stdout, "\n");
275109998Smarkm
276296465Sdelphij    P = EC_POINT_new(group);
277296465Sdelphij    Q = EC_POINT_new(group);
278296465Sdelphij    R = EC_POINT_new(group);
279296465Sdelphij    if (!P || !Q || !R)
280296465Sdelphij        ABORT;
281109998Smarkm
282296465Sdelphij    if (!EC_POINT_set_to_infinity(group, P))
283296465Sdelphij        ABORT;
284296465Sdelphij    if (!EC_POINT_is_at_infinity(group, P))
285296465Sdelphij        ABORT;
286109998Smarkm
287296465Sdelphij    buf[0] = 0;
288296465Sdelphij    if (!EC_POINT_oct2point(group, Q, buf, 1, ctx))
289296465Sdelphij        ABORT;
290109998Smarkm
291296465Sdelphij    if (!EC_POINT_add(group, P, P, Q, ctx))
292296465Sdelphij        ABORT;
293296465Sdelphij    if (!EC_POINT_is_at_infinity(group, P))
294296465Sdelphij        ABORT;
295109998Smarkm
296296465Sdelphij    x = BN_new();
297296465Sdelphij    y = BN_new();
298296465Sdelphij    z = BN_new();
299296465Sdelphij    if (!x || !y || !z)
300296465Sdelphij        ABORT;
301109998Smarkm
302296465Sdelphij    if (!BN_hex2bn(&x, "D"))
303296465Sdelphij        ABORT;
304296465Sdelphij    if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx))
305296465Sdelphij        ABORT;
306296465Sdelphij    if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) {
307296465Sdelphij        if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx))
308296465Sdelphij            ABORT;
309296465Sdelphij        fprintf(stderr, "Point is not on curve: x = 0x");
310296465Sdelphij        BN_print_fp(stderr, x);
311296465Sdelphij        fprintf(stderr, ", y = 0x");
312296465Sdelphij        BN_print_fp(stderr, y);
313296465Sdelphij        fprintf(stderr, "\n");
314296465Sdelphij        ABORT;
315296465Sdelphij    }
316109998Smarkm
317296465Sdelphij    fprintf(stdout, "A cyclic subgroup:\n");
318296465Sdelphij    k = 100;
319296465Sdelphij    do {
320296465Sdelphij        if (k-- == 0)
321296465Sdelphij            ABORT;
322109998Smarkm
323296465Sdelphij        if (EC_POINT_is_at_infinity(group, P))
324296465Sdelphij            fprintf(stdout, "     point at infinity\n");
325296465Sdelphij        else {
326296465Sdelphij            if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
327296465Sdelphij                ABORT;
328109998Smarkm
329296465Sdelphij            fprintf(stdout, "     x = 0x");
330296465Sdelphij            BN_print_fp(stdout, x);
331296465Sdelphij            fprintf(stdout, ", y = 0x");
332296465Sdelphij            BN_print_fp(stdout, y);
333296465Sdelphij            fprintf(stdout, "\n");
334296465Sdelphij        }
335109998Smarkm
336296465Sdelphij        if (!EC_POINT_copy(R, P))
337296465Sdelphij            ABORT;
338296465Sdelphij        if (!EC_POINT_add(group, P, P, Q, ctx))
339296465Sdelphij            ABORT;
340109998Smarkm
341296465Sdelphij# if 0                          /* optional */
342296465Sdelphij        {
343296465Sdelphij            EC_POINT *points[3];
344109998Smarkm
345296465Sdelphij            points[0] = R;
346296465Sdelphij            points[1] = Q;
347296465Sdelphij            points[2] = P;
348296465Sdelphij            if (!EC_POINTs_make_affine(group, 2, points, ctx))
349296465Sdelphij                ABORT;
350296465Sdelphij        }
351296465Sdelphij# endif
352160814Ssimon
353296465Sdelphij    }
354296465Sdelphij    while (!EC_POINT_is_at_infinity(group, P));
355160814Ssimon
356296465Sdelphij    if (!EC_POINT_add(group, P, Q, R, ctx))
357296465Sdelphij        ABORT;
358296465Sdelphij    if (!EC_POINT_is_at_infinity(group, P))
359296465Sdelphij        ABORT;
360160814Ssimon
361296465Sdelphij    len =
362296465Sdelphij        EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
363296465Sdelphij                           sizeof buf, ctx);
364296465Sdelphij    if (len == 0)
365296465Sdelphij        ABORT;
366296465Sdelphij    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
367296465Sdelphij        ABORT;
368296465Sdelphij    if (0 != EC_POINT_cmp(group, P, Q, ctx))
369296465Sdelphij        ABORT;
370296465Sdelphij    fprintf(stdout, "Generator as octect string, compressed form:\n     ");
371296465Sdelphij    for (i = 0; i < len; i++)
372296465Sdelphij        fprintf(stdout, "%02X", buf[i]);
373160814Ssimon
374296465Sdelphij    len =
375296465Sdelphij        EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf,
376296465Sdelphij                           sizeof buf, ctx);
377296465Sdelphij    if (len == 0)
378296465Sdelphij        ABORT;
379296465Sdelphij    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
380296465Sdelphij        ABORT;
381296465Sdelphij    if (0 != EC_POINT_cmp(group, P, Q, ctx))
382296465Sdelphij        ABORT;
383296465Sdelphij    fprintf(stdout,
384296465Sdelphij            "\nGenerator as octect string, uncompressed form:\n     ");
385296465Sdelphij    for (i = 0; i < len; i++)
386296465Sdelphij        fprintf(stdout, "%02X", buf[i]);
387160814Ssimon
388296465Sdelphij    len =
389296465Sdelphij        EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf,
390296465Sdelphij                           ctx);
391296465Sdelphij    if (len == 0)
392296465Sdelphij        ABORT;
393296465Sdelphij    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
394296465Sdelphij        ABORT;
395296465Sdelphij    if (0 != EC_POINT_cmp(group, P, Q, ctx))
396296465Sdelphij        ABORT;
397296465Sdelphij    fprintf(stdout, "\nGenerator as octect string, hybrid form:\n     ");
398296465Sdelphij    for (i = 0; i < len; i++)
399296465Sdelphij        fprintf(stdout, "%02X", buf[i]);
400160814Ssimon
401296465Sdelphij    if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx))
402296465Sdelphij        ABORT;
403296465Sdelphij    fprintf(stdout,
404296465Sdelphij            "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n     X = 0x");
405296465Sdelphij    BN_print_fp(stdout, x);
406296465Sdelphij    fprintf(stdout, ", Y = 0x");
407296465Sdelphij    BN_print_fp(stdout, y);
408296465Sdelphij    fprintf(stdout, ", Z = 0x");
409296465Sdelphij    BN_print_fp(stdout, z);
410296465Sdelphij    fprintf(stdout, "\n");
411109998Smarkm
412296465Sdelphij    if (!EC_POINT_invert(group, P, ctx))
413296465Sdelphij        ABORT;
414296465Sdelphij    if (0 != EC_POINT_cmp(group, P, R, ctx))
415296465Sdelphij        ABORT;
416109998Smarkm
417296465Sdelphij    /*
418296465Sdelphij     * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
419296465Sdelphij     * 2000) -- not a NIST curve, but commonly used
420296465Sdelphij     */
421160814Ssimon
422296465Sdelphij    if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
423296465Sdelphij        ABORT;
424296465Sdelphij    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
425296465Sdelphij        ABORT;
426296465Sdelphij    if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
427296465Sdelphij        ABORT;
428296465Sdelphij    if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"))
429296465Sdelphij        ABORT;
430296465Sdelphij    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
431296465Sdelphij        ABORT;
432109998Smarkm
433296465Sdelphij    if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82"))
434296465Sdelphij        ABORT;
435296465Sdelphij    if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32"))
436296465Sdelphij        ABORT;
437296465Sdelphij    if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
438296465Sdelphij        ABORT;
439296465Sdelphij    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
440296465Sdelphij        ABORT;
441296465Sdelphij    if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257"))
442296465Sdelphij        ABORT;
443296465Sdelphij    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
444296465Sdelphij        ABORT;
445109998Smarkm
446296465Sdelphij    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
447296465Sdelphij        ABORT;
448296465Sdelphij    fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n     x = 0x");
449296465Sdelphij    BN_print_fp(stdout, x);
450296465Sdelphij    fprintf(stdout, "\n     y = 0x");
451296465Sdelphij    BN_print_fp(stdout, y);
452296465Sdelphij    fprintf(stdout, "\n");
453296465Sdelphij    /* G_y value taken from the standard: */
454296465Sdelphij    if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32"))
455296465Sdelphij        ABORT;
456296465Sdelphij    if (0 != BN_cmp(y, z))
457296465Sdelphij        ABORT;
458109998Smarkm
459296465Sdelphij    fprintf(stdout, "verify degree ...");
460296465Sdelphij    if (EC_GROUP_get_degree(group) != 160)
461296465Sdelphij        ABORT;
462296465Sdelphij    fprintf(stdout, " ok\n");
463109998Smarkm
464296465Sdelphij    fprintf(stdout, "verify group order ...");
465296465Sdelphij    fflush(stdout);
466296465Sdelphij    if (!EC_GROUP_get_order(group, z, ctx))
467296465Sdelphij        ABORT;
468296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
469296465Sdelphij        ABORT;
470296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
471296465Sdelphij        ABORT;
472296465Sdelphij    fprintf(stdout, ".");
473296465Sdelphij    fflush(stdout);
474296465Sdelphij    if (!EC_GROUP_precompute_mult(group, ctx))
475296465Sdelphij        ABORT;
476296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
477296465Sdelphij        ABORT;
478296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
479296465Sdelphij        ABORT;
480296465Sdelphij    fprintf(stdout, " ok\n");
481109998Smarkm
482296465Sdelphij    if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group))))
483296465Sdelphij        ABORT;
484296465Sdelphij    if (!EC_GROUP_copy(P_160, group))
485296465Sdelphij        ABORT;
486109998Smarkm
487296465Sdelphij    /* Curve P-192 (FIPS PUB 186-2, App. 6) */
488109998Smarkm
489296465Sdelphij    if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
490296465Sdelphij        ABORT;
491296465Sdelphij    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
492296465Sdelphij        ABORT;
493296465Sdelphij    if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
494296465Sdelphij        ABORT;
495296465Sdelphij    if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"))
496296465Sdelphij        ABORT;
497296465Sdelphij    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
498296465Sdelphij        ABORT;
499109998Smarkm
500296465Sdelphij    if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"))
501296465Sdelphij        ABORT;
502296465Sdelphij    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx))
503296465Sdelphij        ABORT;
504296465Sdelphij    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
505296465Sdelphij        ABORT;
506296465Sdelphij    if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"))
507296465Sdelphij        ABORT;
508296465Sdelphij    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
509296465Sdelphij        ABORT;
510109998Smarkm
511296465Sdelphij    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
512296465Sdelphij        ABORT;
513296465Sdelphij    fprintf(stdout, "\nNIST curve P-192 -- Generator:\n     x = 0x");
514296465Sdelphij    BN_print_fp(stdout, x);
515296465Sdelphij    fprintf(stdout, "\n     y = 0x");
516296465Sdelphij    BN_print_fp(stdout, y);
517296465Sdelphij    fprintf(stdout, "\n");
518296465Sdelphij    /* G_y value taken from the standard: */
519296465Sdelphij    if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"))
520296465Sdelphij        ABORT;
521296465Sdelphij    if (0 != BN_cmp(y, z))
522296465Sdelphij        ABORT;
523109998Smarkm
524296465Sdelphij    fprintf(stdout, "verify degree ...");
525296465Sdelphij    if (EC_GROUP_get_degree(group) != 192)
526296465Sdelphij        ABORT;
527296465Sdelphij    fprintf(stdout, " ok\n");
528109998Smarkm
529296465Sdelphij    fprintf(stdout, "verify group order ...");
530296465Sdelphij    fflush(stdout);
531296465Sdelphij    if (!EC_GROUP_get_order(group, z, ctx))
532296465Sdelphij        ABORT;
533296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
534296465Sdelphij        ABORT;
535296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
536296465Sdelphij        ABORT;
537296465Sdelphij    fprintf(stdout, ".");
538296465Sdelphij    fflush(stdout);
539296465Sdelphij# if 0
540296465Sdelphij    if (!EC_GROUP_precompute_mult(group, ctx))
541296465Sdelphij        ABORT;
542296465Sdelphij# endif
543296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
544296465Sdelphij        ABORT;
545296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
546296465Sdelphij        ABORT;
547296465Sdelphij    fprintf(stdout, " ok\n");
548109998Smarkm
549296465Sdelphij    if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group))))
550296465Sdelphij        ABORT;
551296465Sdelphij    if (!EC_GROUP_copy(P_192, group))
552296465Sdelphij        ABORT;
553109998Smarkm
554296465Sdelphij    /* Curve P-224 (FIPS PUB 186-2, App. 6) */
555109998Smarkm
556296465Sdelphij    if (!BN_hex2bn
557296465Sdelphij        (&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"))
558296465Sdelphij        ABORT;
559296465Sdelphij    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
560296465Sdelphij        ABORT;
561296465Sdelphij    if (!BN_hex2bn
562296465Sdelphij        (&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
563296465Sdelphij        ABORT;
564296465Sdelphij    if (!BN_hex2bn
565296465Sdelphij        (&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"))
566296465Sdelphij        ABORT;
567296465Sdelphij    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
568296465Sdelphij        ABORT;
569109998Smarkm
570296465Sdelphij    if (!BN_hex2bn
571296465Sdelphij        (&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"))
572296465Sdelphij        ABORT;
573296465Sdelphij    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx))
574296465Sdelphij        ABORT;
575296465Sdelphij    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
576296465Sdelphij        ABORT;
577296465Sdelphij    if (!BN_hex2bn
578296465Sdelphij        (&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"))
579296465Sdelphij        ABORT;
580296465Sdelphij    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
581296465Sdelphij        ABORT;
582109998Smarkm
583296465Sdelphij    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
584296465Sdelphij        ABORT;
585296465Sdelphij    fprintf(stdout, "\nNIST curve P-224 -- Generator:\n     x = 0x");
586296465Sdelphij    BN_print_fp(stdout, x);
587296465Sdelphij    fprintf(stdout, "\n     y = 0x");
588296465Sdelphij    BN_print_fp(stdout, y);
589296465Sdelphij    fprintf(stdout, "\n");
590296465Sdelphij    /* G_y value taken from the standard: */
591296465Sdelphij    if (!BN_hex2bn
592296465Sdelphij        (&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"))
593296465Sdelphij        ABORT;
594296465Sdelphij    if (0 != BN_cmp(y, z))
595296465Sdelphij        ABORT;
596109998Smarkm
597296465Sdelphij    fprintf(stdout, "verify degree ...");
598296465Sdelphij    if (EC_GROUP_get_degree(group) != 224)
599296465Sdelphij        ABORT;
600296465Sdelphij    fprintf(stdout, " ok\n");
601109998Smarkm
602296465Sdelphij    fprintf(stdout, "verify group order ...");
603296465Sdelphij    fflush(stdout);
604296465Sdelphij    if (!EC_GROUP_get_order(group, z, ctx))
605296465Sdelphij        ABORT;
606296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
607296465Sdelphij        ABORT;
608296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
609296465Sdelphij        ABORT;
610296465Sdelphij    fprintf(stdout, ".");
611296465Sdelphij    fflush(stdout);
612296465Sdelphij# if 0
613296465Sdelphij    if (!EC_GROUP_precompute_mult(group, ctx))
614296465Sdelphij        ABORT;
615296465Sdelphij# endif
616296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
617296465Sdelphij        ABORT;
618296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
619296465Sdelphij        ABORT;
620296465Sdelphij    fprintf(stdout, " ok\n");
621109998Smarkm
622296465Sdelphij    if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group))))
623296465Sdelphij        ABORT;
624296465Sdelphij    if (!EC_GROUP_copy(P_224, group))
625296465Sdelphij        ABORT;
626109998Smarkm
627296465Sdelphij    /* Curve P-256 (FIPS PUB 186-2, App. 6) */
628109998Smarkm
629296465Sdelphij    if (!BN_hex2bn
630296465Sdelphij        (&p,
631296465Sdelphij         "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"))
632296465Sdelphij        ABORT;
633296465Sdelphij    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
634296465Sdelphij        ABORT;
635296465Sdelphij    if (!BN_hex2bn
636296465Sdelphij        (&a,
637296465Sdelphij         "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"))
638296465Sdelphij        ABORT;
639296465Sdelphij    if (!BN_hex2bn
640296465Sdelphij        (&b,
641296465Sdelphij         "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"))
642296465Sdelphij        ABORT;
643296465Sdelphij    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
644296465Sdelphij        ABORT;
645109998Smarkm
646296465Sdelphij    if (!BN_hex2bn
647296465Sdelphij        (&x,
648296465Sdelphij         "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"))
649296465Sdelphij        ABORT;
650296465Sdelphij    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx))
651296465Sdelphij        ABORT;
652296465Sdelphij    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
653296465Sdelphij        ABORT;
654296465Sdelphij    if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
655296465Sdelphij                   "84F3B9CAC2FC632551"))
656296465Sdelphij        ABORT;
657296465Sdelphij    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
658296465Sdelphij        ABORT;
659109998Smarkm
660296465Sdelphij    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
661296465Sdelphij        ABORT;
662296465Sdelphij    fprintf(stdout, "\nNIST curve P-256 -- Generator:\n     x = 0x");
663296465Sdelphij    BN_print_fp(stdout, x);
664296465Sdelphij    fprintf(stdout, "\n     y = 0x");
665296465Sdelphij    BN_print_fp(stdout, y);
666296465Sdelphij    fprintf(stdout, "\n");
667296465Sdelphij    /* G_y value taken from the standard: */
668296465Sdelphij    if (!BN_hex2bn
669296465Sdelphij        (&z,
670296465Sdelphij         "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"))
671296465Sdelphij        ABORT;
672296465Sdelphij    if (0 != BN_cmp(y, z))
673296465Sdelphij        ABORT;
674109998Smarkm
675296465Sdelphij    fprintf(stdout, "verify degree ...");
676296465Sdelphij    if (EC_GROUP_get_degree(group) != 256)
677296465Sdelphij        ABORT;
678296465Sdelphij    fprintf(stdout, " ok\n");
679109998Smarkm
680296465Sdelphij    fprintf(stdout, "verify group order ...");
681296465Sdelphij    fflush(stdout);
682296465Sdelphij    if (!EC_GROUP_get_order(group, z, ctx))
683296465Sdelphij        ABORT;
684296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
685296465Sdelphij        ABORT;
686296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
687296465Sdelphij        ABORT;
688296465Sdelphij    fprintf(stdout, ".");
689296465Sdelphij    fflush(stdout);
690296465Sdelphij# if 0
691296465Sdelphij    if (!EC_GROUP_precompute_mult(group, ctx))
692296465Sdelphij        ABORT;
693296465Sdelphij# endif
694296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
695296465Sdelphij        ABORT;
696296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
697296465Sdelphij        ABORT;
698296465Sdelphij    fprintf(stdout, " ok\n");
699109998Smarkm
700296465Sdelphij    if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group))))
701296465Sdelphij        ABORT;
702296465Sdelphij    if (!EC_GROUP_copy(P_256, group))
703296465Sdelphij        ABORT;
704109998Smarkm
705296465Sdelphij    /* Curve P-384 (FIPS PUB 186-2, App. 6) */
706109998Smarkm
707296465Sdelphij    if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
708296465Sdelphij                   "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"))
709296465Sdelphij        ABORT;
710296465Sdelphij    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
711296465Sdelphij        ABORT;
712296465Sdelphij    if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
713296465Sdelphij                   "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC"))
714296465Sdelphij        ABORT;
715296465Sdelphij    if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
716296465Sdelphij                   "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"))
717296465Sdelphij        ABORT;
718296465Sdelphij    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
719296465Sdelphij        ABORT;
720109998Smarkm
721296465Sdelphij    if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
722296465Sdelphij                   "9859F741E082542A385502F25DBF55296C3A545E3872760AB7"))
723296465Sdelphij        ABORT;
724296465Sdelphij    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx))
725296465Sdelphij        ABORT;
726296465Sdelphij    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
727296465Sdelphij        ABORT;
728296465Sdelphij    if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
729296465Sdelphij                   "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"))
730296465Sdelphij        ABORT;
731296465Sdelphij    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
732296465Sdelphij        ABORT;
733109998Smarkm
734296465Sdelphij    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
735296465Sdelphij        ABORT;
736296465Sdelphij    fprintf(stdout, "\nNIST curve P-384 -- Generator:\n     x = 0x");
737296465Sdelphij    BN_print_fp(stdout, x);
738296465Sdelphij    fprintf(stdout, "\n     y = 0x");
739296465Sdelphij    BN_print_fp(stdout, y);
740296465Sdelphij    fprintf(stdout, "\n");
741296465Sdelphij    /* G_y value taken from the standard: */
742296465Sdelphij    if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
743296465Sdelphij                   "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"))
744296465Sdelphij        ABORT;
745296465Sdelphij    if (0 != BN_cmp(y, z))
746296465Sdelphij        ABORT;
747109998Smarkm
748296465Sdelphij    fprintf(stdout, "verify degree ...");
749296465Sdelphij    if (EC_GROUP_get_degree(group) != 384)
750296465Sdelphij        ABORT;
751296465Sdelphij    fprintf(stdout, " ok\n");
752109998Smarkm
753296465Sdelphij    fprintf(stdout, "verify group order ...");
754296465Sdelphij    fflush(stdout);
755296465Sdelphij    if (!EC_GROUP_get_order(group, z, ctx))
756296465Sdelphij        ABORT;
757296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
758296465Sdelphij        ABORT;
759296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
760296465Sdelphij        ABORT;
761296465Sdelphij    fprintf(stdout, ".");
762296465Sdelphij    fflush(stdout);
763296465Sdelphij# if 0
764296465Sdelphij    if (!EC_GROUP_precompute_mult(group, ctx))
765296465Sdelphij        ABORT;
766296465Sdelphij# endif
767296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
768296465Sdelphij        ABORT;
769296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
770296465Sdelphij        ABORT;
771296465Sdelphij    fprintf(stdout, " ok\n");
772109998Smarkm
773296465Sdelphij    if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group))))
774296465Sdelphij        ABORT;
775296465Sdelphij    if (!EC_GROUP_copy(P_384, group))
776296465Sdelphij        ABORT;
777109998Smarkm
778296465Sdelphij    /* Curve P-521 (FIPS PUB 186-2, App. 6) */
779109998Smarkm
780296465Sdelphij    if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
781296465Sdelphij                   "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
782296465Sdelphij                   "FFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
783296465Sdelphij        ABORT;
784296465Sdelphij    if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
785296465Sdelphij        ABORT;
786296465Sdelphij    if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
787296465Sdelphij                   "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
788296465Sdelphij                   "FFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
789296465Sdelphij        ABORT;
790296465Sdelphij    if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
791296465Sdelphij                   "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
792296465Sdelphij                   "DF883D2C34F1EF451FD46B503F00"))
793296465Sdelphij        ABORT;
794296465Sdelphij    if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
795296465Sdelphij        ABORT;
796194206Ssimon
797296465Sdelphij    if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
798296465Sdelphij                   "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
799296465Sdelphij                   "3C1856A429BF97E7E31C2E5BD66"))
800296465Sdelphij        ABORT;
801296465Sdelphij    if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx))
802296465Sdelphij        ABORT;
803296465Sdelphij    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
804296465Sdelphij        ABORT;
805296465Sdelphij    if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
806296465Sdelphij                   "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
807296465Sdelphij                   "C9B8899C47AEBB6FB71E91386409"))
808296465Sdelphij        ABORT;
809296465Sdelphij    if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
810296465Sdelphij        ABORT;
811109998Smarkm
812296465Sdelphij    if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
813296465Sdelphij        ABORT;
814296465Sdelphij    fprintf(stdout, "\nNIST curve P-521 -- Generator:\n     x = 0x");
815296465Sdelphij    BN_print_fp(stdout, x);
816296465Sdelphij    fprintf(stdout, "\n     y = 0x");
817296465Sdelphij    BN_print_fp(stdout, y);
818296465Sdelphij    fprintf(stdout, "\n");
819296465Sdelphij    /* G_y value taken from the standard: */
820296465Sdelphij    if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
821296465Sdelphij                   "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
822296465Sdelphij                   "7086A272C24088BE94769FD16650"))
823296465Sdelphij        ABORT;
824296465Sdelphij    if (0 != BN_cmp(y, z))
825296465Sdelphij        ABORT;
826194206Ssimon
827296465Sdelphij    fprintf(stdout, "verify degree ...");
828296465Sdelphij    if (EC_GROUP_get_degree(group) != 521)
829296465Sdelphij        ABORT;
830296465Sdelphij    fprintf(stdout, " ok\n");
831109998Smarkm
832296465Sdelphij    fprintf(stdout, "verify group order ...");
833296465Sdelphij    fflush(stdout);
834296465Sdelphij    if (!EC_GROUP_get_order(group, z, ctx))
835296465Sdelphij        ABORT;
836296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
837296465Sdelphij        ABORT;
838296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
839296465Sdelphij        ABORT;
840296465Sdelphij    fprintf(stdout, ".");
841296465Sdelphij    fflush(stdout);
842296465Sdelphij# if 0
843296465Sdelphij    if (!EC_GROUP_precompute_mult(group, ctx))
844296465Sdelphij        ABORT;
845296465Sdelphij# endif
846296465Sdelphij    if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
847296465Sdelphij        ABORT;
848296465Sdelphij    if (!EC_POINT_is_at_infinity(group, Q))
849296465Sdelphij        ABORT;
850296465Sdelphij    fprintf(stdout, " ok\n");
851109998Smarkm
852296465Sdelphij    if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group))))
853296465Sdelphij        ABORT;
854296465Sdelphij    if (!EC_GROUP_copy(P_521, group))
855296465Sdelphij        ABORT;
856109998Smarkm
857296465Sdelphij    /* more tests using the last curve */
858109998Smarkm
859296465Sdelphij    if (!EC_POINT_copy(Q, P))
860296465Sdelphij        ABORT;
861296465Sdelphij    if (EC_POINT_is_at_infinity(group, Q))
862296465Sdelphij        ABORT;
863296465Sdelphij    if (!EC_POINT_dbl(group, P, P, ctx))
864296465Sdelphij        ABORT;
865296465Sdelphij    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
866296465Sdelphij        ABORT;
867296465Sdelphij    if (!EC_POINT_invert(group, Q, ctx))
868296465Sdelphij        ABORT;                  /* P = -2Q */
869109998Smarkm
870296465Sdelphij    if (!EC_POINT_add(group, R, P, Q, ctx))
871296465Sdelphij        ABORT;
872296465Sdelphij    if (!EC_POINT_add(group, R, R, Q, ctx))
873296465Sdelphij        ABORT;
874296465Sdelphij    if (!EC_POINT_is_at_infinity(group, R))
875296465Sdelphij        ABORT;                  /* R = P + 2Q */
876109998Smarkm
877296465Sdelphij    {
878296465Sdelphij        const EC_POINT *points[4];
879296465Sdelphij        const BIGNUM *scalars[4];
880296465Sdelphij        BIGNUM scalar3;
881160814Ssimon
882296465Sdelphij        if (EC_POINT_is_at_infinity(group, Q))
883296465Sdelphij            ABORT;
884296465Sdelphij        points[0] = Q;
885296465Sdelphij        points[1] = Q;
886296465Sdelphij        points[2] = Q;
887296465Sdelphij        points[3] = Q;
888296465Sdelphij
889296465Sdelphij        if (!BN_add(y, z, BN_value_one()))
890296465Sdelphij            ABORT;
891296465Sdelphij        if (BN_is_odd(y))
892296465Sdelphij            ABORT;
893296465Sdelphij        if (!BN_rshift1(y, y))
894296465Sdelphij            ABORT;
895296465Sdelphij        scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
896296465Sdelphij        scalars[1] = y;
897296465Sdelphij
898296465Sdelphij        fprintf(stdout, "combined multiplication ...");
899296465Sdelphij        fflush(stdout);
900296465Sdelphij
901296465Sdelphij        /* z is still the group order */
902296465Sdelphij        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
903296465Sdelphij            ABORT;
904296465Sdelphij        if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
905296465Sdelphij            ABORT;
906296465Sdelphij        if (0 != EC_POINT_cmp(group, P, R, ctx))
907296465Sdelphij            ABORT;
908296465Sdelphij        if (0 != EC_POINT_cmp(group, R, Q, ctx))
909296465Sdelphij            ABORT;
910296465Sdelphij
911296465Sdelphij        fprintf(stdout, ".");
912296465Sdelphij        fflush(stdout);
913296465Sdelphij
914296465Sdelphij        if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0))
915296465Sdelphij            ABORT;
916296465Sdelphij        if (!BN_add(z, z, y))
917296465Sdelphij            ABORT;
918296465Sdelphij        BN_set_negative(z, 1);
919296465Sdelphij        scalars[0] = y;
920296465Sdelphij        scalars[1] = z;         /* z = -(order + y) */
921296465Sdelphij
922296465Sdelphij        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
923296465Sdelphij            ABORT;
924296465Sdelphij        if (!EC_POINT_is_at_infinity(group, P))
925296465Sdelphij            ABORT;
926296465Sdelphij
927296465Sdelphij        fprintf(stdout, ".");
928296465Sdelphij        fflush(stdout);
929296465Sdelphij
930296465Sdelphij        if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0))
931296465Sdelphij            ABORT;
932296465Sdelphij        if (!BN_add(z, x, y))
933296465Sdelphij            ABORT;
934296465Sdelphij        BN_set_negative(z, 1);
935296465Sdelphij        scalars[0] = x;
936296465Sdelphij        scalars[1] = y;
937296465Sdelphij        scalars[2] = z;         /* z = -(x+y) */
938296465Sdelphij
939296465Sdelphij        BN_init(&scalar3);
940296465Sdelphij        BN_zero(&scalar3);
941296465Sdelphij        scalars[3] = &scalar3;
942296465Sdelphij
943296465Sdelphij        if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
944296465Sdelphij            ABORT;
945296465Sdelphij        if (!EC_POINT_is_at_infinity(group, P))
946296465Sdelphij            ABORT;
947296465Sdelphij
948296465Sdelphij        fprintf(stdout, " ok\n\n");
949296465Sdelphij
950296465Sdelphij        BN_free(&scalar3);
951296465Sdelphij    }
952296465Sdelphij
953296465Sdelphij# if 0
954296465Sdelphij    timings(P_160, TIMING_BASE_PT, ctx);
955296465Sdelphij    timings(P_160, TIMING_RAND_PT, ctx);
956296465Sdelphij    timings(P_160, TIMING_SIMUL, ctx);
957296465Sdelphij    timings(P_192, TIMING_BASE_PT, ctx);
958296465Sdelphij    timings(P_192, TIMING_RAND_PT, ctx);
959296465Sdelphij    timings(P_192, TIMING_SIMUL, ctx);
960296465Sdelphij    timings(P_224, TIMING_BASE_PT, ctx);
961296465Sdelphij    timings(P_224, TIMING_RAND_PT, ctx);
962296465Sdelphij    timings(P_224, TIMING_SIMUL, ctx);
963296465Sdelphij    timings(P_256, TIMING_BASE_PT, ctx);
964296465Sdelphij    timings(P_256, TIMING_RAND_PT, ctx);
965296465Sdelphij    timings(P_256, TIMING_SIMUL, ctx);
966296465Sdelphij    timings(P_384, TIMING_BASE_PT, ctx);
967296465Sdelphij    timings(P_384, TIMING_RAND_PT, ctx);
968296465Sdelphij    timings(P_384, TIMING_SIMUL, ctx);
969296465Sdelphij    timings(P_521, TIMING_BASE_PT, ctx);
970296465Sdelphij    timings(P_521, TIMING_RAND_PT, ctx);
971296465Sdelphij    timings(P_521, TIMING_SIMUL, ctx);
972296465Sdelphij# endif
973296465Sdelphij
974296465Sdelphij    if (ctx)
975296465Sdelphij        BN_CTX_free(ctx);
976296465Sdelphij    BN_free(p);
977296465Sdelphij    BN_free(a);
978296465Sdelphij    BN_free(b);
979296465Sdelphij    EC_GROUP_free(group);
980296465Sdelphij    EC_POINT_free(P);
981296465Sdelphij    EC_POINT_free(Q);
982296465Sdelphij    EC_POINT_free(R);
983296465Sdelphij    BN_free(x);
984296465Sdelphij    BN_free(y);
985296465Sdelphij    BN_free(z);
986296465Sdelphij
987296465Sdelphij    if (P_160)
988296465Sdelphij        EC_GROUP_free(P_160);
989296465Sdelphij    if (P_192)
990296465Sdelphij        EC_GROUP_free(P_192);
991296465Sdelphij    if (P_224)
992296465Sdelphij        EC_GROUP_free(P_224);
993296465Sdelphij    if (P_256)
994296465Sdelphij        EC_GROUP_free(P_256);
995296465Sdelphij    if (P_384)
996296465Sdelphij        EC_GROUP_free(P_384);
997296465Sdelphij    if (P_521)
998296465Sdelphij        EC_GROUP_free(P_521);
999296465Sdelphij
1000296465Sdelphij}
1001296465Sdelphij
1002160814Ssimon/* Change test based on whether binary point compression is enabled or not. */
1003296465Sdelphij# ifdef OPENSSL_EC_BIN_PT_COMP
1004296465Sdelphij#  define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
1005296465Sdelphij        if (!BN_hex2bn(&x, _x)) ABORT; \
1006296465Sdelphij        if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
1007284295Sdelphij        if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
1008296465Sdelphij        if (!BN_hex2bn(&z, _order)) ABORT; \
1009296465Sdelphij        if (!BN_hex2bn(&cof, _cof)) ABORT; \
1010296465Sdelphij        if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
1011296465Sdelphij        if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
1012296465Sdelphij        fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
1013296465Sdelphij        BN_print_fp(stdout, x); \
1014296465Sdelphij        fprintf(stdout, "\n     y = 0x"); \
1015296465Sdelphij        BN_print_fp(stdout, y); \
1016296465Sdelphij        fprintf(stdout, "\n"); \
1017296465Sdelphij        /* G_y value taken from the standard: */ \
1018296465Sdelphij        if (!BN_hex2bn(&z, _y)) ABORT; \
1019296465Sdelphij        if (0 != BN_cmp(y, z)) ABORT;
1020296465Sdelphij# else
1021296465Sdelphij#  define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
1022296465Sdelphij        if (!BN_hex2bn(&x, _x)) ABORT; \
1023296465Sdelphij        if (!BN_hex2bn(&y, _y)) ABORT; \
1024296465Sdelphij        if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
1025284295Sdelphij        if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
1026296465Sdelphij        if (!BN_hex2bn(&z, _order)) ABORT; \
1027296465Sdelphij        if (!BN_hex2bn(&cof, _cof)) ABORT; \
1028296465Sdelphij        if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
1029296465Sdelphij        fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
1030296465Sdelphij        BN_print_fp(stdout, x); \
1031296465Sdelphij        fprintf(stdout, "\n     y = 0x"); \
1032296465Sdelphij        BN_print_fp(stdout, y); \
1033296465Sdelphij        fprintf(stdout, "\n");
1034296465Sdelphij# endif
1035160814Ssimon
1036296465Sdelphij# define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
1037296465Sdelphij        if (!BN_hex2bn(&p, _p)) ABORT; \
1038296465Sdelphij        if (!BN_hex2bn(&a, _a)) ABORT; \
1039296465Sdelphij        if (!BN_hex2bn(&b, _b)) ABORT; \
1040296465Sdelphij        if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \
1041296465Sdelphij        CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
1042296465Sdelphij        fprintf(stdout, "verify degree ..."); \
1043296465Sdelphij        if (EC_GROUP_get_degree(group) != _degree) ABORT; \
1044296465Sdelphij        fprintf(stdout, " ok\n"); \
1045296465Sdelphij        fprintf(stdout, "verify group order ..."); \
1046296465Sdelphij        fflush(stdout); \
1047296465Sdelphij        if (!EC_GROUP_get_order(group, z, ctx)) ABORT; \
1048296465Sdelphij        if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
1049296465Sdelphij        if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
1050296465Sdelphij        fprintf(stdout, "."); \
1051296465Sdelphij        fflush(stdout); \
1052296465Sdelphij        /* if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; */ \
1053296465Sdelphij        if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
1054296465Sdelphij        if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
1055296465Sdelphij        fprintf(stdout, " ok\n"); \
1056296465Sdelphij        if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
1057296465Sdelphij        if (!EC_GROUP_copy(_variable, group)) ABORT;
1058160814Ssimon
1059160814Ssimonvoid char2_field_tests()
1060296465Sdelphij{
1061296465Sdelphij    BN_CTX *ctx = NULL;
1062296465Sdelphij    BIGNUM *p, *a, *b;
1063296465Sdelphij    EC_GROUP *group;
1064296465Sdelphij    EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 =
1065296465Sdelphij        NULL, *C2_K571 = NULL;
1066296465Sdelphij    EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 =
1067296465Sdelphij        NULL, *C2_B571 = NULL;
1068296465Sdelphij    EC_POINT *P, *Q, *R;
1069296465Sdelphij    BIGNUM *x, *y, *z, *cof;
1070296465Sdelphij    unsigned char buf[100];
1071296465Sdelphij    size_t i, len;
1072296465Sdelphij    int k;
1073160814Ssimon
1074296465Sdelphij# if 1                          /* optional */
1075296465Sdelphij    ctx = BN_CTX_new();
1076296465Sdelphij    if (!ctx)
1077296465Sdelphij        ABORT;
1078296465Sdelphij# endif
1079160814Ssimon
1080296465Sdelphij    p = BN_new();
1081296465Sdelphij    a = BN_new();
1082296465Sdelphij    b = BN_new();
1083296465Sdelphij    if (!p || !a || !b)
1084296465Sdelphij        ABORT;
1085160814Ssimon
1086296465Sdelphij    if (!BN_hex2bn(&p, "13"))
1087296465Sdelphij        ABORT;
1088296465Sdelphij    if (!BN_hex2bn(&a, "3"))
1089296465Sdelphij        ABORT;
1090296465Sdelphij    if (!BN_hex2bn(&b, "1"))
1091296465Sdelphij        ABORT;
1092160814Ssimon
1093296465Sdelphij    group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
1094296465Sdelphij                                                    * EC_GROUP_new_curve_GF2m
1095296465Sdelphij                                                    * so that the library gets
1096296465Sdelphij                                                    * to choose the EC_METHOD */
1097296465Sdelphij    if (!group)
1098296465Sdelphij        ABORT;
1099296465Sdelphij    if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx))
1100296465Sdelphij        ABORT;
1101160814Ssimon
1102296465Sdelphij    {
1103296465Sdelphij        EC_GROUP *tmp;
1104296465Sdelphij        tmp = EC_GROUP_new(EC_GROUP_method_of(group));
1105296465Sdelphij        if (!tmp)
1106296465Sdelphij            ABORT;
1107296465Sdelphij        if (!EC_GROUP_copy(tmp, group))
1108296465Sdelphij            ABORT;
1109296465Sdelphij        EC_GROUP_free(group);
1110296465Sdelphij        group = tmp;
1111296465Sdelphij    }
1112160814Ssimon
1113296465Sdelphij    if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx))
1114296465Sdelphij        ABORT;
1115160814Ssimon
1116296465Sdelphij    fprintf(stdout,
1117296465Sdelphij            "Curve defined by Weierstrass equation\n     y^2 + x*y = x^3 + a*x^2 + b  (mod 0x");
1118296465Sdelphij    BN_print_fp(stdout, p);
1119296465Sdelphij    fprintf(stdout, ")\n     a = 0x");
1120296465Sdelphij    BN_print_fp(stdout, a);
1121296465Sdelphij    fprintf(stdout, "\n     b = 0x");
1122296465Sdelphij    BN_print_fp(stdout, b);
1123296465Sdelphij    fprintf(stdout, "\n(0x... means binary polynomial)\n");
1124160814Ssimon
1125296465Sdelphij    P = EC_POINT_new(group);
1126296465Sdelphij    Q = EC_POINT_new(group);
1127296465Sdelphij    R = EC_POINT_new(group);
1128296465Sdelphij    if (!P || !Q || !R)
1129296465Sdelphij        ABORT;
1130160814Ssimon
1131296465Sdelphij    if (!EC_POINT_set_to_infinity(group, P))
1132296465Sdelphij        ABORT;
1133296465Sdelphij    if (!EC_POINT_is_at_infinity(group, P))
1134296465Sdelphij        ABORT;
1135296465Sdelphij
1136296465Sdelphij    buf[0] = 0;
1137296465Sdelphij    if (!EC_POINT_oct2point(group, Q, buf, 1, ctx))
1138296465Sdelphij        ABORT;
1139296465Sdelphij
1140296465Sdelphij    if (!EC_POINT_add(group, P, P, Q, ctx))
1141296465Sdelphij        ABORT;
1142296465Sdelphij    if (!EC_POINT_is_at_infinity(group, P))
1143296465Sdelphij        ABORT;
1144296465Sdelphij
1145296465Sdelphij    x = BN_new();
1146296465Sdelphij    y = BN_new();
1147296465Sdelphij    z = BN_new();
1148296465Sdelphij    cof = BN_new();
1149296465Sdelphij    if (!x || !y || !z || !cof)
1150296465Sdelphij        ABORT;
1151296465Sdelphij
1152296465Sdelphij    if (!BN_hex2bn(&x, "6"))
1153296465Sdelphij        ABORT;
1154160814Ssimon/* Change test based on whether binary point compression is enabled or not. */
1155296465Sdelphij# ifdef OPENSSL_EC_BIN_PT_COMP
1156296465Sdelphij    if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx))
1157296465Sdelphij        ABORT;
1158296465Sdelphij# else
1159296465Sdelphij    if (!BN_hex2bn(&y, "8"))
1160296465Sdelphij        ABORT;
1161296465Sdelphij    if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx))
1162296465Sdelphij        ABORT;
1163296465Sdelphij# endif
1164296465Sdelphij    if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) {
1165160814Ssimon/* Change test based on whether binary point compression is enabled or not. */
1166296465Sdelphij# ifdef OPENSSL_EC_BIN_PT_COMP
1167296465Sdelphij        if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx))
1168296465Sdelphij            ABORT;
1169296465Sdelphij# endif
1170296465Sdelphij        fprintf(stderr, "Point is not on curve: x = 0x");
1171296465Sdelphij        BN_print_fp(stderr, x);
1172296465Sdelphij        fprintf(stderr, ", y = 0x");
1173296465Sdelphij        BN_print_fp(stderr, y);
1174296465Sdelphij        fprintf(stderr, "\n");
1175296465Sdelphij        ABORT;
1176296465Sdelphij    }
1177160814Ssimon
1178296465Sdelphij    fprintf(stdout, "A cyclic subgroup:\n");
1179296465Sdelphij    k = 100;
1180296465Sdelphij    do {
1181296465Sdelphij        if (k-- == 0)
1182296465Sdelphij            ABORT;
1183160814Ssimon
1184296465Sdelphij        if (EC_POINT_is_at_infinity(group, P))
1185296465Sdelphij            fprintf(stdout, "     point at infinity\n");
1186296465Sdelphij        else {
1187296465Sdelphij            if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx))
1188296465Sdelphij                ABORT;
1189160814Ssimon
1190296465Sdelphij            fprintf(stdout, "     x = 0x");
1191296465Sdelphij            BN_print_fp(stdout, x);
1192296465Sdelphij            fprintf(stdout, ", y = 0x");
1193296465Sdelphij            BN_print_fp(stdout, y);
1194296465Sdelphij            fprintf(stdout, "\n");
1195296465Sdelphij        }
1196160814Ssimon
1197296465Sdelphij        if (!EC_POINT_copy(R, P))
1198296465Sdelphij            ABORT;
1199296465Sdelphij        if (!EC_POINT_add(group, P, P, Q, ctx))
1200296465Sdelphij            ABORT;
1201296465Sdelphij    }
1202296465Sdelphij    while (!EC_POINT_is_at_infinity(group, P));
1203160814Ssimon
1204296465Sdelphij    if (!EC_POINT_add(group, P, Q, R, ctx))
1205296465Sdelphij        ABORT;
1206296465Sdelphij    if (!EC_POINT_is_at_infinity(group, P))
1207296465Sdelphij        ABORT;
1208296465Sdelphij
1209160814Ssimon/* Change test based on whether binary point compression is enabled or not. */
1210296465Sdelphij# ifdef OPENSSL_EC_BIN_PT_COMP
1211296465Sdelphij    len =
1212296465Sdelphij        EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
1213296465Sdelphij                           sizeof buf, ctx);
1214296465Sdelphij    if (len == 0)
1215296465Sdelphij        ABORT;
1216296465Sdelphij    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
1217296465Sdelphij        ABORT;
1218296465Sdelphij    if (0 != EC_POINT_cmp(group, P, Q, ctx))
1219296465Sdelphij        ABORT;
1220296465Sdelphij    fprintf(stdout, "Generator as octet string, compressed form:\n     ");
1221296465Sdelphij    for (i = 0; i < len; i++)
1222296465Sdelphij        fprintf(stdout, "%02X", buf[i]);
1223296465Sdelphij# endif
1224296465Sdelphij
1225296465Sdelphij    len =
1226296465Sdelphij        EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf,
1227296465Sdelphij                           sizeof buf, ctx);
1228296465Sdelphij    if (len == 0)
1229296465Sdelphij        ABORT;
1230296465Sdelphij    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
1231296465Sdelphij        ABORT;
1232296465Sdelphij    if (0 != EC_POINT_cmp(group, P, Q, ctx))
1233296465Sdelphij        ABORT;
1234296465Sdelphij    fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
1235296465Sdelphij    for (i = 0; i < len; i++)
1236296465Sdelphij        fprintf(stdout, "%02X", buf[i]);
1237296465Sdelphij
1238160814Ssimon/* Change test based on whether binary point compression is enabled or not. */
1239296465Sdelphij# ifdef OPENSSL_EC_BIN_PT_COMP
1240296465Sdelphij    len =
1241296465Sdelphij        EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf,
1242296465Sdelphij                           ctx);
1243296465Sdelphij    if (len == 0)
1244296465Sdelphij        ABORT;
1245296465Sdelphij    if (!EC_POINT_oct2point(group, P, buf, len, ctx))
1246296465Sdelphij        ABORT;
1247296465Sdelphij    if (0 != EC_POINT_cmp(group, P, Q, ctx))
1248296465Sdelphij        ABORT;
1249296465Sdelphij    fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
1250296465Sdelphij    for (i = 0; i < len; i++)
1251296465Sdelphij        fprintf(stdout, "%02X", buf[i]);
1252296465Sdelphij# endif
1253160814Ssimon
1254296465Sdelphij    fprintf(stdout, "\n");
1255160814Ssimon
1256296465Sdelphij    if (!EC_POINT_invert(group, P, ctx))
1257296465Sdelphij        ABORT;
1258296465Sdelphij    if (0 != EC_POINT_cmp(group, P, R, ctx))
1259296465Sdelphij        ABORT;
1260160814Ssimon
1261296465Sdelphij    /* Curve K-163 (FIPS PUB 186-2, App. 6) */
1262296465Sdelphij    CHAR2_CURVE_TEST
1263296465Sdelphij        ("NIST curve K-163",
1264296465Sdelphij         "0800000000000000000000000000000000000000C9",
1265296465Sdelphij         "1",
1266296465Sdelphij         "1",
1267296465Sdelphij         "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
1268296465Sdelphij         "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
1269296465Sdelphij         1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163, C2_K163);
1270160814Ssimon
1271296465Sdelphij    /* Curve B-163 (FIPS PUB 186-2, App. 6) */
1272296465Sdelphij    CHAR2_CURVE_TEST
1273296465Sdelphij        ("NIST curve B-163",
1274296465Sdelphij         "0800000000000000000000000000000000000000C9",
1275296465Sdelphij         "1",
1276296465Sdelphij         "020A601907B8C953CA1481EB10512F78744A3205FD",
1277296465Sdelphij         "03F0EBA16286A2D57EA0991168D4994637E8343E36",
1278296465Sdelphij         "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
1279296465Sdelphij         1, "040000000000000000000292FE77E70C12A4234C33", "2", 163, C2_B163);
1280160814Ssimon
1281296465Sdelphij    /* Curve K-233 (FIPS PUB 186-2, App. 6) */
1282296465Sdelphij    CHAR2_CURVE_TEST
1283296465Sdelphij        ("NIST curve K-233",
1284296465Sdelphij         "020000000000000000000000000000000000000004000000000000000001",
1285296465Sdelphij         "0",
1286296465Sdelphij         "1",
1287296465Sdelphij         "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
1288296465Sdelphij         "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
1289296465Sdelphij         0,
1290296465Sdelphij         "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
1291296465Sdelphij         "4", 233, C2_K233);
1292160814Ssimon
1293296465Sdelphij    /* Curve B-233 (FIPS PUB 186-2, App. 6) */
1294296465Sdelphij    CHAR2_CURVE_TEST
1295296465Sdelphij        ("NIST curve B-233",
1296296465Sdelphij         "020000000000000000000000000000000000000004000000000000000001",
1297296465Sdelphij         "000000000000000000000000000000000000000000000000000000000001",
1298296465Sdelphij         "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
1299296465Sdelphij         "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
1300296465Sdelphij         "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
1301296465Sdelphij         1,
1302296465Sdelphij         "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
1303296465Sdelphij         "2", 233, C2_B233);
1304160814Ssimon
1305296465Sdelphij    /* Curve K-283 (FIPS PUB 186-2, App. 6) */
1306296465Sdelphij    CHAR2_CURVE_TEST
1307296465Sdelphij        ("NIST curve K-283",
1308296465Sdelphij         "0800000000000000000000000000000000000000000000000000000000000000000010A1",
1309296465Sdelphij         "0",
1310296465Sdelphij         "1",
1311296465Sdelphij         "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
1312296465Sdelphij         "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
1313296465Sdelphij         0,
1314296465Sdelphij         "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
1315296465Sdelphij         "4", 283, C2_K283);
1316160814Ssimon
1317296465Sdelphij    /* Curve B-283 (FIPS PUB 186-2, App. 6) */
1318296465Sdelphij    CHAR2_CURVE_TEST
1319296465Sdelphij        ("NIST curve B-283",
1320296465Sdelphij         "0800000000000000000000000000000000000000000000000000000000000000000010A1",
1321296465Sdelphij         "000000000000000000000000000000000000000000000000000000000000000000000001",
1322296465Sdelphij         "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
1323296465Sdelphij         "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
1324296465Sdelphij         "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
1325296465Sdelphij         1,
1326296465Sdelphij         "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
1327296465Sdelphij         "2", 283, C2_B283);
1328160814Ssimon
1329296465Sdelphij    /* Curve K-409 (FIPS PUB 186-2, App. 6) */
1330296465Sdelphij    CHAR2_CURVE_TEST
1331296465Sdelphij        ("NIST curve K-409",
1332296465Sdelphij         "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
1333296465Sdelphij         "0",
1334296465Sdelphij         "1",
1335296465Sdelphij         "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
1336296465Sdelphij         "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
1337296465Sdelphij         1,
1338296465Sdelphij         "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
1339296465Sdelphij         "4", 409, C2_K409);
1340160814Ssimon
1341296465Sdelphij    /* Curve B-409 (FIPS PUB 186-2, App. 6) */
1342296465Sdelphij    CHAR2_CURVE_TEST
1343296465Sdelphij        ("NIST curve B-409",
1344296465Sdelphij         "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
1345296465Sdelphij         "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
1346296465Sdelphij         "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
1347296465Sdelphij         "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
1348296465Sdelphij         "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
1349296465Sdelphij         1,
1350296465Sdelphij         "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
1351296465Sdelphij         "2", 409, C2_B409);
1352160814Ssimon
1353296465Sdelphij    /* Curve K-571 (FIPS PUB 186-2, App. 6) */
1354296465Sdelphij    CHAR2_CURVE_TEST
1355296465Sdelphij        ("NIST curve K-571",
1356296465Sdelphij         "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
1357296465Sdelphij         "0",
1358296465Sdelphij         "1",
1359296465Sdelphij         "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
1360296465Sdelphij         "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
1361296465Sdelphij         0,
1362296465Sdelphij         "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
1363296465Sdelphij         "4", 571, C2_K571);
1364160814Ssimon
1365296465Sdelphij    /* Curve B-571 (FIPS PUB 186-2, App. 6) */
1366296465Sdelphij    CHAR2_CURVE_TEST
1367296465Sdelphij        ("NIST curve B-571",
1368296465Sdelphij         "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
1369296465Sdelphij         "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
1370296465Sdelphij         "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
1371296465Sdelphij         "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
1372296465Sdelphij         "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
1373296465Sdelphij         1,
1374296465Sdelphij         "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
1375296465Sdelphij         "2", 571, C2_B571);
1376160814Ssimon
1377296465Sdelphij    /* more tests using the last curve */
1378160814Ssimon
1379296465Sdelphij    if (!EC_POINT_copy(Q, P))
1380296465Sdelphij        ABORT;
1381296465Sdelphij    if (EC_POINT_is_at_infinity(group, Q))
1382296465Sdelphij        ABORT;
1383296465Sdelphij    if (!EC_POINT_dbl(group, P, P, ctx))
1384296465Sdelphij        ABORT;
1385296465Sdelphij    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
1386296465Sdelphij        ABORT;
1387296465Sdelphij    if (!EC_POINT_invert(group, Q, ctx))
1388296465Sdelphij        ABORT;                  /* P = -2Q */
1389160814Ssimon
1390296465Sdelphij    if (!EC_POINT_add(group, R, P, Q, ctx))
1391296465Sdelphij        ABORT;
1392296465Sdelphij    if (!EC_POINT_add(group, R, R, Q, ctx))
1393296465Sdelphij        ABORT;
1394296465Sdelphij    if (!EC_POINT_is_at_infinity(group, R))
1395296465Sdelphij        ABORT;                  /* R = P + 2Q */
1396160814Ssimon
1397296465Sdelphij    {
1398296465Sdelphij        const EC_POINT *points[3];
1399296465Sdelphij        const BIGNUM *scalars[3];
1400160814Ssimon
1401296465Sdelphij        if (EC_POINT_is_at_infinity(group, Q))
1402296465Sdelphij            ABORT;
1403296465Sdelphij        points[0] = Q;
1404296465Sdelphij        points[1] = Q;
1405296465Sdelphij        points[2] = Q;
1406160814Ssimon
1407296465Sdelphij        if (!BN_add(y, z, BN_value_one()))
1408296465Sdelphij            ABORT;
1409296465Sdelphij        if (BN_is_odd(y))
1410296465Sdelphij            ABORT;
1411296465Sdelphij        if (!BN_rshift1(y, y))
1412296465Sdelphij            ABORT;
1413296465Sdelphij        scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
1414296465Sdelphij        scalars[1] = y;
1415160814Ssimon
1416296465Sdelphij        fprintf(stdout, "combined multiplication ...");
1417296465Sdelphij        fflush(stdout);
1418160814Ssimon
1419296465Sdelphij        /* z is still the group order */
1420296465Sdelphij        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
1421296465Sdelphij            ABORT;
1422296465Sdelphij        if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
1423296465Sdelphij            ABORT;
1424296465Sdelphij        if (0 != EC_POINT_cmp(group, P, R, ctx))
1425296465Sdelphij            ABORT;
1426296465Sdelphij        if (0 != EC_POINT_cmp(group, R, Q, ctx))
1427296465Sdelphij            ABORT;
1428160814Ssimon
1429296465Sdelphij        fprintf(stdout, ".");
1430296465Sdelphij        fflush(stdout);
1431160814Ssimon
1432296465Sdelphij        if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0))
1433296465Sdelphij            ABORT;
1434296465Sdelphij        if (!BN_add(z, z, y))
1435296465Sdelphij            ABORT;
1436296465Sdelphij        BN_set_negative(z, 1);
1437296465Sdelphij        scalars[0] = y;
1438296465Sdelphij        scalars[1] = z;         /* z = -(order + y) */
1439160814Ssimon
1440296465Sdelphij        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
1441296465Sdelphij            ABORT;
1442296465Sdelphij        if (!EC_POINT_is_at_infinity(group, P))
1443296465Sdelphij            ABORT;
1444160814Ssimon
1445296465Sdelphij        fprintf(stdout, ".");
1446296465Sdelphij        fflush(stdout);
1447160814Ssimon
1448296465Sdelphij        if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0))
1449296465Sdelphij            ABORT;
1450296465Sdelphij        if (!BN_add(z, x, y))
1451296465Sdelphij            ABORT;
1452296465Sdelphij        BN_set_negative(z, 1);
1453296465Sdelphij        scalars[0] = x;
1454296465Sdelphij        scalars[1] = y;
1455296465Sdelphij        scalars[2] = z;         /* z = -(x+y) */
1456160814Ssimon
1457296465Sdelphij        if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
1458296465Sdelphij            ABORT;
1459296465Sdelphij        if (!EC_POINT_is_at_infinity(group, P))
1460296465Sdelphij            ABORT;
1461160814Ssimon
1462296465Sdelphij        fprintf(stdout, " ok\n\n");
1463296465Sdelphij    }
1464160814Ssimon
1465296465Sdelphij# if 0
1466296465Sdelphij    timings(C2_K163, TIMING_BASE_PT, ctx);
1467296465Sdelphij    timings(C2_K163, TIMING_RAND_PT, ctx);
1468296465Sdelphij    timings(C2_K163, TIMING_SIMUL, ctx);
1469296465Sdelphij    timings(C2_B163, TIMING_BASE_PT, ctx);
1470296465Sdelphij    timings(C2_B163, TIMING_RAND_PT, ctx);
1471296465Sdelphij    timings(C2_B163, TIMING_SIMUL, ctx);
1472296465Sdelphij    timings(C2_K233, TIMING_BASE_PT, ctx);
1473296465Sdelphij    timings(C2_K233, TIMING_RAND_PT, ctx);
1474296465Sdelphij    timings(C2_K233, TIMING_SIMUL, ctx);
1475296465Sdelphij    timings(C2_B233, TIMING_BASE_PT, ctx);
1476296465Sdelphij    timings(C2_B233, TIMING_RAND_PT, ctx);
1477296465Sdelphij    timings(C2_B233, TIMING_SIMUL, ctx);
1478296465Sdelphij    timings(C2_K283, TIMING_BASE_PT, ctx);
1479296465Sdelphij    timings(C2_K283, TIMING_RAND_PT, ctx);
1480296465Sdelphij    timings(C2_K283, TIMING_SIMUL, ctx);
1481296465Sdelphij    timings(C2_B283, TIMING_BASE_PT, ctx);
1482296465Sdelphij    timings(C2_B283, TIMING_RAND_PT, ctx);
1483296465Sdelphij    timings(C2_B283, TIMING_SIMUL, ctx);
1484296465Sdelphij    timings(C2_K409, TIMING_BASE_PT, ctx);
1485296465Sdelphij    timings(C2_K409, TIMING_RAND_PT, ctx);
1486296465Sdelphij    timings(C2_K409, TIMING_SIMUL, ctx);
1487296465Sdelphij    timings(C2_B409, TIMING_BASE_PT, ctx);
1488296465Sdelphij    timings(C2_B409, TIMING_RAND_PT, ctx);
1489296465Sdelphij    timings(C2_B409, TIMING_SIMUL, ctx);
1490296465Sdelphij    timings(C2_K571, TIMING_BASE_PT, ctx);
1491296465Sdelphij    timings(C2_K571, TIMING_RAND_PT, ctx);
1492296465Sdelphij    timings(C2_K571, TIMING_SIMUL, ctx);
1493296465Sdelphij    timings(C2_B571, TIMING_BASE_PT, ctx);
1494296465Sdelphij    timings(C2_B571, TIMING_RAND_PT, ctx);
1495296465Sdelphij    timings(C2_B571, TIMING_SIMUL, ctx);
1496296465Sdelphij# endif
1497160814Ssimon
1498296465Sdelphij    if (ctx)
1499296465Sdelphij        BN_CTX_free(ctx);
1500296465Sdelphij    BN_free(p);
1501296465Sdelphij    BN_free(a);
1502296465Sdelphij    BN_free(b);
1503296465Sdelphij    EC_GROUP_free(group);
1504296465Sdelphij    EC_POINT_free(P);
1505296465Sdelphij    EC_POINT_free(Q);
1506296465Sdelphij    EC_POINT_free(R);
1507296465Sdelphij    BN_free(x);
1508296465Sdelphij    BN_free(y);
1509296465Sdelphij    BN_free(z);
1510296465Sdelphij    BN_free(cof);
1511160814Ssimon
1512296465Sdelphij    if (C2_K163)
1513296465Sdelphij        EC_GROUP_free(C2_K163);
1514296465Sdelphij    if (C2_B163)
1515296465Sdelphij        EC_GROUP_free(C2_B163);
1516296465Sdelphij    if (C2_K233)
1517296465Sdelphij        EC_GROUP_free(C2_K233);
1518296465Sdelphij    if (C2_B233)
1519296465Sdelphij        EC_GROUP_free(C2_B233);
1520296465Sdelphij    if (C2_K283)
1521296465Sdelphij        EC_GROUP_free(C2_K283);
1522296465Sdelphij    if (C2_B283)
1523296465Sdelphij        EC_GROUP_free(C2_B283);
1524296465Sdelphij    if (C2_K409)
1525296465Sdelphij        EC_GROUP_free(C2_K409);
1526296465Sdelphij    if (C2_B409)
1527296465Sdelphij        EC_GROUP_free(C2_B409);
1528296465Sdelphij    if (C2_K571)
1529296465Sdelphij        EC_GROUP_free(C2_K571);
1530296465Sdelphij    if (C2_B571)
1531296465Sdelphij        EC_GROUP_free(C2_B571);
1532160814Ssimon
1533296465Sdelphij}
1534160814Ssimon
1535160814Ssimonvoid internal_curve_test(void)
1536296465Sdelphij{
1537296465Sdelphij    EC_builtin_curve *curves = NULL;
1538296465Sdelphij    size_t crv_len = 0, n = 0;
1539296465Sdelphij    int ok = 1;
1540160814Ssimon
1541296465Sdelphij    crv_len = EC_get_builtin_curves(NULL, 0);
1542160814Ssimon
1543296465Sdelphij    curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
1544160814Ssimon
1545296465Sdelphij    if (curves == NULL)
1546296465Sdelphij        return;
1547160814Ssimon
1548296465Sdelphij    if (!EC_get_builtin_curves(curves, crv_len)) {
1549296465Sdelphij        OPENSSL_free(curves);
1550296465Sdelphij        return;
1551296465Sdelphij    }
1552160814Ssimon
1553296465Sdelphij    fprintf(stdout, "testing internal curves: ");
1554160814Ssimon
1555296465Sdelphij    for (n = 0; n < crv_len; n++) {
1556296465Sdelphij        EC_GROUP *group = NULL;
1557296465Sdelphij        int nid = curves[n].nid;
1558296465Sdelphij        if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
1559296465Sdelphij            ok = 0;
1560296465Sdelphij            fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with"
1561296465Sdelphij                    " curve %s\n", OBJ_nid2sn(nid));
1562296465Sdelphij            /* try next curve */
1563296465Sdelphij            continue;
1564296465Sdelphij        }
1565296465Sdelphij        if (!EC_GROUP_check(group, NULL)) {
1566296465Sdelphij            ok = 0;
1567296465Sdelphij            fprintf(stdout, "\nEC_GROUP_check() failed with"
1568296465Sdelphij                    " curve %s\n", OBJ_nid2sn(nid));
1569296465Sdelphij            EC_GROUP_free(group);
1570296465Sdelphij            /* try the next curve */
1571296465Sdelphij            continue;
1572296465Sdelphij        }
1573296465Sdelphij        fprintf(stdout, ".");
1574296465Sdelphij        fflush(stdout);
1575296465Sdelphij        EC_GROUP_free(group);
1576296465Sdelphij    }
1577296465Sdelphij    if (ok)
1578296465Sdelphij        fprintf(stdout, " ok\n");
1579296465Sdelphij    else
1580296465Sdelphij        fprintf(stdout, " failed\n");
1581296465Sdelphij    OPENSSL_free(curves);
1582296465Sdelphij    return;
1583296465Sdelphij}
1584160814Ssimon
1585296465Sdelphijstatic const char rnd_seed[] =
1586296465Sdelphij    "string to make the random number generator think it has entropy";
1587296465Sdelphij
1588160814Ssimonint main(int argc, char *argv[])
1589296465Sdelphij{
1590160814Ssimon
1591296465Sdelphij    /* enable memory leak checking unless explicitly disabled */
1592296465Sdelphij    if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL)
1593296465Sdelphij          && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) {
1594296465Sdelphij        CRYPTO_malloc_debug_init();
1595296465Sdelphij        CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
1596296465Sdelphij    } else {
1597296465Sdelphij        /* OPENSSL_DEBUG_MEMORY=off */
1598296465Sdelphij        CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
1599296465Sdelphij    }
1600296465Sdelphij    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
1601296465Sdelphij    ERR_load_crypto_strings();
1602160814Ssimon
1603296465Sdelphij    RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
1604160814Ssimon
1605296465Sdelphij    prime_field_tests();
1606296465Sdelphij    puts("");
1607296465Sdelphij    char2_field_tests();
1608296465Sdelphij    /* test the internal curves */
1609296465Sdelphij    internal_curve_test();
1610296465Sdelphij
1611296465Sdelphij# ifndef OPENSSL_NO_ENGINE
1612296465Sdelphij    ENGINE_cleanup();
1613296465Sdelphij# endif
1614296465Sdelphij    CRYPTO_cleanup_all_ex_data();
1615296465Sdelphij    ERR_free_strings();
1616296465Sdelphij    ERR_remove_state(0);
1617296465Sdelphij    CRYPTO_mem_leaks_fp(stderr);
1618296465Sdelphij
1619296465Sdelphij    return 0;
1620296465Sdelphij}
1621111147Snectar#endif
1622