summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ec')
-rw-r--r--src/lib/libcrypto/ec/ec.h1163
-rw-r--r--src/lib/libcrypto/ec/ec2_mult.c450
-rw-r--r--src/lib/libcrypto/ec/ec2_oct.c382
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c787
-rw-r--r--src/lib/libcrypto/ec/ec_ameth.c636
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c1618
-rw-r--r--src/lib/libcrypto/ec/ec_check.c115
-rw-r--r--src/lib/libcrypto/ec/ec_curve.c3340
-rw-r--r--src/lib/libcrypto/ec/ec_cvt.c167
-rw-r--r--src/lib/libcrypto/ec/ec_err.c279
-rw-r--r--src/lib/libcrypto/ec/ec_key.c540
-rw-r--r--src/lib/libcrypto/ec/ec_lcl.h446
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c1120
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c886
-rw-r--r--src/lib/libcrypto/ec/ec_oct.c192
-rw-r--r--src/lib/libcrypto/ec/ec_pmeth.c323
-rw-r--r--src/lib/libcrypto/ec/ec_print.c178
-rw-r--r--src/lib/libcrypto/ec/eck_prn.c371
-rw-r--r--src/lib/libcrypto/ec/ecp_mont.c294
-rw-r--r--src/lib/libcrypto/ec/ecp_nist.c212
-rw-r--r--src/lib/libcrypto/ec/ecp_nistp224.c1693
-rw-r--r--src/lib/libcrypto/ec/ecp_nistp256.c2239
-rw-r--r--src/lib/libcrypto/ec/ecp_nistp521.c2113
-rw-r--r--src/lib/libcrypto/ec/ecp_nistputil.c209
-rw-r--r--src/lib/libcrypto/ec/ecp_oct.c395
-rw-r--r--src/lib/libcrypto/ec/ecp_smpl.c1410
26 files changed, 0 insertions, 21558 deletions
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
deleted file mode 100644
index a1ece2e0d5..0000000000
--- a/src/lib/libcrypto/ec/ec.h
+++ /dev/null
@@ -1,1163 +0,0 @@
1/* $OpenBSD: ec.h,v 1.11 2015/10/13 15:25:18 jsing Exp $ */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/**
6 * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
7 * \author Originally written by Bodo Moeller for the OpenSSL project
8 */
9/* ====================================================================
10 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in
21 * the documentation and/or other materials provided with the
22 * distribution.
23 *
24 * 3. All advertising materials mentioning features or use of this
25 * software must display the following acknowledgment:
26 * "This product includes software developed by the OpenSSL Project
27 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
28 *
29 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
30 * endorse or promote products derived from this software without
31 * prior written permission. For written permission, please contact
32 * openssl-core@openssl.org.
33 *
34 * 5. Products derived from this software may not be called "OpenSSL"
35 * nor may "OpenSSL" appear in their names without prior written
36 * permission of the OpenSSL Project.
37 *
38 * 6. Redistributions of any form whatsoever must retain the following
39 * acknowledgment:
40 * "This product includes software developed by the OpenSSL Project
41 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
44 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
46 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
47 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
49 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54 * OF THE POSSIBILITY OF SUCH DAMAGE.
55 * ====================================================================
56 *
57 * This product includes cryptographic software written by Eric Young
58 * (eay@cryptsoft.com). This product includes software written by Tim
59 * Hudson (tjh@cryptsoft.com).
60 *
61 */
62/* ====================================================================
63 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
64 *
65 * Portions of the attached software ("Contribution") are developed by
66 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
67 *
68 * The Contribution is licensed pursuant to the OpenSSL open source
69 * license provided above.
70 *
71 * The elliptic curve binary polynomial software is originally written by
72 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
73 *
74 */
75
76#ifndef HEADER_EC_H
77#define HEADER_EC_H
78
79#include <openssl/opensslconf.h>
80
81#ifdef OPENSSL_NO_EC
82#error EC is disabled.
83#endif
84
85#include <openssl/asn1.h>
86#ifndef OPENSSL_NO_DEPRECATED
87#include <openssl/bn.h>
88#endif
89
90#ifdef __cplusplus
91extern "C" {
92#elif defined(__SUNPRO_C)
93# if __SUNPRO_C >= 0x520
94# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
95# endif
96#endif
97
98
99#ifndef OPENSSL_ECC_MAX_FIELD_BITS
100# define OPENSSL_ECC_MAX_FIELD_BITS 661
101#endif
102
103/** Enum for the point conversion form as defined in X9.62 (ECDSA)
104 * for the encoding of a elliptic curve point (x,y) */
105typedef enum {
106 /** the point is encoded as z||x, where the octet z specifies
107 * which solution of the quadratic equation y is */
108 POINT_CONVERSION_COMPRESSED = 2,
109 /** the point is encoded as z||x||y, where z is the octet 0x02 */
110 POINT_CONVERSION_UNCOMPRESSED = 4,
111 /** the point is encoded as z||x||y, where the octet z specifies
112 * which solution of the quadratic equation y is */
113 POINT_CONVERSION_HYBRID = 6
114} point_conversion_form_t;
115
116
117typedef struct ec_method_st EC_METHOD;
118
119typedef struct ec_group_st
120 /*
121 EC_METHOD *meth;
122 -- field definition
123 -- curve coefficients
124 -- optional generator with associated information (order, cofactor)
125 -- optional extra data (precomputed table for fast computation of multiples of generator)
126 -- ASN1 stuff
127 */
128 EC_GROUP;
129
130typedef struct ec_point_st EC_POINT;
131
132
133/********************************************************************/
134/* EC_METHODs for curves over GF(p) */
135/********************************************************************/
136
137/** Returns the basic GFp ec methods which provides the basis for the
138 * optimized methods.
139 * \return EC_METHOD object
140 */
141const EC_METHOD *EC_GFp_simple_method(void);
142
143/** Returns GFp methods using montgomery multiplication.
144 * \return EC_METHOD object
145 */
146const EC_METHOD *EC_GFp_mont_method(void);
147
148/** Returns GFp methods using optimized methods for NIST recommended curves
149 * \return EC_METHOD object
150 */
151const EC_METHOD *EC_GFp_nist_method(void);
152
153#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
154/** Returns 64-bit optimized methods for nistp224
155 * \return EC_METHOD object
156 */
157const EC_METHOD *EC_GFp_nistp224_method(void);
158
159/** Returns 64-bit optimized methods for nistp256
160 * \return EC_METHOD object
161 */
162const EC_METHOD *EC_GFp_nistp256_method(void);
163
164/** Returns 64-bit optimized methods for nistp521
165 * \return EC_METHOD object
166 */
167const EC_METHOD *EC_GFp_nistp521_method(void);
168#endif
169
170#ifndef OPENSSL_NO_EC2M
171/********************************************************************/
172/* EC_METHOD for curves over GF(2^m) */
173/********************************************************************/
174
175/** Returns the basic GF2m ec method
176 * \return EC_METHOD object
177 */
178const EC_METHOD *EC_GF2m_simple_method(void);
179
180#endif
181
182
183/********************************************************************/
184/* EC_GROUP functions */
185/********************************************************************/
186
187/** Creates a new EC_GROUP object
188 * \param meth EC_METHOD to use
189 * \return newly created EC_GROUP object or NULL in case of an error.
190 */
191EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
192
193/** Frees a EC_GROUP object
194 * \param group EC_GROUP object to be freed.
195 */
196void EC_GROUP_free(EC_GROUP *group);
197
198/** Clears and frees a EC_GROUP object
199 * \param group EC_GROUP object to be cleared and freed.
200 */
201void EC_GROUP_clear_free(EC_GROUP *group);
202
203/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
204 * \param dst destination EC_GROUP object
205 * \param src source EC_GROUP object
206 * \return 1 on success and 0 if an error occurred.
207 */
208int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
209
210/** Creates a new EC_GROUP object and copies the copies the content
211 * form src to the newly created EC_KEY object
212 * \param src source EC_GROUP object
213 * \return newly created EC_GROUP object or NULL in case of an error.
214 */
215EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
216
217/** Returns the EC_METHOD of the EC_GROUP object.
218 * \param group EC_GROUP object
219 * \return EC_METHOD used in this EC_GROUP object.
220 */
221const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
222
223/** Returns the field type of the EC_METHOD.
224 * \param meth EC_METHOD object
225 * \return NID of the underlying field type OID.
226 */
227int EC_METHOD_get_field_type(const EC_METHOD *meth);
228
229/** Sets the generator and it's order/cofactor of a EC_GROUP object.
230 * \param group EC_GROUP object
231 * \param generator EC_POINT object with the generator.
232 * \param order the order of the group generated by the generator.
233 * \param cofactor the index of the sub-group generated by the generator
234 * in the group of all points on the elliptic curve.
235 * \return 1 on success and 0 if an error occured
236 */
237int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
238
239/** Returns the generator of a EC_GROUP object.
240 * \param group EC_GROUP object
241 * \return the currently used generator (possibly NULL).
242 */
243const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
244
245/** Gets the order of a EC_GROUP
246 * \param group EC_GROUP object
247 * \param order BIGNUM to which the order is copied
248 * \param ctx BN_CTX object (optional)
249 * \return 1 on success and 0 if an error occured
250 */
251int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
252
253/** Gets the cofactor of a EC_GROUP
254 * \param group EC_GROUP object
255 * \param cofactor BIGNUM to which the cofactor is copied
256 * \param ctx BN_CTX object (optional)
257 * \return 1 on success and 0 if an error occured
258 */
259int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
260
261/** Sets the name of a EC_GROUP object
262 * \param group EC_GROUP object
263 * \param nid NID of the curve name OID
264 */
265void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
266
267/** Returns the curve name of a EC_GROUP object
268 * \param group EC_GROUP object
269 * \return NID of the curve name OID or 0 if not set.
270 */
271int EC_GROUP_get_curve_name(const EC_GROUP *group);
272
273void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
274int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
275
276void EC_GROUP_set_point_conversion_form(EC_GROUP *group, point_conversion_form_t form);
277point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
278
279unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
280size_t EC_GROUP_get_seed_len(const EC_GROUP *);
281size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
282
283/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
284 * \param group EC_GROUP object
285 * \param p BIGNUM with the prime number
286 * \param a BIGNUM with parameter a of the equation
287 * \param b BIGNUM with parameter b of the equation
288 * \param ctx BN_CTX object (optional)
289 * \return 1 on success and 0 if an error occured
290 */
291int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
292
293/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
294 * \param group EC_GROUP object
295 * \param p BIGNUM for the prime number
296 * \param a BIGNUM for parameter a of the equation
297 * \param b BIGNUM for parameter b of the equation
298 * \param ctx BN_CTX object (optional)
299 * \return 1 on success and 0 if an error occured
300 */
301int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
302
303#ifndef OPENSSL_NO_EC2M
304/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
305 * \param group EC_GROUP object
306 * \param p BIGNUM with the polynomial defining the underlying field
307 * \param a BIGNUM with parameter a of the equation
308 * \param b BIGNUM with parameter b of the equation
309 * \param ctx BN_CTX object (optional)
310 * \return 1 on success and 0 if an error occured
311 */
312int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
313
314/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
315 * \param group EC_GROUP object
316 * \param p BIGNUM for the polynomial defining the underlying field
317 * \param a BIGNUM for parameter a of the equation
318 * \param b BIGNUM for parameter b of the equation
319 * \param ctx BN_CTX object (optional)
320 * \return 1 on success and 0 if an error occured
321 */
322int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
323#endif
324/** Returns the number of bits needed to represent a field element
325 * \param group EC_GROUP object
326 * \return number of bits needed to represent a field element
327 */
328int EC_GROUP_get_degree(const EC_GROUP *group);
329
330/** Checks whether the parameter in the EC_GROUP define a valid ec group
331 * \param group EC_GROUP object
332 * \param ctx BN_CTX object (optional)
333 * \return 1 if group is a valid ec group and 0 otherwise
334 */
335int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
336
337/** Checks whether the discriminant of the elliptic curve is zero or not
338 * \param group EC_GROUP object
339 * \param ctx BN_CTX object (optional)
340 * \return 1 if the discriminant is not zero and 0 otherwise
341 */
342int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
343
344/** Compares two EC_GROUP objects
345 * \param a first EC_GROUP object
346 * \param b second EC_GROUP object
347 * \param ctx BN_CTX object (optional)
348 * \return 0 if both groups are equal and 1 otherwise
349 */
350int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
351
352/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
353 * after choosing an appropriate EC_METHOD */
354
355/** Creates a new EC_GROUP object with the specified parameters defined
356 * over GFp (defined by the equation y^2 = x^3 + a*x + b)
357 * \param p BIGNUM with the prime number
358 * \param a BIGNUM with the parameter a of the equation
359 * \param b BIGNUM with the parameter b of the equation
360 * \param ctx BN_CTX object (optional)
361 * \return newly created EC_GROUP object with the specified parameters
362 */
363EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
364#ifndef OPENSSL_NO_EC2M
365/** Creates a new EC_GROUP object with the specified parameters defined
366 * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
367 * \param p BIGNUM with the polynomial defining the underlying field
368 * \param a BIGNUM with the parameter a of the equation
369 * \param b BIGNUM with the parameter b of the equation
370 * \param ctx BN_CTX object (optional)
371 * \return newly created EC_GROUP object with the specified parameters
372 */
373EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
374#endif
375/** Creates a EC_GROUP object with a curve specified by a NID
376 * \param nid NID of the OID of the curve name
377 * \return newly created EC_GROUP object with specified curve or NULL
378 * if an error occurred
379 */
380EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
381
382
383/********************************************************************/
384/* handling of internal curves */
385/********************************************************************/
386
387typedef struct {
388 int nid;
389 const char *comment;
390 } EC_builtin_curve;
391
392/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number
393 * of all available curves or zero if a error occurred.
394 * In case r ist not zero nitems EC_builtin_curve structures
395 * are filled with the data of the first nitems internal groups */
396size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
397
398const char *EC_curve_nid2nist(int nid);
399int EC_curve_nist2nid(const char *name);
400
401/********************************************************************/
402/* EC_POINT functions */
403/********************************************************************/
404
405/** Creates a new EC_POINT object for the specified EC_GROUP
406 * \param group EC_GROUP the underlying EC_GROUP object
407 * \return newly created EC_POINT object or NULL if an error occurred
408 */
409EC_POINT *EC_POINT_new(const EC_GROUP *group);
410
411/** Frees a EC_POINT object
412 * \param point EC_POINT object to be freed
413 */
414void EC_POINT_free(EC_POINT *point);
415
416/** Clears and frees a EC_POINT object
417 * \param point EC_POINT object to be cleared and freed
418 */
419void EC_POINT_clear_free(EC_POINT *point);
420
421/** Copies EC_POINT object
422 * \param dst destination EC_POINT object
423 * \param src source EC_POINT object
424 * \return 1 on success and 0 if an error occured
425 */
426int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
427
428/** Creates a new EC_POINT object and copies the content of the supplied
429 * EC_POINT
430 * \param src source EC_POINT object
431 * \param group underlying the EC_GROUP object
432 * \return newly created EC_POINT object or NULL if an error occurred
433 */
434EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
435
436/** Returns the EC_METHOD used in EC_POINT object
437 * \param point EC_POINT object
438 * \return the EC_METHOD used
439 */
440const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
441
442/** Sets a point to infinity (neutral element)
443 * \param group underlying EC_GROUP object
444 * \param point EC_POINT to set to infinity
445 * \return 1 on success and 0 if an error occured
446 */
447int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
448
449/** Sets the jacobian projective coordinates of a EC_POINT over GFp
450 * \param group underlying EC_GROUP object
451 * \param p EC_POINT object
452 * \param x BIGNUM with the x-coordinate
453 * \param y BIGNUM with the y-coordinate
454 * \param z BIGNUM with the z-coordinate
455 * \param ctx BN_CTX object (optional)
456 * \return 1 on success and 0 if an error occured
457 */
458int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
459 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
460
461/** Gets the jacobian projective coordinates of a EC_POINT over GFp
462 * \param group underlying EC_GROUP object
463 * \param p EC_POINT object
464 * \param x BIGNUM for the x-coordinate
465 * \param y BIGNUM for the y-coordinate
466 * \param z BIGNUM for the z-coordinate
467 * \param ctx BN_CTX object (optional)
468 * \return 1 on success and 0 if an error occured
469 */
470int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
471 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
472
473/** Sets the affine coordinates of a EC_POINT over GFp
474 * \param group underlying EC_GROUP object
475 * \param p EC_POINT object
476 * \param x BIGNUM with the x-coordinate
477 * \param y BIGNUM with the y-coordinate
478 * \param ctx BN_CTX object (optional)
479 * \return 1 on success and 0 if an error occured
480 */
481int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
482 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
483
484/** Gets the affine coordinates of a EC_POINT over GFp
485 * \param group underlying EC_GROUP object
486 * \param p EC_POINT object
487 * \param x BIGNUM for the x-coordinate
488 * \param y BIGNUM for the y-coordinate
489 * \param ctx BN_CTX object (optional)
490 * \return 1 on success and 0 if an error occured
491 */
492int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
493 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
494
495/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
496 * \param group underlying EC_GROUP object
497 * \param p EC_POINT object
498 * \param x BIGNUM with x-coordinate
499 * \param y_bit integer with the y-Bit (either 0 or 1)
500 * \param ctx BN_CTX object (optional)
501 * \return 1 on success and 0 if an error occured
502 */
503int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
504 const BIGNUM *x, int y_bit, BN_CTX *ctx);
505#ifndef OPENSSL_NO_EC2M
506/** Sets the affine coordinates of a EC_POINT over GF2m
507 * \param group underlying EC_GROUP object
508 * \param p EC_POINT object
509 * \param x BIGNUM with the x-coordinate
510 * \param y BIGNUM with the y-coordinate
511 * \param ctx BN_CTX object (optional)
512 * \return 1 on success and 0 if an error occured
513 */
514int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
515 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
516
517/** Gets the affine coordinates of a EC_POINT over GF2m
518 * \param group underlying EC_GROUP object
519 * \param p EC_POINT object
520 * \param x BIGNUM for the x-coordinate
521 * \param y BIGNUM for the y-coordinate
522 * \param ctx BN_CTX object (optional)
523 * \return 1 on success and 0 if an error occured
524 */
525int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
526 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
527
528/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
529 * \param group underlying EC_GROUP object
530 * \param p EC_POINT object
531 * \param x BIGNUM with x-coordinate
532 * \param y_bit integer with the y-Bit (either 0 or 1)
533 * \param ctx BN_CTX object (optional)
534 * \return 1 on success and 0 if an error occured
535 */
536int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
537 const BIGNUM *x, int y_bit, BN_CTX *ctx);
538#endif
539/** Encodes a EC_POINT object to a octet string
540 * \param group underlying EC_GROUP object
541 * \param p EC_POINT object
542 * \param form point conversion form
543 * \param buf memory buffer for the result. If NULL the function returns
544 * required buffer size.
545 * \param len length of the memory buffer
546 * \param ctx BN_CTX object (optional)
547 * \return the length of the encoded octet string or 0 if an error occurred
548 */
549size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
550 point_conversion_form_t form,
551 unsigned char *buf, size_t len, BN_CTX *ctx);
552
553/** Decodes a EC_POINT from a octet string
554 * \param group underlying EC_GROUP object
555 * \param p EC_POINT object
556 * \param buf memory buffer with the encoded ec point
557 * \param len length of the encoded ec point
558 * \param ctx BN_CTX object (optional)
559 * \return 1 on success and 0 if an error occured
560 */
561int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
562 const unsigned char *buf, size_t len, BN_CTX *ctx);
563
564/* other interfaces to point2oct/oct2point: */
565BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
566 point_conversion_form_t form, BIGNUM *, BN_CTX *);
567EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
568 EC_POINT *, BN_CTX *);
569char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
570 point_conversion_form_t form, BN_CTX *);
571EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
572 EC_POINT *, BN_CTX *);
573
574
575/********************************************************************/
576/* functions for doing EC_POINT arithmetic */
577/********************************************************************/
578
579/** Computes the sum of two EC_POINT
580 * \param group underlying EC_GROUP object
581 * \param r EC_POINT object for the result (r = a + b)
582 * \param a EC_POINT object with the first summand
583 * \param b EC_POINT object with the second summand
584 * \param ctx BN_CTX object (optional)
585 * \return 1 on success and 0 if an error occured
586 */
587int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
588
589/** Computes the double of a EC_POINT
590 * \param group underlying EC_GROUP object
591 * \param r EC_POINT object for the result (r = 2 * a)
592 * \param a EC_POINT object
593 * \param ctx BN_CTX object (optional)
594 * \return 1 on success and 0 if an error occured
595 */
596int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx);
597
598/** Computes the inverse of a EC_POINT
599 * \param group underlying EC_GROUP object
600 * \param a EC_POINT object to be inverted (it's used for the result as well)
601 * \param ctx BN_CTX object (optional)
602 * \return 1 on success and 0 if an error occured
603 */
604int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
605
606/** Checks whether the point is the neutral element of the group
607 * \param group the underlying EC_GROUP object
608 * \param p EC_POINT object
609 * \return 1 if the point is the neutral element and 0 otherwise
610 */
611int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
612
613/** Checks whether the point is on the curve
614 * \param group underlying EC_GROUP object
615 * \param point EC_POINT object to check
616 * \param ctx BN_CTX object (optional)
617 * \return 1 if point if on the curve and 0 otherwise
618 */
619int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx);
620
621/** Compares two EC_POINTs
622 * \param group underlying EC_GROUP object
623 * \param a first EC_POINT object
624 * \param b second EC_POINT object
625 * \param ctx BN_CTX object (optional)
626 * \return 0 if both points are equal and a value != 0 otherwise
627 */
628int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
629
630int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
631int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx);
632
633/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
634 * \param group underlying EC_GROUP object
635 * \param r EC_POINT object for the result
636 * \param n BIGNUM with the multiplier for the group generator (optional)
637 * \param num number futher summands
638 * \param p array of size num of EC_POINT objects
639 * \param m array of size num of BIGNUM objects
640 * \param ctx BN_CTX object (optional)
641 * \return 1 on success and 0 if an error occured
642 */
643int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
644
645/** Computes r = generator * n + q * m
646 * \param group underlying EC_GROUP object
647 * \param r EC_POINT object for the result
648 * \param n BIGNUM with the multiplier for the group generator (optional)
649 * \param q EC_POINT object with the first factor of the second summand
650 * \param m BIGNUM with the second factor of the second summand
651 * \param ctx BN_CTX object (optional)
652 * \return 1 on success and 0 if an error occured
653 */
654int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
655
656/** Stores multiples of generator for faster point multiplication
657 * \param group EC_GROUP object
658 * \param ctx BN_CTX object (optional)
659 * \return 1 on success and 0 if an error occured
660 */
661int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
662
663/** Reports whether a precomputation has been done
664 * \param group EC_GROUP object
665 * \return 1 if a pre-computation has been done and 0 otherwise
666 */
667int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
668
669
670/********************************************************************/
671/* ASN1 stuff */
672/********************************************************************/
673
674/* EC_GROUP_get_basis_type() returns the NID of the basis type
675 * used to represent the field elements */
676int EC_GROUP_get_basis_type(const EC_GROUP *);
677#ifndef OPENSSL_NO_EC2M
678int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
679int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
680 unsigned int *k2, unsigned int *k3);
681#endif
682
683#define OPENSSL_EC_NAMED_CURVE 0x001
684
685typedef struct ecpk_parameters_st ECPKPARAMETERS;
686
687EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
688int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
689
690#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
691#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
692#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
693 (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
694#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
695 (unsigned char *)(x))
696
697#ifndef OPENSSL_NO_BIO
698int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
699#endif
700int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
701
702
703/********************************************************************/
704/* EC_KEY functions */
705/********************************************************************/
706
707typedef struct ec_key_st EC_KEY;
708
709/* some values for the encoding_flag */
710#define EC_PKEY_NO_PARAMETERS 0x001
711#define EC_PKEY_NO_PUBKEY 0x002
712
713/* some values for the flags field */
714#define EC_FLAG_NON_FIPS_ALLOW 0x1
715#define EC_FLAG_FIPS_CHECKED 0x2
716
717/** Creates a new EC_KEY object.
718 * \return EC_KEY object or NULL if an error occurred.
719 */
720EC_KEY *EC_KEY_new(void);
721
722int EC_KEY_get_flags(const EC_KEY *key);
723
724void EC_KEY_set_flags(EC_KEY *key, int flags);
725
726void EC_KEY_clear_flags(EC_KEY *key, int flags);
727
728/** Creates a new EC_KEY object using a named curve as underlying
729 * EC_GROUP object.
730 * \param nid NID of the named curve.
731 * \return EC_KEY object or NULL if an error occurred.
732 */
733EC_KEY *EC_KEY_new_by_curve_name(int nid);
734
735/** Frees a EC_KEY object.
736 * \param key EC_KEY object to be freed.
737 */
738void EC_KEY_free(EC_KEY *key);
739
740/** Copies a EC_KEY object.
741 * \param dst destination EC_KEY object
742 * \param src src EC_KEY object
743 * \return dst or NULL if an error occurred.
744 */
745EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
746
747/** Creates a new EC_KEY object and copies the content from src to it.
748 * \param src the source EC_KEY object
749 * \return newly created EC_KEY object or NULL if an error occurred.
750 */
751EC_KEY *EC_KEY_dup(const EC_KEY *src);
752
753/** Increases the internal reference count of a EC_KEY object.
754 * \param key EC_KEY object
755 * \return 1 on success and 0 if an error occurred.
756 */
757int EC_KEY_up_ref(EC_KEY *key);
758
759/** Returns the EC_GROUP object of a EC_KEY object
760 * \param key EC_KEY object
761 * \return the EC_GROUP object (possibly NULL).
762 */
763const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
764
765/** Sets the EC_GROUP of a EC_KEY object.
766 * \param key EC_KEY object
767 * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY
768 * object will use an own copy of the EC_GROUP).
769 * \return 1 on success and 0 if an error occurred.
770 */
771int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
772
773/** Returns the private key of a EC_KEY object.
774 * \param key EC_KEY object
775 * \return a BIGNUM with the private key (possibly NULL).
776 */
777const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
778
779/** Sets the private key of a EC_KEY object.
780 * \param key EC_KEY object
781 * \param prv BIGNUM with the private key (note: the EC_KEY object
782 * will use an own copy of the BIGNUM).
783 * \return 1 on success and 0 if an error occurred.
784 */
785int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
786
787/** Returns the public key of a EC_KEY object.
788 * \param key the EC_KEY object
789 * \return a EC_POINT object with the public key (possibly NULL)
790 */
791const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
792
793/** Sets the public key of a EC_KEY object.
794 * \param key EC_KEY object
795 * \param pub EC_POINT object with the public key (note: the EC_KEY object
796 * will use an own copy of the EC_POINT object).
797 * \return 1 on success and 0 if an error occurred.
798 */
799int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
800
801unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
802void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
803point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
804void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
805/* functions to set/get method specific data */
806void *EC_KEY_get_key_method_data(EC_KEY *key,
807 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
808/** Sets the key method data of an EC_KEY object, if none has yet been set.
809 * \param key EC_KEY object
810 * \param data opaque data to install.
811 * \param dup_func a function that duplicates |data|.
812 * \param free_func a function that frees |data|.
813 * \param clear_free_func a function that wipes and frees |data|.
814 * \return the previously set data pointer, or NULL if |data| was inserted.
815 */
816void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
817 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
818/* wrapper functions for the underlying EC_GROUP object */
819void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
820
821/** Creates a table of pre-computed multiples of the generator to
822 * accelerate further EC_KEY operations.
823 * \param key EC_KEY object
824 * \param ctx BN_CTX object (optional)
825 * \return 1 on success and 0 if an error occurred.
826 */
827int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
828
829/** Creates a new ec private (and optional a new public) key.
830 * \param key EC_KEY object
831 * \return 1 on success and 0 if an error occurred.
832 */
833int EC_KEY_generate_key(EC_KEY *key);
834
835/** Verifies that a private and/or public key is valid.
836 * \param key the EC_KEY object
837 * \return 1 on success and 0 otherwise.
838 */
839int EC_KEY_check_key(const EC_KEY *key);
840
841/** Sets a public key from affine coordindates performing
842 * neccessary NIST PKV tests.
843 * \param key the EC_KEY object
844 * \param x public key x coordinate
845 * \param y public key y coordinate
846 * \return 1 on success and 0 otherwise.
847 */
848int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y);
849
850
851/********************************************************************/
852/* de- and encoding functions for SEC1 ECPrivateKey */
853/********************************************************************/
854
855/** Decodes a private key from a memory buffer.
856 * \param key a pointer to a EC_KEY object which should be used (or NULL)
857 * \param in pointer to memory with the DER encoded private key
858 * \param len length of the DER encoded private key
859 * \return the decoded private key or NULL if an error occurred.
860 */
861EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
862
863/** Encodes a private key object and stores the result in a buffer.
864 * \param key the EC_KEY object to encode
865 * \param out the buffer for the result (if NULL the function returns number
866 * of bytes needed).
867 * \return 1 on success and 0 if an error occurred.
868 */
869int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
870
871
872/********************************************************************/
873/* de- and encoding functions for EC parameters */
874/********************************************************************/
875
876/** Decodes ec parameter from a memory buffer.
877 * \param key a pointer to a EC_KEY object which should be used (or NULL)
878 * \param in pointer to memory with the DER encoded ec parameters
879 * \param len length of the DER encoded ec parameters
880 * \return a EC_KEY object with the decoded parameters or NULL if an error
881 * occurred.
882 */
883EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
884
885/** Encodes ec parameter and stores the result in a buffer.
886 * \param key the EC_KEY object with ec paramters to encode
887 * \param out the buffer for the result (if NULL the function returns number
888 * of bytes needed).
889 * \return 1 on success and 0 if an error occurred.
890 */
891int i2d_ECParameters(EC_KEY *key, unsigned char **out);
892
893
894/********************************************************************/
895/* de- and encoding functions for EC public key */
896/* (octet string, not DER -- hence 'o2i' and 'i2o') */
897/********************************************************************/
898
899/** Decodes a ec public key from a octet string.
900 * \param key a pointer to a EC_KEY object which should be used
901 * \param in memory buffer with the encoded public key
902 * \param len length of the encoded public key
903 * \return EC_KEY object with decoded public key or NULL if an error
904 * occurred.
905 */
906EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
907
908/** Encodes a ec public key in an octet string.
909 * \param key the EC_KEY object with the public key
910 * \param out the buffer for the result (if NULL the function returns number
911 * of bytes needed).
912 * \return 1 on success and 0 if an error occurred
913 */
914int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
915
916#ifndef OPENSSL_NO_BIO
917/** Prints out the ec parameters on human readable form.
918 * \param bp BIO object to which the information is printed
919 * \param key EC_KEY object
920 * \return 1 on success and 0 if an error occurred
921 */
922int ECParameters_print(BIO *bp, const EC_KEY *key);
923
924/** Prints out the contents of a EC_KEY object
925 * \param bp BIO object to which the information is printed
926 * \param key EC_KEY object
927 * \param off line offset
928 * \return 1 on success and 0 if an error occurred
929 */
930int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
931
932#endif
933/** Prints out the ec parameters on human readable form.
934 * \param fp file descriptor to which the information is printed
935 * \param key EC_KEY object
936 * \return 1 on success and 0 if an error occurred
937 */
938int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
939
940/** Prints out the contents of a EC_KEY object
941 * \param fp file descriptor to which the information is printed
942 * \param key EC_KEY object
943 * \param off line offset
944 * \return 1 on success and 0 if an error occurred
945 */
946int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
947
948EC_KEY *ECParameters_dup(EC_KEY *key);
949
950#ifndef __cplusplus
951#if defined(__SUNPRO_C)
952# if __SUNPRO_C >= 0x520
953# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
954# endif
955# endif
956#endif
957
958#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
959 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
960 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
961
962
963#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
964
965/* BEGIN ERROR CODES */
966/* The following lines are auto generated by the script mkerr.pl. Any changes
967 * made after this point may be overwritten when the script is next run.
968 */
969void ERR_load_EC_strings(void);
970
971/* Error codes for the EC functions. */
972
973/* Function codes. */
974#define EC_F_BN_TO_FELEM 224
975#define EC_F_COMPUTE_WNAF 143
976#define EC_F_D2I_ECPARAMETERS 144
977#define EC_F_D2I_ECPKPARAMETERS 145
978#define EC_F_D2I_ECPRIVATEKEY 146
979#define EC_F_DO_EC_KEY_PRINT 221
980#define EC_F_ECKEY_PARAM2TYPE 223
981#define EC_F_ECKEY_PARAM_DECODE 212
982#define EC_F_ECKEY_PRIV_DECODE 213
983#define EC_F_ECKEY_PRIV_ENCODE 214
984#define EC_F_ECKEY_PUB_DECODE 215
985#define EC_F_ECKEY_PUB_ENCODE 216
986#define EC_F_ECKEY_TYPE2PARAM 220
987#define EC_F_ECPARAMETERS_PRINT 147
988#define EC_F_ECPARAMETERS_PRINT_FP 148
989#define EC_F_ECPKPARAMETERS_PRINT 149
990#define EC_F_ECPKPARAMETERS_PRINT_FP 150
991#define EC_F_ECP_NIST_MOD_192 203
992#define EC_F_ECP_NIST_MOD_224 204
993#define EC_F_ECP_NIST_MOD_256 205
994#define EC_F_ECP_NIST_MOD_521 206
995#define EC_F_EC_ASN1_GROUP2CURVE 153
996#define EC_F_EC_ASN1_GROUP2FIELDID 154
997#define EC_F_EC_ASN1_GROUP2PARAMETERS 155
998#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156
999#define EC_F_EC_ASN1_PARAMETERS2GROUP 157
1000#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158
1001#define EC_F_EC_EX_DATA_SET_DATA 211
1002#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208
1003#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159
1004#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195
1005#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160
1006#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161
1007#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
1008#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
1009#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164
1010#define EC_F_EC_GFP_MONT_FIELD_DECODE 133
1011#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134
1012#define EC_F_EC_GFP_MONT_FIELD_MUL 131
1013#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209
1014#define EC_F_EC_GFP_MONT_FIELD_SQR 132
1015#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189
1016#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135
1017#define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225
1018#define EC_F_EC_GFP_NISTP224_POINTS_MUL 228
1019#define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
1020#define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230
1021#define EC_F_EC_GFP_NISTP256_POINTS_MUL 231
1022#define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
1023#define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233
1024#define EC_F_EC_GFP_NISTP521_POINTS_MUL 234
1025#define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
1026#define EC_F_EC_GFP_NIST_FIELD_MUL 200
1027#define EC_F_EC_GFP_NIST_FIELD_SQR 201
1028#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202
1029#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165
1030#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166
1031#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100
1032#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101
1033#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102
1034#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103
1035#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104
1036#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137
1037#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167
1038#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
1039#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168
1040#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
1041#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169
1042#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
1043#define EC_F_EC_GROUP_CHECK 170
1044#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171
1045#define EC_F_EC_GROUP_COPY 106
1046#define EC_F_EC_GROUP_GET0_GENERATOR 139
1047#define EC_F_EC_GROUP_GET_COFACTOR 140
1048#define EC_F_EC_GROUP_GET_CURVE_GF2M 172
1049#define EC_F_EC_GROUP_GET_CURVE_GFP 130
1050#define EC_F_EC_GROUP_GET_DEGREE 173
1051#define EC_F_EC_GROUP_GET_ORDER 141
1052#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193
1053#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194
1054#define EC_F_EC_GROUP_NEW 108
1055#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174
1056#define EC_F_EC_GROUP_NEW_FROM_DATA 175
1057#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142
1058#define EC_F_EC_GROUP_SET_CURVE_GF2M 176
1059#define EC_F_EC_GROUP_SET_CURVE_GFP 109
1060#define EC_F_EC_GROUP_SET_EXTRA_DATA 110
1061#define EC_F_EC_GROUP_SET_GENERATOR 111
1062#define EC_F_EC_KEY_CHECK_KEY 177
1063#define EC_F_EC_KEY_COPY 178
1064#define EC_F_EC_KEY_GENERATE_KEY 179
1065#define EC_F_EC_KEY_NEW 182
1066#define EC_F_EC_KEY_PRINT 180
1067#define EC_F_EC_KEY_PRINT_FP 181
1068#define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229
1069#define EC_F_EC_POINTS_MAKE_AFFINE 136
1070#define EC_F_EC_POINT_ADD 112
1071#define EC_F_EC_POINT_CMP 113
1072#define EC_F_EC_POINT_COPY 114
1073#define EC_F_EC_POINT_DBL 115
1074#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183
1075#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116
1076#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117
1077#define EC_F_EC_POINT_INVERT 210
1078#define EC_F_EC_POINT_IS_AT_INFINITY 118
1079#define EC_F_EC_POINT_IS_ON_CURVE 119
1080#define EC_F_EC_POINT_MAKE_AFFINE 120
1081#define EC_F_EC_POINT_MUL 184
1082#define EC_F_EC_POINT_NEW 121
1083#define EC_F_EC_POINT_OCT2POINT 122
1084#define EC_F_EC_POINT_POINT2OCT 123
1085#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185
1086#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124
1087#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186
1088#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125
1089#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126
1090#define EC_F_EC_POINT_SET_TO_INFINITY 127
1091#define EC_F_EC_PRE_COMP_DUP 207
1092#define EC_F_EC_PRE_COMP_NEW 196
1093#define EC_F_EC_WNAF_MUL 187
1094#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188
1095#define EC_F_I2D_ECPARAMETERS 190
1096#define EC_F_I2D_ECPKPARAMETERS 191
1097#define EC_F_I2D_ECPRIVATEKEY 192
1098#define EC_F_I2O_ECPUBLICKEY 151
1099#define EC_F_NISTP224_PRE_COMP_NEW 227
1100#define EC_F_NISTP256_PRE_COMP_NEW 236
1101#define EC_F_NISTP521_PRE_COMP_NEW 237
1102#define EC_F_O2I_ECPUBLICKEY 152
1103#define EC_F_OLD_EC_PRIV_DECODE 222
1104#define EC_F_PKEY_EC_CTRL 197
1105#define EC_F_PKEY_EC_CTRL_STR 198
1106#define EC_F_PKEY_EC_DERIVE 217
1107#define EC_F_PKEY_EC_KEYGEN 199
1108#define EC_F_PKEY_EC_PARAMGEN 219
1109#define EC_F_PKEY_EC_SIGN 218
1110
1111/* Reason codes. */
1112#define EC_R_ASN1_ERROR 115
1113#define EC_R_ASN1_UNKNOWN_FIELD 116
1114#define EC_R_BIGNUM_OUT_OF_RANGE 144
1115#define EC_R_BUFFER_TOO_SMALL 100
1116#define EC_R_COORDINATES_OUT_OF_RANGE 146
1117#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
1118#define EC_R_DECODE_ERROR 142
1119#define EC_R_DISCRIMINANT_IS_ZERO 118
1120#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
1121#define EC_R_FIELD_TOO_LARGE 143
1122#define EC_R_GF2M_NOT_SUPPORTED 147
1123#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
1124#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
1125#define EC_R_INCOMPATIBLE_OBJECTS 101
1126#define EC_R_INVALID_ARGUMENT 112
1127#define EC_R_INVALID_COMPRESSED_POINT 110
1128#define EC_R_INVALID_COMPRESSION_BIT 109
1129#define EC_R_INVALID_CURVE 141
1130#define EC_R_INVALID_DIGEST_TYPE 138
1131#define EC_R_INVALID_ENCODING 102
1132#define EC_R_INVALID_FIELD 103
1133#define EC_R_INVALID_FORM 104
1134#define EC_R_INVALID_GROUP_ORDER 122
1135#define EC_R_INVALID_PENTANOMIAL_BASIS 132
1136#define EC_R_INVALID_PRIVATE_KEY 123
1137#define EC_R_INVALID_TRINOMIAL_BASIS 137
1138#define EC_R_KEYS_NOT_SET 140
1139#define EC_R_MISSING_PARAMETERS 124
1140#define EC_R_MISSING_PRIVATE_KEY 125
1141#define EC_R_NOT_A_NIST_PRIME 135
1142#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136
1143#define EC_R_NOT_IMPLEMENTED 126
1144#define EC_R_NOT_INITIALIZED 111
1145#define EC_R_NO_FIELD_MOD 133
1146#define EC_R_NO_PARAMETERS_SET 139
1147#define EC_R_PASSED_NULL_PARAMETER 134
1148#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
1149#define EC_R_POINT_AT_INFINITY 106
1150#define EC_R_POINT_IS_NOT_ON_CURVE 107
1151#define EC_R_SLOT_FULL 108
1152#define EC_R_UNDEFINED_GENERATOR 113
1153#define EC_R_UNDEFINED_ORDER 128
1154#define EC_R_UNKNOWN_GROUP 129
1155#define EC_R_UNKNOWN_ORDER 114
1156#define EC_R_UNSUPPORTED_FIELD 131
1157#define EC_R_WRONG_CURVE_PARAMETERS 145
1158#define EC_R_WRONG_ORDER 130
1159
1160#ifdef __cplusplus
1161}
1162#endif
1163#endif
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c
deleted file mode 100644
index 3812611702..0000000000
--- a/src/lib/libcrypto/ec/ec2_mult.c
+++ /dev/null
@@ -1,450 +0,0 @@
1/* $OpenBSD: ec2_mult.c,v 1.8 2016/03/12 21:44:11 bcook Exp $ */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The software is originally written by Sheueling Chang Shantz and
13 * Douglas Stebila of Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * openssl-core@openssl.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
67 *
68 */
69
70#include <openssl/opensslconf.h>
71
72#include <openssl/err.h>
73
74#include "ec_lcl.h"
75
76#ifndef OPENSSL_NO_EC2M
77
78
79/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
80 * coordinates.
81 * Uses algorithm Mdouble in appendix of
82 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
83 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
84 * modified to not require precomputation of c=b^{2^{m-1}}.
85 */
86static int
87gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
88{
89 BIGNUM *t1;
90 int ret = 0;
91
92 /* Since Mdouble is static we can guarantee that ctx != NULL. */
93 BN_CTX_start(ctx);
94 if ((t1 = BN_CTX_get(ctx)) == NULL)
95 goto err;
96
97 if (!group->meth->field_sqr(group, x, x, ctx))
98 goto err;
99 if (!group->meth->field_sqr(group, t1, z, ctx))
100 goto err;
101 if (!group->meth->field_mul(group, z, x, t1, ctx))
102 goto err;
103 if (!group->meth->field_sqr(group, x, x, ctx))
104 goto err;
105 if (!group->meth->field_sqr(group, t1, t1, ctx))
106 goto err;
107 if (!group->meth->field_mul(group, t1, &group->b, t1, ctx))
108 goto err;
109 if (!BN_GF2m_add(x, x, t1))
110 goto err;
111
112 ret = 1;
113
114err:
115 BN_CTX_end(ctx);
116 return ret;
117}
118
119/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
120 * projective coordinates.
121 * Uses algorithm Madd in appendix of
122 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
123 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
124 */
125static int
126gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1,
127 const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
128{
129 BIGNUM *t1, *t2;
130 int ret = 0;
131
132 /* Since Madd is static we can guarantee that ctx != NULL. */
133 BN_CTX_start(ctx);
134 if ((t1 = BN_CTX_get(ctx)) == NULL)
135 goto err;
136 if ((t2 = BN_CTX_get(ctx)) == NULL)
137 goto err;
138
139 if (!BN_copy(t1, x))
140 goto err;
141 if (!group->meth->field_mul(group, x1, x1, z2, ctx))
142 goto err;
143 if (!group->meth->field_mul(group, z1, z1, x2, ctx))
144 goto err;
145 if (!group->meth->field_mul(group, t2, x1, z1, ctx))
146 goto err;
147 if (!BN_GF2m_add(z1, z1, x1))
148 goto err;
149 if (!group->meth->field_sqr(group, z1, z1, ctx))
150 goto err;
151 if (!group->meth->field_mul(group, x1, z1, t1, ctx))
152 goto err;
153 if (!BN_GF2m_add(x1, x1, t2))
154 goto err;
155
156 ret = 1;
157
158err:
159 BN_CTX_end(ctx);
160 return ret;
161}
162
163/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
164 * using Montgomery point multiplication algorithm Mxy() in appendix of
165 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
166 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
167 * Returns:
168 * 0 on error
169 * 1 if return value should be the point at infinity
170 * 2 otherwise
171 */
172static int
173gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1,
174 BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx)
175{
176 BIGNUM *t3, *t4, *t5;
177 int ret = 0;
178
179 if (BN_is_zero(z1)) {
180 BN_zero(x2);
181 BN_zero(z2);
182 return 1;
183 }
184 if (BN_is_zero(z2)) {
185 if (!BN_copy(x2, x))
186 return 0;
187 if (!BN_GF2m_add(z2, x, y))
188 return 0;
189 return 2;
190 }
191 /* Since Mxy is static we can guarantee that ctx != NULL. */
192 BN_CTX_start(ctx);
193 if ((t3 = BN_CTX_get(ctx)) == NULL)
194 goto err;
195 if ((t4 = BN_CTX_get(ctx)) == NULL)
196 goto err;
197 if ((t5 = BN_CTX_get(ctx)) == NULL)
198 goto err;
199
200 if (!BN_one(t5))
201 goto err;
202
203 if (!group->meth->field_mul(group, t3, z1, z2, ctx))
204 goto err;
205
206 if (!group->meth->field_mul(group, z1, z1, x, ctx))
207 goto err;
208 if (!BN_GF2m_add(z1, z1, x1))
209 goto err;
210 if (!group->meth->field_mul(group, z2, z2, x, ctx))
211 goto err;
212 if (!group->meth->field_mul(group, x1, z2, x1, ctx))
213 goto err;
214 if (!BN_GF2m_add(z2, z2, x2))
215 goto err;
216
217 if (!group->meth->field_mul(group, z2, z2, z1, ctx))
218 goto err;
219 if (!group->meth->field_sqr(group, t4, x, ctx))
220 goto err;
221 if (!BN_GF2m_add(t4, t4, y))
222 goto err;
223 if (!group->meth->field_mul(group, t4, t4, t3, ctx))
224 goto err;
225 if (!BN_GF2m_add(t4, t4, z2))
226 goto err;
227
228 if (!group->meth->field_mul(group, t3, t3, x, ctx))
229 goto err;
230 if (!group->meth->field_div(group, t3, t5, t3, ctx))
231 goto err;
232 if (!group->meth->field_mul(group, t4, t3, t4, ctx))
233 goto err;
234 if (!group->meth->field_mul(group, x2, x1, t3, ctx))
235 goto err;
236 if (!BN_GF2m_add(z2, x2, x))
237 goto err;
238
239 if (!group->meth->field_mul(group, z2, z2, t4, ctx))
240 goto err;
241 if (!BN_GF2m_add(z2, z2, y))
242 goto err;
243
244 ret = 2;
245
246err:
247 BN_CTX_end(ctx);
248 return ret;
249}
250
251
252/* Computes scalar*point and stores the result in r.
253 * point can not equal r.
254 * Uses a modified algorithm 2P of
255 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
256 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
257 *
258 * To protect against side-channel attack the function uses constant time swap,
259 * avoiding conditional branches.
260 */
261static int
262ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r,
263 const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx)
264{
265 BIGNUM *x1, *x2, *z1, *z2;
266 int ret = 0, i;
267 BN_ULONG mask, word;
268
269 if (r == point) {
270 ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
271 return 0;
272 }
273 /* if result should be point at infinity */
274 if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
275 EC_POINT_is_at_infinity(group, point) > 0) {
276 return EC_POINT_set_to_infinity(group, r);
277 }
278 /* only support affine coordinates */
279 if (!point->Z_is_one)
280 return 0;
281
282 /* Since point_multiply is static we can guarantee that ctx != NULL. */
283 BN_CTX_start(ctx);
284 if ((x1 = BN_CTX_get(ctx)) == NULL)
285 goto err;
286 if ((z1 = BN_CTX_get(ctx)) == NULL)
287 goto err;
288
289 x2 = &r->X;
290 z2 = &r->Y;
291
292 if (!bn_wexpand(x1, group->field.top))
293 goto err;
294 if (!bn_wexpand(z1, group->field.top))
295 goto err;
296 if (!bn_wexpand(x2, group->field.top))
297 goto err;
298 if (!bn_wexpand(z2, group->field.top))
299 goto err;
300
301 if (!BN_GF2m_mod_arr(x1, &point->X, group->poly))
302 goto err; /* x1 = x */
303 if (!BN_one(z1))
304 goto err; /* z1 = 1 */
305 if (!group->meth->field_sqr(group, z2, x1, ctx))
306 goto err; /* z2 = x1^2 = x^2 */
307 if (!group->meth->field_sqr(group, x2, z2, ctx))
308 goto err;
309 if (!BN_GF2m_add(x2, x2, &group->b))
310 goto err; /* x2 = x^4 + b */
311
312 /* find top most bit and go one past it */
313 i = scalar->top - 1;
314 mask = BN_TBIT;
315 word = scalar->d[i];
316 while (!(word & mask))
317 mask >>= 1;
318 mask >>= 1;
319 /* if top most bit was at word break, go to next word */
320 if (!mask) {
321 i--;
322 mask = BN_TBIT;
323 }
324 for (; i >= 0; i--) {
325 word = scalar->d[i];
326 while (mask) {
327 BN_consttime_swap(word & mask, x1, x2, group->field.top);
328 BN_consttime_swap(word & mask, z1, z2, group->field.top);
329 if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx))
330 goto err;
331 if (!gf2m_Mdouble(group, x1, z1, ctx))
332 goto err;
333 BN_consttime_swap(word & mask, x1, x2, group->field.top);
334 BN_consttime_swap(word & mask, z1, z2, group->field.top);
335 mask >>= 1;
336 }
337 mask = BN_TBIT;
338 }
339
340 /* convert out of "projective" coordinates */
341 i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
342 if (i == 0)
343 goto err;
344 else if (i == 1) {
345 if (!EC_POINT_set_to_infinity(group, r))
346 goto err;
347 } else {
348 if (!BN_one(&r->Z))
349 goto err;
350 r->Z_is_one = 1;
351 }
352
353 /* GF(2^m) field elements should always have BIGNUM::neg = 0 */
354 BN_set_negative(&r->X, 0);
355 BN_set_negative(&r->Y, 0);
356
357 ret = 1;
358
359err:
360 BN_CTX_end(ctx);
361 return ret;
362}
363
364
365/* Computes the sum
366 * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
367 * gracefully ignoring NULL scalar values.
368 */
369int
370ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
371 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
372{
373 BN_CTX *new_ctx = NULL;
374 int ret = 0;
375 size_t i;
376 EC_POINT *p = NULL;
377 EC_POINT *acc = NULL;
378
379 if (ctx == NULL) {
380 ctx = new_ctx = BN_CTX_new();
381 if (ctx == NULL)
382 return 0;
383 }
384 /*
385 * This implementation is more efficient than the wNAF implementation
386 * for 2 or fewer points. Use the ec_wNAF_mul implementation for 3
387 * or more points, or if we can perform a fast multiplication based
388 * on precomputation.
389 */
390 if ((scalar && (num > 1)) || (num > 2) ||
391 (num == 0 && EC_GROUP_have_precompute_mult(group))) {
392 ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
393 goto err;
394 }
395 if ((p = EC_POINT_new(group)) == NULL)
396 goto err;
397 if ((acc = EC_POINT_new(group)) == NULL)
398 goto err;
399
400 if (!EC_POINT_set_to_infinity(group, acc))
401 goto err;
402
403 if (scalar) {
404 if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx))
405 goto err;
406 if (BN_is_negative(scalar))
407 if (!group->meth->invert(group, p, ctx))
408 goto err;
409 if (!group->meth->add(group, acc, acc, p, ctx))
410 goto err;
411 }
412 for (i = 0; i < num; i++) {
413 if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx))
414 goto err;
415 if (BN_is_negative(scalars[i]))
416 if (!group->meth->invert(group, p, ctx))
417 goto err;
418 if (!group->meth->add(group, acc, acc, p, ctx))
419 goto err;
420 }
421
422 if (!EC_POINT_copy(r, acc))
423 goto err;
424
425 ret = 1;
426
427err:
428 EC_POINT_free(p);
429 EC_POINT_free(acc);
430 BN_CTX_free(new_ctx);
431 return ret;
432}
433
434
435/* Precomputation for point multiplication: fall back to wNAF methods
436 * because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */
437
438int
439ec_GF2m_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
440{
441 return ec_wNAF_precompute_mult(group, ctx);
442}
443
444int
445ec_GF2m_have_precompute_mult(const EC_GROUP * group)
446{
447 return ec_wNAF_have_precompute_mult(group);
448}
449
450#endif
diff --git a/src/lib/libcrypto/ec/ec2_oct.c b/src/lib/libcrypto/ec/ec2_oct.c
deleted file mode 100644
index 72690b1bc7..0000000000
--- a/src/lib/libcrypto/ec/ec2_oct.c
+++ /dev/null
@@ -1,382 +0,0 @@
1/* $OpenBSD: ec2_oct.c,v 1.7 2015/02/09 15:49:22 jsing Exp $ */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The software is originally written by Sheueling Chang Shantz and
13 * Douglas Stebila of Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * openssl-core@openssl.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
67 *
68 */
69
70#include <openssl/opensslconf.h>
71
72#include <openssl/err.h>
73
74#include "ec_lcl.h"
75
76#ifndef OPENSSL_NO_EC2M
77
78/* Calculates and sets the affine coordinates of an EC_POINT from the given
79 * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
80 * Note that the simple implementation only uses affine coordinates.
81 *
82 * The method is from the following publication:
83 *
84 * Harper, Menezes, Vanstone:
85 * "Public-Key Cryptosystems with Very Small Key Lengths",
86 * EUROCRYPT '92, Springer-Verlag LNCS 658,
87 * published February 1993
88 *
89 * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
90 * the same method, but claim no priority date earlier than July 29, 1994
91 * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
92 */
93int
94ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
95 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
96{
97 BN_CTX *new_ctx = NULL;
98 BIGNUM *tmp, *x, *y, *z;
99 int ret = 0, z0;
100
101 /* clear error queue */
102 ERR_clear_error();
103
104 if (ctx == NULL) {
105 ctx = new_ctx = BN_CTX_new();
106 if (ctx == NULL)
107 return 0;
108 }
109 y_bit = (y_bit != 0) ? 1 : 0;
110
111 BN_CTX_start(ctx);
112 if ((tmp = BN_CTX_get(ctx)) == NULL)
113 goto err;
114 if ((x = BN_CTX_get(ctx)) == NULL)
115 goto err;
116 if ((y = BN_CTX_get(ctx)) == NULL)
117 goto err;
118 if ((z = BN_CTX_get(ctx)) == NULL)
119 goto err;
120
121 if (!BN_GF2m_mod_arr(x, x_, group->poly))
122 goto err;
123 if (BN_is_zero(x)) {
124 if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx))
125 goto err;
126 } else {
127 if (!group->meth->field_sqr(group, tmp, x, ctx))
128 goto err;
129 if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx))
130 goto err;
131 if (!BN_GF2m_add(tmp, &group->a, tmp))
132 goto err;
133 if (!BN_GF2m_add(tmp, x, tmp))
134 goto err;
135 if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) {
136 unsigned long err = ERR_peek_last_error();
137
138 if (ERR_GET_LIB(err) == ERR_LIB_BN &&
139 ERR_GET_REASON(err) == BN_R_NO_SOLUTION) {
140 ERR_clear_error();
141 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
142 } else
143 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
144 goto err;
145 }
146 z0 = (BN_is_odd(z)) ? 1 : 0;
147 if (!group->meth->field_mul(group, y, x, z, ctx))
148 goto err;
149 if (z0 != y_bit) {
150 if (!BN_GF2m_add(y, y, x))
151 goto err;
152 }
153 }
154
155 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
156 goto err;
157
158 ret = 1;
159
160err:
161 BN_CTX_end(ctx);
162 BN_CTX_free(new_ctx);
163 return ret;
164}
165
166
167/* Converts an EC_POINT to an octet string.
168 * If buf is NULL, the encoded length will be returned.
169 * If the length len of buf is smaller than required an error will be returned.
170 */
171size_t
172ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
173 point_conversion_form_t form,
174 unsigned char *buf, size_t len, BN_CTX * ctx)
175{
176 size_t ret;
177 BN_CTX *new_ctx = NULL;
178 int used_ctx = 0;
179 BIGNUM *x, *y, *yxi;
180 size_t field_len, i, skip;
181
182 if ((form != POINT_CONVERSION_COMPRESSED)
183 && (form != POINT_CONVERSION_UNCOMPRESSED)
184 && (form != POINT_CONVERSION_HYBRID)) {
185 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
186 goto err;
187 }
188 if (EC_POINT_is_at_infinity(group, point) > 0) {
189 /* encodes to a single 0 octet */
190 if (buf != NULL) {
191 if (len < 1) {
192 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
193 return 0;
194 }
195 buf[0] = 0;
196 }
197 return 1;
198 }
199 /* ret := required output buffer length */
200 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
201 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len :
202 1 + 2 * field_len;
203
204 /* if 'buf' is NULL, just return required length */
205 if (buf != NULL) {
206 if (len < ret) {
207 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
208 goto err;
209 }
210 if (ctx == NULL) {
211 ctx = new_ctx = BN_CTX_new();
212 if (ctx == NULL)
213 return 0;
214 }
215 BN_CTX_start(ctx);
216 used_ctx = 1;
217 if ((x = BN_CTX_get(ctx)) == NULL)
218 goto err;
219 if ((y = BN_CTX_get(ctx)) == NULL)
220 goto err;
221 if ((yxi = BN_CTX_get(ctx)) == NULL)
222 goto err;
223
224 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
225 goto err;
226
227 buf[0] = form;
228 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) {
229 if (!group->meth->field_div(group, yxi, y, x, ctx))
230 goto err;
231 if (BN_is_odd(yxi))
232 buf[0]++;
233 }
234 i = 1;
235
236 skip = field_len - BN_num_bytes(x);
237 if (skip > field_len) {
238 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
239 goto err;
240 }
241 while (skip > 0) {
242 buf[i++] = 0;
243 skip--;
244 }
245 skip = BN_bn2bin(x, buf + i);
246 i += skip;
247 if (i != 1 + field_len) {
248 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
249 goto err;
250 }
251 if (form == POINT_CONVERSION_UNCOMPRESSED ||
252 form == POINT_CONVERSION_HYBRID) {
253 skip = field_len - BN_num_bytes(y);
254 if (skip > field_len) {
255 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
256 goto err;
257 }
258 while (skip > 0) {
259 buf[i++] = 0;
260 skip--;
261 }
262 skip = BN_bn2bin(y, buf + i);
263 i += skip;
264 }
265 if (i != ret) {
266 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
267 goto err;
268 }
269 }
270 if (used_ctx)
271 BN_CTX_end(ctx);
272 BN_CTX_free(new_ctx);
273 return ret;
274
275err:
276 if (used_ctx)
277 BN_CTX_end(ctx);
278 BN_CTX_free(new_ctx);
279 return 0;
280}
281
282
283/* Converts an octet string representation to an EC_POINT.
284 * Note that the simple implementation only uses affine coordinates.
285 */
286int
287ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
288 const unsigned char *buf, size_t len, BN_CTX *ctx)
289{
290 point_conversion_form_t form;
291 int y_bit;
292 BN_CTX *new_ctx = NULL;
293 BIGNUM *x, *y, *yxi;
294 size_t field_len, enc_len;
295 int ret = 0;
296
297 if (len == 0) {
298 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
299 return 0;
300 }
301 form = buf[0];
302 y_bit = form & 1;
303 form = form & ~1U;
304 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
305 (form != POINT_CONVERSION_UNCOMPRESSED) &&
306 (form != POINT_CONVERSION_HYBRID)) {
307 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
308 return 0;
309 }
310 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
311 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
312 return 0;
313 }
314 if (form == 0) {
315 if (len != 1) {
316 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
317 return 0;
318 }
319 return EC_POINT_set_to_infinity(group, point);
320 }
321 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
322 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len :
323 1 + 2 * field_len;
324
325 if (len != enc_len) {
326 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
327 return 0;
328 }
329 if (ctx == NULL) {
330 ctx = new_ctx = BN_CTX_new();
331 if (ctx == NULL)
332 return 0;
333 }
334 BN_CTX_start(ctx);
335 if ((x = BN_CTX_get(ctx)) == NULL)
336 goto err;
337 if ((y = BN_CTX_get(ctx)) == NULL)
338 goto err;
339 if ((yxi = BN_CTX_get(ctx)) == NULL)
340 goto err;
341
342 if (!BN_bin2bn(buf + 1, field_len, x))
343 goto err;
344 if (BN_ucmp(x, &group->field) >= 0) {
345 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
346 goto err;
347 }
348 if (form == POINT_CONVERSION_COMPRESSED) {
349 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx))
350 goto err;
351 } else {
352 if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
353 goto err;
354 if (BN_ucmp(y, &group->field) >= 0) {
355 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
356 goto err;
357 }
358 if (form == POINT_CONVERSION_HYBRID) {
359 if (!group->meth->field_div(group, yxi, y, x, ctx))
360 goto err;
361 if (y_bit != BN_is_odd(yxi)) {
362 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
363 goto err;
364 }
365 }
366 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
367 goto err;
368 }
369
370 /* test required by X9.62 */
371 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
372 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
373 goto err;
374 }
375 ret = 1;
376
377err:
378 BN_CTX_end(ctx);
379 BN_CTX_free(new_ctx);
380 return ret;
381}
382#endif
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c
deleted file mode 100644
index 43f0afd5ae..0000000000
--- a/src/lib/libcrypto/ec/ec2_smpl.c
+++ /dev/null
@@ -1,787 +0,0 @@
1/* $OpenBSD: ec2_smpl.c,v 1.14 2015/02/09 15:49:22 jsing Exp $ */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The software is originally written by Sheueling Chang Shantz and
13 * Douglas Stebila of Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * openssl-core@openssl.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
67 *
68 */
69
70#include <openssl/opensslconf.h>
71
72#include <openssl/err.h>
73
74#include "ec_lcl.h"
75
76#ifndef OPENSSL_NO_EC2M
77
78const EC_METHOD *
79EC_GF2m_simple_method(void)
80{
81 static const EC_METHOD ret = {
82 .flags = EC_FLAGS_DEFAULT_OCT,
83 .field_type = NID_X9_62_characteristic_two_field,
84 .group_init = ec_GF2m_simple_group_init,
85 .group_finish = ec_GF2m_simple_group_finish,
86 .group_clear_finish = ec_GF2m_simple_group_clear_finish,
87 .group_copy = ec_GF2m_simple_group_copy,
88 .group_set_curve = ec_GF2m_simple_group_set_curve,
89 .group_get_curve = ec_GF2m_simple_group_get_curve,
90 .group_get_degree = ec_GF2m_simple_group_get_degree,
91 .group_check_discriminant =
92 ec_GF2m_simple_group_check_discriminant,
93 .point_init = ec_GF2m_simple_point_init,
94 .point_finish = ec_GF2m_simple_point_finish,
95 .point_clear_finish = ec_GF2m_simple_point_clear_finish,
96 .point_copy = ec_GF2m_simple_point_copy,
97 .point_set_to_infinity = ec_GF2m_simple_point_set_to_infinity,
98 .point_set_affine_coordinates =
99 ec_GF2m_simple_point_set_affine_coordinates,
100 .point_get_affine_coordinates =
101 ec_GF2m_simple_point_get_affine_coordinates,
102 .add = ec_GF2m_simple_add,
103 .dbl = ec_GF2m_simple_dbl,
104 .invert = ec_GF2m_simple_invert,
105 .is_at_infinity = ec_GF2m_simple_is_at_infinity,
106 .is_on_curve = ec_GF2m_simple_is_on_curve,
107 .point_cmp = ec_GF2m_simple_cmp,
108 .make_affine = ec_GF2m_simple_make_affine,
109 .points_make_affine = ec_GF2m_simple_points_make_affine,
110
111 /*
112 * the following three method functions are defined in
113 * ec2_mult.c
114 */
115 .mul = ec_GF2m_simple_mul,
116 .precompute_mult = ec_GF2m_precompute_mult,
117 .have_precompute_mult = ec_GF2m_have_precompute_mult,
118
119 .field_mul = ec_GF2m_simple_field_mul,
120 .field_sqr = ec_GF2m_simple_field_sqr,
121 .field_div = ec_GF2m_simple_field_div,
122 };
123
124 return &ret;
125}
126
127
128/* Initialize a GF(2^m)-based EC_GROUP structure.
129 * Note that all other members are handled by EC_GROUP_new.
130 */
131int
132ec_GF2m_simple_group_init(EC_GROUP * group)
133{
134 BN_init(&group->field);
135 BN_init(&group->a);
136 BN_init(&group->b);
137 return 1;
138}
139
140
141/* Free a GF(2^m)-based EC_GROUP structure.
142 * Note that all other members are handled by EC_GROUP_free.
143 */
144void
145ec_GF2m_simple_group_finish(EC_GROUP * group)
146{
147 BN_free(&group->field);
148 BN_free(&group->a);
149 BN_free(&group->b);
150}
151
152
153/* Clear and free a GF(2^m)-based EC_GROUP structure.
154 * Note that all other members are handled by EC_GROUP_clear_free.
155 */
156void
157ec_GF2m_simple_group_clear_finish(EC_GROUP * group)
158{
159 BN_clear_free(&group->field);
160 BN_clear_free(&group->a);
161 BN_clear_free(&group->b);
162 group->poly[0] = 0;
163 group->poly[1] = 0;
164 group->poly[2] = 0;
165 group->poly[3] = 0;
166 group->poly[4] = 0;
167 group->poly[5] = -1;
168}
169
170
171/* Copy a GF(2^m)-based EC_GROUP structure.
172 * Note that all other members are handled by EC_GROUP_copy.
173 */
174int
175ec_GF2m_simple_group_copy(EC_GROUP * dest, const EC_GROUP * src)
176{
177 int i;
178
179 if (!BN_copy(&dest->field, &src->field))
180 return 0;
181 if (!BN_copy(&dest->a, &src->a))
182 return 0;
183 if (!BN_copy(&dest->b, &src->b))
184 return 0;
185 dest->poly[0] = src->poly[0];
186 dest->poly[1] = src->poly[1];
187 dest->poly[2] = src->poly[2];
188 dest->poly[3] = src->poly[3];
189 dest->poly[4] = src->poly[4];
190 dest->poly[5] = src->poly[5];
191 if (bn_wexpand(&dest->a, (int) (dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
192 return 0;
193 if (bn_wexpand(&dest->b, (int) (dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
194 return 0;
195 for (i = dest->a.top; i < dest->a.dmax; i++)
196 dest->a.d[i] = 0;
197 for (i = dest->b.top; i < dest->b.dmax; i++)
198 dest->b.d[i] = 0;
199 return 1;
200}
201
202
203/* Set the curve parameters of an EC_GROUP structure. */
204int
205ec_GF2m_simple_group_set_curve(EC_GROUP * group,
206 const BIGNUM * p, const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
207{
208 int ret = 0, i;
209
210 /* group->field */
211 if (!BN_copy(&group->field, p))
212 goto err;
213 i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
214 if ((i != 5) && (i != 3)) {
215 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
216 goto err;
217 }
218 /* group->a */
219 if (!BN_GF2m_mod_arr(&group->a, a, group->poly))
220 goto err;
221 if (bn_wexpand(&group->a, (int) (group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
222 goto err;
223 for (i = group->a.top; i < group->a.dmax; i++)
224 group->a.d[i] = 0;
225
226 /* group->b */
227 if (!BN_GF2m_mod_arr(&group->b, b, group->poly))
228 goto err;
229 if (bn_wexpand(&group->b, (int) (group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
230 goto err;
231 for (i = group->b.top; i < group->b.dmax; i++)
232 group->b.d[i] = 0;
233
234 ret = 1;
235err:
236 return ret;
237}
238
239
240/* Get the curve parameters of an EC_GROUP structure.
241 * If p, a, or b are NULL then there values will not be set but the method will return with success.
242 */
243int
244ec_GF2m_simple_group_get_curve(const EC_GROUP *group,
245 BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
246{
247 int ret = 0;
248
249 if (p != NULL) {
250 if (!BN_copy(p, &group->field))
251 return 0;
252 }
253 if (a != NULL) {
254 if (!BN_copy(a, &group->a))
255 goto err;
256 }
257 if (b != NULL) {
258 if (!BN_copy(b, &group->b))
259 goto err;
260 }
261 ret = 1;
262
263err:
264 return ret;
265}
266
267
268/* Gets the degree of the field. For a curve over GF(2^m) this is the value m. */
269int
270ec_GF2m_simple_group_get_degree(const EC_GROUP * group)
271{
272 return BN_num_bits(&group->field) - 1;
273}
274
275
276/* Checks the discriminant of the curve.
277 * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
278 */
279int
280ec_GF2m_simple_group_check_discriminant(const EC_GROUP * group, BN_CTX * ctx)
281{
282 int ret = 0;
283 BIGNUM *b;
284 BN_CTX *new_ctx = NULL;
285
286 if (ctx == NULL) {
287 ctx = new_ctx = BN_CTX_new();
288 if (ctx == NULL) {
289 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
290 goto err;
291 }
292 }
293 BN_CTX_start(ctx);
294 if ((b = BN_CTX_get(ctx)) == NULL)
295 goto err;
296
297 if (!BN_GF2m_mod_arr(b, &group->b, group->poly))
298 goto err;
299
300 /*
301 * check the discriminant: y^2 + x*y = x^3 + a*x^2 + b is an elliptic
302 * curve <=> b != 0 (mod p)
303 */
304 if (BN_is_zero(b))
305 goto err;
306
307 ret = 1;
308
309err:
310 if (ctx != NULL)
311 BN_CTX_end(ctx);
312 BN_CTX_free(new_ctx);
313 return ret;
314}
315
316
317/* Initializes an EC_POINT. */
318int
319ec_GF2m_simple_point_init(EC_POINT * point)
320{
321 BN_init(&point->X);
322 BN_init(&point->Y);
323 BN_init(&point->Z);
324 return 1;
325}
326
327
328/* Frees an EC_POINT. */
329void
330ec_GF2m_simple_point_finish(EC_POINT * point)
331{
332 BN_free(&point->X);
333 BN_free(&point->Y);
334 BN_free(&point->Z);
335}
336
337
338/* Clears and frees an EC_POINT. */
339void
340ec_GF2m_simple_point_clear_finish(EC_POINT * point)
341{
342 BN_clear_free(&point->X);
343 BN_clear_free(&point->Y);
344 BN_clear_free(&point->Z);
345 point->Z_is_one = 0;
346}
347
348
349/* Copy the contents of one EC_POINT into another. Assumes dest is initialized. */
350int
351ec_GF2m_simple_point_copy(EC_POINT * dest, const EC_POINT * src)
352{
353 if (!BN_copy(&dest->X, &src->X))
354 return 0;
355 if (!BN_copy(&dest->Y, &src->Y))
356 return 0;
357 if (!BN_copy(&dest->Z, &src->Z))
358 return 0;
359 dest->Z_is_one = src->Z_is_one;
360
361 return 1;
362}
363
364
365/* Set an EC_POINT to the point at infinity.
366 * A point at infinity is represented by having Z=0.
367 */
368int
369ec_GF2m_simple_point_set_to_infinity(const EC_GROUP * group, EC_POINT * point)
370{
371 point->Z_is_one = 0;
372 BN_zero(&point->Z);
373 return 1;
374}
375
376
377/* Set the coordinates of an EC_POINT using affine coordinates.
378 * Note that the simple implementation only uses affine coordinates.
379 */
380int
381ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP * group, EC_POINT * point,
382 const BIGNUM * x, const BIGNUM * y, BN_CTX * ctx)
383{
384 int ret = 0;
385 if (x == NULL || y == NULL) {
386 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
387 return 0;
388 }
389 if (!BN_copy(&point->X, x))
390 goto err;
391 BN_set_negative(&point->X, 0);
392 if (!BN_copy(&point->Y, y))
393 goto err;
394 BN_set_negative(&point->Y, 0);
395 if (!BN_copy(&point->Z, BN_value_one()))
396 goto err;
397 BN_set_negative(&point->Z, 0);
398 point->Z_is_one = 1;
399 ret = 1;
400
401err:
402 return ret;
403}
404
405
406/* Gets the affine coordinates of an EC_POINT.
407 * Note that the simple implementation only uses affine coordinates.
408 */
409int
410ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group,
411 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
412{
413 int ret = 0;
414
415 if (EC_POINT_is_at_infinity(group, point) > 0) {
416 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
417 return 0;
418 }
419 if (BN_cmp(&point->Z, BN_value_one())) {
420 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
421 return 0;
422 }
423 if (x != NULL) {
424 if (!BN_copy(x, &point->X))
425 goto err;
426 BN_set_negative(x, 0);
427 }
428 if (y != NULL) {
429 if (!BN_copy(y, &point->Y))
430 goto err;
431 BN_set_negative(y, 0);
432 }
433 ret = 1;
434
435err:
436 return ret;
437}
438
439/* Computes a + b and stores the result in r. r could be a or b, a could be b.
440 * Uses algorithm A.10.2 of IEEE P1363.
441 */
442int
443ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
444 const EC_POINT *b, BN_CTX *ctx)
445{
446 BN_CTX *new_ctx = NULL;
447 BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
448 int ret = 0;
449
450 if (EC_POINT_is_at_infinity(group, a) > 0) {
451 if (!EC_POINT_copy(r, b))
452 return 0;
453 return 1;
454 }
455 if (EC_POINT_is_at_infinity(group, b) > 0) {
456 if (!EC_POINT_copy(r, a))
457 return 0;
458 return 1;
459 }
460 if (ctx == NULL) {
461 ctx = new_ctx = BN_CTX_new();
462 if (ctx == NULL)
463 return 0;
464 }
465 BN_CTX_start(ctx);
466 if ((x0 = BN_CTX_get(ctx)) == NULL)
467 goto err;
468 if ((y0 = BN_CTX_get(ctx)) == NULL)
469 goto err;
470 if ((x1 = BN_CTX_get(ctx)) == NULL)
471 goto err;
472 if ((y1 = BN_CTX_get(ctx)) == NULL)
473 goto err;
474 if ((x2 = BN_CTX_get(ctx)) == NULL)
475 goto err;
476 if ((y2 = BN_CTX_get(ctx)) == NULL)
477 goto err;
478 if ((s = BN_CTX_get(ctx)) == NULL)
479 goto err;
480 if ((t = BN_CTX_get(ctx)) == NULL)
481 goto err;
482
483 if (a->Z_is_one) {
484 if (!BN_copy(x0, &a->X))
485 goto err;
486 if (!BN_copy(y0, &a->Y))
487 goto err;
488 } else {
489 if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx))
490 goto err;
491 }
492 if (b->Z_is_one) {
493 if (!BN_copy(x1, &b->X))
494 goto err;
495 if (!BN_copy(y1, &b->Y))
496 goto err;
497 } else {
498 if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx))
499 goto err;
500 }
501
502
503 if (BN_GF2m_cmp(x0, x1)) {
504 if (!BN_GF2m_add(t, x0, x1))
505 goto err;
506 if (!BN_GF2m_add(s, y0, y1))
507 goto err;
508 if (!group->meth->field_div(group, s, s, t, ctx))
509 goto err;
510 if (!group->meth->field_sqr(group, x2, s, ctx))
511 goto err;
512 if (!BN_GF2m_add(x2, x2, &group->a))
513 goto err;
514 if (!BN_GF2m_add(x2, x2, s))
515 goto err;
516 if (!BN_GF2m_add(x2, x2, t))
517 goto err;
518 } else {
519 if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) {
520 if (!EC_POINT_set_to_infinity(group, r))
521 goto err;
522 ret = 1;
523 goto err;
524 }
525 if (!group->meth->field_div(group, s, y1, x1, ctx))
526 goto err;
527 if (!BN_GF2m_add(s, s, x1))
528 goto err;
529
530 if (!group->meth->field_sqr(group, x2, s, ctx))
531 goto err;
532 if (!BN_GF2m_add(x2, x2, s))
533 goto err;
534 if (!BN_GF2m_add(x2, x2, &group->a))
535 goto err;
536 }
537
538 if (!BN_GF2m_add(y2, x1, x2))
539 goto err;
540 if (!group->meth->field_mul(group, y2, y2, s, ctx))
541 goto err;
542 if (!BN_GF2m_add(y2, y2, x2))
543 goto err;
544 if (!BN_GF2m_add(y2, y2, y1))
545 goto err;
546
547 if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx))
548 goto err;
549
550 ret = 1;
551
552err:
553 BN_CTX_end(ctx);
554 BN_CTX_free(new_ctx);
555 return ret;
556}
557
558
559/* Computes 2 * a and stores the result in r. r could be a.
560 * Uses algorithm A.10.2 of IEEE P1363.
561 */
562int
563ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
564 BN_CTX *ctx)
565{
566 return ec_GF2m_simple_add(group, r, a, a, ctx);
567}
568
569int
570ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
571{
572 if (EC_POINT_is_at_infinity(group, point) > 0 || BN_is_zero(&point->Y))
573 /* point is its own inverse */
574 return 1;
575
576 if (!EC_POINT_make_affine(group, point, ctx))
577 return 0;
578 return BN_GF2m_add(&point->Y, &point->X, &point->Y);
579}
580
581
582/* Indicates whether the given point is the point at infinity. */
583int
584ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
585{
586 return BN_is_zero(&point->Z);
587}
588
589
590/* Determines whether the given EC_POINT is an actual point on the curve defined
591 * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
592 * y^2 + x*y = x^3 + a*x^2 + b.
593 */
594int
595ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
596{
597 int ret = -1;
598 BN_CTX *new_ctx = NULL;
599 BIGNUM *lh, *y2;
600 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
601 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
602
603 if (EC_POINT_is_at_infinity(group, point) > 0)
604 return 1;
605
606 field_mul = group->meth->field_mul;
607 field_sqr = group->meth->field_sqr;
608
609 /* only support affine coordinates */
610 if (!point->Z_is_one)
611 return -1;
612
613 if (ctx == NULL) {
614 ctx = new_ctx = BN_CTX_new();
615 if (ctx == NULL)
616 return -1;
617 }
618 BN_CTX_start(ctx);
619 if ((y2 = BN_CTX_get(ctx)) == NULL)
620 goto err;
621 if ((lh = BN_CTX_get(ctx)) == NULL)
622 goto err;
623
624 /*
625 * We have a curve defined by a Weierstrass equation y^2 + x*y = x^3
626 * + a*x^2 + b. <=> x^3 + a*x^2 + x*y + b + y^2 = 0 <=> ((x + a) * x
627 * + y ) * x + b + y^2 = 0
628 */
629 if (!BN_GF2m_add(lh, &point->X, &group->a))
630 goto err;
631 if (!field_mul(group, lh, lh, &point->X, ctx))
632 goto err;
633 if (!BN_GF2m_add(lh, lh, &point->Y))
634 goto err;
635 if (!field_mul(group, lh, lh, &point->X, ctx))
636 goto err;
637 if (!BN_GF2m_add(lh, lh, &group->b))
638 goto err;
639 if (!field_sqr(group, y2, &point->Y, ctx))
640 goto err;
641 if (!BN_GF2m_add(lh, lh, y2))
642 goto err;
643 ret = BN_is_zero(lh);
644err:
645 if (ctx)
646 BN_CTX_end(ctx);
647 BN_CTX_free(new_ctx);
648 return ret;
649}
650
651
652/* Indicates whether two points are equal.
653 * Return values:
654 * -1 error
655 * 0 equal (in affine coordinates)
656 * 1 not equal
657 */
658int
659ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
660 const EC_POINT *b, BN_CTX *ctx)
661{
662 BIGNUM *aX, *aY, *bX, *bY;
663 BN_CTX *new_ctx = NULL;
664 int ret = -1;
665
666 if (EC_POINT_is_at_infinity(group, a) > 0) {
667 return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1;
668 }
669 if (EC_POINT_is_at_infinity(group, b) > 0)
670 return 1;
671
672 if (a->Z_is_one && b->Z_is_one) {
673 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
674 }
675 if (ctx == NULL) {
676 ctx = new_ctx = BN_CTX_new();
677 if (ctx == NULL)
678 return -1;
679 }
680 BN_CTX_start(ctx);
681 if ((aX = BN_CTX_get(ctx)) == NULL)
682 goto err;
683 if ((aY = BN_CTX_get(ctx)) == NULL)
684 goto err;
685 if ((bX = BN_CTX_get(ctx)) == NULL)
686 goto err;
687 if ((bY = BN_CTX_get(ctx)) == NULL)
688 goto err;
689
690 if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx))
691 goto err;
692 if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx))
693 goto err;
694 ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
695
696err:
697 if (ctx)
698 BN_CTX_end(ctx);
699 BN_CTX_free(new_ctx);
700 return ret;
701}
702
703
704/* Forces the given EC_POINT to internally use affine coordinates. */
705int
706ec_GF2m_simple_make_affine(const EC_GROUP * group, EC_POINT * point, BN_CTX * ctx)
707{
708 BN_CTX *new_ctx = NULL;
709 BIGNUM *x, *y;
710 int ret = 0;
711
712 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0)
713 return 1;
714
715 if (ctx == NULL) {
716 ctx = new_ctx = BN_CTX_new();
717 if (ctx == NULL)
718 return 0;
719 }
720 BN_CTX_start(ctx);
721 if ((x = BN_CTX_get(ctx)) == NULL)
722 goto err;
723 if ((y = BN_CTX_get(ctx)) == NULL)
724 goto err;
725
726 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
727 goto err;
728 if (!BN_copy(&point->X, x))
729 goto err;
730 if (!BN_copy(&point->Y, y))
731 goto err;
732 if (!BN_one(&point->Z))
733 goto err;
734
735 ret = 1;
736
737err:
738 if (ctx)
739 BN_CTX_end(ctx);
740 BN_CTX_free(new_ctx);
741 return ret;
742}
743
744
745/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
746int
747ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num,
748 EC_POINT *points[], BN_CTX *ctx)
749{
750 size_t i;
751
752 for (i = 0; i < num; i++) {
753 if (!group->meth->make_affine(group, points[i], ctx))
754 return 0;
755 }
756
757 return 1;
758}
759
760
761/* Wrapper to simple binary polynomial field multiplication implementation. */
762int
763ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
764 const BIGNUM *b, BN_CTX *ctx)
765{
766 return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
767}
768
769
770/* Wrapper to simple binary polynomial field squaring implementation. */
771int
772ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
773 BN_CTX *ctx)
774{
775 return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
776}
777
778
779/* Wrapper to simple binary polynomial field division implementation. */
780int
781ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
782 const BIGNUM *b, BN_CTX *ctx)
783{
784 return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
785}
786
787#endif
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c
deleted file mode 100644
index dd1c31883e..0000000000
--- a/src/lib/libcrypto/ec/ec_ameth.c
+++ /dev/null
@@ -1,636 +0,0 @@
1/* $OpenBSD: ec_ameth.c,v 1.16 2015/02/11 04:05:14 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 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 * licensing@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#include <stdio.h>
60
61#include <openssl/opensslconf.h>
62
63#include <openssl/bn.h>
64#include <openssl/ec.h>
65#include <openssl/err.h>
66#include <openssl/x509.h>
67
68#ifndef OPENSSL_NO_CMS
69#include <openssl/cms.h>
70#endif
71
72#include "asn1_locl.h"
73
74static int
75eckey_param2type(int *pptype, void **ppval, EC_KEY * ec_key)
76{
77 const EC_GROUP *group;
78 int nid;
79 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
80 ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
81 return 0;
82 }
83 if (EC_GROUP_get_asn1_flag(group) &&
84 (nid = EC_GROUP_get_curve_name(group))) {
85 /* we have a 'named curve' => just set the OID */
86 *ppval = OBJ_nid2obj(nid);
87 *pptype = V_ASN1_OBJECT;
88 } else {
89 /* explicit parameters */
90 ASN1_STRING *pstr = NULL;
91 pstr = ASN1_STRING_new();
92 if (!pstr)
93 return 0;
94 pstr->length = i2d_ECParameters(ec_key, &pstr->data);
95 if (pstr->length <= 0) {
96 ASN1_STRING_free(pstr);
97 ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
98 return 0;
99 }
100 *ppval = pstr;
101 *pptype = V_ASN1_SEQUENCE;
102 }
103 return 1;
104}
105
106static int
107eckey_pub_encode(X509_PUBKEY * pk, const EVP_PKEY * pkey)
108{
109 EC_KEY *ec_key = pkey->pkey.ec;
110 void *pval = NULL;
111 int ptype;
112 unsigned char *penc = NULL, *p;
113 int penclen;
114
115 if (!eckey_param2type(&ptype, &pval, ec_key)) {
116 ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
117 return 0;
118 }
119 penclen = i2o_ECPublicKey(ec_key, NULL);
120 if (penclen <= 0)
121 goto err;
122 penc = malloc(penclen);
123 if (!penc)
124 goto err;
125 p = penc;
126 penclen = i2o_ECPublicKey(ec_key, &p);
127 if (penclen <= 0)
128 goto err;
129 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
130 ptype, pval, penc, penclen))
131 return 1;
132err:
133 if (ptype == V_ASN1_OBJECT)
134 ASN1_OBJECT_free(pval);
135 else
136 ASN1_STRING_free(pval);
137 free(penc);
138 return 0;
139}
140
141static EC_KEY *
142eckey_type2param(int ptype, void *pval)
143{
144 EC_KEY *eckey = NULL;
145
146 if (ptype == V_ASN1_SEQUENCE) {
147 ASN1_STRING *pstr = pval;
148 const unsigned char *pm = NULL;
149 int pmlen;
150
151 pm = pstr->data;
152 pmlen = pstr->length;
153 if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
154 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
155 goto ecerr;
156 }
157 } else if (ptype == V_ASN1_OBJECT) {
158 ASN1_OBJECT *poid = pval;
159 EC_GROUP *group;
160
161 /*
162 * type == V_ASN1_OBJECT => the parameters are given by an
163 * asn1 OID
164 */
165 if ((eckey = EC_KEY_new()) == NULL) {
166 ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
167 goto ecerr;
168 }
169 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
170 if (group == NULL)
171 goto ecerr;
172 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
173 if (EC_KEY_set_group(eckey, group) == 0)
174 goto ecerr;
175 EC_GROUP_free(group);
176 } else {
177 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
178 goto ecerr;
179 }
180
181 return eckey;
182
183ecerr:
184 if (eckey)
185 EC_KEY_free(eckey);
186 return NULL;
187}
188
189static int
190eckey_pub_decode(EVP_PKEY * pkey, X509_PUBKEY * pubkey)
191{
192 const unsigned char *p = NULL;
193 void *pval;
194 int ptype, pklen;
195 EC_KEY *eckey = NULL;
196 X509_ALGOR *palg;
197
198 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
199 return 0;
200 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
201
202 eckey = eckey_type2param(ptype, pval);
203
204 if (!eckey) {
205 ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
206 return 0;
207 }
208 /* We have parameters now set public key */
209 if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
210 ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
211 goto ecerr;
212 }
213 EVP_PKEY_assign_EC_KEY(pkey, eckey);
214 return 1;
215
216ecerr:
217 if (eckey)
218 EC_KEY_free(eckey);
219 return 0;
220}
221
222static int
223eckey_pub_cmp(const EVP_PKEY * a, const EVP_PKEY * b)
224{
225 int r;
226 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
227 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec);
228
229 r = EC_POINT_cmp(group, pa, pb, NULL);
230 if (r == 0)
231 return 1;
232 if (r == 1)
233 return 0;
234 return -2;
235}
236
237static int
238eckey_priv_decode(EVP_PKEY * pkey, PKCS8_PRIV_KEY_INFO * p8)
239{
240 const unsigned char *p = NULL;
241 void *pval;
242 int ptype, pklen;
243 EC_KEY *eckey = NULL;
244 X509_ALGOR *palg;
245
246 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
247 return 0;
248 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
249
250 eckey = eckey_type2param(ptype, pval);
251
252 if (!eckey)
253 goto ecliberr;
254
255 /* We have parameters now set private key */
256 if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
257 ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
258 goto ecerr;
259 }
260 /* calculate public key (if necessary) */
261 if (EC_KEY_get0_public_key(eckey) == NULL) {
262 const BIGNUM *priv_key;
263 const EC_GROUP *group;
264 EC_POINT *pub_key;
265 /*
266 * the public key was not included in the SEC1 private key =>
267 * calculate the public key
268 */
269 group = EC_KEY_get0_group(eckey);
270 pub_key = EC_POINT_new(group);
271 if (pub_key == NULL) {
272 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
273 goto ecliberr;
274 }
275 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
276 EC_POINT_free(pub_key);
277 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
278 goto ecliberr;
279 }
280 priv_key = EC_KEY_get0_private_key(eckey);
281 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
282 EC_POINT_free(pub_key);
283 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
284 goto ecliberr;
285 }
286 if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
287 EC_POINT_free(pub_key);
288 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
289 goto ecliberr;
290 }
291 EC_POINT_free(pub_key);
292 }
293 EVP_PKEY_assign_EC_KEY(pkey, eckey);
294 return 1;
295
296ecliberr:
297 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
298ecerr:
299 if (eckey)
300 EC_KEY_free(eckey);
301 return 0;
302}
303
304static int
305eckey_priv_encode(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pkey)
306{
307 EC_KEY *ec_key;
308 unsigned char *ep, *p;
309 int eplen, ptype;
310 void *pval;
311 unsigned int tmp_flags, old_flags;
312
313 ec_key = pkey->pkey.ec;
314
315 if (!eckey_param2type(&ptype, &pval, ec_key)) {
316 ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
317 return 0;
318 }
319 /* set the private key */
320
321 /*
322 * do not include the parameters in the SEC1 private key see PKCS#11
323 * 12.11
324 */
325 old_flags = EC_KEY_get_enc_flags(ec_key);
326 tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
327 EC_KEY_set_enc_flags(ec_key, tmp_flags);
328 eplen = i2d_ECPrivateKey(ec_key, NULL);
329 if (!eplen) {
330 EC_KEY_set_enc_flags(ec_key, old_flags);
331 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
332 return 0;
333 }
334 ep = malloc(eplen);
335 if (!ep) {
336 EC_KEY_set_enc_flags(ec_key, old_flags);
337 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
338 return 0;
339 }
340 p = ep;
341 if (!i2d_ECPrivateKey(ec_key, &p)) {
342 EC_KEY_set_enc_flags(ec_key, old_flags);
343 free(ep);
344 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
345 return 0;
346 }
347 /* restore old encoding flags */
348 EC_KEY_set_enc_flags(ec_key, old_flags);
349
350 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
351 ptype, pval, ep, eplen))
352 return 0;
353
354 return 1;
355}
356
357static int
358int_ec_size(const EVP_PKEY * pkey)
359{
360 return ECDSA_size(pkey->pkey.ec);
361}
362
363static int
364ec_bits(const EVP_PKEY * pkey)
365{
366 BIGNUM *order = BN_new();
367 const EC_GROUP *group;
368 int ret;
369
370 if (!order) {
371 ERR_clear_error();
372 return 0;
373 }
374 group = EC_KEY_get0_group(pkey->pkey.ec);
375 if (!EC_GROUP_get_order(group, order, NULL)) {
376 BN_free(order);
377 ERR_clear_error();
378 return 0;
379 }
380 ret = BN_num_bits(order);
381 BN_free(order);
382 return ret;
383}
384
385static int
386ec_missing_parameters(const EVP_PKEY * pkey)
387{
388 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
389 return 1;
390 return 0;
391}
392
393static int
394ec_copy_parameters(EVP_PKEY * to, const EVP_PKEY * from)
395{
396 return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec));
397}
398
399static int
400ec_cmp_parameters(const EVP_PKEY * a, const EVP_PKEY * b)
401{
402 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec);
403 if (EC_GROUP_cmp(group_a, group_b, NULL))
404 return 0;
405 else
406 return 1;
407}
408
409static void
410int_ec_free(EVP_PKEY * pkey)
411{
412 EC_KEY_free(pkey->pkey.ec);
413}
414
415static int
416do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype)
417{
418 unsigned char *buffer = NULL;
419 const char *ecstr;
420 size_t buf_len = 0, i;
421 int ret = 0, reason = ERR_R_BIO_LIB;
422 BIGNUM *pub_key = NULL, *order = NULL;
423 BN_CTX *ctx = NULL;
424 const EC_GROUP *group;
425 const EC_POINT *public_key;
426 const BIGNUM *priv_key;
427
428 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
429 reason = ERR_R_PASSED_NULL_PARAMETER;
430 goto err;
431 }
432 ctx = BN_CTX_new();
433 if (ctx == NULL) {
434 reason = ERR_R_MALLOC_FAILURE;
435 goto err;
436 }
437 if (ktype > 0) {
438 public_key = EC_KEY_get0_public_key(x);
439 if ((pub_key = EC_POINT_point2bn(group, public_key,
440 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) {
441 reason = ERR_R_EC_LIB;
442 goto err;
443 }
444 if (pub_key)
445 buf_len = (size_t) BN_num_bytes(pub_key);
446 }
447 if (ktype == 2) {
448 priv_key = EC_KEY_get0_private_key(x);
449 if (priv_key && (i = (size_t) BN_num_bytes(priv_key)) > buf_len)
450 buf_len = i;
451 } else
452 priv_key = NULL;
453
454 if (ktype > 0) {
455 buf_len += 10;
456 if ((buffer = malloc(buf_len)) == NULL) {
457 reason = ERR_R_MALLOC_FAILURE;
458 goto err;
459 }
460 }
461 if (ktype == 2)
462 ecstr = "Private-Key";
463 else if (ktype == 1)
464 ecstr = "Public-Key";
465 else
466 ecstr = "ECDSA-Parameters";
467
468 if (!BIO_indent(bp, off, 128))
469 goto err;
470 if ((order = BN_new()) == NULL)
471 goto err;
472 if (!EC_GROUP_get_order(group, order, NULL))
473 goto err;
474 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
475 BN_num_bits(order)) <= 0)
476 goto err;
477
478 if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
479 buffer, off))
480 goto err;
481 if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
482 buffer, off))
483 goto err;
484 if (!ECPKParameters_print(bp, group, off))
485 goto err;
486 ret = 1;
487err:
488 if (!ret)
489 ECerr(EC_F_DO_EC_KEY_PRINT, reason);
490 BN_free(pub_key);
491 BN_free(order);
492 BN_CTX_free(ctx);
493 free(buffer);
494 return (ret);
495}
496
497static int
498eckey_param_decode(EVP_PKEY * pkey,
499 const unsigned char **pder, int derlen)
500{
501 EC_KEY *eckey;
502 if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
503 ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
504 return 0;
505 }
506 EVP_PKEY_assign_EC_KEY(pkey, eckey);
507 return 1;
508}
509
510static int
511eckey_param_encode(const EVP_PKEY * pkey, unsigned char **pder)
512{
513 return i2d_ECParameters(pkey->pkey.ec, pder);
514}
515
516static int
517eckey_param_print(BIO * bp, const EVP_PKEY * pkey, int indent,
518 ASN1_PCTX * ctx)
519{
520 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
521}
522
523static int
524eckey_pub_print(BIO * bp, const EVP_PKEY * pkey, int indent,
525 ASN1_PCTX * ctx)
526{
527 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
528}
529
530
531static int
532eckey_priv_print(BIO * bp, const EVP_PKEY * pkey, int indent,
533 ASN1_PCTX * ctx)
534{
535 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
536}
537
538static int
539old_ec_priv_decode(EVP_PKEY * pkey,
540 const unsigned char **pder, int derlen)
541{
542 EC_KEY *ec;
543 if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
544 ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
545 return 0;
546 }
547 EVP_PKEY_assign_EC_KEY(pkey, ec);
548 return 1;
549}
550
551static int
552old_ec_priv_encode(const EVP_PKEY * pkey, unsigned char **pder)
553{
554 return i2d_ECPrivateKey(pkey->pkey.ec, pder);
555}
556
557static int
558ec_pkey_ctrl(EVP_PKEY * pkey, int op, long arg1, void *arg2)
559{
560 switch (op) {
561 case ASN1_PKEY_CTRL_PKCS7_SIGN:
562 if (arg1 == 0) {
563 int snid, hnid;
564 X509_ALGOR *alg1, *alg2;
565 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
566 if (alg1 == NULL || alg1->algorithm == NULL)
567 return -1;
568 hnid = OBJ_obj2nid(alg1->algorithm);
569 if (hnid == NID_undef)
570 return -1;
571 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
572 return -1;
573 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
574 }
575 return 1;
576#ifndef OPENSSL_NO_CMS
577 case ASN1_PKEY_CTRL_CMS_SIGN:
578 if (arg1 == 0) {
579 int snid, hnid;
580 X509_ALGOR *alg1, *alg2;
581 CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
582 &alg1, &alg2);
583 if (alg1 == NULL || alg1->algorithm == NULL)
584 return -1;
585 hnid = OBJ_obj2nid(alg1->algorithm);
586 if (hnid == NID_undef)
587 return -1;
588 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
589 return -1;
590 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
591 }
592 return 1;
593#endif
594
595 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
596 *(int *) arg2 = NID_sha1;
597 return 2;
598
599 default:
600 return -2;
601
602 }
603
604}
605
606const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
607 .pkey_id = EVP_PKEY_EC,
608 .pkey_base_id = EVP_PKEY_EC,
609
610 .pem_str = "EC",
611 .info = "OpenSSL EC algorithm",
612
613 .pub_decode = eckey_pub_decode,
614 .pub_encode = eckey_pub_encode,
615 .pub_cmp = eckey_pub_cmp,
616 .pub_print = eckey_pub_print,
617
618 .priv_decode = eckey_priv_decode,
619 .priv_encode = eckey_priv_encode,
620 .priv_print = eckey_priv_print,
621
622 .pkey_size = int_ec_size,
623 .pkey_bits = ec_bits,
624
625 .param_decode = eckey_param_decode,
626 .param_encode = eckey_param_encode,
627 .param_missing = ec_missing_parameters,
628 .param_copy = ec_copy_parameters,
629 .param_cmp = ec_cmp_parameters,
630 .param_print = eckey_param_print,
631
632 .pkey_free = int_ec_free,
633 .pkey_ctrl = ec_pkey_ctrl,
634 .old_priv_decode = old_ec_priv_decode,
635 .old_priv_encode = old_ec_priv_encode
636};
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
deleted file mode 100644
index 3234e7a6f2..0000000000
--- a/src/lib/libcrypto/ec/ec_asn1.c
+++ /dev/null
@@ -1,1618 +0,0 @@
1/* $OpenBSD: ec_asn1.c,v 1.22 2016/03/20 16:50:29 krw Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2003 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 * licensing@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#include <string.h>
60
61#include <openssl/opensslconf.h>
62
63#include "ec_lcl.h"
64#include <openssl/err.h>
65#include <openssl/asn1t.h>
66#include <openssl/objects.h>
67
68int
69EC_GROUP_get_basis_type(const EC_GROUP * group)
70{
71 int i = 0;
72
73 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
74 NID_X9_62_characteristic_two_field)
75 /* everything else is currently not supported */
76 return 0;
77
78 while (group->poly[i] != 0)
79 i++;
80
81 if (i == 4)
82 return NID_X9_62_ppBasis;
83 else if (i == 2)
84 return NID_X9_62_tpBasis;
85 else
86 /* everything else is currently not supported */
87 return 0;
88}
89#ifndef OPENSSL_NO_EC2M
90int
91EC_GROUP_get_trinomial_basis(const EC_GROUP * group, unsigned int *k)
92{
93 if (group == NULL)
94 return 0;
95
96 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
97 NID_X9_62_characteristic_two_field
98 || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0))) {
99 ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
100 return 0;
101 }
102 if (k)
103 *k = group->poly[1];
104
105 return 1;
106}
107int
108EC_GROUP_get_pentanomial_basis(const EC_GROUP * group, unsigned int *k1,
109 unsigned int *k2, unsigned int *k3)
110{
111 if (group == NULL)
112 return 0;
113
114 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
115 NID_X9_62_characteristic_two_field
116 || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0))) {
117 ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
118 return 0;
119 }
120 if (k1)
121 *k1 = group->poly[3];
122 if (k2)
123 *k2 = group->poly[2];
124 if (k3)
125 *k3 = group->poly[1];
126
127 return 1;
128}
129#endif
130
131
132/* some structures needed for the asn1 encoding */
133typedef struct x9_62_pentanomial_st {
134 long k1;
135 long k2;
136 long k3;
137} X9_62_PENTANOMIAL;
138
139typedef struct x9_62_characteristic_two_st {
140 long m;
141 ASN1_OBJECT *type;
142 union {
143 char *ptr;
144 /* NID_X9_62_onBasis */
145 ASN1_NULL *onBasis;
146 /* NID_X9_62_tpBasis */
147 ASN1_INTEGER *tpBasis;
148 /* NID_X9_62_ppBasis */
149 X9_62_PENTANOMIAL *ppBasis;
150 /* anything else */
151 ASN1_TYPE *other;
152 } p;
153} X9_62_CHARACTERISTIC_TWO;
154
155typedef struct x9_62_fieldid_st {
156 ASN1_OBJECT *fieldType;
157 union {
158 char *ptr;
159 /* NID_X9_62_prime_field */
160 ASN1_INTEGER *prime;
161 /* NID_X9_62_characteristic_two_field */
162 X9_62_CHARACTERISTIC_TWO *char_two;
163 /* anything else */
164 ASN1_TYPE *other;
165 } p;
166} X9_62_FIELDID;
167
168typedef struct x9_62_curve_st {
169 ASN1_OCTET_STRING *a;
170 ASN1_OCTET_STRING *b;
171 ASN1_BIT_STRING *seed;
172} X9_62_CURVE;
173
174typedef struct ec_parameters_st {
175 long version;
176 X9_62_FIELDID *fieldID;
177 X9_62_CURVE *curve;
178 ASN1_OCTET_STRING *base;
179 ASN1_INTEGER *order;
180 ASN1_INTEGER *cofactor;
181} ECPARAMETERS;
182
183struct ecpk_parameters_st {
184 int type;
185 union {
186 ASN1_OBJECT *named_curve;
187 ECPARAMETERS *parameters;
188 ASN1_NULL *implicitlyCA;
189 } value;
190} /* ECPKPARAMETERS */ ;
191
192/* SEC1 ECPrivateKey */
193typedef struct ec_privatekey_st {
194 long version;
195 ASN1_OCTET_STRING *privateKey;
196 ECPKPARAMETERS *parameters;
197 ASN1_BIT_STRING *publicKey;
198} EC_PRIVATEKEY;
199
200/* the OpenSSL ASN.1 definitions */
201static const ASN1_TEMPLATE X9_62_PENTANOMIAL_seq_tt[] = {
202 {
203 .flags = 0,
204 .tag = 0,
205 .offset = offsetof(X9_62_PENTANOMIAL, k1),
206 .field_name = "k1",
207 .item = &LONG_it,
208 },
209 {
210 .flags = 0,
211 .tag = 0,
212 .offset = offsetof(X9_62_PENTANOMIAL, k2),
213 .field_name = "k2",
214 .item = &LONG_it,
215 },
216 {
217 .flags = 0,
218 .tag = 0,
219 .offset = offsetof(X9_62_PENTANOMIAL, k3),
220 .field_name = "k3",
221 .item = &LONG_it,
222 },
223};
224
225const ASN1_ITEM X9_62_PENTANOMIAL_it = {
226 .itype = ASN1_ITYPE_SEQUENCE,
227 .utype = V_ASN1_SEQUENCE,
228 .templates = X9_62_PENTANOMIAL_seq_tt,
229 .tcount = sizeof(X9_62_PENTANOMIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
230 .funcs = NULL,
231 .size = sizeof(X9_62_PENTANOMIAL),
232 .sname = "X9_62_PENTANOMIAL",
233};
234
235X9_62_PENTANOMIAL *X9_62_PENTANOMIAL_new(void);
236void X9_62_PENTANOMIAL_free(X9_62_PENTANOMIAL *a);
237
238X9_62_PENTANOMIAL *
239X9_62_PENTANOMIAL_new(void)
240{
241 return (X9_62_PENTANOMIAL*)ASN1_item_new(&X9_62_PENTANOMIAL_it);
242}
243
244void
245X9_62_PENTANOMIAL_free(X9_62_PENTANOMIAL *a)
246{
247 ASN1_item_free((ASN1_VALUE *)a, &X9_62_PENTANOMIAL_it);
248}
249
250static const ASN1_TEMPLATE char_two_def_tt = {
251 .flags = 0,
252 .tag = 0,
253 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.other),
254 .field_name = "p.other",
255 .item = &ASN1_ANY_it,
256};
257
258static const ASN1_ADB_TABLE X9_62_CHARACTERISTIC_TWO_adbtbl[] = {
259 {
260 .value = NID_X9_62_onBasis,
261 .tt = {
262 .flags = 0,
263 .tag = 0,
264 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.onBasis),
265 .field_name = "p.onBasis",
266 .item = &ASN1_NULL_it,
267 },
268
269 },
270 {
271 .value = NID_X9_62_tpBasis,
272 .tt = {
273 .flags = 0,
274 .tag = 0,
275 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.tpBasis),
276 .field_name = "p.tpBasis",
277 .item = &ASN1_INTEGER_it,
278 },
279
280 },
281 {
282 .value = NID_X9_62_ppBasis,
283 .tt = {
284 .flags = 0,
285 .tag = 0,
286 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.ppBasis),
287 .field_name = "p.ppBasis",
288 .item = &X9_62_PENTANOMIAL_it,
289 },
290
291 },
292};
293
294static const ASN1_ADB X9_62_CHARACTERISTIC_TWO_adb = {
295 .flags = 0,
296 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
297 .app_items = 0,
298 .tbl = X9_62_CHARACTERISTIC_TWO_adbtbl,
299 .tblcount = sizeof(X9_62_CHARACTERISTIC_TWO_adbtbl) / sizeof(ASN1_ADB_TABLE),
300 .default_tt = &char_two_def_tt,
301 .null_tt = NULL,
302};
303
304static const ASN1_TEMPLATE X9_62_CHARACTERISTIC_TWO_seq_tt[] = {
305 {
306 .flags = 0,
307 .tag = 0,
308 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, m),
309 .field_name = "m",
310 .item = &LONG_it,
311 },
312 {
313 .flags = 0,
314 .tag = 0,
315 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
316 .field_name = "type",
317 .item = &ASN1_OBJECT_it,
318 },
319 {
320 .flags = ASN1_TFLG_ADB_OID,
321 .tag = -1,
322 .offset = 0,
323 .field_name = "X9_62_CHARACTERISTIC_TWO",
324 .item = (const ASN1_ITEM *)&X9_62_CHARACTERISTIC_TWO_adb,
325 },
326};
327
328const ASN1_ITEM X9_62_CHARACTERISTIC_TWO_it = {
329 .itype = ASN1_ITYPE_SEQUENCE,
330 .utype = V_ASN1_SEQUENCE,
331 .templates = X9_62_CHARACTERISTIC_TWO_seq_tt,
332 .tcount = sizeof(X9_62_CHARACTERISTIC_TWO_seq_tt) / sizeof(ASN1_TEMPLATE),
333 .funcs = NULL,
334 .size = sizeof(X9_62_CHARACTERISTIC_TWO),
335 .sname = "X9_62_CHARACTERISTIC_TWO",
336};
337X9_62_CHARACTERISTIC_TWO *X9_62_CHARACTERISTIC_TWO_new(void);
338void X9_62_CHARACTERISTIC_TWO_free(X9_62_CHARACTERISTIC_TWO *a);
339
340X9_62_CHARACTERISTIC_TWO *
341X9_62_CHARACTERISTIC_TWO_new(void)
342{
343 return (X9_62_CHARACTERISTIC_TWO*)ASN1_item_new(&X9_62_CHARACTERISTIC_TWO_it);
344}
345
346void
347X9_62_CHARACTERISTIC_TWO_free(X9_62_CHARACTERISTIC_TWO *a)
348{
349 ASN1_item_free((ASN1_VALUE *)a, &X9_62_CHARACTERISTIC_TWO_it);
350}
351static const ASN1_TEMPLATE fieldID_def_tt = {
352 .flags = 0,
353 .tag = 0,
354 .offset = offsetof(X9_62_FIELDID, p.other),
355 .field_name = "p.other",
356 .item = &ASN1_ANY_it,
357};
358
359static const ASN1_ADB_TABLE X9_62_FIELDID_adbtbl[] = {
360 {
361 .value = NID_X9_62_prime_field,
362 .tt = {
363 .flags = 0,
364 .tag = 0,
365 .offset = offsetof(X9_62_FIELDID, p.prime),
366 .field_name = "p.prime",
367 .item = &ASN1_INTEGER_it,
368 },
369
370 },
371 {
372 .value = NID_X9_62_characteristic_two_field,
373 .tt = {
374 .flags = 0,
375 .tag = 0,
376 .offset = offsetof(X9_62_FIELDID, p.char_two),
377 .field_name = "p.char_two",
378 .item = &X9_62_CHARACTERISTIC_TWO_it,
379 },
380
381 },
382};
383
384static const ASN1_ADB X9_62_FIELDID_adb = {
385 .flags = 0,
386 .offset = offsetof(X9_62_FIELDID, fieldType),
387 .app_items = 0,
388 .tbl = X9_62_FIELDID_adbtbl,
389 .tblcount = sizeof(X9_62_FIELDID_adbtbl) / sizeof(ASN1_ADB_TABLE),
390 .default_tt = &fieldID_def_tt,
391 .null_tt = NULL,
392};
393
394static const ASN1_TEMPLATE X9_62_FIELDID_seq_tt[] = {
395 {
396 .flags = 0,
397 .tag = 0,
398 .offset = offsetof(X9_62_FIELDID, fieldType),
399 .field_name = "fieldType",
400 .item = &ASN1_OBJECT_it,
401 },
402 {
403 .flags = ASN1_TFLG_ADB_OID,
404 .tag = -1,
405 .offset = 0,
406 .field_name = "X9_62_FIELDID",
407 .item = (const ASN1_ITEM *)&X9_62_FIELDID_adb,
408 },
409};
410
411const ASN1_ITEM X9_62_FIELDID_it = {
412 .itype = ASN1_ITYPE_SEQUENCE,
413 .utype = V_ASN1_SEQUENCE,
414 .templates = X9_62_FIELDID_seq_tt,
415 .tcount = sizeof(X9_62_FIELDID_seq_tt) / sizeof(ASN1_TEMPLATE),
416 .funcs = NULL,
417 .size = sizeof(X9_62_FIELDID),
418 .sname = "X9_62_FIELDID",
419};
420
421static const ASN1_TEMPLATE X9_62_CURVE_seq_tt[] = {
422 {
423 .flags = 0,
424 .tag = 0,
425 .offset = offsetof(X9_62_CURVE, a),
426 .field_name = "a",
427 .item = &ASN1_OCTET_STRING_it,
428 },
429 {
430 .flags = 0,
431 .tag = 0,
432 .offset = offsetof(X9_62_CURVE, b),
433 .field_name = "b",
434 .item = &ASN1_OCTET_STRING_it,
435 },
436 {
437 .flags = ASN1_TFLG_OPTIONAL,
438 .tag = 0,
439 .offset = offsetof(X9_62_CURVE, seed),
440 .field_name = "seed",
441 .item = &ASN1_BIT_STRING_it,
442 },
443};
444
445const ASN1_ITEM X9_62_CURVE_it = {
446 .itype = ASN1_ITYPE_SEQUENCE,
447 .utype = V_ASN1_SEQUENCE,
448 .templates = X9_62_CURVE_seq_tt,
449 .tcount = sizeof(X9_62_CURVE_seq_tt) / sizeof(ASN1_TEMPLATE),
450 .funcs = NULL,
451 .size = sizeof(X9_62_CURVE),
452 .sname = "X9_62_CURVE",
453};
454
455static const ASN1_TEMPLATE ECPARAMETERS_seq_tt[] = {
456 {
457 .flags = 0,
458 .tag = 0,
459 .offset = offsetof(ECPARAMETERS, version),
460 .field_name = "version",
461 .item = &LONG_it,
462 },
463 {
464 .flags = 0,
465 .tag = 0,
466 .offset = offsetof(ECPARAMETERS, fieldID),
467 .field_name = "fieldID",
468 .item = &X9_62_FIELDID_it,
469 },
470 {
471 .flags = 0,
472 .tag = 0,
473 .offset = offsetof(ECPARAMETERS, curve),
474 .field_name = "curve",
475 .item = &X9_62_CURVE_it,
476 },
477 {
478 .flags = 0,
479 .tag = 0,
480 .offset = offsetof(ECPARAMETERS, base),
481 .field_name = "base",
482 .item = &ASN1_OCTET_STRING_it,
483 },
484 {
485 .flags = 0,
486 .tag = 0,
487 .offset = offsetof(ECPARAMETERS, order),
488 .field_name = "order",
489 .item = &ASN1_INTEGER_it,
490 },
491 {
492 .flags = ASN1_TFLG_OPTIONAL,
493 .tag = 0,
494 .offset = offsetof(ECPARAMETERS, cofactor),
495 .field_name = "cofactor",
496 .item = &ASN1_INTEGER_it,
497 },
498};
499
500const ASN1_ITEM ECPARAMETERS_it = {
501 .itype = ASN1_ITYPE_SEQUENCE,
502 .utype = V_ASN1_SEQUENCE,
503 .templates = ECPARAMETERS_seq_tt,
504 .tcount = sizeof(ECPARAMETERS_seq_tt) / sizeof(ASN1_TEMPLATE),
505 .funcs = NULL,
506 .size = sizeof(ECPARAMETERS),
507 .sname = "ECPARAMETERS",
508};
509ECPARAMETERS *ECPARAMETERS_new(void);
510void ECPARAMETERS_free(ECPARAMETERS *a);
511
512ECPARAMETERS *
513ECPARAMETERS_new(void)
514{
515 return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it);
516}
517
518void
519ECPARAMETERS_free(ECPARAMETERS *a)
520{
521 ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it);
522}
523
524static const ASN1_TEMPLATE ECPKPARAMETERS_ch_tt[] = {
525 {
526 .flags = 0,
527 .tag = 0,
528 .offset = offsetof(ECPKPARAMETERS, value.named_curve),
529 .field_name = "value.named_curve",
530 .item = &ASN1_OBJECT_it,
531 },
532 {
533 .flags = 0,
534 .tag = 0,
535 .offset = offsetof(ECPKPARAMETERS, value.parameters),
536 .field_name = "value.parameters",
537 .item = &ECPARAMETERS_it,
538 },
539 {
540 .flags = 0,
541 .tag = 0,
542 .offset = offsetof(ECPKPARAMETERS, value.implicitlyCA),
543 .field_name = "value.implicitlyCA",
544 .item = &ASN1_NULL_it,
545 },
546};
547
548const ASN1_ITEM ECPKPARAMETERS_it = {
549 .itype = ASN1_ITYPE_CHOICE,
550 .utype = offsetof(ECPKPARAMETERS, type),
551 .templates = ECPKPARAMETERS_ch_tt,
552 .tcount = sizeof(ECPKPARAMETERS_ch_tt) / sizeof(ASN1_TEMPLATE),
553 .funcs = NULL,
554 .size = sizeof(ECPKPARAMETERS),
555 .sname = "ECPKPARAMETERS",
556};
557
558ECPKPARAMETERS *ECPKPARAMETERS_new(void);
559void ECPKPARAMETERS_free(ECPKPARAMETERS *a);
560ECPKPARAMETERS *d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len);
561int i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out);
562
563ECPKPARAMETERS *
564d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len)
565{
566 return (ECPKPARAMETERS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
567 &ECPKPARAMETERS_it);
568}
569
570int
571i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out)
572{
573 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it);
574}
575
576ECPKPARAMETERS *
577ECPKPARAMETERS_new(void)
578{
579 return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it);
580}
581
582void
583ECPKPARAMETERS_free(ECPKPARAMETERS *a)
584{
585 ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it);
586}
587
588static const ASN1_TEMPLATE EC_PRIVATEKEY_seq_tt[] = {
589 {
590 .flags = 0,
591 .tag = 0,
592 .offset = offsetof(EC_PRIVATEKEY, version),
593 .field_name = "version",
594 .item = &LONG_it,
595 },
596 {
597 .flags = 0,
598 .tag = 0,
599 .offset = offsetof(EC_PRIVATEKEY, privateKey),
600 .field_name = "privateKey",
601 .item = &ASN1_OCTET_STRING_it,
602 },
603 {
604 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
605 .tag = 0,
606 .offset = offsetof(EC_PRIVATEKEY, parameters),
607 .field_name = "parameters",
608 .item = &ECPKPARAMETERS_it,
609 },
610 {
611 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
612 .tag = 1,
613 .offset = offsetof(EC_PRIVATEKEY, publicKey),
614 .field_name = "publicKey",
615 .item = &ASN1_BIT_STRING_it,
616 },
617};
618
619const ASN1_ITEM EC_PRIVATEKEY_it = {
620 .itype = ASN1_ITYPE_SEQUENCE,
621 .utype = V_ASN1_SEQUENCE,
622 .templates = EC_PRIVATEKEY_seq_tt,
623 .tcount = sizeof(EC_PRIVATEKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
624 .funcs = NULL,
625 .size = sizeof(EC_PRIVATEKEY),
626 .sname = "EC_PRIVATEKEY",
627};
628
629EC_PRIVATEKEY *EC_PRIVATEKEY_new(void);
630void EC_PRIVATEKEY_free(EC_PRIVATEKEY *a);
631EC_PRIVATEKEY *d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len);
632int i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out);
633
634EC_PRIVATEKEY *
635d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len)
636{
637 return (EC_PRIVATEKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
638 &EC_PRIVATEKEY_it);
639}
640
641int
642i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out)
643{
644 return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it);
645}
646
647EC_PRIVATEKEY *
648EC_PRIVATEKEY_new(void)
649{
650 return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it);
651}
652
653void
654EC_PRIVATEKEY_free(EC_PRIVATEKEY *a)
655{
656 ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it);
657}
658/* some declarations of internal function */
659
660/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
661static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
662/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
663static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
664/* ec_asn1_parameters2group() creates a EC_GROUP object from a
665 * ECPARAMETERS object */
666static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
667/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a
668 * EC_GROUP object */
669static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, ECPARAMETERS *);
670/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
671 * ECPKPARAMETERS object */
672static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
673/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
674 * EC_GROUP object */
675static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
676 ECPKPARAMETERS *);
677
678
679/* the function definitions */
680
681static int
682ec_asn1_group2fieldid(const EC_GROUP * group, X9_62_FIELDID * field)
683{
684 int ok = 0, nid;
685 BIGNUM *tmp = NULL;
686
687 if (group == NULL || field == NULL)
688 return 0;
689
690 /* clear the old values (if necessary) */
691 if (field->fieldType != NULL)
692 ASN1_OBJECT_free(field->fieldType);
693 if (field->p.other != NULL)
694 ASN1_TYPE_free(field->p.other);
695
696 nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
697 /* set OID for the field */
698 if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
699 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
700 goto err;
701 }
702 if (nid == NID_X9_62_prime_field) {
703 if ((tmp = BN_new()) == NULL) {
704 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
705 goto err;
706 }
707 /* the parameters are specified by the prime number p */
708 if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) {
709 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
710 goto err;
711 }
712 /* set the prime number */
713 field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
714 if (field->p.prime == NULL) {
715 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
716 goto err;
717 }
718 } else /* nid == NID_X9_62_characteristic_two_field */
719#ifdef OPENSSL_NO_EC2M
720 {
721 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
722 goto err;
723 }
724#else
725 {
726 int field_type;
727 X9_62_CHARACTERISTIC_TWO *char_two;
728
729 field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
730 char_two = field->p.char_two;
731
732 if (char_two == NULL) {
733 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
734 goto err;
735 }
736 char_two->m = (long) EC_GROUP_get_degree(group);
737
738 field_type = EC_GROUP_get_basis_type(group);
739
740 if (field_type == 0) {
741 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
742 goto err;
743 }
744 /* set base type OID */
745 if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
746 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
747 goto err;
748 }
749 if (field_type == NID_X9_62_tpBasis) {
750 unsigned int k;
751
752 if (!EC_GROUP_get_trinomial_basis(group, &k))
753 goto err;
754
755 char_two->p.tpBasis = ASN1_INTEGER_new();
756 if (!char_two->p.tpBasis) {
757 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
758 goto err;
759 }
760 if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long) k)) {
761 ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
762 ERR_R_ASN1_LIB);
763 goto err;
764 }
765 } else if (field_type == NID_X9_62_ppBasis) {
766 unsigned int k1, k2, k3;
767
768 if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
769 goto err;
770
771 char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
772 if (!char_two->p.ppBasis) {
773 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
774 goto err;
775 }
776 /* set k? values */
777 char_two->p.ppBasis->k1 = (long) k1;
778 char_two->p.ppBasis->k2 = (long) k2;
779 char_two->p.ppBasis->k3 = (long) k3;
780 } else { /* field_type == NID_X9_62_onBasis */
781 /* for ONB the parameters are (asn1) NULL */
782 char_two->p.onBasis = ASN1_NULL_new();
783 if (!char_two->p.onBasis) {
784 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
785 goto err;
786 }
787 }
788 }
789#endif
790
791 ok = 1;
792
793err:
794 BN_free(tmp);
795 return (ok);
796}
797
798static int
799ec_asn1_group2curve(const EC_GROUP * group, X9_62_CURVE * curve)
800{
801 int ok = 0, nid;
802 BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
803 unsigned char *buffer_1 = NULL, *buffer_2 = NULL, *a_buf = NULL,
804 *b_buf = NULL;
805 size_t len_1, len_2;
806 unsigned char char_zero = 0;
807
808 if (!group || !curve || !curve->a || !curve->b)
809 return 0;
810
811 if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
812 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
813 goto err;
814 }
815 nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
816
817 /* get a and b */
818 if (nid == NID_X9_62_prime_field) {
819 if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) {
820 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
821 goto err;
822 }
823 }
824#ifndef OPENSSL_NO_EC2M
825 else { /* nid == NID_X9_62_characteristic_two_field */
826 if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) {
827 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
828 goto err;
829 }
830 }
831#endif
832 len_1 = (size_t) BN_num_bytes(tmp_1);
833 len_2 = (size_t) BN_num_bytes(tmp_2);
834
835 if (len_1 == 0) {
836 /* len_1 == 0 => a == 0 */
837 a_buf = &char_zero;
838 len_1 = 1;
839 } else {
840 if ((buffer_1 = malloc(len_1)) == NULL) {
841 ECerr(EC_F_EC_ASN1_GROUP2CURVE,
842 ERR_R_MALLOC_FAILURE);
843 goto err;
844 }
845 if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
846 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
847 goto err;
848 }
849 a_buf = buffer_1;
850 }
851
852 if (len_2 == 0) {
853 /* len_2 == 0 => b == 0 */
854 b_buf = &char_zero;
855 len_2 = 1;
856 } else {
857 if ((buffer_2 = malloc(len_2)) == NULL) {
858 ECerr(EC_F_EC_ASN1_GROUP2CURVE,
859 ERR_R_MALLOC_FAILURE);
860 goto err;
861 }
862 if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
863 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
864 goto err;
865 }
866 b_buf = buffer_2;
867 }
868
869 /* set a and b */
870 if (!ASN1_STRING_set(curve->a, a_buf, len_1) ||
871 !ASN1_STRING_set(curve->b, b_buf, len_2)) {
872 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
873 goto err;
874 }
875 /* set the seed (optional) */
876 if (group->seed) {
877 if (!curve->seed)
878 if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
879 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
880 goto err;
881 }
882 curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
883 curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
884 if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
885 (int) group->seed_len)) {
886 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
887 goto err;
888 }
889 } else {
890 if (curve->seed) {
891 ASN1_BIT_STRING_free(curve->seed);
892 curve->seed = NULL;
893 }
894 }
895
896 ok = 1;
897
898err:
899 free(buffer_1);
900 free(buffer_2);
901 BN_free(tmp_1);
902 BN_free(tmp_2);
903 return (ok);
904}
905
906static ECPARAMETERS *
907ec_asn1_group2parameters(const EC_GROUP * group, ECPARAMETERS * param)
908{
909 int ok = 0;
910 size_t len = 0;
911 ECPARAMETERS *ret = NULL;
912 BIGNUM *tmp = NULL;
913 unsigned char *buffer = NULL;
914 const EC_POINT *point = NULL;
915 point_conversion_form_t form;
916
917 if ((tmp = BN_new()) == NULL) {
918 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
919 goto err;
920 }
921 if (param == NULL) {
922 if ((ret = ECPARAMETERS_new()) == NULL) {
923 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS,
924 ERR_R_MALLOC_FAILURE);
925 goto err;
926 }
927 } else
928 ret = param;
929
930 /* set the version (always one) */
931 ret->version = (long) 0x1;
932
933 /* set the fieldID */
934 if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
935 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
936 goto err;
937 }
938 /* set the curve */
939 if (!ec_asn1_group2curve(group, ret->curve)) {
940 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
941 goto err;
942 }
943 /* set the base point */
944 if ((point = EC_GROUP_get0_generator(group)) == NULL) {
945 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
946 goto err;
947 }
948 form = EC_GROUP_get_point_conversion_form(group);
949
950 len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
951 if (len == 0) {
952 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
953 goto err;
954 }
955 if ((buffer = malloc(len)) == NULL) {
956 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
957 goto err;
958 }
959 if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) {
960 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
961 goto err;
962 }
963 if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
964 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
965 goto err;
966 }
967 if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) {
968 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
969 goto err;
970 }
971 /* set the order */
972 if (!EC_GROUP_get_order(group, tmp, NULL)) {
973 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
974 goto err;
975 }
976 ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
977 if (ret->order == NULL) {
978 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
979 goto err;
980 }
981 /* set the cofactor (optional) */
982 if (EC_GROUP_get_cofactor(group, tmp, NULL)) {
983 ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
984 if (ret->cofactor == NULL) {
985 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
986 goto err;
987 }
988 }
989 ok = 1;
990
991err: if (!ok) {
992 if (ret && !param)
993 ECPARAMETERS_free(ret);
994 ret = NULL;
995 }
996 BN_free(tmp);
997 free(buffer);
998 return (ret);
999}
1000
1001ECPKPARAMETERS *
1002ec_asn1_group2pkparameters(const EC_GROUP * group, ECPKPARAMETERS * params)
1003{
1004 int ok = 1, tmp;
1005 ECPKPARAMETERS *ret = params;
1006
1007 if (ret == NULL) {
1008 if ((ret = ECPKPARAMETERS_new()) == NULL) {
1009 ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS,
1010 ERR_R_MALLOC_FAILURE);
1011 return NULL;
1012 }
1013 } else {
1014 if (ret->type == 0 && ret->value.named_curve)
1015 ASN1_OBJECT_free(ret->value.named_curve);
1016 else if (ret->type == 1 && ret->value.parameters)
1017 ECPARAMETERS_free(ret->value.parameters);
1018 }
1019
1020 if (EC_GROUP_get_asn1_flag(group)) {
1021 /*
1022 * use the asn1 OID to describe the elliptic curve
1023 * parameters
1024 */
1025 tmp = EC_GROUP_get_curve_name(group);
1026 if (tmp) {
1027 ret->type = 0;
1028 if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
1029 ok = 0;
1030 } else
1031 /* we don't kmow the nid => ERROR */
1032 ok = 0;
1033 } else {
1034 /* use the ECPARAMETERS structure */
1035 ret->type = 1;
1036 if ((ret->value.parameters = ec_asn1_group2parameters(
1037 group, NULL)) == NULL)
1038 ok = 0;
1039 }
1040
1041 if (!ok) {
1042 ECPKPARAMETERS_free(ret);
1043 return NULL;
1044 }
1045 return ret;
1046}
1047
1048static EC_GROUP *
1049ec_asn1_parameters2group(const ECPARAMETERS * params)
1050{
1051 int ok = 0, tmp;
1052 EC_GROUP *ret = NULL;
1053 BIGNUM *p = NULL, *a = NULL, *b = NULL;
1054 EC_POINT *point = NULL;
1055 long field_bits;
1056
1057 if (!params->fieldID || !params->fieldID->fieldType ||
1058 !params->fieldID->p.ptr) {
1059 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
1060 goto err;
1061 }
1062 /* now extract the curve parameters a and b */
1063 if (!params->curve || !params->curve->a ||
1064 !params->curve->a->data || !params->curve->b ||
1065 !params->curve->b->data) {
1066 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
1067 goto err;
1068 }
1069 a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
1070 if (a == NULL) {
1071 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
1072 goto err;
1073 }
1074 b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
1075 if (b == NULL) {
1076 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
1077 goto err;
1078 }
1079 /* get the field parameters */
1080 tmp = OBJ_obj2nid(params->fieldID->fieldType);
1081 if (tmp == NID_X9_62_characteristic_two_field)
1082#ifdef OPENSSL_NO_EC2M
1083 {
1084 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
1085 goto err;
1086 }
1087#else
1088 {
1089 X9_62_CHARACTERISTIC_TWO *char_two;
1090
1091 char_two = params->fieldID->p.char_two;
1092
1093 field_bits = char_two->m;
1094 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
1095 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
1096 goto err;
1097 }
1098 if ((p = BN_new()) == NULL) {
1099 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
1100 goto err;
1101 }
1102 /* get the base type */
1103 tmp = OBJ_obj2nid(char_two->type);
1104
1105 if (tmp == NID_X9_62_tpBasis) {
1106 long tmp_long;
1107
1108 if (!char_two->p.tpBasis) {
1109 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
1110 goto err;
1111 }
1112 tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
1113
1114 if (!(char_two->m > tmp_long && tmp_long > 0)) {
1115 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
1116 goto err;
1117 }
1118 /* create the polynomial */
1119 if (!BN_set_bit(p, (int) char_two->m))
1120 goto err;
1121 if (!BN_set_bit(p, (int) tmp_long))
1122 goto err;
1123 if (!BN_set_bit(p, 0))
1124 goto err;
1125 } else if (tmp == NID_X9_62_ppBasis) {
1126 X9_62_PENTANOMIAL *penta;
1127
1128 penta = char_two->p.ppBasis;
1129 if (!penta) {
1130 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
1131 goto err;
1132 }
1133 if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0)) {
1134 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
1135 goto err;
1136 }
1137 /* create the polynomial */
1138 if (!BN_set_bit(p, (int) char_two->m))
1139 goto err;
1140 if (!BN_set_bit(p, (int) penta->k1))
1141 goto err;
1142 if (!BN_set_bit(p, (int) penta->k2))
1143 goto err;
1144 if (!BN_set_bit(p, (int) penta->k3))
1145 goto err;
1146 if (!BN_set_bit(p, 0))
1147 goto err;
1148 } else if (tmp == NID_X9_62_onBasis) {
1149 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
1150 goto err;
1151 } else { /* error */
1152 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
1153 goto err;
1154 }
1155
1156 /* create the EC_GROUP structure */
1157 ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
1158 }
1159#endif
1160 else if (tmp == NID_X9_62_prime_field) {
1161 /* we have a curve over a prime field */
1162 /* extract the prime number */
1163 if (!params->fieldID->p.prime) {
1164 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
1165 goto err;
1166 }
1167 p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
1168 if (p == NULL) {
1169 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
1170 goto err;
1171 }
1172 if (BN_is_negative(p) || BN_is_zero(p)) {
1173 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
1174 goto err;
1175 }
1176 field_bits = BN_num_bits(p);
1177 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
1178 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
1179 goto err;
1180 }
1181 /* create the EC_GROUP structure */
1182 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
1183 } else {
1184 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
1185 goto err;
1186 }
1187
1188 if (ret == NULL) {
1189 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
1190 goto err;
1191 }
1192 /* extract seed (optional) */
1193 if (params->curve->seed != NULL) {
1194 free(ret->seed);
1195 if (!(ret->seed = malloc(params->curve->seed->length))) {
1196 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
1197 ERR_R_MALLOC_FAILURE);
1198 goto err;
1199 }
1200 memcpy(ret->seed, params->curve->seed->data,
1201 params->curve->seed->length);
1202 ret->seed_len = params->curve->seed->length;
1203 }
1204 if (!params->order || !params->base || !params->base->data) {
1205 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
1206 goto err;
1207 }
1208 if ((point = EC_POINT_new(ret)) == NULL)
1209 goto err;
1210
1211 /* set the point conversion form */
1212 EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
1213 (params->base->data[0] & ~0x01));
1214
1215 /* extract the ec point */
1216 if (!EC_POINT_oct2point(ret, point, params->base->data,
1217 params->base->length, NULL)) {
1218 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
1219 goto err;
1220 }
1221 /* extract the order */
1222 if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
1223 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
1224 goto err;
1225 }
1226 if (BN_is_negative(a) || BN_is_zero(a)) {
1227 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
1228 goto err;
1229 }
1230 if (BN_num_bits(a) > (int) field_bits + 1) { /* Hasse bound */
1231 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
1232 goto err;
1233 }
1234 /* extract the cofactor (optional) */
1235 if (params->cofactor == NULL) {
1236 BN_free(b);
1237 b = NULL;
1238 } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
1239 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
1240 goto err;
1241 }
1242 /* set the generator, order and cofactor (if present) */
1243 if (!EC_GROUP_set_generator(ret, point, a, b)) {
1244 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
1245 goto err;
1246 }
1247 ok = 1;
1248
1249err: if (!ok) {
1250 EC_GROUP_clear_free(ret);
1251 ret = NULL;
1252 }
1253 BN_free(p);
1254 BN_free(a);
1255 BN_free(b);
1256 EC_POINT_free(point);
1257 return (ret);
1258}
1259
1260EC_GROUP *
1261ec_asn1_pkparameters2group(const ECPKPARAMETERS * params)
1262{
1263 EC_GROUP *ret = NULL;
1264 int tmp = 0;
1265
1266 if (params == NULL) {
1267 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1268 EC_R_MISSING_PARAMETERS);
1269 return NULL;
1270 }
1271 if (params->type == 0) {/* the curve is given by an OID */
1272 tmp = OBJ_obj2nid(params->value.named_curve);
1273 if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
1274 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1275 EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1276 return NULL;
1277 }
1278 EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
1279 } else if (params->type == 1) { /* the parameters are given by a
1280 * ECPARAMETERS structure */
1281 ret = ec_asn1_parameters2group(params->value.parameters);
1282 if (!ret) {
1283 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
1284 return NULL;
1285 }
1286 EC_GROUP_set_asn1_flag(ret, 0x0);
1287 } else if (params->type == 2) { /* implicitlyCA */
1288 return NULL;
1289 } else {
1290 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
1291 return NULL;
1292 }
1293
1294 return ret;
1295}
1296
1297/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1298
1299EC_GROUP *
1300d2i_ECPKParameters(EC_GROUP ** a, const unsigned char **in, long len)
1301{
1302 EC_GROUP *group = NULL;
1303 ECPKPARAMETERS *params = NULL;
1304
1305 if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
1306 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1307 goto err;
1308 }
1309 if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
1310 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1311 goto err;
1312 }
1313
1314 if (a != NULL) {
1315 EC_GROUP_clear_free(*a);
1316 *a = group;
1317 }
1318
1319err:
1320 ECPKPARAMETERS_free(params);
1321 return (group);
1322}
1323
1324int
1325i2d_ECPKParameters(const EC_GROUP * a, unsigned char **out)
1326{
1327 int ret = 0;
1328 ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
1329 if (tmp == NULL) {
1330 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1331 return 0;
1332 }
1333 if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
1334 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1335 ECPKPARAMETERS_free(tmp);
1336 return 0;
1337 }
1338 ECPKPARAMETERS_free(tmp);
1339 return (ret);
1340}
1341
1342/* some EC_KEY functions */
1343
1344EC_KEY *
1345d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len)
1346{
1347 EC_KEY *ret = NULL;
1348 EC_PRIVATEKEY *priv_key = NULL;
1349
1350 if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1351 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1352 return NULL;
1353 }
1354 if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL) {
1355 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1356 EC_PRIVATEKEY_free(priv_key);
1357 return NULL;
1358 }
1359 if (a == NULL || *a == NULL) {
1360 if ((ret = EC_KEY_new()) == NULL) {
1361 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1362 goto err;
1363 }
1364 } else
1365 ret = *a;
1366
1367 if (priv_key->parameters) {
1368 EC_GROUP_clear_free(ret->group);
1369 ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1370 }
1371 if (ret->group == NULL) {
1372 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1373 goto err;
1374 }
1375 ret->version = priv_key->version;
1376
1377 if (priv_key->privateKey) {
1378 ret->priv_key = BN_bin2bn(
1379 ASN1_STRING_data(priv_key->privateKey),
1380 ASN1_STRING_length(priv_key->privateKey),
1381 ret->priv_key);
1382 if (ret->priv_key == NULL) {
1383 ECerr(EC_F_D2I_ECPRIVATEKEY,
1384 ERR_R_BN_LIB);
1385 goto err;
1386 }
1387 } else {
1388 ECerr(EC_F_D2I_ECPRIVATEKEY,
1389 EC_R_MISSING_PRIVATE_KEY);
1390 goto err;
1391 }
1392
1393 if (priv_key->publicKey) {
1394 const unsigned char *pub_oct;
1395 size_t pub_oct_len;
1396
1397 EC_POINT_clear_free(ret->pub_key);
1398 ret->pub_key = EC_POINT_new(ret->group);
1399 if (ret->pub_key == NULL) {
1400 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1401 goto err;
1402 }
1403 pub_oct = ASN1_STRING_data(priv_key->publicKey);
1404 pub_oct_len = ASN1_STRING_length(priv_key->publicKey);
1405 /* save the point conversion form */
1406 ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01);
1407 if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1408 pub_oct, pub_oct_len, NULL)) {
1409 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1410 goto err;
1411 }
1412 }
1413
1414 EC_PRIVATEKEY_free(priv_key);
1415 if (a != NULL)
1416 *a = ret;
1417 return (ret);
1418
1419err:
1420 if (a == NULL || *a != ret)
1421 EC_KEY_free(ret);
1422 if (priv_key)
1423 EC_PRIVATEKEY_free(priv_key);
1424
1425 return (NULL);
1426}
1427
1428int
1429i2d_ECPrivateKey(EC_KEY * a, unsigned char **out)
1430{
1431 int ret = 0, ok = 0;
1432 unsigned char *buffer = NULL;
1433 size_t buf_len = 0, tmp_len;
1434 EC_PRIVATEKEY *priv_key = NULL;
1435
1436 if (a == NULL || a->group == NULL || a->priv_key == NULL) {
1437 ECerr(EC_F_I2D_ECPRIVATEKEY,
1438 ERR_R_PASSED_NULL_PARAMETER);
1439 goto err;
1440 }
1441 if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1442 ECerr(EC_F_I2D_ECPRIVATEKEY,
1443 ERR_R_MALLOC_FAILURE);
1444 goto err;
1445 }
1446 priv_key->version = a->version;
1447
1448 buf_len = (size_t) BN_num_bytes(a->priv_key);
1449 buffer = malloc(buf_len);
1450 if (buffer == NULL) {
1451 ECerr(EC_F_I2D_ECPRIVATEKEY,
1452 ERR_R_MALLOC_FAILURE);
1453 goto err;
1454 }
1455 if (!BN_bn2bin(a->priv_key, buffer)) {
1456 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1457 goto err;
1458 }
1459 if (!ASN1_STRING_set(priv_key->privateKey, buffer, buf_len)) {
1460 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1461 goto err;
1462 }
1463 if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
1464 if ((priv_key->parameters = ec_asn1_group2pkparameters(
1465 a->group, priv_key->parameters)) == NULL) {
1466 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1467 goto err;
1468 }
1469 }
1470 if (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key != NULL) {
1471 priv_key->publicKey = ASN1_BIT_STRING_new();
1472 if (priv_key->publicKey == NULL) {
1473 ECerr(EC_F_I2D_ECPRIVATEKEY,
1474 ERR_R_MALLOC_FAILURE);
1475 goto err;
1476 }
1477 tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1478 a->conv_form, NULL, 0, NULL);
1479
1480 if (tmp_len > buf_len) {
1481 unsigned char *tmp_buffer = realloc(buffer, tmp_len);
1482 if (!tmp_buffer) {
1483 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1484 goto err;
1485 }
1486 buffer = tmp_buffer;
1487 buf_len = tmp_len;
1488 }
1489 if (!EC_POINT_point2oct(a->group, a->pub_key,
1490 a->conv_form, buffer, buf_len, NULL)) {
1491 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1492 goto err;
1493 }
1494 priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
1495 priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1496 if (!ASN1_STRING_set(priv_key->publicKey, buffer,
1497 buf_len)) {
1498 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1499 goto err;
1500 }
1501 }
1502 if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
1503 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1504 goto err;
1505 }
1506 ok = 1;
1507err:
1508 free(buffer);
1509 if (priv_key)
1510 EC_PRIVATEKEY_free(priv_key);
1511 return (ok ? ret : 0);
1512}
1513
1514int
1515i2d_ECParameters(EC_KEY * a, unsigned char **out)
1516{
1517 if (a == NULL) {
1518 ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1519 return 0;
1520 }
1521 return i2d_ECPKParameters(a->group, out);
1522}
1523
1524EC_KEY *
1525d2i_ECParameters(EC_KEY ** a, const unsigned char **in, long len)
1526{
1527 EC_KEY *ret;
1528
1529 if (in == NULL || *in == NULL) {
1530 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1531 return NULL;
1532 }
1533 if (a == NULL || *a == NULL) {
1534 if ((ret = EC_KEY_new()) == NULL) {
1535 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1536 return NULL;
1537 }
1538 } else
1539 ret = *a;
1540
1541 if (!d2i_ECPKParameters(&ret->group, in, len)) {
1542 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1543 if (a == NULL || *a != ret)
1544 EC_KEY_free(ret);
1545 return NULL;
1546 }
1547
1548 if (a != NULL)
1549 *a = ret;
1550 return ret;
1551}
1552
1553EC_KEY *
1554o2i_ECPublicKey(EC_KEY ** a, const unsigned char **in, long len)
1555{
1556 EC_KEY *ret = NULL;
1557
1558 if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
1559 /*
1560 * sorry, but a EC_GROUP-structur is necessary to set the
1561 * public key
1562 */
1563 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1564 return 0;
1565 }
1566 ret = *a;
1567 if (ret->pub_key == NULL &&
1568 (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
1569 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1570 return 0;
1571 }
1572 if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) {
1573 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1574 return 0;
1575 }
1576 /* save the point conversion form */
1577 ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01);
1578 *in += len;
1579 return ret;
1580}
1581
1582int
1583i2o_ECPublicKey(EC_KEY * a, unsigned char **out)
1584{
1585 size_t buf_len = 0;
1586 int new_buffer = 0;
1587
1588 if (a == NULL) {
1589 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1590 return 0;
1591 }
1592 buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1593 a->conv_form, NULL, 0, NULL);
1594
1595 if (out == NULL || buf_len == 0)
1596 /* out == NULL => just return the length of the octet string */
1597 return buf_len;
1598
1599 if (*out == NULL) {
1600 if ((*out = malloc(buf_len)) == NULL) {
1601 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1602 return 0;
1603 }
1604 new_buffer = 1;
1605 }
1606 if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1607 *out, buf_len, NULL)) {
1608 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1609 if (new_buffer) {
1610 free(*out);
1611 *out = NULL;
1612 }
1613 return 0;
1614 }
1615 if (!new_buffer)
1616 *out += buf_len;
1617 return buf_len;
1618}
diff --git a/src/lib/libcrypto/ec/ec_check.c b/src/lib/libcrypto/ec/ec_check.c
deleted file mode 100644
index 21072305d5..0000000000
--- a/src/lib/libcrypto/ec/ec_check.c
+++ /dev/null
@@ -1,115 +0,0 @@
1/* $OpenBSD: ec_check.c,v 1.5 2015/02/08 22:25:03 miod Exp $ */
2/* ====================================================================
3 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include "ec_lcl.h"
57#include <openssl/err.h>
58
59int
60EC_GROUP_check(const EC_GROUP * group, BN_CTX * ctx)
61{
62 int ret = 0;
63 BIGNUM *order;
64 BN_CTX *new_ctx = NULL;
65 EC_POINT *point = NULL;
66
67 if (ctx == NULL) {
68 ctx = new_ctx = BN_CTX_new();
69 if (ctx == NULL) {
70 ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
71 goto err;
72 }
73 }
74 BN_CTX_start(ctx);
75 if ((order = BN_CTX_get(ctx)) == NULL)
76 goto err;
77
78 /* check the discriminant */
79 if (!EC_GROUP_check_discriminant(group, ctx)) {
80 ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
81 goto err;
82 }
83 /* check the generator */
84 if (group->generator == NULL) {
85 ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
86 goto err;
87 }
88 if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
89 ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
90 goto err;
91 }
92 /* check the order of the generator */
93 if ((point = EC_POINT_new(group)) == NULL)
94 goto err;
95 if (!EC_GROUP_get_order(group, order, ctx))
96 goto err;
97 if (BN_is_zero(order)) {
98 ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
99 goto err;
100 }
101 if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
102 goto err;
103 if (EC_POINT_is_at_infinity(group, point) <= 0) {
104 ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
105 goto err;
106 }
107 ret = 1;
108
109err:
110 if (ctx != NULL)
111 BN_CTX_end(ctx);
112 BN_CTX_free(new_ctx);
113 EC_POINT_free(point);
114 return ret;
115}
diff --git a/src/lib/libcrypto/ec/ec_curve.c b/src/lib/libcrypto/ec/ec_curve.c
deleted file mode 100644
index f852ccaee3..0000000000
--- a/src/lib/libcrypto/ec/ec_curve.c
+++ /dev/null
@@ -1,3340 +0,0 @@
1/* $OpenBSD: ec_curve.c,v 1.13 2016/03/10 23:21:46 mmcc Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2010 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 <string.h>
73
74#include <openssl/opensslconf.h>
75
76#include "ec_lcl.h"
77#include <openssl/err.h>
78#include <openssl/obj_mac.h>
79
80typedef struct {
81 int field_type, /* either NID_X9_62_prime_field or
82 * NID_X9_62_characteristic_two_field */
83 seed_len, param_len;
84 unsigned int cofactor; /* promoted to BN_ULONG */
85} EC_CURVE_DATA;
86
87/* the nist prime curves */
88static const struct {
89 EC_CURVE_DATA h;
90 unsigned char data[20 + 24 * 6];
91}
92 _EC_NIST_PRIME_192 = {
93 {
94 NID_X9_62_prime_field, 20, 24, 1
95 },
96 {
97 0x30, 0x45, 0xAE, 0x6F, 0xC8, 0x42, 0x2F, 0x64, 0xED, 0x57, /* seed */
98 0x95, 0x28, 0xD3, 0x81, 0x20, 0xEA, 0xE1, 0x21, 0x96, 0xD5,
99
100 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
101 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
102 0xFF, 0xFF, 0xFF, 0xFF,
103 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
104 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
105 0xFF, 0xFF, 0xFF, 0xFC,
106 0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, /* b */
107 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC,
108 0xC1, 0x46, 0xB9, 0xB1,
109 0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, /* x */
110 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD,
111 0x82, 0xFF, 0x10, 0x12,
112 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, /* y */
113 0x11, 0xed, 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1,
114 0x1e, 0x79, 0x48, 0x11,
115 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
116 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1,
117 0xB4, 0xD2, 0x28, 0x31
118 }
119};
120
121static const struct {
122 EC_CURVE_DATA h;
123 unsigned char data[20 + 28 * 6];
124}
125 _EC_NIST_PRIME_224 = {
126 {
127 NID_X9_62_prime_field, 20, 28, 1
128 },
129 {
130 0xBD, 0x71, 0x34, 0x47, 0x99, 0xD5, 0xC7, 0xFC, 0xDC, 0x45, /* seed */
131 0xB5, 0x9F, 0xA3, 0xB9, 0xAB, 0x8F, 0x6A, 0x94, 0x8B, 0xC5,
132
133 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
134 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
136 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
137 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
138 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
139 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
140 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA,
141 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4,
142 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
143 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22,
144 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21,
145 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
146 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
147 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
148 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
149 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E,
150 0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D
151 }
152};
153
154static const struct {
155 EC_CURVE_DATA h;
156 unsigned char data[20 + 48 * 6];
157}
158 _EC_NIST_PRIME_384 = {
159 {
160 NID_X9_62_prime_field, 20, 48, 1
161 },
162 {
163 0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, /* seed */
164 0x89, 0x6A, 0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73,
165
166 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
167 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
168 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
169 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
171 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
172 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
173 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
174 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
176 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, /* b */
177 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E,
178 0xFE, 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13,
179 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D,
180 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
181 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, /* x */
182 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62,
183 0x8B, 0xA7, 0x9B, 0x98, 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54,
184 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C,
185 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
186 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, /* y */
187 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd,
188 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0,
189 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
190 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
191 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
192 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
193 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37,
194 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A,
195 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
196 }
197};
198
199static const struct {
200 EC_CURVE_DATA h;
201 unsigned char data[20 + 66 * 6];
202}
203 _EC_NIST_PRIME_521 = {
204 {
205 NID_X9_62_prime_field, 20, 66, 1
206 },
207 {
208 0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, /* seed */
209 0x67, 0x17, 0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA,
210
211 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
212 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
213 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
214 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
215 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
216 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
217 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
218 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
219 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
220 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
221 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
222 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
223 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
224 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
225 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, /* b */
226 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA,
227 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91,
228 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E,
229 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 0xBF, 0x07,
230 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
231 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
232 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, /* x */
233 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64,
234 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60,
235 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7,
236 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 0xA8, 0xDE,
237 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
238 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
239 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, /* y */
240 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5,
241 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
242 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
243 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
244 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
245 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
246 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
247 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
248 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
249 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
250 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 0xA5, 0xD0,
251 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
252 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09
253 }
254};
255
256/* the x9.62 prime curves (minus the nist prime curves) */
257static const struct {
258 EC_CURVE_DATA h;
259 unsigned char data[20 + 24 * 6];
260}
261 _EC_X9_62_PRIME_192V2 = {
262 {
263 NID_X9_62_prime_field, 20, 24, 1
264 },
265 {
266 0x31, 0xA9, 0x2E, 0xE2, 0x02, 0x9F, 0xD1, 0x0D, 0x90, 0x1B, /* seed */
267 0x11, 0x3E, 0x99, 0x07, 0x10, 0xF0, 0xD2, 0x1A, 0xC6, 0xB6,
268
269 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
270 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
271 0xFF, 0xFF, 0xFF, 0xFF,
272 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
273 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
274 0xFF, 0xFF, 0xFF, 0xFC,
275 0xCC, 0x22, 0xD6, 0xDF, 0xB9, 0x5C, 0x6B, 0x25, 0xE4, 0x9C, /* b */
276 0x0D, 0x63, 0x64, 0xA4, 0xE5, 0x98, 0x0C, 0x39, 0x3A, 0xA2,
277 0x16, 0x68, 0xD9, 0x53,
278 0xEE, 0xA2, 0xBA, 0xE7, 0xE1, 0x49, 0x78, 0x42, 0xF2, 0xDE, /* x */
279 0x77, 0x69, 0xCF, 0xE9, 0xC9, 0x89, 0xC0, 0x72, 0xAD, 0x69,
280 0x6F, 0x48, 0x03, 0x4A,
281 0x65, 0x74, 0xd1, 0x1d, 0x69, 0xb6, 0xec, 0x7a, 0x67, 0x2b, /* y */
282 0xb8, 0x2a, 0x08, 0x3d, 0xf2, 0xf2, 0xb0, 0x84, 0x7d, 0xe9,
283 0x70, 0xb2, 0xde, 0x15,
284 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
285 0xFF, 0xFE, 0x5F, 0xB1, 0xA7, 0x24, 0xDC, 0x80, 0x41, 0x86,
286 0x48, 0xD8, 0xDD, 0x31
287 }
288};
289
290static const struct {
291 EC_CURVE_DATA h;
292 unsigned char data[20 + 24 * 6];
293}
294 _EC_X9_62_PRIME_192V3 = {
295 {
296 NID_X9_62_prime_field, 20, 24, 1
297 },
298 {
299 0xC4, 0x69, 0x68, 0x44, 0x35, 0xDE, 0xB3, 0x78, 0xC4, 0xB6, /* seed */
300 0x5C, 0xA9, 0x59, 0x1E, 0x2A, 0x57, 0x63, 0x05, 0x9A, 0x2E,
301
302 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
303 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
304 0xFF, 0xFF, 0xFF, 0xFF,
305 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
306 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
307 0xFF, 0xFF, 0xFF, 0xFC,
308 0x22, 0x12, 0x3D, 0xC2, 0x39, 0x5A, 0x05, 0xCA, 0xA7, 0x42, /* b */
309 0x3D, 0xAE, 0xCC, 0xC9, 0x47, 0x60, 0xA7, 0xD4, 0x62, 0x25,
310 0x6B, 0xD5, 0x69, 0x16,
311 0x7D, 0x29, 0x77, 0x81, 0x00, 0xC6, 0x5A, 0x1D, 0xA1, 0x78, /* x */
312 0x37, 0x16, 0x58, 0x8D, 0xCE, 0x2B, 0x8B, 0x4A, 0xEE, 0x8E,
313 0x22, 0x8F, 0x18, 0x96,
314 0x38, 0xa9, 0x0f, 0x22, 0x63, 0x73, 0x37, 0x33, 0x4b, 0x49, /* y */
315 0xdc, 0xb6, 0x6a, 0x6d, 0xc8, 0xf9, 0x97, 0x8a, 0xca, 0x76,
316 0x48, 0xa9, 0x43, 0xb0,
317 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
318 0xFF, 0xFF, 0x7A, 0x62, 0xD0, 0x31, 0xC8, 0x3F, 0x42, 0x94,
319 0xF6, 0x40, 0xEC, 0x13
320 }
321};
322
323static const struct {
324 EC_CURVE_DATA h;
325 unsigned char data[20 + 30 * 6];
326}
327 _EC_X9_62_PRIME_239V1 = {
328 {
329 NID_X9_62_prime_field, 20, 30, 1
330 },
331 {
332 0xE4, 0x3B, 0xB4, 0x60, 0xF0, 0xB8, 0x0C, 0xC0, 0xC0, 0xB0, /* seed */
333 0x75, 0x79, 0x8E, 0x94, 0x80, 0x60, 0xF8, 0x32, 0x1B, 0x7D,
334
335 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
336 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
338
339 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
340 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
342
343 0x6B, 0x01, 0x6C, 0x3B, 0xDC, 0xF1, 0x89, 0x41, 0xD0, 0xD6, /* b */
344 0x54, 0x92, 0x14, 0x75, 0xCA, 0x71, 0xA9, 0xDB, 0x2F, 0xB2,
345 0x7D, 0x1D, 0x37, 0x79, 0x61, 0x85, 0xC2, 0x94, 0x2C, 0x0A,
346
347 0x0F, 0xFA, 0x96, 0x3C, 0xDC, 0xA8, 0x81, 0x6C, 0xCC, 0x33, /* x */
348 0xB8, 0x64, 0x2B, 0xED, 0xF9, 0x05, 0xC3, 0xD3, 0x58, 0x57,
349 0x3D, 0x3F, 0x27, 0xFB, 0xBD, 0x3B, 0x3C, 0xB9, 0xAA, 0xAF,
350
351 0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40, /* y */
352 0x54, 0xca, 0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18,
353 0xce, 0x22, 0x6b, 0x39, 0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae,
354
355 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
356 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x9E, 0x5E, 0x9A, 0x9F, 0x5D,
357 0x90, 0x71, 0xFB, 0xD1, 0x52, 0x26, 0x88, 0x90, 0x9D, 0x0B
358 }
359};
360
361static const struct {
362 EC_CURVE_DATA h;
363 unsigned char data[20 + 30 * 6];
364}
365 _EC_X9_62_PRIME_239V2 = {
366 {
367 NID_X9_62_prime_field, 20, 30, 1
368 },
369 {
370 0xE8, 0xB4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xCA, 0x3B, /* seed */
371 0x80, 0x99, 0x98, 0x2B, 0xE0, 0x9F, 0xCB, 0x9A, 0xE6, 0x16,
372
373 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
374 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
376
377 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
378 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
380
381 0x61, 0x7F, 0xAB, 0x68, 0x32, 0x57, 0x6C, 0xBB, 0xFE, 0xD5, /* b */
382 0x0D, 0x99, 0xF0, 0x24, 0x9C, 0x3F, 0xEE, 0x58, 0xB9, 0x4B,
383 0xA0, 0x03, 0x8C, 0x7A, 0xE8, 0x4C, 0x8C, 0x83, 0x2F, 0x2C,
384
385 0x38, 0xAF, 0x09, 0xD9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xC9, /* x */
386 0x21, 0xBB, 0x5E, 0x9E, 0x26, 0x29, 0x6A, 0x3C, 0xDC, 0xF2,
387 0xF3, 0x57, 0x57, 0xA0, 0xEA, 0xFD, 0x87, 0xB8, 0x30, 0xE7,
388
389 0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d, /* y */
390 0xa0, 0xfc, 0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55,
391 0xde, 0x6e, 0xf4, 0x60, 0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba,
392
393 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
394 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xCF, 0xA7, 0xE8, 0x59, 0x43,
395 0x77, 0xD4, 0x14, 0xC0, 0x38, 0x21, 0xBC, 0x58, 0x20, 0x63
396 }
397};
398
399static const struct {
400 EC_CURVE_DATA h;
401 unsigned char data[20 + 30 * 6];
402}
403 _EC_X9_62_PRIME_239V3 = {
404 {
405 NID_X9_62_prime_field, 20, 30, 1
406 },
407 {
408 0x7D, 0x73, 0x74, 0x16, 0x8F, 0xFE, 0x34, 0x71, 0xB6, 0x0A, /* seed */
409 0x85, 0x76, 0x86, 0xA1, 0x94, 0x75, 0xD3, 0xBF, 0xA2, 0xFF,
410
411 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
412 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
414
415 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
416 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
417 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
418
419 0x25, 0x57, 0x05, 0xFA, 0x2A, 0x30, 0x66, 0x54, 0xB1, 0xF4, /* b */
420 0xCB, 0x03, 0xD6, 0xA7, 0x50, 0xA3, 0x0C, 0x25, 0x01, 0x02,
421 0xD4, 0x98, 0x87, 0x17, 0xD9, 0xBA, 0x15, 0xAB, 0x6D, 0x3E,
422
423 0x67, 0x68, 0xAE, 0x8E, 0x18, 0xBB, 0x92, 0xCF, 0xCF, 0x00, /* x */
424 0x5C, 0x94, 0x9A, 0xA2, 0xC6, 0xD9, 0x48, 0x53, 0xD0, 0xE6,
425 0x60, 0xBB, 0xF8, 0x54, 0xB1, 0xC9, 0x50, 0x5F, 0xE9, 0x5A,
426
427 0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d, /* y */
428 0x55, 0x2b, 0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b,
429 0x6e, 0x81, 0x84, 0x99, 0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3,
430
431 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
432 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x97, 0x5D, 0xEB, 0x41, 0xB3,
433 0xA6, 0x05, 0x7C, 0x3C, 0x43, 0x21, 0x46, 0x52, 0x65, 0x51
434 }
435};
436
437
438static const struct {
439 EC_CURVE_DATA h;
440 unsigned char data[20 + 32 * 6];
441}
442 _EC_X9_62_PRIME_256V1 = {
443 {
444 NID_X9_62_prime_field, 20, 32, 1
445 },
446 {
447 0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, /* seed */
448 0x78, 0xE1, 0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90,
449
450 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* p */
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
453 0xFF, 0xFF,
454 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* a */
455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
457 0xFF, 0xFC,
458 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, /* b */
459 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0,
460 0xCC, 0x53, 0xB0, 0xF6, 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2,
461 0x60, 0x4B,
462 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, /* x */
463 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81,
464 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98,
465 0xC2, 0x96,
466 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, /* y */
467 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
468 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf,
469 0x51, 0xf5,
470 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, /* order */
471 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD,
472 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63,
473 0x25, 0x51
474 }
475};
476
477/* the secg prime curves (minus the nist and x9.62 prime curves) */
478static const struct {
479 EC_CURVE_DATA h;
480 unsigned char data[20 + 14 * 6];
481}
482 _EC_SECG_PRIME_112R1 = {
483 {
484 NID_X9_62_prime_field, 20, 14, 1
485 },
486 {
487 0x00, 0xF5, 0x0B, 0x02, 0x8E, 0x4D, 0x69, 0x6E, 0x67, 0x68, /* seed */
488 0x75, 0x61, 0x51, 0x75, 0x29, 0x04, 0x72, 0x78, 0x3F, 0xB1,
489
490 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, /* p */
491 0xBE, 0xAD, 0x20, 0x8B,
492 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, /* a */
493 0xBE, 0xAD, 0x20, 0x88,
494 0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, /* b */
495 0x11, 0x70, 0x2B, 0x22,
496 0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, /* x */
497 0xF9, 0xC2, 0xF0, 0x98,
498 0xa8, 0x9c, 0xe5, 0xaf, 0x87, 0x24, 0xc0, 0xa2, 0x3e, 0x0e, /* y */
499 0x0f, 0xf7, 0x75, 0x00,
500 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, /* order */
501 0xAC, 0x65, 0x61, 0xC5
502 }
503};
504
505static const struct {
506 EC_CURVE_DATA h;
507 unsigned char data[20 + 14 * 6];
508}
509 _EC_SECG_PRIME_112R2 = {
510 {
511 NID_X9_62_prime_field, 20, 14, 4
512 },
513 {
514 0x00, 0x27, 0x57, 0xA1, 0x11, 0x4D, 0x69, 0x6E, 0x67, 0x68, /* seed */
515 0x75, 0x61, 0x51, 0x75, 0x53, 0x16, 0xC0, 0x5E, 0x0B, 0xD4,
516
517 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, /* p */
518 0xBE, 0xAD, 0x20, 0x8B,
519 0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, /* a */
520 0x5C, 0x0E, 0xF0, 0x2C,
521 0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, /* b */
522 0x4C, 0x85, 0xD7, 0x09,
523 0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, /* x */
524 0xD0, 0x92, 0x86, 0x43,
525 0xad, 0xcd, 0x46, 0xf5, 0x88, 0x2e, 0x37, 0x47, 0xde, 0xf3, /* y */
526 0x6e, 0x95, 0x6e, 0x97,
527 0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, /* order */
528 0x05, 0x20, 0xD0, 0x4B
529 }
530};
531
532static const struct {
533 EC_CURVE_DATA h;
534 unsigned char data[20 + 16 * 6];
535}
536 _EC_SECG_PRIME_128R1 = {
537 {
538 NID_X9_62_prime_field, 20, 16, 1
539 },
540 {
541 0x00, 0x0E, 0x0D, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, /* seed */
542 0x51, 0x75, 0x0C, 0xC0, 0x3A, 0x44, 0x73, 0xD0, 0x36, 0x79,
543
544 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
545 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
546 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
547 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
548 0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, /* b */
549 0x99, 0x3C, 0x2C, 0xEE, 0x5E, 0xD3,
550 0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, /* x */
551 0x60, 0x7C, 0xA5, 0x2C, 0x5B, 0x86,
552 0xcf, 0x5a, 0xc8, 0x39, 0x5b, 0xaf, 0xeb, 0x13, 0xc0, 0x2d, /* y */
553 0xa2, 0x92, 0xdd, 0xed, 0x7a, 0x83,
554 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, /* order */
555 0x0D, 0x1B, 0x90, 0x38, 0xA1, 0x15
556 }
557};
558
559static const struct {
560 EC_CURVE_DATA h;
561 unsigned char data[20 + 16 * 6];
562}
563 _EC_SECG_PRIME_128R2 = {
564 {
565 NID_X9_62_prime_field, 20, 16, 4
566 },
567 {
568 0x00, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, /* seed */
569 0x12, 0xD8, 0xF0, 0x34, 0x31, 0xFC, 0xE6, 0x3B, 0x88, 0xF4,
570
571 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
572 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
573 0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, /* a */
574 0xCC, 0x9B, 0xBF, 0xF9, 0xAE, 0xE1,
575 0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, /* b */
576 0x65, 0x58, 0xBB, 0x6D, 0x8A, 0x5D,
577 0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, /* x */
578 0x32, 0xA7, 0xCD, 0xEB, 0xC1, 0x40,
579 0x27, 0xb6, 0x91, 0x6a, 0x89, 0x4d, 0x3a, 0xee, 0x71, 0x06, /* y */
580 0xfe, 0x80, 0x5f, 0xc3, 0x4b, 0x44,
581 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, /* order */
582 0x24, 0x72, 0x06, 0x13, 0xB5, 0xA3
583 }
584};
585
586static const struct {
587 EC_CURVE_DATA h;
588 unsigned char data[0 + 21 * 6];
589}
590 _EC_SECG_PRIME_160K1 = {
591 {
592 NID_X9_62_prime_field, 0, 21, 1
593 },
594 { /* no seed */
595 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
596 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC,
597 0x73,
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x07,
604 0x00, 0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, /* x */
605 0x01, 0x9E, 0x76, 0x30, 0x36, 0xF4, 0xF5, 0xDD, 0x4D, 0x7E,
606 0xBB,
607 0x00, 0x93, 0x8c, 0xf9, 0x35, 0x31, 0x8f, 0xdc, 0xed, 0x6b, /* y */
608 0xc2, 0x82, 0x86, 0x53, 0x17, 0x33, 0xc3, 0xf0, 0x3c, 0x4f,
609 0xee,
610 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
611 0x01, 0xB8, 0xFA, 0x16, 0xDF, 0xAB, 0x9A, 0xCA, 0x16, 0xB6,
612 0xB3
613 }
614};
615
616static const struct {
617 EC_CURVE_DATA h;
618 unsigned char data[20 + 21 * 6];
619}
620 _EC_SECG_PRIME_160R1 = {
621 {
622 NID_X9_62_prime_field, 20, 21, 1
623 },
624 {
625 0x10, 0x53, 0xCD, 0xE4, 0x2C, 0x14, 0xD6, 0x96, 0xE6, 0x76, /* seed */
626 0x87, 0x56, 0x15, 0x17, 0x53, 0x3B, 0xF3, 0xF8, 0x33, 0x45,
627
628 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
629 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
630 0xFF,
631 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
632 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
633 0xFC,
634 0x00, 0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, /* b */
635 0xAC, 0xF8, 0x9F, 0x81, 0xD4, 0xD4, 0xAD, 0xC5, 0x65, 0xFA,
636 0x45,
637 0x00, 0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, /* x */
638 0x64, 0x69, 0x89, 0x68, 0xC3, 0x8B, 0xB9, 0x13, 0xCB, 0xFC,
639 0x82,
640 0x00, 0x23, 0xa6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7d, 0x59, /* y */
641 0xdc, 0xc9, 0x12, 0x04, 0x23, 0x51, 0x37, 0x7a, 0xc5, 0xfb,
642 0x32,
643 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
644 0x01, 0xF4, 0xC8, 0xF9, 0x27, 0xAE, 0xD3, 0xCA, 0x75, 0x22,
645 0x57
646 }
647};
648
649static const struct {
650 EC_CURVE_DATA h;
651 unsigned char data[20 + 21 * 6];
652}
653 _EC_SECG_PRIME_160R2 = {
654 {
655 NID_X9_62_prime_field, 20, 21, 1
656 },
657 {
658 0xB9, 0x9B, 0x99, 0xB0, 0x99, 0xB3, 0x23, 0xE0, 0x27, 0x09, /* seed */
659 0xA4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51,
660
661 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
662 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC,
663 0x73,
664 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
665 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC,
666 0x70,
667 0x00, 0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, /* b */
668 0x57, 0x27, 0x49, 0x04, 0x66, 0x4D, 0x5A, 0xF5, 0x03, 0x88,
669 0xBA,
670 0x00, 0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, /* x */
671 0x4F, 0xF1, 0x1B, 0x30, 0xF7, 0x19, 0x9D, 0x31, 0x44, 0xCE,
672 0x6D,
673 0x00, 0xfe, 0xaf, 0xfe, 0xf2, 0xe3, 0x31, 0xf2, 0x96, 0xe0, /* y */
674 0x71, 0xfa, 0x0d, 0xf9, 0x98, 0x2c, 0xfe, 0xa7, 0xd4, 0x3f,
675 0x2e,
676 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
677 0x00, 0x35, 0x1E, 0xE7, 0x86, 0xA8, 0x18, 0xF3, 0xA1, 0xA1,
678 0x6B
679 }
680};
681
682static const struct {
683 EC_CURVE_DATA h;
684 unsigned char data[0 + 24 * 6];
685}
686 _EC_SECG_PRIME_192K1 = {
687 {
688 NID_X9_62_prime_field, 0, 24, 1
689 },
690 { /* no seed */
691 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
692 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
693 0xFF, 0xFF, 0xEE, 0x37,
694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x03,
700 0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, /* x */
701 0x7D, 0x02, 0x80, 0xB7, 0xF4, 0x34, 0x1D, 0xA5, 0xD1, 0xB1,
702 0xEA, 0xE0, 0x6C, 0x7D,
703 0x9b, 0x2f, 0x2f, 0x6d, 0x9c, 0x56, 0x28, 0xa7, 0x84, 0x41, /* y */
704 0x63, 0xd0, 0x15, 0xbe, 0x86, 0x34, 0x40, 0x82, 0xaa, 0x88,
705 0xd9, 0x5e, 0x2f, 0x9d,
706 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
707 0xFF, 0xFE, 0x26, 0xF2, 0xFC, 0x17, 0x0F, 0x69, 0x46, 0x6A,
708 0x74, 0xDE, 0xFD, 0x8D
709 }
710};
711
712static const struct {
713 EC_CURVE_DATA h;
714 unsigned char data[0 + 29 * 6];
715}
716 _EC_SECG_PRIME_224K1 = {
717 {
718 NID_X9_62_prime_field, 0, 29, 1
719 },
720 { /* no seed */
721 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
722 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
723 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE5, 0x6D,
724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
728 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
730 0x00, 0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, /* x */
731 0xFC, 0x28, 0xA1, 0x69, 0xA4, 0x67, 0xE9, 0xE4, 0x70, 0x75,
732 0xA9, 0x0F, 0x7E, 0x65, 0x0E, 0xB6, 0xB7, 0xA4, 0x5C,
733 0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82, /* y */
734 0xca, 0xfb, 0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd,
735 0x59, 0xe2, 0xca, 0x4b, 0xdb, 0x55, 0x6d, 0x61, 0xa5,
736 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
737 0x00, 0x00, 0x00, 0x00, 0x01, 0xDC, 0xE8, 0xD2, 0xEC, 0x61,
738 0x84, 0xCA, 0xF0, 0xA9, 0x71, 0x76, 0x9F, 0xB1, 0xF7
739 }
740};
741
742static const struct {
743 EC_CURVE_DATA h;
744 unsigned char data[0 + 32 * 6];
745}
746 _EC_SECG_PRIME_256K1 = {
747 {
748 NID_X9_62_prime_field, 0, 32, 1
749 },
750 { /* no seed */
751 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
752 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
753 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
754 0xFC, 0x2F,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
758 0x00, 0x00,
759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
761 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
762 0x00, 0x07,
763 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, /* x */
764 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB,
765 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8,
766 0x17, 0x98,
767 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, /* y */
768 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48,
769 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10,
770 0xd4, 0xb8,
771 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
772 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6,
773 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36,
774 0x41, 0x41
775 }
776};
777
778/* some wap/wtls curves */
779static const struct {
780 EC_CURVE_DATA h;
781 unsigned char data[0 + 15 * 6];
782}
783 _EC_WTLS_8 = {
784 {
785 NID_X9_62_prime_field, 0, 15, 1
786 },
787 { /* no seed */
788 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
789 0xFF, 0xFF, 0xFF, 0xFD, 0xE7,
790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
791 0x00, 0x00, 0x00, 0x00, 0x00,
792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
793 0x00, 0x00, 0x00, 0x00, 0x03,
794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
795 0x00, 0x00, 0x00, 0x00, 0x01,
796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* y */
797 0x00, 0x00, 0x00, 0x00, 0x02,
798 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEC, 0xEA, /* order */
799 0x55, 0x1A, 0xD8, 0x37, 0xE9
800 }
801};
802
803static const struct {
804 EC_CURVE_DATA h;
805 unsigned char data[0 + 21 * 6];
806}
807 _EC_WTLS_9 = {
808 {
809 NID_X9_62_prime_field, 0, 21, 1
810 },
811 { /* no seed */
812 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
813 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80,
814 0x8F,
815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
817 0x00,
818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
820 0x03,
821 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
822 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
823 0x01,
824 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* y */
825 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
826 0x02,
827 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
828 0x01, 0xCD, 0xC9, 0x8A, 0xE0, 0xE2, 0xDE, 0x57, 0x4A, 0xBF,
829 0x33
830 }
831};
832
833static const struct {
834 EC_CURVE_DATA h;
835 unsigned char data[0 + 28 * 6];
836}
837 _EC_WTLS_12 = {
838 {
839 NID_X9_62_prime_field, 0, 28, 1
840 },
841 { /* no seed */
842 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
843 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
845 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
846 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
847 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
848 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
849 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA,
850 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4,
851 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
852 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22,
853 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21,
854 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
855 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
856 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
857 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
858 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E,
859 0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D
860 }
861};
862
863#ifndef OPENSSL_NO_EC2M
864
865/* characteristic two curves */
866static const struct {
867 EC_CURVE_DATA h;
868 unsigned char data[20 + 15 * 6];
869}
870 _EC_SECG_CHAR2_113R1 = {
871 {
872 NID_X9_62_characteristic_two_field, 20, 15, 2
873 },
874 {
875 0x10, 0xE7, 0x23, 0xAB, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, /* seed */
876 0x56, 0x15, 0x17, 0x56, 0xFE, 0xBF, 0x8F, 0xCB, 0x49, 0xA9,
877
878 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
879 0x00, 0x00, 0x00, 0x02, 0x01,
880 0x00, 0x30, 0x88, 0x25, 0x0C, 0xA6, 0xE7, 0xC7, 0xFE, 0x64, /* a */
881 0x9C, 0xE8, 0x58, 0x20, 0xF7,
882 0x00, 0xE8, 0xBE, 0xE4, 0xD3, 0xE2, 0x26, 0x07, 0x44, 0x18, /* b */
883 0x8B, 0xE0, 0xE9, 0xC7, 0x23,
884 0x00, 0x9D, 0x73, 0x61, 0x6F, 0x35, 0xF4, 0xAB, 0x14, 0x07, /* x */
885 0xD7, 0x35, 0x62, 0xC1, 0x0F,
886 0x00, 0xA5, 0x28, 0x30, 0x27, 0x79, 0x58, 0xEE, 0x84, 0xD1, /* y */
887 0x31, 0x5E, 0xD3, 0x18, 0x86,
888 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xCC, /* order */
889 0xEC, 0x8A, 0x39, 0xE5, 0x6F
890 }
891};
892
893static const struct {
894 EC_CURVE_DATA h;
895 unsigned char data[20 + 15 * 6];
896}
897 _EC_SECG_CHAR2_113R2 = {
898 {
899 NID_X9_62_characteristic_two_field, 20, 15, 2
900 },
901 {
902 0x10, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, /* seed */
903 0xF4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x5D,
904
905 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
906 0x00, 0x00, 0x00, 0x02, 0x01,
907 0x00, 0x68, 0x99, 0x18, 0xDB, 0xEC, 0x7E, 0x5A, 0x0D, 0xD6, /* a */
908 0xDF, 0xC0, 0xAA, 0x55, 0xC7,
909 0x00, 0x95, 0xE9, 0xA9, 0xEC, 0x9B, 0x29, 0x7B, 0xD4, 0xBF, /* b */
910 0x36, 0xE0, 0x59, 0x18, 0x4F,
911 0x01, 0xA5, 0x7A, 0x6A, 0x7B, 0x26, 0xCA, 0x5E, 0xF5, 0x2F, /* x */
912 0xCD, 0xB8, 0x16, 0x47, 0x97,
913 0x00, 0xB3, 0xAD, 0xC9, 0x4E, 0xD1, 0xFE, 0x67, 0x4C, 0x06, /* y */
914 0xE6, 0x95, 0xBA, 0xBA, 0x1D,
915 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x78, /* order */
916 0x9B, 0x24, 0x96, 0xAF, 0x93
917 }
918};
919
920static const struct {
921 EC_CURVE_DATA h;
922 unsigned char data[20 + 17 * 6];
923}
924 _EC_SECG_CHAR2_131R1 = {
925 {
926 NID_X9_62_characteristic_two_field, 20, 17, 2
927 },
928 {
929 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x98, /* seed */
930 0x5B, 0xD3, 0xAD, 0xBA, 0xDA, 0x21, 0xB4, 0x3A, 0x97, 0xE2,
931
932 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
933 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0D,
934 0x07, 0xA1, 0x1B, 0x09, 0xA7, 0x6B, 0x56, 0x21, 0x44, 0x41, /* a */
935 0x8F, 0xF3, 0xFF, 0x8C, 0x25, 0x70, 0xB8,
936 0x02, 0x17, 0xC0, 0x56, 0x10, 0x88, 0x4B, 0x63, 0xB9, 0xC6, /* b */
937 0xC7, 0x29, 0x16, 0x78, 0xF9, 0xD3, 0x41,
938 0x00, 0x81, 0xBA, 0xF9, 0x1F, 0xDF, 0x98, 0x33, 0xC4, 0x0F, /* x */
939 0x9C, 0x18, 0x13, 0x43, 0x63, 0x83, 0x99,
940 0x07, 0x8C, 0x6E, 0x7E, 0xA3, 0x8C, 0x00, 0x1F, 0x73, 0xC8, /* y */
941 0x13, 0x4B, 0x1B, 0x4E, 0xF9, 0xE1, 0x50,
942 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, /* order */
943 0x23, 0x95, 0x3A, 0x94, 0x64, 0xB5, 0x4D
944 }
945};
946
947static const struct {
948 EC_CURVE_DATA h;
949 unsigned char data[20 + 17 * 6];
950}
951 _EC_SECG_CHAR2_131R2 = {
952 {
953 NID_X9_62_characteristic_two_field, 20, 17, 2
954 },
955 {
956 0x98, 0x5B, 0xD3, 0xAD, 0xBA, 0xD4, 0xD6, 0x96, 0xE6, 0x76, /* seed */
957 0x87, 0x56, 0x15, 0x17, 0x5A, 0x21, 0xB4, 0x3A, 0x97, 0xE3,
958
959 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
960 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0D,
961 0x03, 0xE5, 0xA8, 0x89, 0x19, 0xD7, 0xCA, 0xFC, 0xBF, 0x41, /* a */
962 0x5F, 0x07, 0xC2, 0x17, 0x65, 0x73, 0xB2,
963 0x04, 0xB8, 0x26, 0x6A, 0x46, 0xC5, 0x56, 0x57, 0xAC, 0x73, /* b */
964 0x4C, 0xE3, 0x8F, 0x01, 0x8F, 0x21, 0x92,
965 0x03, 0x56, 0xDC, 0xD8, 0xF2, 0xF9, 0x50, 0x31, 0xAD, 0x65, /* x */
966 0x2D, 0x23, 0x95, 0x1B, 0xB3, 0x66, 0xA8,
967 0x06, 0x48, 0xF0, 0x6D, 0x86, 0x79, 0x40, 0xA5, 0x36, 0x6D, /* y */
968 0x9E, 0x26, 0x5D, 0xE9, 0xEB, 0x24, 0x0F,
969 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, /* order */
970 0x54, 0xA2, 0x33, 0x04, 0x9B, 0xA9, 0x8F
971 }
972};
973
974static const struct {
975 EC_CURVE_DATA h;
976 unsigned char data[0 + 21 * 6];
977}
978 _EC_NIST_CHAR2_163K = {
979 {
980 NID_X9_62_characteristic_two_field, 0, 21, 2
981 },
982 { /* no seed */
983 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
984 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
985 0xC9,
986 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
988 0x01,
989 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
991 0x01,
992 0x02, 0xFE, 0x13, 0xC0, 0x53, 0x7B, 0xBC, 0x11, 0xAC, 0xAA, /* x */
993 0x07, 0xD7, 0x93, 0xDE, 0x4E, 0x6D, 0x5E, 0x5C, 0x94, 0xEE,
994 0xE8,
995 0x02, 0x89, 0x07, 0x0F, 0xB0, 0x5D, 0x38, 0xFF, 0x58, 0x32, /* y */
996 0x1F, 0x2E, 0x80, 0x05, 0x36, 0xD5, 0x38, 0xCC, 0xDA, 0xA3,
997 0xD9,
998 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
999 0x02, 0x01, 0x08, 0xA2, 0xE0, 0xCC, 0x0D, 0x99, 0xF8, 0xA5,
1000 0xEF
1001 }
1002};
1003
1004static const struct {
1005 EC_CURVE_DATA h;
1006 unsigned char data[0 + 21 * 6];
1007}
1008 _EC_SECG_CHAR2_163R1 = {
1009 {
1010 NID_X9_62_characteristic_two_field, 0, 21, 2
1011 },
1012 { /* no seed */
1013 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1014 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1015 0xC9,
1016 0x07, 0xB6, 0x88, 0x2C, 0xAA, 0xEF, 0xA8, 0x4F, 0x95, 0x54, /* a */
1017 0xFF, 0x84, 0x28, 0xBD, 0x88, 0xE2, 0x46, 0xD2, 0x78, 0x2A,
1018 0xE2,
1019 0x07, 0x13, 0x61, 0x2D, 0xCD, 0xDC, 0xB4, 0x0A, 0xAB, 0x94, /* b */
1020 0x6B, 0xDA, 0x29, 0xCA, 0x91, 0xF7, 0x3A, 0xF9, 0x58, 0xAF,
1021 0xD9,
1022 0x03, 0x69, 0x97, 0x96, 0x97, 0xAB, 0x43, 0x89, 0x77, 0x89, /* x */
1023 0x56, 0x67, 0x89, 0x56, 0x7F, 0x78, 0x7A, 0x78, 0x76, 0xA6,
1024 0x54,
1025 0x00, 0x43, 0x5E, 0xDB, 0x42, 0xEF, 0xAF, 0xB2, 0x98, 0x9D, /* y */
1026 0x51, 0xFE, 0xFC, 0xE3, 0xC8, 0x09, 0x88, 0xF4, 0x1F, 0xF8,
1027 0x83,
1028 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1029 0xFF, 0x48, 0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27,
1030 0x9B
1031 }
1032};
1033
1034static const struct {
1035 EC_CURVE_DATA h;
1036 unsigned char data[0 + 21 * 6];
1037}
1038 _EC_NIST_CHAR2_163B = {
1039 {
1040 NID_X9_62_characteristic_two_field, 0, 21, 2
1041 },
1042 { /* no seed */
1043 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1044 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1045 0xC9,
1046 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1047 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1048 0x01,
1049 0x02, 0x0A, 0x60, 0x19, 0x07, 0xB8, 0xC9, 0x53, 0xCA, 0x14, /* b */
1050 0x81, 0xEB, 0x10, 0x51, 0x2F, 0x78, 0x74, 0x4A, 0x32, 0x05,
1051 0xFD,
1052 0x03, 0xF0, 0xEB, 0xA1, 0x62, 0x86, 0xA2, 0xD5, 0x7E, 0xA0, /* x */
1053 0x99, 0x11, 0x68, 0xD4, 0x99, 0x46, 0x37, 0xE8, 0x34, 0x3E,
1054 0x36,
1055 0x00, 0xD5, 0x1F, 0xBC, 0x6C, 0x71, 0xA0, 0x09, 0x4F, 0xA2, /* y */
1056 0xCD, 0xD5, 0x45, 0xB1, 0x1C, 0x5C, 0x0C, 0x79, 0x73, 0x24,
1057 0xF1,
1058 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1059 0x02, 0x92, 0xFE, 0x77, 0xE7, 0x0C, 0x12, 0xA4, 0x23, 0x4C,
1060 0x33
1061 }
1062};
1063
1064static const struct {
1065 EC_CURVE_DATA h;
1066 unsigned char data[20 + 25 * 6];
1067}
1068 _EC_SECG_CHAR2_193R1 = {
1069 {
1070 NID_X9_62_characteristic_two_field, 20, 25, 2
1071 },
1072 {
1073 0x10, 0x3F, 0xAE, 0xC7, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, /* seed */
1074 0x61, 0x51, 0x75, 0x77, 0x7F, 0xC5, 0xB1, 0x91, 0xEF, 0x30,
1075
1076 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1077 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1078 0x00, 0x00, 0x00, 0x80, 0x01,
1079 0x00, 0x17, 0x85, 0x8F, 0xEB, 0x7A, 0x98, 0x97, 0x51, 0x69, /* a */
1080 0xE1, 0x71, 0xF7, 0x7B, 0x40, 0x87, 0xDE, 0x09, 0x8A, 0xC8,
1081 0xA9, 0x11, 0xDF, 0x7B, 0x01,
1082 0x00, 0xFD, 0xFB, 0x49, 0xBF, 0xE6, 0xC3, 0xA8, 0x9F, 0xAC, /* b */
1083 0xAD, 0xAA, 0x7A, 0x1E, 0x5B, 0xBC, 0x7C, 0xC1, 0xC2, 0xE5,
1084 0xD8, 0x31, 0x47, 0x88, 0x14,
1085 0x01, 0xF4, 0x81, 0xBC, 0x5F, 0x0F, 0xF8, 0x4A, 0x74, 0xAD, /* x */
1086 0x6C, 0xDF, 0x6F, 0xDE, 0xF4, 0xBF, 0x61, 0x79, 0x62, 0x53,
1087 0x72, 0xD8, 0xC0, 0xC5, 0xE1,
1088 0x00, 0x25, 0xE3, 0x99, 0xF2, 0x90, 0x37, 0x12, 0xCC, 0xF3, /* y */
1089 0xEA, 0x9E, 0x3A, 0x1A, 0xD1, 0x7F, 0xB0, 0xB3, 0x20, 0x1B,
1090 0x6A, 0xF7, 0xCE, 0x1B, 0x05,
1091 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1092 0x00, 0x00, 0x00, 0xC7, 0xF3, 0x4A, 0x77, 0x8F, 0x44, 0x3A,
1093 0xCC, 0x92, 0x0E, 0xBA, 0x49
1094 }
1095};
1096
1097static const struct {
1098 EC_CURVE_DATA h;
1099 unsigned char data[20 + 25 * 6];
1100}
1101 _EC_SECG_CHAR2_193R2 = {
1102 {
1103 NID_X9_62_characteristic_two_field, 20, 25, 2
1104 },
1105 {
1106 0x10, 0xB7, 0xB4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, /* seed */
1107 0x17, 0x51, 0x37, 0xC8, 0xA1, 0x6F, 0xD0, 0xDA, 0x22, 0x11,
1108
1109 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1111 0x00, 0x00, 0x00, 0x80, 0x01,
1112 0x01, 0x63, 0xF3, 0x5A, 0x51, 0x37, 0xC2, 0xCE, 0x3E, 0xA6, /* a */
1113 0xED, 0x86, 0x67, 0x19, 0x0B, 0x0B, 0xC4, 0x3E, 0xCD, 0x69,
1114 0x97, 0x77, 0x02, 0x70, 0x9B,
1115 0x00, 0xC9, 0xBB, 0x9E, 0x89, 0x27, 0xD4, 0xD6, 0x4C, 0x37, /* b */
1116 0x7E, 0x2A, 0xB2, 0x85, 0x6A, 0x5B, 0x16, 0xE3, 0xEF, 0xB7,
1117 0xF6, 0x1D, 0x43, 0x16, 0xAE,
1118 0x00, 0xD9, 0xB6, 0x7D, 0x19, 0x2E, 0x03, 0x67, 0xC8, 0x03, /* x */
1119 0xF3, 0x9E, 0x1A, 0x7E, 0x82, 0xCA, 0x14, 0xA6, 0x51, 0x35,
1120 0x0A, 0xAE, 0x61, 0x7E, 0x8F,
1121 0x01, 0xCE, 0x94, 0x33, 0x56, 0x07, 0xC3, 0x04, 0xAC, 0x29, /* y */
1122 0xE7, 0xDE, 0xFB, 0xD9, 0xCA, 0x01, 0xF5, 0x96, 0xF9, 0x27,
1123 0x22, 0x4C, 0xDE, 0xCF, 0x6C,
1124 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1125 0x00, 0x00, 0x01, 0x5A, 0xAB, 0x56, 0x1B, 0x00, 0x54, 0x13,
1126 0xCC, 0xD4, 0xEE, 0x99, 0xD5
1127 }
1128};
1129
1130static const struct {
1131 EC_CURVE_DATA h;
1132 unsigned char data[0 + 30 * 6];
1133}
1134 _EC_NIST_CHAR2_233K = {
1135 {
1136 NID_X9_62_characteristic_two_field, 0, 30, 4
1137 },
1138 { /* no seed */
1139 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1141 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1142
1143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1146
1147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1150
1151 0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, /* x */
1152 0x29, 0xF2, 0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2,
1153 0x6B, 0xF5, 0x0A, 0x4C, 0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
1154
1155 0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, /* y */
1156 0x55, 0x5A, 0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A,
1157 0xEB, 0x9B, 0x56, 0xE0, 0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3,
1158
1159 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1160 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15,
1161 0xBC, 0xD4, 0x6E, 0xFB, 0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
1162 }
1163};
1164
1165static const struct {
1166 EC_CURVE_DATA h;
1167 unsigned char data[20 + 30 * 6];
1168}
1169 _EC_NIST_CHAR2_233B = {
1170 {
1171 NID_X9_62_characteristic_two_field, 20, 30, 2
1172 },
1173 {
1174 0x74, 0xD5, 0x9F, 0xF0, 0x7F, 0x6B, 0x41, 0x3D, 0x0E, 0xA1, /* seed */
1175 0x4B, 0x34, 0x4B, 0x20, 0xA2, 0xDB, 0x04, 0x9B, 0x50, 0xC3,
1176
1177 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1179 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1180
1181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1184
1185 0x00, 0x66, 0x64, 0x7E, 0xDE, 0x6C, 0x33, 0x2C, 0x7F, 0x8C, /* b */
1186 0x09, 0x23, 0xBB, 0x58, 0x21, 0x3B, 0x33, 0x3B, 0x20, 0xE9,
1187 0xCE, 0x42, 0x81, 0xFE, 0x11, 0x5F, 0x7D, 0x8F, 0x90, 0xAD,
1188
1189 0x00, 0xFA, 0xC9, 0xDF, 0xCB, 0xAC, 0x83, 0x13, 0xBB, 0x21, /* x */
1190 0x39, 0xF1, 0xBB, 0x75, 0x5F, 0xEF, 0x65, 0xBC, 0x39, 0x1F,
1191 0x8B, 0x36, 0xF8, 0xF8, 0xEB, 0x73, 0x71, 0xFD, 0x55, 0x8B,
1192
1193 0x01, 0x00, 0x6A, 0x08, 0xA4, 0x19, 0x03, 0x35, 0x06, 0x78, /* y */
1194 0xE5, 0x85, 0x28, 0xBE, 0xBF, 0x8A, 0x0B, 0xEF, 0xF8, 0x67,
1195 0xA7, 0xCA, 0x36, 0x71, 0x6F, 0x7E, 0x01, 0xF8, 0x10, 0x52,
1196
1197 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1198 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F,
1199 0x8A, 0x69, 0x22, 0x03, 0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7
1200 }
1201};
1202
1203static const struct {
1204 EC_CURVE_DATA h;
1205 unsigned char data[0 + 30 * 6];
1206}
1207 _EC_SECG_CHAR2_239K1 = {
1208 {
1209 NID_X9_62_characteristic_two_field, 0, 30, 4
1210 },
1211 { /* no seed */
1212 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1213 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1215
1216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1219
1220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1223
1224 0x29, 0xA0, 0xB6, 0xA8, 0x87, 0xA9, 0x83, 0xE9, 0x73, 0x09, /* x */
1225 0x88, 0xA6, 0x87, 0x27, 0xA8, 0xB2, 0xD1, 0x26, 0xC4, 0x4C,
1226 0xC2, 0xCC, 0x7B, 0x2A, 0x65, 0x55, 0x19, 0x30, 0x35, 0xDC,
1227
1228 0x76, 0x31, 0x08, 0x04, 0xF1, 0x2E, 0x54, 0x9B, 0xDB, 0x01, /* y */
1229 0x1C, 0x10, 0x30, 0x89, 0xE7, 0x35, 0x10, 0xAC, 0xB2, 0x75,
1230 0xFC, 0x31, 0x2A, 0x5D, 0xC6, 0xB7, 0x65, 0x53, 0xF0, 0xCA,
1231
1232 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1233 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0x79, 0xFE, 0xC6, 0x7C,
1234 0xB6, 0xE9, 0x1F, 0x1C, 0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5
1235 }
1236};
1237
1238static const struct {
1239 EC_CURVE_DATA h;
1240 unsigned char data[0 + 36 * 6];
1241}
1242 _EC_NIST_CHAR2_283K = {
1243 {
1244 NID_X9_62_characteristic_two_field, 0, 36, 4
1245 },
1246 { /* no seed */
1247 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1250 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
1251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1258 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1259 0x05, 0x03, 0x21, 0x3F, 0x78, 0xCA, 0x44, 0x88, 0x3F, 0x1A, /* x */
1260 0x3B, 0x81, 0x62, 0xF1, 0x88, 0xE5, 0x53, 0xCD, 0x26, 0x5F,
1261 0x23, 0xC1, 0x56, 0x7A, 0x16, 0x87, 0x69, 0x13, 0xB0, 0xC2,
1262 0xAC, 0x24, 0x58, 0x49, 0x28, 0x36,
1263 0x01, 0xCC, 0xDA, 0x38, 0x0F, 0x1C, 0x9E, 0x31, 0x8D, 0x90, /* y */
1264 0xF9, 0x5D, 0x07, 0xE5, 0x42, 0x6F, 0xE8, 0x7E, 0x45, 0xC0,
1265 0xE8, 0x18, 0x46, 0x98, 0xE4, 0x59, 0x62, 0x36, 0x4E, 0x34,
1266 0x11, 0x61, 0x77, 0xDD, 0x22, 0x59,
1267 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1268 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xAE,
1269 0x2E, 0xD0, 0x75, 0x77, 0x26, 0x5D, 0xFF, 0x7F, 0x94, 0x45,
1270 0x1E, 0x06, 0x1E, 0x16, 0x3C, 0x61
1271 }
1272};
1273
1274static const struct {
1275 EC_CURVE_DATA h;
1276 unsigned char data[20 + 36 * 6];
1277}
1278 _EC_NIST_CHAR2_283B = {
1279 {
1280 NID_X9_62_characteristic_two_field, 20, 36, 2
1281 },
1282 {
1283 0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D, /* no seed */
1284 0xD5, 0xB6, 0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE,
1285
1286 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1289 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
1290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1293 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1294 0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, /* b */
1295 0xAF, 0x8A, 0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76,
1296 0x45, 0x30, 0x9F, 0xA2, 0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26,
1297 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5,
1298 0x05, 0xF9, 0x39, 0x25, 0x8D, 0xB7, 0xDD, 0x90, 0xE1, 0x93, /* x */
1299 0x4F, 0x8C, 0x70, 0xB0, 0xDF, 0xEC, 0x2E, 0xED, 0x25, 0xB8,
1300 0x55, 0x7E, 0xAC, 0x9C, 0x80, 0xE2, 0xE1, 0x98, 0xF8, 0xCD,
1301 0xBE, 0xCD, 0x86, 0xB1, 0x20, 0x53,
1302 0x03, 0x67, 0x68, 0x54, 0xFE, 0x24, 0x14, 0x1C, 0xB9, 0x8F, /* y */
1303 0xE6, 0xD4, 0xB2, 0x0D, 0x02, 0xB4, 0x51, 0x6F, 0xF7, 0x02,
1304 0x35, 0x0E, 0xDD, 0xB0, 0x82, 0x67, 0x79, 0xC8, 0x13, 0xF0,
1305 0xDF, 0x45, 0xBE, 0x81, 0x12, 0xF4,
1306 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1307 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x90,
1308 0x39, 0x96, 0x60, 0xFC, 0x93, 0x8A, 0x90, 0x16, 0x5B, 0x04,
1309 0x2A, 0x7C, 0xEF, 0xAD, 0xB3, 0x07
1310 }
1311};
1312
1313static const struct {
1314 EC_CURVE_DATA h;
1315 unsigned char data[0 + 52 * 6];
1316}
1317 _EC_NIST_CHAR2_409K = {
1318 {
1319 NID_X9_62_characteristic_two_field, 0, 52, 4
1320 },
1321 { /* no seed */
1322 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1326 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1327 0x00, 0x01,
1328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1333 0x00, 0x00,
1334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1339 0x00, 0x01,
1340 0x00, 0x60, 0xF0, 0x5F, 0x65, 0x8F, 0x49, 0xC1, 0xAD, 0x3A, /* x */
1341 0xB1, 0x89, 0x0F, 0x71, 0x84, 0x21, 0x0E, 0xFD, 0x09, 0x87,
1342 0xE3, 0x07, 0xC8, 0x4C, 0x27, 0xAC, 0xCF, 0xB8, 0xF9, 0xF6,
1343 0x7C, 0xC2, 0xC4, 0x60, 0x18, 0x9E, 0xB5, 0xAA, 0xAA, 0x62,
1344 0xEE, 0x22, 0x2E, 0xB1, 0xB3, 0x55, 0x40, 0xCF, 0xE9, 0x02,
1345 0x37, 0x46,
1346 0x01, 0xE3, 0x69, 0x05, 0x0B, 0x7C, 0x4E, 0x42, 0xAC, 0xBA, /* y */
1347 0x1D, 0xAC, 0xBF, 0x04, 0x29, 0x9C, 0x34, 0x60, 0x78, 0x2F,
1348 0x91, 0x8E, 0xA4, 0x27, 0xE6, 0x32, 0x51, 0x65, 0xE9, 0xEA,
1349 0x10, 0xE3, 0xDA, 0x5F, 0x6C, 0x42, 0xE9, 0xC5, 0x52, 0x15,
1350 0xAA, 0x9C, 0xA2, 0x7A, 0x58, 0x63, 0xEC, 0x48, 0xD8, 0xE0,
1351 0x28, 0x6B,
1352 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1353 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1354 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x5F, 0x83, 0xB2,
1355 0xD4, 0xEA, 0x20, 0x40, 0x0E, 0xC4, 0x55, 0x7D, 0x5E, 0xD3,
1356 0xE3, 0xE7, 0xCA, 0x5B, 0x4B, 0x5C, 0x83, 0xB8, 0xE0, 0x1E,
1357 0x5F, 0xCF
1358 }
1359};
1360
1361static const struct {
1362 EC_CURVE_DATA h;
1363 unsigned char data[20 + 52 * 6];
1364}
1365 _EC_NIST_CHAR2_409B = {
1366 {
1367 NID_X9_62_characteristic_two_field, 20, 52, 2
1368 },
1369 {
1370 0x40, 0x99, 0xB5, 0xA4, 0x57, 0xF9, 0xD6, 0x9F, 0x79, 0x21, /* seed */
1371 0x3D, 0x09, 0x4C, 0x4B, 0xCD, 0x4D, 0x42, 0x62, 0x21, 0x0B,
1372
1373 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1378 0x00, 0x01,
1379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1384 0x00, 0x01,
1385 0x00, 0x21, 0xA5, 0xC2, 0xC8, 0xEE, 0x9F, 0xEB, 0x5C, 0x4B, /* b */
1386 0x9A, 0x75, 0x3B, 0x7B, 0x47, 0x6B, 0x7F, 0xD6, 0x42, 0x2E,
1387 0xF1, 0xF3, 0xDD, 0x67, 0x47, 0x61, 0xFA, 0x99, 0xD6, 0xAC,
1388 0x27, 0xC8, 0xA9, 0xA1, 0x97, 0xB2, 0x72, 0x82, 0x2F, 0x6C,
1389 0xD5, 0x7A, 0x55, 0xAA, 0x4F, 0x50, 0xAE, 0x31, 0x7B, 0x13,
1390 0x54, 0x5F,
1391 0x01, 0x5D, 0x48, 0x60, 0xD0, 0x88, 0xDD, 0xB3, 0x49, 0x6B, /* x */
1392 0x0C, 0x60, 0x64, 0x75, 0x62, 0x60, 0x44, 0x1C, 0xDE, 0x4A,
1393 0xF1, 0x77, 0x1D, 0x4D, 0xB0, 0x1F, 0xFE, 0x5B, 0x34, 0xE5,
1394 0x97, 0x03, 0xDC, 0x25, 0x5A, 0x86, 0x8A, 0x11, 0x80, 0x51,
1395 0x56, 0x03, 0xAE, 0xAB, 0x60, 0x79, 0x4E, 0x54, 0xBB, 0x79,
1396 0x96, 0xA7,
1397 0x00, 0x61, 0xB1, 0xCF, 0xAB, 0x6B, 0xE5, 0xF3, 0x2B, 0xBF, /* y */
1398 0xA7, 0x83, 0x24, 0xED, 0x10, 0x6A, 0x76, 0x36, 0xB9, 0xC5,
1399 0xA7, 0xBD, 0x19, 0x8D, 0x01, 0x58, 0xAA, 0x4F, 0x54, 0x88,
1400 0xD0, 0x8F, 0x38, 0x51, 0x4F, 0x1F, 0xDF, 0x4B, 0x4F, 0x40,
1401 0xD2, 0x18, 0x1B, 0x36, 0x81, 0xC3, 0x64, 0xBA, 0x02, 0x73,
1402 0xC7, 0x06,
1403 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE2, 0xAA, 0xD6,
1406 0xA6, 0x12, 0xF3, 0x33, 0x07, 0xBE, 0x5F, 0xA4, 0x7C, 0x3C,
1407 0x9E, 0x05, 0x2F, 0x83, 0x81, 0x64, 0xCD, 0x37, 0xD9, 0xA2,
1408 0x11, 0x73
1409 }
1410};
1411
1412static const struct {
1413 EC_CURVE_DATA h;
1414 unsigned char data[0 + 72 * 6];
1415}
1416 _EC_NIST_CHAR2_571K = {
1417 {
1418 NID_X9_62_characteristic_two_field, 0, 72, 4
1419 },
1420 { /* no seed */
1421 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1428 0x04, 0x25,
1429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1431 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1436 0x00, 0x00,
1437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1444 0x00, 0x01,
1445 0x02, 0x6E, 0xB7, 0xA8, 0x59, 0x92, 0x3F, 0xBC, 0x82, 0x18, /* x */
1446 0x96, 0x31, 0xF8, 0x10, 0x3F, 0xE4, 0xAC, 0x9C, 0xA2, 0x97,
1447 0x00, 0x12, 0xD5, 0xD4, 0x60, 0x24, 0x80, 0x48, 0x01, 0x84,
1448 0x1C, 0xA4, 0x43, 0x70, 0x95, 0x84, 0x93, 0xB2, 0x05, 0xE6,
1449 0x47, 0xDA, 0x30, 0x4D, 0xB4, 0xCE, 0xB0, 0x8C, 0xBB, 0xD1,
1450 0xBA, 0x39, 0x49, 0x47, 0x76, 0xFB, 0x98, 0x8B, 0x47, 0x17,
1451 0x4D, 0xCA, 0x88, 0xC7, 0xE2, 0x94, 0x52, 0x83, 0xA0, 0x1C,
1452 0x89, 0x72,
1453 0x03, 0x49, 0xDC, 0x80, 0x7F, 0x4F, 0xBF, 0x37, 0x4F, 0x4A, /* y */
1454 0xEA, 0xDE, 0x3B, 0xCA, 0x95, 0x31, 0x4D, 0xD5, 0x8C, 0xEC,
1455 0x9F, 0x30, 0x7A, 0x54, 0xFF, 0xC6, 0x1E, 0xFC, 0x00, 0x6D,
1456 0x8A, 0x2C, 0x9D, 0x49, 0x79, 0xC0, 0xAC, 0x44, 0xAE, 0xA7,
1457 0x4F, 0xBE, 0xBB, 0xB9, 0xF7, 0x72, 0xAE, 0xDC, 0xB6, 0x20,
1458 0xB0, 0x1A, 0x7B, 0xA7, 0xAF, 0x1B, 0x32, 0x04, 0x30, 0xC8,
1459 0x59, 0x19, 0x84, 0xF6, 0x01, 0xCD, 0x4C, 0x14, 0x3E, 0xF1,
1460 0xC7, 0xA3,
1461 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x18, 0x50, 0xE1,
1465 0xF1, 0x9A, 0x63, 0xE4, 0xB3, 0x91, 0xA8, 0xDB, 0x91, 0x7F,
1466 0x41, 0x38, 0xB6, 0x30, 0xD8, 0x4B, 0xE5, 0xD6, 0x39, 0x38,
1467 0x1E, 0x91, 0xDE, 0xB4, 0x5C, 0xFE, 0x77, 0x8F, 0x63, 0x7C,
1468 0x10, 0x01
1469 }
1470};
1471
1472static const struct {
1473 EC_CURVE_DATA h;
1474 unsigned char data[20 + 72 * 6];
1475}
1476 _EC_NIST_CHAR2_571B = {
1477 {
1478 NID_X9_62_characteristic_two_field, 20, 72, 2
1479 },
1480 {
1481 0x2A, 0xA0, 0x58, 0xF7, 0x3A, 0x0E, 0x33, 0xAB, 0x48, 0x6B, /* seed */
1482 0x0F, 0x61, 0x04, 0x10, 0xC5, 0x3A, 0x7F, 0x13, 0x23, 0x10,
1483
1484 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1491 0x04, 0x25,
1492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1493 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1499 0x00, 0x01,
1500 0x02, 0xF4, 0x0E, 0x7E, 0x22, 0x21, 0xF2, 0x95, 0xDE, 0x29, /* b */
1501 0x71, 0x17, 0xB7, 0xF3, 0xD6, 0x2F, 0x5C, 0x6A, 0x97, 0xFF,
1502 0xCB, 0x8C, 0xEF, 0xF1, 0xCD, 0x6B, 0xA8, 0xCE, 0x4A, 0x9A,
1503 0x18, 0xAD, 0x84, 0xFF, 0xAB, 0xBD, 0x8E, 0xFA, 0x59, 0x33,
1504 0x2B, 0xE7, 0xAD, 0x67, 0x56, 0xA6, 0x6E, 0x29, 0x4A, 0xFD,
1505 0x18, 0x5A, 0x78, 0xFF, 0x12, 0xAA, 0x52, 0x0E, 0x4D, 0xE7,
1506 0x39, 0xBA, 0xCA, 0x0C, 0x7F, 0xFE, 0xFF, 0x7F, 0x29, 0x55,
1507 0x72, 0x7A,
1508 0x03, 0x03, 0x00, 0x1D, 0x34, 0xB8, 0x56, 0x29, 0x6C, 0x16, /* x */
1509 0xC0, 0xD4, 0x0D, 0x3C, 0xD7, 0x75, 0x0A, 0x93, 0xD1, 0xD2,
1510 0x95, 0x5F, 0xA8, 0x0A, 0xA5, 0xF4, 0x0F, 0xC8, 0xDB, 0x7B,
1511 0x2A, 0xBD, 0xBD, 0xE5, 0x39, 0x50, 0xF4, 0xC0, 0xD2, 0x93,
1512 0xCD, 0xD7, 0x11, 0xA3, 0x5B, 0x67, 0xFB, 0x14, 0x99, 0xAE,
1513 0x60, 0x03, 0x86, 0x14, 0xF1, 0x39, 0x4A, 0xBF, 0xA3, 0xB4,
1514 0xC8, 0x50, 0xD9, 0x27, 0xE1, 0xE7, 0x76, 0x9C, 0x8E, 0xEC,
1515 0x2D, 0x19,
1516 0x03, 0x7B, 0xF2, 0x73, 0x42, 0xDA, 0x63, 0x9B, 0x6D, 0xCC, /* y */
1517 0xFF, 0xFE, 0xB7, 0x3D, 0x69, 0xD7, 0x8C, 0x6C, 0x27, 0xA6,
1518 0x00, 0x9C, 0xBB, 0xCA, 0x19, 0x80, 0xF8, 0x53, 0x39, 0x21,
1519 0xE8, 0xA6, 0x84, 0x42, 0x3E, 0x43, 0xBA, 0xB0, 0x8A, 0x57,
1520 0x62, 0x91, 0xAF, 0x8F, 0x46, 0x1B, 0xB2, 0xA8, 0xB3, 0x53,
1521 0x1D, 0x2F, 0x04, 0x85, 0xC1, 0x9B, 0x16, 0xE2, 0xF1, 0x51,
1522 0x6E, 0x23, 0xDD, 0x3C, 0x1A, 0x48, 0x27, 0xAF, 0x1B, 0x8A,
1523 0xC1, 0x5B,
1524 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1525 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1526 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1527 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x61, 0xCE, 0x18,
1528 0xFF, 0x55, 0x98, 0x73, 0x08, 0x05, 0x9B, 0x18, 0x68, 0x23,
1529 0x85, 0x1E, 0xC7, 0xDD, 0x9C, 0xA1, 0x16, 0x1D, 0xE9, 0x3D,
1530 0x51, 0x74, 0xD6, 0x6E, 0x83, 0x82, 0xE9, 0xBB, 0x2F, 0xE8,
1531 0x4E, 0x47
1532 }
1533};
1534
1535static const struct {
1536 EC_CURVE_DATA h;
1537 unsigned char data[20 + 21 * 6];
1538}
1539 _EC_X9_62_CHAR2_163V1 = {
1540 {
1541 NID_X9_62_characteristic_two_field, 20, 21, 2
1542 },
1543 {
1544 0xD2, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE,
1545 0xF4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x54, /* seed */
1546
1547 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1549 0x07,
1550 0x07, 0x25, 0x46, 0xB5, 0x43, 0x52, 0x34, 0xA4, 0x22, 0xE0, /* a */
1551 0x78, 0x96, 0x75, 0xF4, 0x32, 0xC8, 0x94, 0x35, 0xDE, 0x52,
1552 0x42,
1553 0x00, 0xC9, 0x51, 0x7D, 0x06, 0xD5, 0x24, 0x0D, 0x3C, 0xFF, /* b */
1554 0x38, 0xC7, 0x4B, 0x20, 0xB6, 0xCD, 0x4D, 0x6F, 0x9D, 0xD4,
1555 0xD9,
1556 0x07, 0xAF, 0x69, 0x98, 0x95, 0x46, 0x10, 0x3D, 0x79, 0x32, /* x */
1557 0x9F, 0xCC, 0x3D, 0x74, 0x88, 0x0F, 0x33, 0xBB, 0xE8, 0x03,
1558 0xCB,
1559 0x01, 0xEC, 0x23, 0x21, 0x1B, 0x59, 0x66, 0xAD, 0xEA, 0x1D, /* y */
1560 0x3F, 0x87, 0xF7, 0xEA, 0x58, 0x48, 0xAE, 0xF0, 0xB7, 0xCA,
1561 0x9F,
1562 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1563 0x01, 0xE6, 0x0F, 0xC8, 0x82, 0x1C, 0xC7, 0x4D, 0xAE, 0xAF,
1564 0xC1
1565 }
1566};
1567
1568static const struct {
1569 EC_CURVE_DATA h;
1570 unsigned char data[20 + 21 * 6];
1571}
1572 _EC_X9_62_CHAR2_163V2 = {
1573 {
1574 NID_X9_62_characteristic_two_field, 20, 21, 2
1575 },
1576 {
1577 0x53, 0x81, 0x4C, 0x05, 0x0D, 0x44, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1578 0x87, 0x56, 0x15, 0x17, 0x58, 0x0C, 0xA4, 0xE2, 0x9F, 0xFD,
1579
1580 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1582 0x07,
1583 0x01, 0x08, 0xB3, 0x9E, 0x77, 0xC4, 0xB1, 0x08, 0xBE, 0xD9, /* a */
1584 0x81, 0xED, 0x0E, 0x89, 0x0E, 0x11, 0x7C, 0x51, 0x1C, 0xF0,
1585 0x72,
1586 0x06, 0x67, 0xAC, 0xEB, 0x38, 0xAF, 0x4E, 0x48, 0x8C, 0x40, /* b */
1587 0x74, 0x33, 0xFF, 0xAE, 0x4F, 0x1C, 0x81, 0x16, 0x38, 0xDF,
1588 0x20,
1589 0x00, 0x24, 0x26, 0x6E, 0x4E, 0xB5, 0x10, 0x6D, 0x0A, 0x96, /* x */
1590 0x4D, 0x92, 0xC4, 0x86, 0x0E, 0x26, 0x71, 0xDB, 0x9B, 0x6C,
1591 0xC5,
1592 0x07, 0x9F, 0x68, 0x4D, 0xDF, 0x66, 0x84, 0xC5, 0xCD, 0x25, /* y */
1593 0x8B, 0x38, 0x90, 0x02, 0x1B, 0x23, 0x86, 0xDF, 0xD1, 0x9F,
1594 0xC5,
1595 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1596 0xFD, 0xF6, 0x4D, 0xE1, 0x15, 0x1A, 0xDB, 0xB7, 0x8F, 0x10,
1597 0xA7
1598 }
1599};
1600
1601static const struct {
1602 EC_CURVE_DATA h;
1603 unsigned char data[20 + 21 * 6];
1604}
1605 _EC_X9_62_CHAR2_163V3 = {
1606 {
1607 NID_X9_62_characteristic_two_field, 20, 21, 2
1608 },
1609 {
1610 0x50, 0xCB, 0xF1, 0xD9, 0x5C, 0xA9, 0x4D, 0x69, 0x6E, 0x67, /* seed */
1611 0x68, 0x75, 0x61, 0x51, 0x75, 0xF1, 0x6A, 0x36, 0xA3, 0xB8,
1612
1613 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1615 0x07,
1616 0x07, 0xA5, 0x26, 0xC6, 0x3D, 0x3E, 0x25, 0xA2, 0x56, 0xA0, /* a */
1617 0x07, 0x69, 0x9F, 0x54, 0x47, 0xE3, 0x2A, 0xE4, 0x56, 0xB5,
1618 0x0E,
1619 0x03, 0xF7, 0x06, 0x17, 0x98, 0xEB, 0x99, 0xE2, 0x38, 0xFD, /* b */
1620 0x6F, 0x1B, 0xF9, 0x5B, 0x48, 0xFE, 0xEB, 0x48, 0x54, 0x25,
1621 0x2B,
1622 0x02, 0xF9, 0xF8, 0x7B, 0x7C, 0x57, 0x4D, 0x0B, 0xDE, 0xCF, /* x */
1623 0x8A, 0x22, 0xE6, 0x52, 0x47, 0x75, 0xF9, 0x8C, 0xDE, 0xBD,
1624 0xCB,
1625 0x05, 0xB9, 0x35, 0x59, 0x0C, 0x15, 0x5E, 0x17, 0xEA, 0x48, /* y */
1626 0xEB, 0x3F, 0xF3, 0x71, 0x8B, 0x89, 0x3D, 0xF5, 0x9A, 0x05,
1627 0xD0,
1628 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1629 0xFE, 0x1A, 0xEE, 0x14, 0x0F, 0x11, 0x0A, 0xFF, 0x96, 0x13,
1630 0x09
1631 }
1632};
1633
1634static const struct {
1635 EC_CURVE_DATA h;
1636 unsigned char data[0 + 23 * 6];
1637}
1638 _EC_X9_62_CHAR2_176V1 = {
1639 {
1640 NID_X9_62_characteristic_two_field, 0, 23, 0xFF6E
1641 },
1642 { /* no seed */
1643 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
1645 0x00, 0x00, 0x07,
1646 0x00, 0xE4, 0xE6, 0xDB, 0x29, 0x95, 0x06, 0x5C, 0x40, 0x7D, /* a */
1647 0x9D, 0x39, 0xB8, 0xD0, 0x96, 0x7B, 0x96, 0x70, 0x4B, 0xA8,
1648 0xE9, 0xC9, 0x0B,
1649 0x00, 0x5D, 0xDA, 0x47, 0x0A, 0xBE, 0x64, 0x14, 0xDE, 0x8E, /* b */
1650 0xC1, 0x33, 0xAE, 0x28, 0xE9, 0xBB, 0xD7, 0xFC, 0xEC, 0x0A,
1651 0xE0, 0xFF, 0xF2,
1652 0x00, 0x8D, 0x16, 0xC2, 0x86, 0x67, 0x98, 0xB6, 0x00, 0xF9, /* x */
1653 0xF0, 0x8B, 0xB4, 0xA8, 0xE8, 0x60, 0xF3, 0x29, 0x8C, 0xE0,
1654 0x4A, 0x57, 0x98,
1655 0x00, 0x6F, 0xA4, 0x53, 0x9C, 0x2D, 0xAD, 0xDD, 0xD6, 0xBA, /* y */
1656 0xB5, 0x16, 0x7D, 0x61, 0xB4, 0x36, 0xE1, 0xD9, 0x2B, 0xB1,
1657 0x6A, 0x56, 0x2C,
1658 0x00, 0x00, 0x01, 0x00, 0x92, 0x53, 0x73, 0x97, 0xEC, 0xA4, /* order */
1659 0xF6, 0x14, 0x57, 0x99, 0xD6, 0x2B, 0x0A, 0x19, 0xCE, 0x06,
1660 0xFE, 0x26, 0xAD
1661 }
1662};
1663
1664static const struct {
1665 EC_CURVE_DATA h;
1666 unsigned char data[20 + 24 * 6];
1667}
1668 _EC_X9_62_CHAR2_191V1 = {
1669 {
1670 NID_X9_62_characteristic_two_field, 20, 24, 2
1671 },
1672 {
1673 0x4E, 0x13, 0xCA, 0x54, 0x27, 0x44, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1674 0x87, 0x56, 0x15, 0x17, 0x55, 0x2F, 0x27, 0x9A, 0x8C, 0x84,
1675
1676 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1678 0x00, 0x00, 0x02, 0x01,
1679 0x28, 0x66, 0x53, 0x7B, 0x67, 0x67, 0x52, 0x63, 0x6A, 0x68, /* a */
1680 0xF5, 0x65, 0x54, 0xE1, 0x26, 0x40, 0x27, 0x6B, 0x64, 0x9E,
1681 0xF7, 0x52, 0x62, 0x67,
1682 0x2E, 0x45, 0xEF, 0x57, 0x1F, 0x00, 0x78, 0x6F, 0x67, 0xB0, /* b */
1683 0x08, 0x1B, 0x94, 0x95, 0xA3, 0xD9, 0x54, 0x62, 0xF5, 0xDE,
1684 0x0A, 0xA1, 0x85, 0xEC,
1685 0x36, 0xB3, 0xDA, 0xF8, 0xA2, 0x32, 0x06, 0xF9, 0xC4, 0xF2, /* x */
1686 0x99, 0xD7, 0xB2, 0x1A, 0x9C, 0x36, 0x91, 0x37, 0xF2, 0xC8,
1687 0x4A, 0xE1, 0xAA, 0x0D,
1688 0x76, 0x5B, 0xE7, 0x34, 0x33, 0xB3, 0xF9, 0x5E, 0x33, 0x29, /* y */
1689 0x32, 0xE7, 0x0E, 0xA2, 0x45, 0xCA, 0x24, 0x18, 0xEA, 0x0E,
1690 0xF9, 0x80, 0x18, 0xFB,
1691 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1692 0x00, 0x00, 0x04, 0xA2, 0x0E, 0x90, 0xC3, 0x90, 0x67, 0xC8,
1693 0x93, 0xBB, 0xB9, 0xA5
1694 }
1695};
1696
1697static const struct {
1698 EC_CURVE_DATA h;
1699 unsigned char data[20 + 24 * 6];
1700}
1701 _EC_X9_62_CHAR2_191V2 = {
1702 {
1703 NID_X9_62_characteristic_two_field, 20, 24, 4
1704 },
1705 {
1706 0x08, 0x71, 0xEF, 0x2F, 0xEF, 0x24, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1707 0x87, 0x56, 0x15, 0x17, 0x58, 0xBE, 0xE0, 0xD9, 0x5C, 0x15,
1708
1709 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1711 0x00, 0x00, 0x02, 0x01,
1712 0x40, 0x10, 0x28, 0x77, 0x4D, 0x77, 0x77, 0xC7, 0xB7, 0x66, /* a */
1713 0x6D, 0x13, 0x66, 0xEA, 0x43, 0x20, 0x71, 0x27, 0x4F, 0x89,
1714 0xFF, 0x01, 0xE7, 0x18,
1715 0x06, 0x20, 0x04, 0x8D, 0x28, 0xBC, 0xBD, 0x03, 0xB6, 0x24, /* b */
1716 0x9C, 0x99, 0x18, 0x2B, 0x7C, 0x8C, 0xD1, 0x97, 0x00, 0xC3,
1717 0x62, 0xC4, 0x6A, 0x01,
1718 0x38, 0x09, 0xB2, 0xB7, 0xCC, 0x1B, 0x28, 0xCC, 0x5A, 0x87, /* x */
1719 0x92, 0x6A, 0xAD, 0x83, 0xFD, 0x28, 0x78, 0x9E, 0x81, 0xE2,
1720 0xC9, 0xE3, 0xBF, 0x10,
1721 0x17, 0x43, 0x43, 0x86, 0x62, 0x6D, 0x14, 0xF3, 0xDB, 0xF0, /* y */
1722 0x17, 0x60, 0xD9, 0x21, 0x3A, 0x3E, 0x1C, 0xF3, 0x7A, 0xEC,
1723 0x43, 0x7D, 0x66, 0x8A,
1724 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1725 0x00, 0x00, 0x50, 0x50, 0x8C, 0xB8, 0x9F, 0x65, 0x28, 0x24,
1726 0xE0, 0x6B, 0x81, 0x73
1727 }
1728};
1729
1730static const struct {
1731 EC_CURVE_DATA h;
1732 unsigned char data[20 + 24 * 6];
1733}
1734 _EC_X9_62_CHAR2_191V3 = {
1735 {
1736 NID_X9_62_characteristic_two_field, 20, 24, 6
1737 },
1738 {
1739 0xE0, 0x53, 0x51, 0x2D, 0xC6, 0x84, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1740 0x87, 0x56, 0x15, 0x17, 0x50, 0x67, 0xAE, 0x78, 0x6D, 0x1F,
1741
1742 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1744 0x00, 0x00, 0x02, 0x01,
1745 0x6C, 0x01, 0x07, 0x47, 0x56, 0x09, 0x91, 0x22, 0x22, 0x10, /* a */
1746 0x56, 0x91, 0x1C, 0x77, 0xD7, 0x7E, 0x77, 0xA7, 0x77, 0xE7,
1747 0xE7, 0xE7, 0x7F, 0xCB,
1748 0x71, 0xFE, 0x1A, 0xF9, 0x26, 0xCF, 0x84, 0x79, 0x89, 0xEF, /* b */
1749 0xEF, 0x8D, 0xB4, 0x59, 0xF6, 0x63, 0x94, 0xD9, 0x0F, 0x32,
1750 0xAD, 0x3F, 0x15, 0xE8,
1751 0x37, 0x5D, 0x4C, 0xE2, 0x4F, 0xDE, 0x43, 0x44, 0x89, 0xDE, /* x */
1752 0x87, 0x46, 0xE7, 0x17, 0x86, 0x01, 0x50, 0x09, 0xE6, 0x6E,
1753 0x38, 0xA9, 0x26, 0xDD,
1754 0x54, 0x5A, 0x39, 0x17, 0x61, 0x96, 0x57, 0x5D, 0x98, 0x59, /* y */
1755 0x99, 0x36, 0x6E, 0x6A, 0xD3, 0x4C, 0xE0, 0xA7, 0x7C, 0xD7,
1756 0x12, 0x7B, 0x06, 0xBE,
1757 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, /* order */
1758 0x55, 0x55, 0x61, 0x0C, 0x0B, 0x19, 0x68, 0x12, 0xBF, 0xB6,
1759 0x28, 0x8A, 0x3E, 0xA3
1760 }
1761};
1762
1763static const struct {
1764 EC_CURVE_DATA h;
1765 unsigned char data[0 + 27 * 6];
1766}
1767 _EC_X9_62_CHAR2_208W1 = {
1768 {
1769 NID_X9_62_characteristic_two_field, 0, 27, 0xFE48
1770 },
1771 { /* no seed */
1772 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
1775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1778 0x00, 0xC8, 0x61, 0x9E, 0xD4, 0x5A, 0x62, 0xE6, 0x21, 0x2E, /* b */
1779 0x11, 0x60, 0x34, 0x9E, 0x2B, 0xFA, 0x84, 0x44, 0x39, 0xFA,
1780 0xFC, 0x2A, 0x3F, 0xD1, 0x63, 0x8F, 0x9E,
1781 0x00, 0x89, 0xFD, 0xFB, 0xE4, 0xAB, 0xE1, 0x93, 0xDF, 0x95, /* x */
1782 0x59, 0xEC, 0xF0, 0x7A, 0xC0, 0xCE, 0x78, 0x55, 0x4E, 0x27,
1783 0x84, 0xEB, 0x8C, 0x1E, 0xD1, 0xA5, 0x7A,
1784 0x00, 0x0F, 0x55, 0xB5, 0x1A, 0x06, 0xE7, 0x8E, 0x9A, 0xC3, /* y */
1785 0x8A, 0x03, 0x5F, 0xF5, 0x20, 0xD8, 0xB0, 0x17, 0x81, 0xBE,
1786 0xB1, 0xA6, 0xBB, 0x08, 0x61, 0x7D, 0xE3,
1787 0x00, 0x00, 0x01, 0x01, 0xBA, 0xF9, 0x5C, 0x97, 0x23, 0xC5, /* order */
1788 0x7B, 0x6C, 0x21, 0xDA, 0x2E, 0xFF, 0x2D, 0x5E, 0xD5, 0x88,
1789 0xBD, 0xD5, 0x71, 0x7E, 0x21, 0x2F, 0x9D
1790 }
1791};
1792
1793static const struct {
1794 EC_CURVE_DATA h;
1795 unsigned char data[20 + 30 * 6];
1796}
1797 _EC_X9_62_CHAR2_239V1 = {
1798 {
1799 NID_X9_62_characteristic_two_field, 20, 30, 4
1800 },
1801 {
1802 0xD3, 0x4B, 0x9A, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, /* seed */
1803 0x51, 0x75, 0xCA, 0x71, 0xB9, 0x20, 0xBF, 0xEF, 0xB0, 0x5D,
1804
1805 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
1808
1809 0x32, 0x01, 0x08, 0x57, 0x07, 0x7C, 0x54, 0x31, 0x12, 0x3A, /* a */
1810 0x46, 0xB8, 0x08, 0x90, 0x67, 0x56, 0xF5, 0x43, 0x42, 0x3E,
1811 0x8D, 0x27, 0x87, 0x75, 0x78, 0x12, 0x57, 0x78, 0xAC, 0x76,
1812
1813 0x79, 0x04, 0x08, 0xF2, 0xEE, 0xDA, 0xF3, 0x92, 0xB0, 0x12, /* b */
1814 0xED, 0xEF, 0xB3, 0x39, 0x2F, 0x30, 0xF4, 0x32, 0x7C, 0x0C,
1815 0xA3, 0xF3, 0x1F, 0xC3, 0x83, 0xC4, 0x22, 0xAA, 0x8C, 0x16,
1816
1817 0x57, 0x92, 0x70, 0x98, 0xFA, 0x93, 0x2E, 0x7C, 0x0A, 0x96, /* x */
1818 0xD3, 0xFD, 0x5B, 0x70, 0x6E, 0xF7, 0xE5, 0xF5, 0xC1, 0x56,
1819 0xE1, 0x6B, 0x7E, 0x7C, 0x86, 0x03, 0x85, 0x52, 0xE9, 0x1D,
1820
1821 0x61, 0xD8, 0xEE, 0x50, 0x77, 0xC3, 0x3F, 0xEC, 0xF6, 0xF1, /* y */
1822 0xA1, 0x6B, 0x26, 0x8D, 0xE4, 0x69, 0xC3, 0xC7, 0x74, 0x4E,
1823 0xA9, 0xA9, 0x71, 0x64, 0x9F, 0xC7, 0xA9, 0x61, 0x63, 0x05,
1824
1825 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1826 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x4D, 0x42, 0xFF, 0xE1,
1827 0x49, 0x2A, 0x49, 0x93, 0xF1, 0xCA, 0xD6, 0x66, 0xE4, 0x47
1828 }
1829};
1830
1831static const struct {
1832 EC_CURVE_DATA h;
1833 unsigned char data[20 + 30 * 6];
1834}
1835 _EC_X9_62_CHAR2_239V2 = {
1836 {
1837 NID_X9_62_characteristic_two_field, 20, 30, 6
1838 },
1839 {
1840 0x2A, 0xA6, 0x98, 0x2F, 0xDF, 0xA4, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1841 0x87, 0x56, 0x15, 0x17, 0x5D, 0x26, 0x67, 0x27, 0x27, 0x7D,
1842
1843 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
1846
1847 0x42, 0x30, 0x01, 0x77, 0x57, 0xA7, 0x67, 0xFA, 0xE4, 0x23, /* a */
1848 0x98, 0x56, 0x9B, 0x74, 0x63, 0x25, 0xD4, 0x53, 0x13, 0xAF,
1849 0x07, 0x66, 0x26, 0x64, 0x79, 0xB7, 0x56, 0x54, 0xE6, 0x5F,
1850
1851 0x50, 0x37, 0xEA, 0x65, 0x41, 0x96, 0xCF, 0xF0, 0xCD, 0x82, /* b */
1852 0xB2, 0xC1, 0x4A, 0x2F, 0xCF, 0x2E, 0x3F, 0xF8, 0x77, 0x52,
1853 0x85, 0xB5, 0x45, 0x72, 0x2F, 0x03, 0xEA, 0xCD, 0xB7, 0x4B,
1854
1855 0x28, 0xF9, 0xD0, 0x4E, 0x90, 0x00, 0x69, 0xC8, 0xDC, 0x47, /* x */
1856 0xA0, 0x85, 0x34, 0xFE, 0x76, 0xD2, 0xB9, 0x00, 0xB7, 0xD7,
1857 0xEF, 0x31, 0xF5, 0x70, 0x9F, 0x20, 0x0C, 0x4C, 0xA2, 0x05,
1858
1859 0x56, 0x67, 0x33, 0x4C, 0x45, 0xAF, 0xF3, 0xB5, 0xA0, 0x3B, /* y */
1860 0xAD, 0x9D, 0xD7, 0x5E, 0x2C, 0x71, 0xA9, 0x93, 0x62, 0x56,
1861 0x7D, 0x54, 0x53, 0xF7, 0xFA, 0x6E, 0x22, 0x7E, 0xC8, 0x33,
1862
1863 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, /* order */
1864 0x55, 0x55, 0x55, 0x55, 0x55, 0x3C, 0x6F, 0x28, 0x85, 0x25,
1865 0x9C, 0x31, 0xE3, 0xFC, 0xDF, 0x15, 0x46, 0x24, 0x52, 0x2D
1866 }
1867};
1868
1869static const struct {
1870 EC_CURVE_DATA h;
1871 unsigned char data[20 + 30 * 6];
1872}
1873 _EC_X9_62_CHAR2_239V3 = {
1874 {
1875 NID_X9_62_characteristic_two_field, 20, 30, 0xA
1876 },
1877 {
1878 0x9E, 0x07, 0x6F, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, /* seed */
1879 0x51, 0x75, 0xE1, 0x1E, 0x9F, 0xDD, 0x77, 0xF9, 0x20, 0x41,
1880
1881 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1882 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1883 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
1884
1885 0x01, 0x23, 0x87, 0x74, 0x66, 0x6A, 0x67, 0x76, 0x6D, 0x66, /* a */
1886 0x76, 0xF7, 0x78, 0xE6, 0x76, 0xB6, 0x69, 0x99, 0x17, 0x66,
1887 0x66, 0xE6, 0x87, 0x66, 0x6D, 0x87, 0x66, 0xC6, 0x6A, 0x9F,
1888
1889 0x6A, 0x94, 0x19, 0x77, 0xBA, 0x9F, 0x6A, 0x43, 0x51, 0x99, /* b */
1890 0xAC, 0xFC, 0x51, 0x06, 0x7E, 0xD5, 0x87, 0xF5, 0x19, 0xC5,
1891 0xEC, 0xB5, 0x41, 0xB8, 0xE4, 0x41, 0x11, 0xDE, 0x1D, 0x40,
1892
1893 0x70, 0xF6, 0xE9, 0xD0, 0x4D, 0x28, 0x9C, 0x4E, 0x89, 0x91, /* x */
1894 0x3C, 0xE3, 0x53, 0x0B, 0xFD, 0xE9, 0x03, 0x97, 0x7D, 0x42,
1895 0xB1, 0x46, 0xD5, 0x39, 0xBF, 0x1B, 0xDE, 0x4E, 0x9C, 0x92,
1896
1897 0x2E, 0x5A, 0x0E, 0xAF, 0x6E, 0x5E, 0x13, 0x05, 0xB9, 0x00, /* y */
1898 0x4D, 0xCE, 0x5C, 0x0E, 0xD7, 0xFE, 0x59, 0xA3, 0x56, 0x08,
1899 0xF3, 0x38, 0x37, 0xC8, 0x16, 0xD8, 0x0B, 0x79, 0xF4, 0x61,
1900
1901 0x0C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, /* order */
1902 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xAC, 0x49, 0x12, 0xD2, 0xD9,
1903 0xDF, 0x90, 0x3E, 0xF9, 0x88, 0x8B, 0x8A, 0x0E, 0x4C, 0xFF
1904 }
1905};
1906
1907static const struct {
1908 EC_CURVE_DATA h;
1909 unsigned char data[0 + 35 * 6];
1910}
1911 _EC_X9_62_CHAR2_272W1 = {
1912 {
1913 NID_X9_62_characteristic_two_field, 0, 35, 0xFF06
1914 },
1915 { /* no seed */
1916 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1917 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1918 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
1919 0x00, 0x00, 0x00, 0x00, 0x0B,
1920 0x00, 0x91, 0xA0, 0x91, 0xF0, 0x3B, 0x5F, 0xBA, 0x4A, 0xB2, /* a */
1921 0xCC, 0xF4, 0x9C, 0x4E, 0xDD, 0x22, 0x0F, 0xB0, 0x28, 0x71,
1922 0x2D, 0x42, 0xBE, 0x75, 0x2B, 0x2C, 0x40, 0x09, 0x4D, 0xBA,
1923 0xCD, 0xB5, 0x86, 0xFB, 0x20,
1924 0x00, 0x71, 0x67, 0xEF, 0xC9, 0x2B, 0xB2, 0xE3, 0xCE, 0x7C, /* b */
1925 0x8A, 0xAA, 0xFF, 0x34, 0xE1, 0x2A, 0x9C, 0x55, 0x70, 0x03,
1926 0xD7, 0xC7, 0x3A, 0x6F, 0xAF, 0x00, 0x3F, 0x99, 0xF6, 0xCC,
1927 0x84, 0x82, 0xE5, 0x40, 0xF7,
1928 0x00, 0x61, 0x08, 0xBA, 0xBB, 0x2C, 0xEE, 0xBC, 0xF7, 0x87, /* x */
1929 0x05, 0x8A, 0x05, 0x6C, 0xBE, 0x0C, 0xFE, 0x62, 0x2D, 0x77,
1930 0x23, 0xA2, 0x89, 0xE0, 0x8A, 0x07, 0xAE, 0x13, 0xEF, 0x0D,
1931 0x10, 0xD1, 0x71, 0xDD, 0x8D,
1932 0x00, 0x10, 0xC7, 0x69, 0x57, 0x16, 0x85, 0x1E, 0xEF, 0x6B, /* y */
1933 0xA7, 0xF6, 0x87, 0x2E, 0x61, 0x42, 0xFB, 0xD2, 0x41, 0xB8,
1934 0x30, 0xFF, 0x5E, 0xFC, 0xAC, 0xEC, 0xCA, 0xB0, 0x5E, 0x02,
1935 0x00, 0x5D, 0xDE, 0x9D, 0x23,
1936 0x00, 0x00, 0x01, 0x00, 0xFA, 0xF5, 0x13, 0x54, 0xE0, 0xE3, /* order */
1937 0x9E, 0x48, 0x92, 0xDF, 0x6E, 0x31, 0x9C, 0x72, 0xC8, 0x16,
1938 0x16, 0x03, 0xFA, 0x45, 0xAA, 0x7B, 0x99, 0x8A, 0x16, 0x7B,
1939 0x8F, 0x1E, 0x62, 0x95, 0x21
1940 }
1941};
1942
1943static const struct {
1944 EC_CURVE_DATA h;
1945 unsigned char data[0 + 39 * 6];
1946}
1947 _EC_X9_62_CHAR2_304W1 = {
1948 {
1949 NID_X9_62_characteristic_two_field, 0, 39, 0xFE2E
1950 },
1951 { /* no seed */
1952 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1953 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1954 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1955 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07,
1956 0x00, 0xFD, 0x0D, 0x69, 0x31, 0x49, 0xA1, 0x18, 0xF6, 0x51, /* a */
1957 0xE6, 0xDC, 0xE6, 0x80, 0x20, 0x85, 0x37, 0x7E, 0x5F, 0x88,
1958 0x2D, 0x1B, 0x51, 0x0B, 0x44, 0x16, 0x00, 0x74, 0xC1, 0x28,
1959 0x80, 0x78, 0x36, 0x5A, 0x03, 0x96, 0xC8, 0xE6, 0x81,
1960 0x00, 0xBD, 0xDB, 0x97, 0xE5, 0x55, 0xA5, 0x0A, 0x90, 0x8E, /* b */
1961 0x43, 0xB0, 0x1C, 0x79, 0x8E, 0xA5, 0xDA, 0xA6, 0x78, 0x8F,
1962 0x1E, 0xA2, 0x79, 0x4E, 0xFC, 0xF5, 0x71, 0x66, 0xB8, 0xC1,
1963 0x40, 0x39, 0x60, 0x1E, 0x55, 0x82, 0x73, 0x40, 0xBE,
1964 0x00, 0x19, 0x7B, 0x07, 0x84, 0x5E, 0x9B, 0xE2, 0xD9, 0x6A, /* x */
1965 0xDB, 0x0F, 0x5F, 0x3C, 0x7F, 0x2C, 0xFF, 0xBD, 0x7A, 0x3E,
1966 0xB8, 0xB6, 0xFE, 0xC3, 0x5C, 0x7F, 0xD6, 0x7F, 0x26, 0xDD,
1967 0xF6, 0x28, 0x5A, 0x64, 0x4F, 0x74, 0x0A, 0x26, 0x14,
1968 0x00, 0xE1, 0x9F, 0xBE, 0xB7, 0x6E, 0x0D, 0xA1, 0x71, 0x51, /* y */
1969 0x7E, 0xCF, 0x40, 0x1B, 0x50, 0x28, 0x9B, 0xF0, 0x14, 0x10,
1970 0x32, 0x88, 0x52, 0x7A, 0x9B, 0x41, 0x6A, 0x10, 0x5E, 0x80,
1971 0x26, 0x0B, 0x54, 0x9F, 0xDC, 0x1B, 0x92, 0xC0, 0x3B,
1972 0x00, 0x00, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, /* order */
1973 0x80, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80,
1974 0x01, 0x02, 0x2D, 0x5C, 0x91, 0xDD, 0x17, 0x3F, 0x8F, 0xB5,
1975 0x61, 0xDA, 0x68, 0x99, 0x16, 0x44, 0x43, 0x05, 0x1D
1976 }
1977};
1978
1979static const struct {
1980 EC_CURVE_DATA h;
1981 unsigned char data[20 + 45 * 6];
1982}
1983 _EC_X9_62_CHAR2_359V1 = {
1984 {
1985 NID_X9_62_characteristic_two_field, 20, 45, 0x4C
1986 },
1987 {
1988 0x2B, 0x35, 0x49, 0x20, 0xB7, 0x24, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1989 0x87, 0x56, 0x15, 0x17, 0x58, 0x5B, 0xA1, 0x33, 0x2D, 0xC6,
1990
1991 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1994 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1995 0x00, 0x00, 0x00, 0x00, 0x01,
1996 0x56, 0x67, 0x67, 0x6A, 0x65, 0x4B, 0x20, 0x75, 0x4F, 0x35, /* a */
1997 0x6E, 0xA9, 0x20, 0x17, 0xD9, 0x46, 0x56, 0x7C, 0x46, 0x67,
1998 0x55, 0x56, 0xF1, 0x95, 0x56, 0xA0, 0x46, 0x16, 0xB5, 0x67,
1999 0xD2, 0x23, 0xA5, 0xE0, 0x56, 0x56, 0xFB, 0x54, 0x90, 0x16,
2000 0xA9, 0x66, 0x56, 0xA5, 0x57,
2001 0x24, 0x72, 0xE2, 0xD0, 0x19, 0x7C, 0x49, 0x36, 0x3F, 0x1F, /* b */
2002 0xE7, 0xF5, 0xB6, 0xDB, 0x07, 0x5D, 0x52, 0xB6, 0x94, 0x7D,
2003 0x13, 0x5D, 0x8C, 0xA4, 0x45, 0x80, 0x5D, 0x39, 0xBC, 0x34,
2004 0x56, 0x26, 0x08, 0x96, 0x87, 0x74, 0x2B, 0x63, 0x29, 0xE7,
2005 0x06, 0x80, 0x23, 0x19, 0x88,
2006 0x3C, 0x25, 0x8E, 0xF3, 0x04, 0x77, 0x67, 0xE7, 0xED, 0xE0, /* x */
2007 0xF1, 0xFD, 0xAA, 0x79, 0xDA, 0xEE, 0x38, 0x41, 0x36, 0x6A,
2008 0x13, 0x2E, 0x16, 0x3A, 0xCE, 0xD4, 0xED, 0x24, 0x01, 0xDF,
2009 0x9C, 0x6B, 0xDC, 0xDE, 0x98, 0xE8, 0xE7, 0x07, 0xC0, 0x7A,
2010 0x22, 0x39, 0xB1, 0xB0, 0x97,
2011 0x53, 0xD7, 0xE0, 0x85, 0x29, 0x54, 0x70, 0x48, 0x12, 0x1E, /* y */
2012 0x9C, 0x95, 0xF3, 0x79, 0x1D, 0xD8, 0x04, 0x96, 0x39, 0x48,
2013 0xF3, 0x4F, 0xAE, 0x7B, 0xF4, 0x4E, 0xA8, 0x23, 0x65, 0xDC,
2014 0x78, 0x68, 0xFE, 0x57, 0xE4, 0xAE, 0x2D, 0xE2, 0x11, 0x30,
2015 0x5A, 0x40, 0x71, 0x04, 0xBD,
2016 0x01, 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, /* order */
2017 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF,
2018 0x28, 0x6B, 0xC9, 0xFB, 0x8F, 0x6B, 0x85, 0xC5, 0x56, 0x89,
2019 0x2C, 0x20, 0xA7, 0xEB, 0x96, 0x4F, 0xE7, 0x71, 0x9E, 0x74,
2020 0xF4, 0x90, 0x75, 0x8D, 0x3B
2021 }
2022};
2023
2024static const struct {
2025 EC_CURVE_DATA h;
2026 unsigned char data[0 + 47 * 6];
2027}
2028 _EC_X9_62_CHAR2_368W1 = {
2029 {
2030 NID_X9_62_characteristic_two_field, 0, 47, 0xFF70
2031 },
2032 { /* no seed */
2033 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2034 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2035 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2036 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
2037 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
2038 0x00, 0xE0, 0xD2, 0xEE, 0x25, 0x09, 0x52, 0x06, 0xF5, 0xE2, /* a */
2039 0xA4, 0xF9, 0xED, 0x22, 0x9F, 0x1F, 0x25, 0x6E, 0x79, 0xA0,
2040 0xE2, 0xB4, 0x55, 0x97, 0x0D, 0x8D, 0x0D, 0x86, 0x5B, 0xD9,
2041 0x47, 0x78, 0xC5, 0x76, 0xD6, 0x2F, 0x0A, 0xB7, 0x51, 0x9C,
2042 0xCD, 0x2A, 0x1A, 0x90, 0x6A, 0xE3, 0x0D,
2043 0x00, 0xFC, 0x12, 0x17, 0xD4, 0x32, 0x0A, 0x90, 0x45, 0x2C, /* b */
2044 0x76, 0x0A, 0x58, 0xED, 0xCD, 0x30, 0xC8, 0xDD, 0x06, 0x9B,
2045 0x3C, 0x34, 0x45, 0x38, 0x37, 0xA3, 0x4E, 0xD5, 0x0C, 0xB5,
2046 0x49, 0x17, 0xE1, 0xC2, 0x11, 0x2D, 0x84, 0xD1, 0x64, 0xF4,
2047 0x44, 0xF8, 0xF7, 0x47, 0x86, 0x04, 0x6A,
2048 0x00, 0x10, 0x85, 0xE2, 0x75, 0x53, 0x81, 0xDC, 0xCC, 0xE3, /* x */
2049 0xC1, 0x55, 0x7A, 0xFA, 0x10, 0xC2, 0xF0, 0xC0, 0xC2, 0x82,
2050 0x56, 0x46, 0xC5, 0xB3, 0x4A, 0x39, 0x4C, 0xBC, 0xFA, 0x8B,
2051 0xC1, 0x6B, 0x22, 0xE7, 0xE7, 0x89, 0xE9, 0x27, 0xBE, 0x21,
2052 0x6F, 0x02, 0xE1, 0xFB, 0x13, 0x6A, 0x5F,
2053 0x00, 0x7B, 0x3E, 0xB1, 0xBD, 0xDC, 0xBA, 0x62, 0xD5, 0xD8, /* y */
2054 0xB2, 0x05, 0x9B, 0x52, 0x57, 0x97, 0xFC, 0x73, 0x82, 0x2C,
2055 0x59, 0x05, 0x9C, 0x62, 0x3A, 0x45, 0xFF, 0x38, 0x43, 0xCE,
2056 0xE8, 0xF8, 0x7C, 0xD1, 0x85, 0x5A, 0xDA, 0xA8, 0x1E, 0x2A,
2057 0x07, 0x50, 0xB8, 0x0F, 0xDA, 0x23, 0x10,
2058 0x00, 0x00, 0x01, 0x00, 0x90, 0x51, 0x2D, 0xA9, 0xAF, 0x72, /* order */
2059 0xB0, 0x83, 0x49, 0xD9, 0x8A, 0x5D, 0xD4, 0xC7, 0xB0, 0x53,
2060 0x2E, 0xCA, 0x51, 0xCE, 0x03, 0xE2, 0xD1, 0x0F, 0x3B, 0x7A,
2061 0xC5, 0x79, 0xBD, 0x87, 0xE9, 0x09, 0xAE, 0x40, 0xA6, 0xF1,
2062 0x31, 0xE9, 0xCF, 0xCE, 0x5B, 0xD9, 0x67
2063 }
2064};
2065
2066static const struct {
2067 EC_CURVE_DATA h;
2068 unsigned char data[0 + 54 * 6];
2069}
2070 _EC_X9_62_CHAR2_431R1 = {
2071 {
2072 NID_X9_62_characteristic_two_field, 0, 54, 0x2760
2073 },
2074 { /* no seed */
2075 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2077 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
2079 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2080 0x00, 0x00, 0x00, 0x01,
2081 0x1A, 0x82, 0x7E, 0xF0, 0x0D, 0xD6, 0xFC, 0x0E, 0x23, 0x4C, /* a */
2082 0xAF, 0x04, 0x6C, 0x6A, 0x5D, 0x8A, 0x85, 0x39, 0x5B, 0x23,
2083 0x6C, 0xC4, 0xAD, 0x2C, 0xF3, 0x2A, 0x0C, 0xAD, 0xBD, 0xC9,
2084 0xDD, 0xF6, 0x20, 0xB0, 0xEB, 0x99, 0x06, 0xD0, 0x95, 0x7F,
2085 0x6C, 0x6F, 0xEA, 0xCD, 0x61, 0x54, 0x68, 0xDF, 0x10, 0x4D,
2086 0xE2, 0x96, 0xCD, 0x8F,
2087 0x10, 0xD9, 0xB4, 0xA3, 0xD9, 0x04, 0x7D, 0x8B, 0x15, 0x43, /* b */
2088 0x59, 0xAB, 0xFB, 0x1B, 0x7F, 0x54, 0x85, 0xB0, 0x4C, 0xEB,
2089 0x86, 0x82, 0x37, 0xDD, 0xC9, 0xDE, 0xDA, 0x98, 0x2A, 0x67,
2090 0x9A, 0x5A, 0x91, 0x9B, 0x62, 0x6D, 0x4E, 0x50, 0xA8, 0xDD,
2091 0x73, 0x1B, 0x10, 0x7A, 0x99, 0x62, 0x38, 0x1F, 0xB5, 0xD8,
2092 0x07, 0xBF, 0x26, 0x18,
2093 0x12, 0x0F, 0xC0, 0x5D, 0x3C, 0x67, 0xA9, 0x9D, 0xE1, 0x61, /* x */
2094 0xD2, 0xF4, 0x09, 0x26, 0x22, 0xFE, 0xCA, 0x70, 0x1B, 0xE4,
2095 0xF5, 0x0F, 0x47, 0x58, 0x71, 0x4E, 0x8A, 0x87, 0xBB, 0xF2,
2096 0xA6, 0x58, 0xEF, 0x8C, 0x21, 0xE7, 0xC5, 0xEF, 0xE9, 0x65,
2097 0x36, 0x1F, 0x6C, 0x29, 0x99, 0xC0, 0xC2, 0x47, 0xB0, 0xDB,
2098 0xD7, 0x0C, 0xE6, 0xB7,
2099 0x20, 0xD0, 0xAF, 0x89, 0x03, 0xA9, 0x6F, 0x8D, 0x5F, 0xA2, /* y */
2100 0xC2, 0x55, 0x74, 0x5D, 0x3C, 0x45, 0x1B, 0x30, 0x2C, 0x93,
2101 0x46, 0xD9, 0xB7, 0xE4, 0x85, 0xE7, 0xBC, 0xE4, 0x1F, 0x6B,
2102 0x59, 0x1F, 0x3E, 0x8F, 0x6A, 0xDD, 0xCB, 0xB0, 0xBC, 0x4C,
2103 0x2F, 0x94, 0x7A, 0x7D, 0xE1, 0xA8, 0x9B, 0x62, 0x5D, 0x6A,
2104 0x59, 0x8B, 0x37, 0x60,
2105 0x00, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, /* order */
2106 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03,
2107 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x23,
2108 0xC3, 0x13, 0xFA, 0xB5, 0x05, 0x89, 0x70, 0x3B, 0x5E, 0xC6,
2109 0x8D, 0x35, 0x87, 0xFE, 0xC6, 0x0D, 0x16, 0x1C, 0xC1, 0x49,
2110 0xC1, 0xAD, 0x4A, 0x91
2111 }
2112};
2113
2114static const struct {
2115 EC_CURVE_DATA h;
2116 unsigned char data[0 + 15 * 6];
2117}
2118 _EC_WTLS_1 = {
2119 {
2120 NID_X9_62_characteristic_two_field, 0, 15, 2
2121 },
2122 { /* no seed */
2123 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2124 0x00, 0x00, 0x00, 0x02, 0x01,
2125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2126 0x00, 0x00, 0x00, 0x00, 0x01,
2127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2128 0x00, 0x00, 0x00, 0x00, 0x01,
2129 0x01, 0x66, 0x79, 0x79, 0xA4, 0x0B, 0xA4, 0x97, 0xE5, 0xD5, /* x */
2130 0xC2, 0x70, 0x78, 0x06, 0x17,
2131 0x00, 0xF4, 0x4B, 0x4A, 0xF1, 0xEC, 0xC2, 0x63, 0x0E, 0x08, /* y */
2132 0x78, 0x5C, 0xEB, 0xCC, 0x15,
2133 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBF, /* order */
2134 0x91, 0xAF, 0x6D, 0xEA, 0x73
2135 }
2136};
2137
2138/* IPSec curves */
2139/* NOTE: The of curves over a extension field of non prime degree
2140 * is not recommended (Weil-descent).
2141 * As the group order is not a prime this curve is not suitable
2142 * for ECDSA.
2143 */
2144static const struct {
2145 EC_CURVE_DATA h;
2146 unsigned char data[0 + 20 * 6];
2147}
2148 _EC_IPSEC_155_ID3 = {
2149 {
2150 NID_X9_62_characteristic_two_field, 0, 20, 3
2151 },
2152 { /* no seed */
2153 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2154 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
2155
2156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2158
2159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x33, 0x8f,
2161
2162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
2164
2165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* y */
2166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8,
2167
2168 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, /* order */
2169 0xC7, 0xF3, 0xC7, 0x88, 0x1B, 0xD0, 0x86, 0x8F, 0xA8, 0x6C
2170 }
2171};
2172
2173/* NOTE: The of curves over a extension field of non prime degree
2174 * is not recommended (Weil-descent).
2175 * As the group order is not a prime this curve is not suitable
2176 * for ECDSA.
2177 */
2178static const struct {
2179 EC_CURVE_DATA h;
2180 unsigned char data[0 + 24 * 6];
2181}
2182 _EC_IPSEC_185_ID4 = {
2183 {
2184 NID_X9_62_characteristic_two_field, 0, 24, 2
2185 },
2186 { /* no seed */
2187 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2188 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
2189 0x00, 0x00, 0x00, 0x01,
2190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2192 0x00, 0x00, 0x00, 0x00,
2193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2195 0x00, 0x00, 0x1e, 0xe9,
2196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2198 0x00, 0x00, 0x00, 0x18,
2199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* y */
2200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2201 0x00, 0x00, 0x00, 0x0d,
2202 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
2203 0xFF, 0xFF, 0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20,
2204 0xBA, 0xFC, 0xA7, 0x5E
2205 }
2206};
2207
2208#endif
2209
2210/* These curves were added by Annie Yousar <a.yousar@informatik.hu-berlin.de>
2211 * For the definition of RFC 5639 curves see
2212 * https://www.ietf.org/rfc/rfc5639.txt
2213 * These curves are generated verifiable at random, nevertheless the seed is
2214 * omitted as parameter because the generation mechanism is different from
2215 * those defined in ANSI X9.62.
2216 */
2217
2218static const struct {
2219 EC_CURVE_DATA h;
2220 unsigned char data[0 + 20 * 6];
2221}
2222 _EC_brainpoolP160r1 = {
2223 {
2224 NID_X9_62_prime_field, 0, 20, 1
2225 },
2226 { /* no seed */
2227 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* p */
2228 0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F,
2229 0x34, 0x0E, 0x7B, 0xE2, 0xA2, 0x80, 0xEB, 0x74, 0xE2, 0xBE, /* a */
2230 0x61, 0xBA, 0xDA, 0x74, 0x5D, 0x97, 0xE8, 0xF7, 0xC3, 0x00,
2231 0x1E, 0x58, 0x9A, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4F, /* b */
2232 0xAA, 0x2D, 0xBD, 0xEC, 0x95, 0xC8, 0xD8, 0x67, 0x5E, 0x58,
2233 0xBE, 0xD5, 0xAF, 0x16, 0xEA, 0x3F, 0x6A, 0x4F, 0x62, 0x93, /* x */
2234 0x8C, 0x46, 0x31, 0xEB, 0x5A, 0xF7, 0xBD, 0xBC, 0xDB, 0xC3,
2235 0x16, 0x67, 0xCB, 0x47, 0x7A, 0x1A, 0x8E, 0xC3, 0x38, 0xF9, /* y */
2236 0x47, 0x41, 0x66, 0x9C, 0x97, 0x63, 0x16, 0xDA, 0x63, 0x21,
2237 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* order */
2238 0x59, 0x91, 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09
2239 }
2240};
2241
2242static const struct {
2243 EC_CURVE_DATA h;
2244 unsigned char data[0 + 20 * 6];
2245}
2246 _EC_brainpoolP160t1 = {
2247 {
2248 NID_X9_62_prime_field, 0, 20, 1
2249 },
2250 { /* no seed */
2251 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* p */
2252 0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F,
2253 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* a */
2254 0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0C,
2255 0x7A, 0x55, 0x6B, 0x6D, 0xAE, 0x53, 0x5B, 0x7B, 0x51, 0xED, /* b */
2256 0x2C, 0x4D, 0x7D, 0xAA, 0x7A, 0x0B, 0x5C, 0x55, 0xF3, 0x80,
2257 0xB1, 0x99, 0xB1, 0x3B, 0x9B, 0x34, 0xEF, 0xC1, 0x39, 0x7E, /* x */
2258 0x64, 0xBA, 0xEB, 0x05, 0xAC, 0xC2, 0x65, 0xFF, 0x23, 0x78,
2259 0xAD, 0xD6, 0x71, 0x8B, 0x7C, 0x7C, 0x19, 0x61, 0xF0, 0x99, /* y */
2260 0x1B, 0x84, 0x24, 0x43, 0x77, 0x21, 0x52, 0xC9, 0xE0, 0xAD,
2261 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* order */
2262 0x59, 0x91, 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09
2263 }
2264};
2265
2266static const struct {
2267 EC_CURVE_DATA h;
2268 unsigned char data[0 + 24 * 6];
2269}
2270 _EC_brainpoolP192r1 = {
2271 {
2272 NID_X9_62_prime_field, 0, 24, 1
2273 },
2274 { /* no seed */
2275 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* p */
2276 0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D,
2277 0xE1, 0xA8, 0x62, 0x97,
2278 0x6A, 0x91, 0x17, 0x40, 0x76, 0xB1, 0xE0, 0xE1, 0x9C, 0x39, /* a */
2279 0xC0, 0x31, 0xFE, 0x86, 0x85, 0xC1, 0xCA, 0xE0, 0x40, 0xE5,
2280 0xC6, 0x9A, 0x28, 0xEF,
2281 0x46, 0x9A, 0x28, 0xEF, 0x7C, 0x28, 0xCC, 0xA3, 0xDC, 0x72, /* b */
2282 0x1D, 0x04, 0x4F, 0x44, 0x96, 0xBC, 0xCA, 0x7E, 0xF4, 0x14,
2283 0x6F, 0xBF, 0x25, 0xC9,
2284 0xC0, 0xA0, 0x64, 0x7E, 0xAA, 0xB6, 0xA4, 0x87, 0x53, 0xB0, /* x */
2285 0x33, 0xC5, 0x6C, 0xB0, 0xF0, 0x90, 0x0A, 0x2F, 0x5C, 0x48,
2286 0x53, 0x37, 0x5F, 0xD6,
2287 0x14, 0xB6, 0x90, 0x86, 0x6A, 0xBD, 0x5B, 0xB8, 0x8B, 0x5F, /* y */
2288 0x48, 0x28, 0xC1, 0x49, 0x00, 0x02, 0xE6, 0x77, 0x3F, 0xA2,
2289 0xFA, 0x29, 0x9B, 0x8F,
2290 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* order */
2291 0x46, 0x2F, 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02,
2292 0x9A, 0xC4, 0xAC, 0xC1
2293 }
2294};
2295
2296static const struct {
2297 EC_CURVE_DATA h;
2298 unsigned char data[0 + 24 * 6];
2299}
2300 _EC_brainpoolP192t1 = {
2301 {
2302 NID_X9_62_prime_field, 0, 24, 1
2303 },
2304 { /* no seed */
2305 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* p */
2306 0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D,
2307 0xE1, 0xA8, 0x62, 0x97,
2308 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* a */
2309 0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D,
2310 0xE1, 0xA8, 0x62, 0x94,
2311 0x13, 0xD5, 0x6F, 0xFA, 0xEC, 0x78, 0x68, 0x1E, 0x68, 0xF9, /* b */
2312 0xDE, 0xB4, 0x3B, 0x35, 0xBE, 0xC2, 0xFB, 0x68, 0x54, 0x2E,
2313 0x27, 0x89, 0x7B, 0x79,
2314 0x3A, 0xE9, 0xE5, 0x8C, 0x82, 0xF6, 0x3C, 0x30, 0x28, 0x2E, /* x */
2315 0x1F, 0xE7, 0xBB, 0xF4, 0x3F, 0xA7, 0x2C, 0x44, 0x6A, 0xF6,
2316 0xF4, 0x61, 0x81, 0x29,
2317 0x09, 0x7E, 0x2C, 0x56, 0x67, 0xC2, 0x22, 0x3A, 0x90, 0x2A, /* y */
2318 0xB5, 0xCA, 0x44, 0x9D, 0x00, 0x84, 0xB7, 0xE5, 0xB3, 0xDE,
2319 0x7C, 0xCC, 0x01, 0xC9,
2320 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* order */
2321 0x46, 0x2F, 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02,
2322 0x9A, 0xC4, 0xAC, 0xC1
2323 }
2324};
2325
2326static const struct {
2327 EC_CURVE_DATA h;
2328 unsigned char data[0 + 28 * 6];
2329}
2330 _EC_brainpoolP224r1 = {
2331 {
2332 NID_X9_62_prime_field, 0, 28, 1
2333 },
2334 { /* no seed */
2335 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* p */
2336 0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57,
2337 0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFF,
2338 0x68, 0xA5, 0xE6, 0x2C, 0xA9, 0xCE, 0x6C, 0x1C, 0x29, 0x98, /* a */
2339 0x03, 0xA6, 0xC1, 0x53, 0x0B, 0x51, 0x4E, 0x18, 0x2A, 0xD8,
2340 0xB0, 0x04, 0x2A, 0x59, 0xCA, 0xD2, 0x9F, 0x43,
2341 0x25, 0x80, 0xF6, 0x3C, 0xCF, 0xE4, 0x41, 0x38, 0x87, 0x07, /* b */
2342 0x13, 0xB1, 0xA9, 0x23, 0x69, 0xE3, 0x3E, 0x21, 0x35, 0xD2,
2343 0x66, 0xDB, 0xB3, 0x72, 0x38, 0x6C, 0x40, 0x0B,
2344 0x0D, 0x90, 0x29, 0xAD, 0x2C, 0x7E, 0x5C, 0xF4, 0x34, 0x08, /* x */
2345 0x23, 0xB2, 0xA8, 0x7D, 0xC6, 0x8C, 0x9E, 0x4C, 0xE3, 0x17,
2346 0x4C, 0x1E, 0x6E, 0xFD, 0xEE, 0x12, 0xC0, 0x7D,
2347 0x58, 0xAA, 0x56, 0xF7, 0x72, 0xC0, 0x72, 0x6F, 0x24, 0xC6, /* y */
2348 0xB8, 0x9E, 0x4E, 0xCD, 0xAC, 0x24, 0x35, 0x4B, 0x9E, 0x99,
2349 0xCA, 0xA3, 0xF6, 0xD3, 0x76, 0x14, 0x02, 0xCD,
2350 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* order */
2351 0x30, 0x25, 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B,
2352 0x6D, 0xDE, 0xBC, 0xA3, 0xA5, 0xA7, 0x93, 0x9F
2353 }
2354};
2355
2356static const struct {
2357 EC_CURVE_DATA h;
2358 unsigned char data[0 + 28 * 6];
2359}
2360 _EC_brainpoolP224t1 = {
2361 {
2362 NID_X9_62_prime_field, 0, 28, 1
2363 },
2364 { /* no seed */
2365 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* p */
2366 0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57,
2367 0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFF,
2368 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* a */
2369 0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57,
2370 0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFC,
2371 0x4B, 0x33, 0x7D, 0x93, 0x41, 0x04, 0xCD, 0x7B, 0xEF, 0x27, /* b */
2372 0x1B, 0xF6, 0x0C, 0xED, 0x1E, 0xD2, 0x0D, 0xA1, 0x4C, 0x08,
2373 0xB3, 0xBB, 0x64, 0xF1, 0x8A, 0x60, 0x88, 0x8D,
2374 0x6A, 0xB1, 0xE3, 0x44, 0xCE, 0x25, 0xFF, 0x38, 0x96, 0x42, /* x */
2375 0x4E, 0x7F, 0xFE, 0x14, 0x76, 0x2E, 0xCB, 0x49, 0xF8, 0x92,
2376 0x8A, 0xC0, 0xC7, 0x60, 0x29, 0xB4, 0xD5, 0x80,
2377 0x03, 0x74, 0xE9, 0xF5, 0x14, 0x3E, 0x56, 0x8C, 0xD2, 0x3F, /* y */
2378 0x3F, 0x4D, 0x7C, 0x0D, 0x4B, 0x1E, 0x41, 0xC8, 0xCC, 0x0D,
2379 0x1C, 0x6A, 0xBD, 0x5F, 0x1A, 0x46, 0xDB, 0x4C,
2380 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* order */
2381 0x30, 0x25, 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B,
2382 0x6D, 0xDE, 0xBC, 0xA3, 0xA5, 0xA7, 0x93, 0x9F
2383 }
2384};
2385
2386static const struct {
2387 EC_CURVE_DATA h;
2388 unsigned char data[0 + 32 * 6];
2389}
2390 _EC_brainpoolP256r1 = {
2391 {
2392 NID_X9_62_prime_field, 0, 32, 1
2393 },
2394 { /* no seed */
2395 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* p */
2396 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23,
2397 0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E,
2398 0x53, 0x77,
2399 0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, /* a */
2400 0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7, 0xFB, 0x80, 0x55, 0xC1,
2401 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30,
2402 0xB5, 0xD9,
2403 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, /* b */
2404 0xB5, 0xD9, 0xBB, 0xD7, 0x7C, 0xBF, 0x95, 0x84, 0x16, 0x29,
2405 0x5C, 0xF7, 0xE1, 0xCE, 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C,
2406 0x07, 0xB6,
2407 0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, /* x */
2408 0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF, 0xB9, 0xDE, 0x27, 0xE1,
2409 0xE3, 0xBD, 0x23, 0xC2, 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE,
2410 0x32, 0x62,
2411 0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, /* y */
2412 0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9, 0xC2, 0x77, 0x45, 0x13,
2413 0x2D, 0xED, 0x8E, 0x54, 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04,
2414 0x69, 0x97,
2415 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* order */
2416 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3,
2417 0xB5, 0x61, 0xA6, 0xF7, 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48,
2418 0x56, 0xA7
2419 }
2420};
2421
2422static const struct {
2423 EC_CURVE_DATA h;
2424 unsigned char data[0 + 32 * 6];
2425}
2426 _EC_brainpoolP256t1 = {
2427 {
2428 NID_X9_62_prime_field, 0, 32, 1
2429 },
2430 { /* no seed */
2431 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* p */
2432 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23,
2433 0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E,
2434 0x53, 0x77,
2435 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* a */
2436 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23,
2437 0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E,
2438 0x53, 0x74,
2439 0x66, 0x2C, 0x61, 0xC4, 0x30, 0xD8, 0x4E, 0xA4, 0xFE, 0x66, /* b */
2440 0xA7, 0x73, 0x3D, 0x0B, 0x76, 0xB7, 0xBF, 0x93, 0xEB, 0xC4,
2441 0xAF, 0x2F, 0x49, 0x25, 0x6A, 0xE5, 0x81, 0x01, 0xFE, 0xE9,
2442 0x2B, 0x04,
2443 0xA3, 0xE8, 0xEB, 0x3C, 0xC1, 0xCF, 0xE7, 0xB7, 0x73, 0x22, /* x */
2444 0x13, 0xB2, 0x3A, 0x65, 0x61, 0x49, 0xAF, 0xA1, 0x42, 0xC4,
2445 0x7A, 0xAF, 0xBC, 0x2B, 0x79, 0xA1, 0x91, 0x56, 0x2E, 0x13,
2446 0x05, 0xF4,
2447 0x2D, 0x99, 0x6C, 0x82, 0x34, 0x39, 0xC5, 0x6D, 0x7F, 0x7B, /* y */
2448 0x22, 0xE1, 0x46, 0x44, 0x41, 0x7E, 0x69, 0xBC, 0xB6, 0xDE,
2449 0x39, 0xD0, 0x27, 0x00, 0x1D, 0xAB, 0xE8, 0xF3, 0x5B, 0x25,
2450 0xC9, 0xBE,
2451 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* order */
2452 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3,
2453 0xB5, 0x61, 0xA6, 0xF7, 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48,
2454 0x56, 0xA7
2455 }
2456};
2457
2458static const struct {
2459 EC_CURVE_DATA h;
2460 unsigned char data[0 + 40 * 6];
2461}
2462 _EC_brainpoolP320r1 = {
2463 {
2464 NID_X9_62_prime_field, 0, 40, 1
2465 },
2466 { /* no seed */
2467 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* p */
2468 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6,
2469 0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93,
2470 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x27,
2471 0x3E, 0xE3, 0x0B, 0x56, 0x8F, 0xBA, 0xB0, 0xF8, 0x83, 0xCC, /* a */
2472 0xEB, 0xD4, 0x6D, 0x3F, 0x3B, 0xB8, 0xA2, 0xA7, 0x35, 0x13,
2473 0xF5, 0xEB, 0x79, 0xDA, 0x66, 0x19, 0x0E, 0xB0, 0x85, 0xFF,
2474 0xA9, 0xF4, 0x92, 0xF3, 0x75, 0xA9, 0x7D, 0x86, 0x0E, 0xB4,
2475 0x52, 0x08, 0x83, 0x94, 0x9D, 0xFD, 0xBC, 0x42, 0xD3, 0xAD, /* b */
2476 0x19, 0x86, 0x40, 0x68, 0x8A, 0x6F, 0xE1, 0x3F, 0x41, 0x34,
2477 0x95, 0x54, 0xB4, 0x9A, 0xCC, 0x31, 0xDC, 0xCD, 0x88, 0x45,
2478 0x39, 0x81, 0x6F, 0x5E, 0xB4, 0xAC, 0x8F, 0xB1, 0xF1, 0xA6,
2479 0x43, 0xBD, 0x7E, 0x9A, 0xFB, 0x53, 0xD8, 0xB8, 0x52, 0x89, /* x */
2480 0xBC, 0xC4, 0x8E, 0xE5, 0xBF, 0xE6, 0xF2, 0x01, 0x37, 0xD1,
2481 0x0A, 0x08, 0x7E, 0xB6, 0xE7, 0x87, 0x1E, 0x2A, 0x10, 0xA5,
2482 0x99, 0xC7, 0x10, 0xAF, 0x8D, 0x0D, 0x39, 0xE2, 0x06, 0x11,
2483 0x14, 0xFD, 0xD0, 0x55, 0x45, 0xEC, 0x1C, 0xC8, 0xAB, 0x40, /* y */
2484 0x93, 0x24, 0x7F, 0x77, 0x27, 0x5E, 0x07, 0x43, 0xFF, 0xED,
2485 0x11, 0x71, 0x82, 0xEA, 0xA9, 0xC7, 0x78, 0x77, 0xAA, 0xAC,
2486 0x6A, 0xC7, 0xD3, 0x52, 0x45, 0xD1, 0x69, 0x2E, 0x8E, 0xE1,
2487 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* order */
2488 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5,
2489 0xB6, 0x8F, 0x12, 0xA3, 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86,
2490 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, 0x44, 0xC5, 0x93, 0x11
2491 }
2492};
2493
2494static const struct {
2495 EC_CURVE_DATA h;
2496 unsigned char data[0 + 40 * 6];
2497}
2498 _EC_brainpoolP320t1 = {
2499 {
2500 NID_X9_62_prime_field, 0, 40, 1
2501 },
2502 { /* no seed */
2503 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* p */
2504 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6,
2505 0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93,
2506 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x27,
2507 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* a */
2508 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6,
2509 0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93,
2510 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x24,
2511 0xA7, 0xF5, 0x61, 0xE0, 0x38, 0xEB, 0x1E, 0xD5, 0x60, 0xB3, /* b */
2512 0xD1, 0x47, 0xDB, 0x78, 0x20, 0x13, 0x06, 0x4C, 0x19, 0xF2,
2513 0x7E, 0xD2, 0x7C, 0x67, 0x80, 0xAA, 0xF7, 0x7F, 0xB8, 0xA5,
2514 0x47, 0xCE, 0xB5, 0xB4, 0xFE, 0xF4, 0x22, 0x34, 0x03, 0x53,
2515 0x92, 0x5B, 0xE9, 0xFB, 0x01, 0xAF, 0xC6, 0xFB, 0x4D, 0x3E, /* x */
2516 0x7D, 0x49, 0x90, 0x01, 0x0F, 0x81, 0x34, 0x08, 0xAB, 0x10,
2517 0x6C, 0x4F, 0x09, 0xCB, 0x7E, 0xE0, 0x78, 0x68, 0xCC, 0x13,
2518 0x6F, 0xFF, 0x33, 0x57, 0xF6, 0x24, 0xA2, 0x1B, 0xED, 0x52,
2519 0x63, 0xBA, 0x3A, 0x7A, 0x27, 0x48, 0x3E, 0xBF, 0x66, 0x71, /* y */
2520 0xDB, 0xEF, 0x7A, 0xBB, 0x30, 0xEB, 0xEE, 0x08, 0x4E, 0x58,
2521 0xA0, 0xB0, 0x77, 0xAD, 0x42, 0xA5, 0xA0, 0x98, 0x9D, 0x1E,
2522 0xE7, 0x1B, 0x1B, 0x9B, 0xC0, 0x45, 0x5F, 0xB0, 0xD2, 0xC3,
2523 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* order */
2524 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5,
2525 0xB6, 0x8F, 0x12, 0xA3, 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86,
2526 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, 0x44, 0xC5, 0x93, 0x11
2527 }
2528};
2529
2530static const struct {
2531 EC_CURVE_DATA h;
2532 unsigned char data[0 + 48 * 6];
2533}
2534 _EC_brainpoolP384r1 = {
2535 {
2536 NID_X9_62_prime_field, 0, 48, 1
2537 },
2538 { /* no seed */
2539 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* p */
2540 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2541 0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7,
2542 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71,
2543 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53,
2544 0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, /* a */
2545 0x08, 0x0A, 0xCE, 0x05, 0xAF, 0xA0, 0xC2, 0xBE, 0xA2, 0x8E,
2546 0x4F, 0xB2, 0x27, 0x87, 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91,
2547 0xF9, 0x0F, 0x8A, 0xA5, 0x81, 0x4A, 0x50, 0x3A, 0xD4, 0xEB,
2548 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26,
2549 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, /* b */
2550 0xB5, 0x54, 0x16, 0xF0, 0x44, 0x7C, 0x2F, 0xB7, 0x7D, 0xE1,
2551 0x07, 0xDC, 0xD2, 0xA6, 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB,
2552 0x62, 0xD5, 0x7C, 0xB4, 0x39, 0x02, 0x95, 0xDB, 0xC9, 0x94,
2553 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11,
2554 0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, /* x */
2555 0x3A, 0x81, 0xB7, 0xC1, 0x3F, 0x6B, 0x88, 0x47, 0xA3, 0xE7,
2556 0x7E, 0xF1, 0x4F, 0xE3, 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD,
2557 0x10, 0xE8, 0xE8, 0x26, 0xE0, 0x34, 0x36, 0xD6, 0x46, 0xAA,
2558 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E,
2559 0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, /* y */
2560 0xEB, 0x8E, 0x95, 0xCF, 0xD5, 0x52, 0x62, 0xB7, 0x0B, 0x29,
2561 0xFE, 0xEC, 0x58, 0x64, 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91,
2562 0x29, 0x28, 0x0E, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11,
2563 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15,
2564 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* order */
2565 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2566 0xED, 0x54, 0x56, 0xB3, 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04,
2567 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10,
2568 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65
2569 }
2570};
2571
2572static const struct {
2573 EC_CURVE_DATA h;
2574 unsigned char data[0 + 48 * 6];
2575}
2576 _EC_brainpoolP384t1 = {
2577 {
2578 NID_X9_62_prime_field, 0, 48, 1
2579 },
2580 { /* no seed */
2581 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* p */
2582 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2583 0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7,
2584 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71,
2585 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53,
2586 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* a */
2587 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2588 0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7,
2589 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71,
2590 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x50,
2591 0x7F, 0x51, 0x9E, 0xAD, 0xA7, 0xBD, 0xA8, 0x1B, 0xD8, 0x26, /* b */
2592 0xDB, 0xA6, 0x47, 0x91, 0x0F, 0x8C, 0x4B, 0x93, 0x46, 0xED,
2593 0x8C, 0xCD, 0xC6, 0x4E, 0x4B, 0x1A, 0xBD, 0x11, 0x75, 0x6D,
2594 0xCE, 0x1D, 0x20, 0x74, 0xAA, 0x26, 0x3B, 0x88, 0x80, 0x5C,
2595 0xED, 0x70, 0x35, 0x5A, 0x33, 0xB4, 0x71, 0xEE,
2596 0x18, 0xDE, 0x98, 0xB0, 0x2D, 0xB9, 0xA3, 0x06, 0xF2, 0xAF, /* x */
2597 0xCD, 0x72, 0x35, 0xF7, 0x2A, 0x81, 0x9B, 0x80, 0xAB, 0x12,
2598 0xEB, 0xD6, 0x53, 0x17, 0x24, 0x76, 0xFE, 0xCD, 0x46, 0x2A,
2599 0xAB, 0xFF, 0xC4, 0xFF, 0x19, 0x1B, 0x94, 0x6A, 0x5F, 0x54,
2600 0xD8, 0xD0, 0xAA, 0x2F, 0x41, 0x88, 0x08, 0xCC,
2601 0x25, 0xAB, 0x05, 0x69, 0x62, 0xD3, 0x06, 0x51, 0xA1, 0x14, /* y */
2602 0xAF, 0xD2, 0x75, 0x5A, 0xD3, 0x36, 0x74, 0x7F, 0x93, 0x47,
2603 0x5B, 0x7A, 0x1F, 0xCA, 0x3B, 0x88, 0xF2, 0xB6, 0xA2, 0x08,
2604 0xCC, 0xFE, 0x46, 0x94, 0x08, 0x58, 0x4D, 0xC2, 0xB2, 0x91,
2605 0x26, 0x75, 0xBF, 0x5B, 0x9E, 0x58, 0x29, 0x28,
2606 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* order */
2607 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2608 0xED, 0x54, 0x56, 0xB3, 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04,
2609 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10,
2610 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65
2611 }
2612};
2613
2614static const struct {
2615 EC_CURVE_DATA h;
2616 unsigned char data[0 + 64 * 6];
2617}
2618 _EC_brainpoolP512r1 = {
2619 {
2620 NID_X9_62_prime_field, 0, 64, 1
2621 },
2622 { /* no seed */
2623 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* p */
2624 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2625 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2626 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42,
2627 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, 0x28, 0x81,
2628 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
2629 0x58, 0x3A, 0x48, 0xF3,
2630 0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, /* a */
2631 0x71, 0x45, 0xAC, 0x23, 0x4C, 0xC5, 0x94, 0xCB, 0xDD, 0x8D,
2632 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98,
2633 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1,
2634 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11,
2635 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D,
2636 0x77, 0xFC, 0x94, 0xCA,
2637 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, /* b */
2638 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1,
2639 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11,
2640 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D,
2641 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67, 0x98, 0x40,
2642 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63,
2643 0x80, 0x16, 0xF7, 0x23,
2644 0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, /* x */
2645 0x32, 0x2E, 0x9C, 0x4C, 0x6A, 0x93, 0x85, 0xED, 0x9F, 0x70,
2646 0xB5, 0xD9, 0x16, 0xC1, 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0,
2647 0x09, 0x8E, 0xFF, 0x3B, 0x1F, 0x78, 0xE2, 0xD0, 0xD4, 0x8D,
2648 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F, 0x7C, 0x6D,
2649 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09,
2650 0xBC, 0xB9, 0xF8, 0x22,
2651 0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, /* y */
2652 0xBF, 0xA9, 0xCF, 0x78, 0x22, 0xFD, 0xF2, 0x09, 0xF7, 0x00,
2653 0x24, 0xA5, 0x7B, 0x1A, 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F,
2654 0x81, 0x11, 0xB2, 0xDC, 0xDE, 0x49, 0x4A, 0x5F, 0x48, 0x5E,
2655 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE, 0xD1, 0xCA,
2656 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F,
2657 0x3A, 0xD8, 0x08, 0x92,
2658 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* order */
2659 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2660 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2661 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19,
2662 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, 0x1D, 0xB1,
2663 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82,
2664 0x9C, 0xA9, 0x00, 0x69
2665 }
2666};
2667
2668static const struct {
2669 EC_CURVE_DATA h;
2670 unsigned char data[0 + 64 * 6];
2671}
2672 _EC_brainpoolP512t1 = {
2673 {
2674 NID_X9_62_prime_field, 0, 64, 1
2675 },
2676 { /* no seed */
2677 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* p */
2678 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2679 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2680 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42,
2681 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, 0x28, 0x81,
2682 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
2683 0x58, 0x3A, 0x48, 0xF3,
2684 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* a */
2685 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2686 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2687 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42,
2688 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, 0x28, 0x81,
2689 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
2690 0x58, 0x3A, 0x48, 0xF0,
2691 0x7C, 0xBB, 0xBC, 0xF9, 0x44, 0x1C, 0xFA, 0xB7, 0x6E, 0x18, /* b */
2692 0x90, 0xE4, 0x68, 0x84, 0xEA, 0xE3, 0x21, 0xF7, 0x0C, 0x0B,
2693 0xCB, 0x49, 0x81, 0x52, 0x78, 0x97, 0x50, 0x4B, 0xEC, 0x3E,
2694 0x36, 0xA6, 0x2B, 0xCD, 0xFA, 0x23, 0x04, 0x97, 0x65, 0x40,
2695 0xF6, 0x45, 0x00, 0x85, 0xF2, 0xDA, 0xE1, 0x45, 0xC2, 0x25,
2696 0x53, 0xB4, 0x65, 0x76, 0x36, 0x89, 0x18, 0x0E, 0xA2, 0x57,
2697 0x18, 0x67, 0x42, 0x3E,
2698 0x64, 0x0E, 0xCE, 0x5C, 0x12, 0x78, 0x87, 0x17, 0xB9, 0xC1, /* x */
2699 0xBA, 0x06, 0xCB, 0xC2, 0xA6, 0xFE, 0xBA, 0x85, 0x84, 0x24,
2700 0x58, 0xC5, 0x6D, 0xDE, 0x9D, 0xB1, 0x75, 0x8D, 0x39, 0xC0,
2701 0x31, 0x3D, 0x82, 0xBA, 0x51, 0x73, 0x5C, 0xDB, 0x3E, 0xA4,
2702 0x99, 0xAA, 0x77, 0xA7, 0xD6, 0x94, 0x3A, 0x64, 0xF7, 0xA3,
2703 0xF2, 0x5F, 0xE2, 0x6F, 0x06, 0xB5, 0x1B, 0xAA, 0x26, 0x96,
2704 0xFA, 0x90, 0x35, 0xDA,
2705 0x5B, 0x53, 0x4B, 0xD5, 0x95, 0xF5, 0xAF, 0x0F, 0xA2, 0xC8, /* y */
2706 0x92, 0x37, 0x6C, 0x84, 0xAC, 0xE1, 0xBB, 0x4E, 0x30, 0x19,
2707 0xB7, 0x16, 0x34, 0xC0, 0x11, 0x31, 0x15, 0x9C, 0xAE, 0x03,
2708 0xCE, 0xE9, 0xD9, 0x93, 0x21, 0x84, 0xBE, 0xEF, 0x21, 0x6B,
2709 0xD7, 0x1D, 0xF2, 0xDA, 0xDF, 0x86, 0xA6, 0x27, 0x30, 0x6E,
2710 0xCF, 0xF9, 0x6D, 0xBB, 0x8B, 0xAC, 0xE1, 0x98, 0xB6, 0x1E,
2711 0x00, 0xF8, 0xB3, 0x32,
2712 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* order */
2713 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2714 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2715 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19,
2716 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, 0x1D, 0xB1,
2717 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82,
2718 0x9C, 0xA9, 0x00, 0x69
2719 }
2720};
2721
2722static const struct {
2723 EC_CURVE_DATA h;
2724 unsigned char data[0 + 32 * 6];
2725}
2726 _EC_FRP256v1 = {
2727 {
2728 NID_X9_62_prime_field, 0, 32, 1
2729 },
2730 { /* no seed */
2731 0xF1, 0xFD, 0x17, 0x8C, 0x0B, 0x3A, 0xD5, 0x8F, 0x10, 0x12, /* p */
2732 0x6D, 0xE8, 0xCE, 0x42, 0x43, 0x5B, 0x39, 0x61, 0xAD, 0xBC,
2733 0xAB, 0xC8, 0xCA, 0x6D, 0xE8, 0xFC, 0xF3, 0x53, 0xD8, 0x6E,
2734 0x9C, 0x03,
2735 0xF1, 0xFD, 0x17, 0x8C, 0x0B, 0x3A, 0xD5, 0x8F, 0x10, 0x12, /* a */
2736 0x6D, 0xE8, 0xCE, 0x42, 0x43, 0x5B, 0x39, 0x61, 0xAD, 0xBC,
2737 0xAB, 0xC8, 0xCA, 0x6D, 0xE8, 0xFC, 0xF3, 0x53, 0xD8, 0x6E,
2738 0x9C, 0x00,
2739 0xEE, 0x35, 0x3F, 0xCA, 0x54, 0x28, 0xA9, 0x30, 0x0D, 0x4A, /* b */
2740 0xBA, 0x75, 0x4A, 0x44, 0xC0, 0x0F, 0xDF, 0xEC, 0x0C, 0x9A,
2741 0xE4, 0xB1, 0xA1, 0x80, 0x30, 0x75, 0xED, 0x96, 0x7B, 0x7B,
2742 0xB7, 0x3F,
2743 0xB6, 0xB3, 0xD4, 0xC3, 0x56, 0xC1, 0x39, 0xEB, 0x31, 0x18, /* x */
2744 0x3D, 0x47, 0x49, 0xD4, 0x23, 0x95, 0x8C, 0x27, 0xD2, 0xDC,
2745 0xAF, 0x98, 0xB7, 0x01, 0x64, 0xC9, 0x7A, 0x2D, 0xD9, 0x8F,
2746 0x5C, 0xFF,
2747 0x61, 0x42, 0xE0, 0xF7, 0xC8, 0xB2, 0x04, 0x91, 0x1F, 0x92, /* y */
2748 0x71, 0xF0, 0xF3, 0xEC, 0xEF, 0x8C, 0x27, 0x01, 0xC3, 0x07,
2749 0xE8, 0xE4, 0xC9, 0xE1, 0x83, 0x11, 0x5A, 0x15, 0x54, 0x06,
2750 0x2C, 0xFB,
2751 0xF1, 0xFD, 0x17, 0x8C, 0x0B, 0x3A, 0xD5, 0x8F, 0x10, 0x12, /* order */
2752 0x6D, 0xE8, 0xCE, 0x42, 0x43, 0x5B, 0x53, 0xDC, 0x67, 0xE1,
2753 0x40, 0xD2, 0xBF, 0x94, 0x1F, 0xFD, 0xD4, 0x59, 0xC6, 0xD6,
2754 0x55, 0xE1
2755 }
2756};
2757
2758#ifndef OPENSSL_NO_GOST
2759static const struct {
2760 EC_CURVE_DATA h;
2761 unsigned char data[0 + 32 * 6];
2762}
2763 _EC_GOST_2001_Test = {
2764 {
2765 NID_X9_62_prime_field, 0, 32, 1
2766 },
2767 { /* no seed */
2768 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2769 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2771 0x04, 0x31,
2772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2775 0x00, 0x07,
2776 0x5F, 0xBF, 0xF4, 0x98, 0xAA, 0x93, 0x8C, 0xE7, 0x39, 0xB8, /* b */
2777 0xE0, 0x22, 0xFB, 0xAF, 0xEF, 0x40, 0x56, 0x3F, 0x6E, 0x6A,
2778 0x34, 0x72, 0xFC, 0x2A, 0x51, 0x4C, 0x0C, 0xE9, 0xDA, 0xE2,
2779 0x3B, 0x7E,
2780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2783 0x00, 0x02,
2784 0x08, 0xE2, 0xA8, 0xA0, 0xE6, 0x51, 0x47, 0xD4, 0xBD, 0x63, /* y */
2785 0x16, 0x03, 0x0E, 0x16, 0xD1, 0x9C, 0x85, 0xC9, 0x7F, 0x0A,
2786 0x9C, 0xA2, 0x67, 0x12, 0x2B, 0x96, 0xAB, 0xBC, 0xEA, 0x7E,
2787 0x8F, 0xC8,
2788 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
2789 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0xFE, 0x8A, 0x18,
2790 0x92, 0x97, 0x61, 0x54, 0xC5, 0x9C, 0xFC, 0x19, 0x3A, 0xCC,
2791 0xF5, 0xB3,
2792 }
2793};
2794
2795static const struct {
2796 EC_CURVE_DATA h;
2797 unsigned char data[0 + 32 * 6];
2798}
2799 _EC_GOST_2001_CryptoPro_A = {
2800 {
2801 NID_X9_62_prime_field, 0, 32, 1
2802 },
2803 { /* no seed */
2804 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
2805 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2806 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2807 0xFD, 0x97,
2808 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
2809 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2810 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2811 0xFD, 0x94,
2812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2815 0x00, 0xA6,
2816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2819 0x00, 0x01,
2820 0x8D, 0x91, 0xE4, 0x71, 0xE0, 0x98, 0x9C, 0xDA, 0x27, 0xDF, /* y */
2821 0x50, 0x5A, 0x45, 0x3F, 0x2B, 0x76, 0x35, 0x29, 0x4F, 0x2D,
2822 0xDF, 0x23, 0xE3, 0xB1, 0x22, 0xAC, 0xC9, 0x9C, 0x9E, 0x9F,
2823 0x1E, 0x14,
2824 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
2825 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6C, 0x61, 0x10, 0x70,
2826 0x99, 0x5A, 0xD1, 0x00, 0x45, 0x84, 0x1B, 0x09, 0xB7, 0x61,
2827 0xB8, 0x93,
2828 }
2829};
2830
2831static const struct {
2832 EC_CURVE_DATA h;
2833 unsigned char data[0 + 32 * 6];
2834}
2835 _EC_GOST_2001_CryptoPro_B = {
2836 {
2837 NID_X9_62_prime_field, 0, 32, 1
2838 },
2839 { /* no seed */
2840 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2843 0x0C, 0x99,
2844 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2847 0x0C, 0x96,
2848 0x3E, 0x1A, 0xF4, 0x19, 0xA2, 0x69, 0xA5, 0xF8, 0x66, 0xA7, /* b */
2849 0xD3, 0xC2, 0x5C, 0x3D, 0xF8, 0x0A, 0xE9, 0x79, 0x25, 0x93,
2850 0x73, 0xFF, 0x2B, 0x18, 0x2F, 0x49, 0xD4, 0xCE, 0x7E, 0x1B,
2851 0xBC, 0x8B,
2852 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2854 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2855 0x00, 0x01,
2856 0x3F, 0xA8, 0x12, 0x43, 0x59, 0xF9, 0x66, 0x80, 0xB8, 0x3D, /* y */
2857 0x1C, 0x3E, 0xB2, 0xC0, 0x70, 0xE5, 0xC5, 0x45, 0xC9, 0x85,
2858 0x8D, 0x03, 0xEC, 0xFB, 0x74, 0x4B, 0xF8, 0xD7, 0x17, 0x71,
2859 0x7E, 0xFC,
2860 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
2861 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5F, 0x70, 0x0C, 0xFF,
2862 0xF1, 0xA6, 0x24, 0xE5, 0xE4, 0x97, 0x16, 0x1B, 0xCC, 0x8A,
2863 0x19, 0x8F,
2864 }
2865};
2866
2867static const struct {
2868 EC_CURVE_DATA h;
2869 unsigned char data[0 + 32 * 6];
2870}
2871 _EC_GOST_2001_CryptoPro_C = {
2872 {
2873 NID_X9_62_prime_field, 0, 32, 1
2874 },
2875 { /* no seed */
2876 0x9B, 0x9F, 0x60, 0x5F, 0x5A, 0x85, 0x81, 0x07, 0xAB, 0x1E, /* p */
2877 0xC8, 0x5E, 0x6B, 0x41, 0xC8, 0xAA, 0xCF, 0x84, 0x6E, 0x86,
2878 0x78, 0x90, 0x51, 0xD3, 0x79, 0x98, 0xF7, 0xB9, 0x02, 0x2D,
2879 0x75, 0x9B,
2880 0x9B, 0x9F, 0x60, 0x5F, 0x5A, 0x85, 0x81, 0x07, 0xAB, 0x1E, /* a */
2881 0xC8, 0x5E, 0x6B, 0x41, 0xC8, 0xAA, 0xCF, 0x84, 0x6E, 0x86,
2882 0x78, 0x90, 0x51, 0xD3, 0x79, 0x98, 0xF7, 0xB9, 0x02, 0x2D,
2883 0x75, 0x98,
2884 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2885 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2886 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2887 0x80, 0x5A,
2888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2889 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2890 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2891 0x00, 0x00,
2892 0x41, 0xEC, 0xE5, 0x57, 0x43, 0x71, 0x1A, 0x8C, 0x3C, 0xBF, /* y */
2893 0x37, 0x83, 0xCD, 0x08, 0xC0, 0xEE, 0x4D, 0x4D, 0xC4, 0x40,
2894 0xD4, 0x64, 0x1A, 0x8F, 0x36, 0x6E, 0x55, 0x0D, 0xFD, 0xB3,
2895 0xBB, 0x67,
2896 0x9B, 0x9F, 0x60, 0x5F, 0x5A, 0x85, 0x81, 0x07, 0xAB, 0x1E, /* order */
2897 0xC8, 0x5E, 0x6B, 0x41, 0xC8, 0xAA, 0x58, 0x2C, 0xA3, 0x51,
2898 0x1E, 0xDD, 0xFB, 0x74, 0xF0, 0x2F, 0x3A, 0x65, 0x98, 0x98,
2899 0x0B, 0xB9,
2900 }
2901};
2902
2903static const struct {
2904 EC_CURVE_DATA h;
2905 unsigned char data[0 + 64 * 6];
2906}
2907 _EC_GOST_2012_TC26_A = {
2908 {
2909 NID_X9_62_prime_field, 0, 64, 1
2910 },
2911 { /* no seed */
2912 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */
2913 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2914 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2915 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2916 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2917 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2918 0xff, 0xff, 0xfd, 0xc7,
2919 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a */
2920 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2921 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2922 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2923 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2924 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2925 0xff, 0xff, 0xfd, 0xc4,
2926 0xe8, 0xc2, 0x50, 0x5d, 0xed, 0xfc, 0x86, 0xdd, 0xc1, 0xbd, /* b */
2927 0x0b, 0x2b, 0x66, 0x67, 0xf1, 0xda, 0x34, 0xb8, 0x25, 0x74,
2928 0x76, 0x1c, 0xb0, 0xe8, 0x79, 0xbd, 0x08, 0x1c, 0xfd, 0x0b,
2929 0x62, 0x65, 0xee, 0x3c, 0xb0, 0x90, 0xf3, 0x0d, 0x27, 0x61,
2930 0x4c, 0xb4, 0x57, 0x40, 0x10, 0xda, 0x90, 0xdd, 0x86, 0x2e,
2931 0xf9, 0xd4, 0xeb, 0xee, 0x47, 0x61, 0x50, 0x31, 0x90, 0x78,
2932 0x5a, 0x71, 0xc7, 0x60,
2933 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2934 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2935 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2936 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2937 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2938 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2939 0x00, 0x00, 0x00, 0x03,
2940 0x75, 0x03, 0xcf, 0xe8, 0x7a, 0x83, 0x6a, 0xe3, 0xa6, 0x1b, /* y */
2941 0x88, 0x16, 0xe2, 0x54, 0x50, 0xe6, 0xce, 0x5e, 0x1c, 0x93,
2942 0xac, 0xf1, 0xab, 0xc1, 0x77, 0x80, 0x64, 0xfd, 0xcb, 0xef,
2943 0xa9, 0x21, 0xdf, 0x16, 0x26, 0xbe, 0x4f, 0xd0, 0x36, 0xe9,
2944 0x3d, 0x75, 0xe6, 0xa5, 0x0e, 0x3a, 0x41, 0xe9, 0x80, 0x28,
2945 0xfe, 0x5f, 0xc2, 0x35, 0xf5, 0xb8, 0x89, 0xa5, 0x89, 0xcb,
2946 0x52, 0x15, 0xf2, 0xa4,
2947 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* order */
2948 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2949 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2950 0xff, 0xff, 0x27, 0xe6, 0x95, 0x32, 0xf4, 0x8d, 0x89, 0x11,
2951 0x6f, 0xf2, 0x2b, 0x8d, 0x4e, 0x05, 0x60, 0x60, 0x9b, 0x4b,
2952 0x38, 0xab, 0xfa, 0xd2, 0xb8, 0x5d, 0xca, 0xcd, 0xb1, 0x41,
2953 0x1f, 0x10, 0xb2, 0x75
2954 }
2955};
2956
2957static const struct {
2958 EC_CURVE_DATA h;
2959 unsigned char data[0 + 64 * 6];
2960}
2961 _EC_GOST_2012_TC26_B = {
2962 {
2963 NID_X9_62_prime_field, 0, 64, 1
2964 },
2965 { /* no seed */
2966 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2967 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2968 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2969 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2970 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2971 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2972 0x00, 0x00, 0x00, 0x6f,
2973 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2974 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2975 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2976 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2977 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2978 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2979 0x00, 0x00, 0x00, 0x6c,
2980 0x68, 0x7d, 0x1b, 0x45, 0x9d, 0xc8, 0x41, 0x45, 0x7e, 0x3e, /* b */
2981 0x06, 0xcf, 0x6f, 0x5e, 0x25, 0x17, 0xb9, 0x7c, 0x7d, 0x61,
2982 0x4a, 0xf1, 0x38, 0xbc, 0xbf, 0x85, 0xdc, 0x80, 0x6c, 0x4b,
2983 0x28, 0x9f, 0x3e, 0x96, 0x5d, 0x2d, 0xb1, 0x41, 0x6d, 0x21,
2984 0x7f, 0x8b, 0x27, 0x6f, 0xad, 0x1a, 0xb6, 0x9c, 0x50, 0xf7,
2985 0x8b, 0xee, 0x1f, 0xa3, 0x10, 0x6e, 0xfb, 0x8c, 0xcb, 0xc7,
2986 0xc5, 0x14, 0x01, 0x16,
2987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2988 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2989 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2993 0x00, 0x00, 0x00, 0x02,
2994 0x1a, 0x8f, 0x7e, 0xda, 0x38, 0x9b, 0x09, 0x4c, 0x2c, 0x07, /* y */
2995 0x1e, 0x36, 0x47, 0xa8, 0x94, 0x0f, 0x3c, 0x12, 0x3b, 0x69,
2996 0x75, 0x78, 0xc2, 0x13, 0xbe, 0x6d, 0xd9, 0xe6, 0xc8, 0xec,
2997 0x73, 0x35, 0xdc, 0xb2, 0x28, 0xfd, 0x1e, 0xdf, 0x4a, 0x39,
2998 0x15, 0x2c, 0xbc, 0xaa, 0xf8, 0xc0, 0x39, 0x88, 0x28, 0x04,
2999 0x10, 0x55, 0xf9, 0x4c, 0xee, 0xec, 0x7e, 0x21, 0x34, 0x07,
3000 0x80, 0xfe, 0x41, 0xbd,
3001 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
3002 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3003 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3004 0x00, 0x01, 0x49, 0xa1, 0xec, 0x14, 0x25, 0x65, 0xa5, 0x45,
3005 0xac, 0xfd, 0xb7, 0x7b, 0xd9, 0xd4, 0x0c, 0xfa, 0x8b, 0x99,
3006 0x67, 0x12, 0x10, 0x1b, 0xea, 0x0e, 0xc6, 0x34, 0x6c, 0x54,
3007 0x37, 0x4f, 0x25, 0xbd
3008 }
3009};
3010
3011#endif
3012
3013typedef struct _ec_list_element_st {
3014 int nid;
3015 const EC_CURVE_DATA *data;
3016 const EC_METHOD *(*meth) (void);
3017 const char *comment;
3018} ec_list_element;
3019
3020static const ec_list_element curve_list[] = {
3021 /* prime field curves */
3022 /* secg curves */
3023 {NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field"},
3024 {NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0, "SECG curve over a 112 bit prime field"},
3025 {NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0, "SECG curve over a 128 bit prime field"},
3026 {NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0, "SECG curve over a 128 bit prime field"},
3027 {NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0, "SECG curve over a 160 bit prime field"},
3028 {NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0, "SECG curve over a 160 bit prime field"},
3029 {NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field"},
3030 /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
3031 {NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, "SECG curve over a 192 bit prime field"},
3032 {NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field"},
3033#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
3034 {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field"},
3035#else
3036 {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field"},
3037#endif
3038 {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field"},
3039 /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
3040 {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field"},
3041#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
3042 {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field"},
3043#else
3044 {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field"},
3045#endif
3046 /* X9.62 curves */
3047 {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field"},
3048 {NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, "X9.62 curve over a 192 bit prime field"},
3049 {NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0, "X9.62 curve over a 192 bit prime field"},
3050 {NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, "X9.62 curve over a 239 bit prime field"},
3051 {NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field"},
3052 {NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field"},
3053#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
3054 {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, "X9.62/SECG curve over a 256 bit prime field"},
3055#else
3056 {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field"},
3057#endif
3058#ifndef OPENSSL_NO_EC2M
3059 /* characteristic two field curves */
3060 /* NIST/SECG curves */
3061 {NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field"},
3062 {NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0, "SECG curve over a 113 bit binary field"},
3063 {NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0, "SECG/WTLS curve over a 131 bit binary field"},
3064 {NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0, "SECG curve over a 131 bit binary field"},
3065 {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field"},
3066 {NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0, "SECG curve over a 163 bit binary field"},
3067 {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, "NIST/SECG curve over a 163 bit binary field"},
3068 {NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0, "SECG curve over a 193 bit binary field"},
3069 {NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0, "SECG curve over a 193 bit binary field"},
3070 {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
3071 {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
3072 {NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0, "SECG curve over a 239 bit binary field"},
3073 {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, "NIST/SECG curve over a 283 bit binary field"},
3074 {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, "NIST/SECG curve over a 283 bit binary field"},
3075 {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, "NIST/SECG curve over a 409 bit binary field"},
3076 {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, "NIST/SECG curve over a 409 bit binary field"},
3077 {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, "NIST/SECG curve over a 571 bit binary field"},
3078 {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, "NIST/SECG curve over a 571 bit binary field"},
3079 /* X9.62 curves */
3080 {NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field"},
3081 {NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0, "X9.62 curve over a 163 bit binary field"},
3082 {NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0, "X9.62 curve over a 163 bit binary field"},
3083 {NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0, "X9.62 curve over a 176 bit binary field"},
3084 {NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0, "X9.62 curve over a 191 bit binary field"},
3085 {NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0, "X9.62 curve over a 191 bit binary field"},
3086 {NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0, "X9.62 curve over a 191 bit binary field"},
3087 {NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0, "X9.62 curve over a 208 bit binary field"},
3088 {NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0, "X9.62 curve over a 239 bit binary field"},
3089 {NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0, "X9.62 curve over a 239 bit binary field"},
3090 {NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0, "X9.62 curve over a 239 bit binary field"},
3091 {NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0, "X9.62 curve over a 272 bit binary field"},
3092 {NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0, "X9.62 curve over a 304 bit binary field"},
3093 {NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0, "X9.62 curve over a 359 bit binary field"},
3094 {NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0, "X9.62 curve over a 368 bit binary field"},
3095 {NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0, "X9.62 curve over a 431 bit binary field"},
3096 /*
3097 * the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves
3098 * from X9.62]
3099 */
3100 {NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0, "WTLS curve over a 113 bit binary field"},
3101 {NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field"},
3102 {NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field"},
3103 {NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field"},
3104#endif
3105 {NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field"},
3106 {NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field"},
3107 {NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, "WTLS curve over a 112 bit prime field"},
3108 {NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, "WTLS curve over a 160 bit prime field"},
3109#ifndef OPENSSL_NO_EC2M
3110 {NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
3111 {NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
3112#endif
3113 {NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, "WTLS curve over a 224 bit prime field"},
3114#ifndef OPENSSL_NO_EC2M
3115 /* IPSec curves */
3116 {NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
3117 "\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
3118 {NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
3119 "\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
3120#endif
3121 /* RFC 5639 curves */
3122 {NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0, "RFC 5639 curve over a 160 bit prime field"},
3123 {NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0, "RFC 5639 curve over a 160 bit prime field"},
3124 {NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0, "RFC 5639 curve over a 192 bit prime field"},
3125 {NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0, "RFC 5639 curve over a 192 bit prime field"},
3126 {NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0, "RFC 5639 curve over a 224 bit prime field"},
3127 {NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0, "RFC 5639 curve over a 224 bit prime field"},
3128 {NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0, "RFC 5639 curve over a 256 bit prime field"},
3129 {NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0, "RFC 5639 curve over a 256 bit prime field"},
3130 {NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0, "RFC 5639 curve over a 320 bit prime field"},
3131 {NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0, "RFC 5639 curve over a 320 bit prime field"},
3132 {NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0, "RFC 5639 curve over a 384 bit prime field"},
3133 {NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0, "RFC 5639 curve over a 384 bit prime field"},
3134 {NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0, "RFC 5639 curve over a 512 bit prime field"},
3135 {NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0, "RFC 5639 curve over a 512 bit prime field"},
3136 /* ANSSI */
3137 {NID_FRP256v1, &_EC_FRP256v1.h, 0, "FRP256v1"},
3138#ifndef OPENSSL_NO_GOST
3139 /* GOST R 34.10-2001 */
3140 {NID_id_GostR3410_2001_TestParamSet, &_EC_GOST_2001_Test.h, 0, "GOST R 34.10-2001 Test Curve"},
3141 {NID_id_GostR3410_2001_CryptoPro_A_ParamSet, &_EC_GOST_2001_CryptoPro_A.h, 0, "GOST R 34.10-2001 CryptoPro-A"},
3142 {NID_id_GostR3410_2001_CryptoPro_B_ParamSet, &_EC_GOST_2001_CryptoPro_B.h, 0, "GOST R 34.10-2001 CryptoPro-B"},
3143 {NID_id_GostR3410_2001_CryptoPro_C_ParamSet, &_EC_GOST_2001_CryptoPro_C.h, 0, "GOST R 34.10-2001 CryptoPro-C"},
3144 {NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, &_EC_GOST_2001_CryptoPro_A.h, 0, "GOST R 34.10-2001 CryptoPro-XchA"},
3145 {NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, &_EC_GOST_2001_CryptoPro_C.h, 0, "GOST R 34.10-2001 CryptoPro-XchB"},
3146 {NID_id_tc26_gost_3410_2012_512_paramSetA, &_EC_GOST_2012_TC26_A.h, 0, "GOST R 34.10-2012 TC26-A"},
3147 {NID_id_tc26_gost_3410_2012_512_paramSetB, &_EC_GOST_2012_TC26_B.h, 0, "GOST R 34.10-2012 TC26-B"},
3148#endif
3149};
3150
3151#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
3152
3153static EC_GROUP *
3154ec_group_new_from_data(const ec_list_element curve)
3155{
3156 EC_GROUP *group = NULL;
3157 EC_POINT *P = NULL;
3158 BN_CTX *ctx = NULL;
3159 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
3160 int ok = 0;
3161 int seed_len, param_len;
3162 const EC_METHOD *meth;
3163 const EC_CURVE_DATA *data;
3164 const unsigned char *params;
3165
3166 if ((ctx = BN_CTX_new()) == NULL) {
3167 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
3168 goto err;
3169 }
3170 data = curve.data;
3171 seed_len = data->seed_len;
3172 param_len = data->param_len;
3173 params = (const unsigned char *) (data + 1); /* skip header */
3174 params += seed_len; /* skip seed */
3175
3176 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
3177 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
3178 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
3179 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
3180 goto err;
3181 }
3182 if (curve.meth != 0) {
3183 meth = curve.meth();
3184 if (((group = EC_GROUP_new(meth)) == NULL) ||
3185 (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
3186 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3187 goto err;
3188 }
3189 } else if (data->field_type == NID_X9_62_prime_field) {
3190 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
3191 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3192 goto err;
3193 }
3194 }
3195#ifndef OPENSSL_NO_EC2M
3196 else { /* field_type ==
3197 * NID_X9_62_characteristic_two_field */
3198 if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) {
3199 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3200 goto err;
3201 }
3202 }
3203#endif
3204
3205 if ((P = EC_POINT_new(group)) == NULL) {
3206 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3207 goto err;
3208 }
3209 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL))
3210 || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
3211 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
3212 goto err;
3213 }
3214 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
3215 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3216 goto err;
3217 }
3218 if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL))
3219 || !BN_set_word(x, (BN_ULONG) data->cofactor)) {
3220 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
3221 goto err;
3222 }
3223 if (!EC_GROUP_set_generator(group, P, order, x)) {
3224 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3225 goto err;
3226 }
3227 if (seed_len) {
3228 if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) {
3229 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3230 goto err;
3231 }
3232 }
3233 ok = 1;
3234err:
3235 if (!ok) {
3236 EC_GROUP_free(group);
3237 group = NULL;
3238 }
3239 EC_POINT_free(P);
3240 BN_CTX_free(ctx);
3241 BN_free(p);
3242 BN_free(a);
3243 BN_free(b);
3244 BN_free(order);
3245 BN_free(x);
3246 BN_free(y);
3247 return group;
3248}
3249
3250EC_GROUP *
3251EC_GROUP_new_by_curve_name(int nid)
3252{
3253 size_t i;
3254 EC_GROUP *ret = NULL;
3255
3256 if (nid <= 0)
3257 return NULL;
3258
3259 for (i = 0; i < curve_list_length; i++)
3260 if (curve_list[i].nid == nid) {
3261 ret = ec_group_new_from_data(curve_list[i]);
3262 break;
3263 }
3264 if (ret == NULL) {
3265 ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
3266 return NULL;
3267 }
3268 EC_GROUP_set_curve_name(ret, nid);
3269
3270 return ret;
3271}
3272
3273size_t
3274EC_get_builtin_curves(EC_builtin_curve * r, size_t nitems)
3275{
3276 size_t i, min;
3277
3278 if (r == NULL || nitems == 0)
3279 return curve_list_length;
3280
3281 min = nitems < curve_list_length ? nitems : curve_list_length;
3282
3283 for (i = 0; i < min; i++) {
3284 r[i].nid = curve_list[i].nid;
3285 r[i].comment = curve_list[i].comment;
3286 }
3287
3288 return curve_list_length;
3289}
3290
3291/*
3292 * Functions to translate between common NIST curve names and NIDs.
3293 */
3294
3295typedef struct {
3296 const char *name; /* NIST Name of curve */
3297 int nid; /* Curve NID */
3298} EC_NIST_NAME;
3299
3300static EC_NIST_NAME nist_curves[] = {
3301 { "B-163", NID_sect163r2 },
3302 { "B-233", NID_sect233r1 },
3303 { "B-283", NID_sect283r1 },
3304 { "B-409", NID_sect409r1 },
3305 { "B-571", NID_sect571r1 },
3306 { "K-163", NID_sect163k1 },
3307 { "K-233", NID_sect233k1 },
3308 { "K-283", NID_sect283k1 },
3309 { "K-409", NID_sect409k1 },
3310 { "K-571", NID_sect571k1 },
3311 { "P-192", NID_X9_62_prime192v1 },
3312 { "P-224", NID_secp224r1 },
3313 { "P-256", NID_X9_62_prime256v1 },
3314 { "P-384", NID_secp384r1 },
3315 { "P-521", NID_secp521r1 }
3316};
3317
3318const char *
3319EC_curve_nid2nist(int nid)
3320{
3321 size_t i;
3322
3323 for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) {
3324 if (nist_curves[i].nid == nid)
3325 return (nist_curves[i].name);
3326 }
3327 return (NULL);
3328}
3329
3330int
3331EC_curve_nist2nid(const char *name)
3332{
3333 size_t i;
3334
3335 for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) {
3336 if (!strcmp(nist_curves[i].name, name))
3337 return (nist_curves[i].nid);
3338 }
3339 return (NID_undef);
3340}
diff --git a/src/lib/libcrypto/ec/ec_cvt.c b/src/lib/libcrypto/ec/ec_cvt.c
deleted file mode 100644
index a0982064b8..0000000000
--- a/src/lib/libcrypto/ec/ec_cvt.c
+++ /dev/null
@@ -1,167 +0,0 @@
1/* $OpenBSD: ec_cvt.c,v 1.6 2014/07/10 22:45:57 jsing Exp $ */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2002 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 <openssl/opensslconf.h>
73
74#include <openssl/err.h>
75#include "ec_lcl.h"
76
77EC_GROUP *
78EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b,
79 BN_CTX *ctx)
80{
81 const EC_METHOD *meth;
82 EC_GROUP *ret;
83
84#if defined(OPENSSL_BN_ASM_MONT)
85 /*
86 * This might appear controversial, but the fact is that generic
87 * prime method was observed to deliver better performance even
88 * for NIST primes on a range of platforms, e.g.: 60%-15%
89 * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
90 * in 32-bit build and 35%--12% in 64-bit build on Core2...
91 * Coefficients are relative to optimized bn_nist.c for most
92 * intensive ECDSA verify and ECDH operations for 192- and 521-
93 * bit keys respectively. Choice of these boundary values is
94 * arguable, because the dependency of improvement coefficient
95 * from key length is not a "monotone" curve. For example while
96 * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
97 * generally faster, sometimes "respectfully" faster, sometimes
98 * "tolerably" slower... What effectively happens is that loop
99 * with bn_mul_add_words is put against bn_mul_mont, and the
100 * latter "wins" on short vectors. Correct solution should be
101 * implementing dedicated NxN multiplication subroutines for
102 * small N. But till it materializes, let's stick to generic
103 * prime method...
104 * <appro>
105 */
106 meth = EC_GFp_mont_method();
107#else
108 meth = EC_GFp_nist_method();
109#endif
110
111 ret = EC_GROUP_new(meth);
112 if (ret == NULL)
113 return NULL;
114
115 if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
116 unsigned long err;
117
118 err = ERR_peek_last_error();
119
120 if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
121 ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
122 (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) {
123 /* real error */
124
125 EC_GROUP_clear_free(ret);
126 return NULL;
127 }
128 /* not an actual error, we just cannot use EC_GFp_nist_method */
129
130 ERR_clear_error();
131
132 EC_GROUP_clear_free(ret);
133 meth = EC_GFp_mont_method();
134
135 ret = EC_GROUP_new(meth);
136 if (ret == NULL)
137 return NULL;
138
139 if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
140 EC_GROUP_clear_free(ret);
141 return NULL;
142 }
143 }
144 return ret;
145}
146
147#ifndef OPENSSL_NO_EC2M
148EC_GROUP *
149EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b,
150 BN_CTX *ctx)
151{
152 const EC_METHOD *meth;
153 EC_GROUP *ret;
154
155 meth = EC_GF2m_simple_method();
156
157 ret = EC_GROUP_new(meth);
158 if (ret == NULL)
159 return NULL;
160
161 if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) {
162 EC_GROUP_clear_free(ret);
163 return NULL;
164 }
165 return ret;
166}
167#endif
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c
deleted file mode 100644
index 0ba510adae..0000000000
--- a/src/lib/libcrypto/ec/ec_err.c
+++ /dev/null
@@ -1,279 +0,0 @@
1/* $OpenBSD: ec_err.c,v 1.9 2014/07/10 22:45:57 jsing Exp $ */
2/* ====================================================================
3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62
63#include <openssl/opensslconf.h>
64
65#include <openssl/err.h>
66#include <openssl/ec.h>
67
68/* BEGIN ERROR CODES */
69#ifndef OPENSSL_NO_ERR
70
71#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
72#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
73
74static ERR_STRING_DATA EC_str_functs[] =
75{
76 {ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"},
77 {ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
78 {ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
79 {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
80 {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
81 {ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"},
82 {ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"},
83 {ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"},
84 {ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"},
85 {ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"},
86 {ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"},
87 {ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"},
88 {ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"},
89 {ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
90 {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
91 {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
92 {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
93 {ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"},
94 {ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"},
95 {ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"},
96 {ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"},
97 {ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"},
98 {ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"},
99 {ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"},
100 {ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"},
101 {ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"},
102 {ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"},
103 {ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"},
104 {ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY), "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
105 {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GF2m_simple_group_check_discriminant"},
106 {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE), "ec_GF2m_simple_group_set_curve"},
107 {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
108 {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
109 {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GF2m_simple_point_get_affine_coordinates"},
110 {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GF2m_simple_point_set_affine_coordinates"},
111 {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GF2m_simple_set_compressed_coordinates"},
112 {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
113 {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
114 {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
115 {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), "ec_GFp_mont_field_set_to_one"},
116 {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
117 {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), "ec_GFp_mont_group_set_curve"},
118 {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), "EC_GFP_MONT_GROUP_SET_CURVE_GFP"},
119 {ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE), "ec_GFp_nistp224_group_set_curve"},
120 {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"},
121 {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp224_point_get_affine_coordinates"},
122 {ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE), "ec_GFp_nistp256_group_set_curve"},
123 {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"},
124 {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp256_point_get_affine_coordinates"},
125 {ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE), "ec_GFp_nistp521_group_set_curve"},
126 {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"},
127 {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp521_point_get_affine_coordinates"},
128 {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
129 {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
130 {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), "ec_GFp_nist_group_set_curve"},
131 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GFp_simple_group_check_discriminant"},
132 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE), "ec_GFp_simple_group_set_curve"},
133 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
134 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"},
135 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
136 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
137 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
138 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), "ec_GFp_simple_points_make_affine"},
139 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GFp_simple_point_get_affine_coordinates"},
140 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"},
141 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GFp_simple_point_set_affine_coordinates"},
142 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"},
143 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GFp_simple_set_compressed_coordinates"},
144 {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"},
145 {ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
146 {ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), "EC_GROUP_check_discriminant"},
147 {ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
148 {ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"},
149 {ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"},
150 {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
151 {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
152 {ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
153 {ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"},
154 {ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), "EC_GROUP_get_pentanomial_basis"},
155 {ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), "EC_GROUP_get_trinomial_basis"},
156 {ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
157 {ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
158 {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"},
159 {ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"},
160 {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
161 {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
162 {ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"},
163 {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
164 {ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
165 {ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
166 {ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
167 {ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
168 {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
169 {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
170 {ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES), "EC_KEY_set_public_key_affine_coordinates"},
171 {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
172 {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
173 {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
174 {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
175 {ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
176 {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), "EC_POINT_get_affine_coordinates_GF2m"},
177 {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), "EC_POINT_get_affine_coordinates_GFp"},
178 {ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_get_Jprojective_coordinates_GFp"},
179 {ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
180 {ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
181 {ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
182 {ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
183 {ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"},
184 {ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
185 {ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
186 {ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
187 {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), "EC_POINT_set_affine_coordinates_GF2m"},
188 {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), "EC_POINT_set_affine_coordinates_GFp"},
189 {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), "EC_POINT_set_compressed_coordinates_GF2m"},
190 {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), "EC_POINT_set_compressed_coordinates_GFp"},
191 {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_set_Jprojective_coordinates_GFp"},
192 {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
193 {ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"},
194 {ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"},
195 {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
196 {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
197 {ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
198 {ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
199 {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
200 {ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
201 {ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"},
202 {ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"},
203 {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"},
204 {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
205 {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"},
206 {ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"},
207 {ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"},
208 {ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"},
209 {ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"},
210 {ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"},
211 {ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"},
212 {0, NULL}
213};
214
215static ERR_STRING_DATA EC_str_reasons[] =
216{
217 {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"},
218 {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"},
219 {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
220 {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"},
221 {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"},
222 {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE), "d2i ecpkparameters failure"},
223 {ERR_REASON(EC_R_DECODE_ERROR), "decode error"},
224 {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"},
225 {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), "ec group new by name failure"},
226 {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
227 {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
228 {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE), "group2pkparameters failure"},
229 {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE), "i2d ecpkparameters failure"},
230 {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
231 {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"},
232 {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
233 {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
234 {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"},
235 {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
236 {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
237 {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
238 {ERR_REASON(EC_R_INVALID_FORM), "invalid form"},
239 {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"},
240 {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
241 {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
242 {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
243 {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
244 {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
245 {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
246 {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
247 {ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME), "not a supported NIST prime"},
248 {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"},
249 {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"},
250 {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"},
251 {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
252 {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
253 {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), "pkparameters2group failure"},
254 {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
255 {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
256 {ERR_REASON(EC_R_SLOT_FULL), "slot full"},
257 {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
258 {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
259 {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
260 {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
261 {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
262 {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"},
263 {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"},
264 {0, NULL}
265};
266
267#endif
268
269void
270ERR_load_EC_strings(void)
271{
272#ifndef OPENSSL_NO_ERR
273
274 if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
275 ERR_load_strings(0, EC_str_functs);
276 ERR_load_strings(0, EC_str_reasons);
277 }
278#endif
279}
diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c
deleted file mode 100644
index fa962e4d0f..0000000000
--- a/src/lib/libcrypto/ec/ec_key.c
+++ /dev/null
@@ -1,540 +0,0 @@
1/* $OpenBSD: ec_key.c,v 1.12 2015/09/10 15:56:25 jsing Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2005 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 * Portions originally developed by SUN MICROSYSTEMS, INC., and
61 * contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65
66#include <openssl/opensslconf.h>
67
68#include "ec_lcl.h"
69#include <openssl/err.h>
70
71EC_KEY *
72EC_KEY_new(void)
73{
74 EC_KEY *ret;
75
76 ret = malloc(sizeof(EC_KEY));
77 if (ret == NULL) {
78 ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
79 return (NULL);
80 }
81 ret->version = 1;
82 ret->flags = 0;
83 ret->group = NULL;
84 ret->pub_key = NULL;
85 ret->priv_key = NULL;
86 ret->enc_flag = 0;
87 ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
88 ret->references = 1;
89 ret->method_data = NULL;
90 return (ret);
91}
92
93EC_KEY *
94EC_KEY_new_by_curve_name(int nid)
95{
96 EC_KEY *ret = EC_KEY_new();
97 if (ret == NULL)
98 return NULL;
99 ret->group = EC_GROUP_new_by_curve_name(nid);
100 if (ret->group == NULL) {
101 EC_KEY_free(ret);
102 return NULL;
103 }
104 return ret;
105}
106
107void
108EC_KEY_free(EC_KEY * r)
109{
110 int i;
111
112 if (r == NULL)
113 return;
114
115 i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC);
116 if (i > 0)
117 return;
118
119 EC_GROUP_free(r->group);
120 EC_POINT_free(r->pub_key);
121 BN_clear_free(r->priv_key);
122
123 EC_EX_DATA_free_all_data(&r->method_data);
124
125 explicit_bzero((void *) r, sizeof(EC_KEY));
126
127 free(r);
128}
129
130EC_KEY *
131EC_KEY_copy(EC_KEY * dest, const EC_KEY * src)
132{
133 EC_EXTRA_DATA *d;
134
135 if (dest == NULL || src == NULL) {
136 ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
137 return NULL;
138 }
139 /* copy the parameters */
140 if (src->group) {
141 const EC_METHOD *meth = EC_GROUP_method_of(src->group);
142 /* clear the old group */
143 EC_GROUP_free(dest->group);
144 dest->group = EC_GROUP_new(meth);
145 if (dest->group == NULL)
146 return NULL;
147 if (!EC_GROUP_copy(dest->group, src->group))
148 return NULL;
149 }
150 /* copy the public key */
151 if (src->pub_key && src->group) {
152 EC_POINT_free(dest->pub_key);
153 dest->pub_key = EC_POINT_new(src->group);
154 if (dest->pub_key == NULL)
155 return NULL;
156 if (!EC_POINT_copy(dest->pub_key, src->pub_key))
157 return NULL;
158 }
159 /* copy the private key */
160 if (src->priv_key) {
161 if (dest->priv_key == NULL) {
162 dest->priv_key = BN_new();
163 if (dest->priv_key == NULL)
164 return NULL;
165 }
166 if (!BN_copy(dest->priv_key, src->priv_key))
167 return NULL;
168 }
169 /* copy method/extra data */
170 EC_EX_DATA_free_all_data(&dest->method_data);
171
172 for (d = src->method_data; d != NULL; d = d->next) {
173 void *t = d->dup_func(d->data);
174
175 if (t == NULL)
176 return 0;
177 if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func,
178 d->free_func, d->clear_free_func))
179 return 0;
180 }
181
182 /* copy the rest */
183 dest->enc_flag = src->enc_flag;
184 dest->conv_form = src->conv_form;
185 dest->version = src->version;
186 dest->flags = src->flags;
187
188 return dest;
189}
190
191EC_KEY *
192EC_KEY_dup(const EC_KEY * ec_key)
193{
194 EC_KEY *ret = EC_KEY_new();
195 if (ret == NULL)
196 return NULL;
197 if (EC_KEY_copy(ret, ec_key) == NULL) {
198 EC_KEY_free(ret);
199 return NULL;
200 }
201 return ret;
202}
203
204int
205EC_KEY_up_ref(EC_KEY * r)
206{
207 int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
208 return ((i > 1) ? 1 : 0);
209}
210
211int
212EC_KEY_generate_key(EC_KEY * eckey)
213{
214 int ok = 0;
215 BN_CTX *ctx = NULL;
216 BIGNUM *priv_key = NULL, *order = NULL;
217 EC_POINT *pub_key = NULL;
218
219 if (!eckey || !eckey->group) {
220 ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
221 return 0;
222 }
223 if ((order = BN_new()) == NULL)
224 goto err;
225 if ((ctx = BN_CTX_new()) == NULL)
226 goto err;
227
228 if (eckey->priv_key == NULL) {
229 priv_key = BN_new();
230 if (priv_key == NULL)
231 goto err;
232 } else
233 priv_key = eckey->priv_key;
234
235 if (!EC_GROUP_get_order(eckey->group, order, ctx))
236 goto err;
237
238 do
239 if (!BN_rand_range(priv_key, order))
240 goto err;
241 while (BN_is_zero(priv_key));
242
243 if (eckey->pub_key == NULL) {
244 pub_key = EC_POINT_new(eckey->group);
245 if (pub_key == NULL)
246 goto err;
247 } else
248 pub_key = eckey->pub_key;
249
250 if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
251 goto err;
252
253 eckey->priv_key = priv_key;
254 eckey->pub_key = pub_key;
255
256 ok = 1;
257
258err:
259 BN_free(order);
260 if (pub_key != NULL && eckey->pub_key == NULL)
261 EC_POINT_free(pub_key);
262 if (priv_key != NULL && eckey->priv_key == NULL)
263 BN_free(priv_key);
264 BN_CTX_free(ctx);
265 return (ok);
266}
267
268int
269EC_KEY_check_key(const EC_KEY * eckey)
270{
271 int ok = 0;
272 BN_CTX *ctx = NULL;
273 const BIGNUM *order = NULL;
274 EC_POINT *point = NULL;
275
276 if (!eckey || !eckey->group || !eckey->pub_key) {
277 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
278 return 0;
279 }
280 if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key) > 0) {
281 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
282 goto err;
283 }
284 if ((ctx = BN_CTX_new()) == NULL)
285 goto err;
286 if ((point = EC_POINT_new(eckey->group)) == NULL)
287 goto err;
288
289 /* testing whether the pub_key is on the elliptic curve */
290 if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
291 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
292 goto err;
293 }
294 /* testing whether pub_key * order is the point at infinity */
295 order = &eckey->group->order;
296 if (BN_is_zero(order)) {
297 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
298 goto err;
299 }
300 if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
301 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
302 goto err;
303 }
304 if (EC_POINT_is_at_infinity(eckey->group, point) <= 0) {
305 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
306 goto err;
307 }
308 /*
309 * in case the priv_key is present : check if generator * priv_key ==
310 * pub_key
311 */
312 if (eckey->priv_key) {
313 if (BN_cmp(eckey->priv_key, order) >= 0) {
314 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
315 goto err;
316 }
317 if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
318 NULL, NULL, ctx)) {
319 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
320 goto err;
321 }
322 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key,
323 ctx) != 0) {
324 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
325 goto err;
326 }
327 }
328 ok = 1;
329err:
330 BN_CTX_free(ctx);
331 EC_POINT_free(point);
332 return (ok);
333}
334
335int
336EC_KEY_set_public_key_affine_coordinates(EC_KEY * key, BIGNUM * x, BIGNUM * y)
337{
338 BN_CTX *ctx = NULL;
339 BIGNUM *tx, *ty;
340 EC_POINT *point = NULL;
341 int ok = 0, tmp_nid, is_char_two = 0;
342
343 if (!key || !key->group || !x || !y) {
344 ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
345 ERR_R_PASSED_NULL_PARAMETER);
346 return 0;
347 }
348 ctx = BN_CTX_new();
349 if (!ctx)
350 goto err;
351
352 point = EC_POINT_new(key->group);
353
354 if (!point)
355 goto err;
356
357 tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
358
359 if (tmp_nid == NID_X9_62_characteristic_two_field)
360 is_char_two = 1;
361
362 if ((tx = BN_CTX_get(ctx)) == NULL)
363 goto err;
364 if ((ty = BN_CTX_get(ctx)) == NULL)
365 goto err;
366
367#ifndef OPENSSL_NO_EC2M
368 if (is_char_two) {
369 if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
370 x, y, ctx))
371 goto err;
372 if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
373 tx, ty, ctx))
374 goto err;
375 } else
376#endif
377 {
378 if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
379 x, y, ctx))
380 goto err;
381 if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
382 tx, ty, ctx))
383 goto err;
384 }
385 /*
386 * Check if retrieved coordinates match originals: if not values are
387 * out of range.
388 */
389 if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
390 ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
391 EC_R_COORDINATES_OUT_OF_RANGE);
392 goto err;
393 }
394 if (!EC_KEY_set_public_key(key, point))
395 goto err;
396
397 if (EC_KEY_check_key(key) == 0)
398 goto err;
399
400 ok = 1;
401
402err:
403 BN_CTX_free(ctx);
404 EC_POINT_free(point);
405 return ok;
406
407}
408
409const EC_GROUP *
410EC_KEY_get0_group(const EC_KEY * key)
411{
412 return key->group;
413}
414
415int
416EC_KEY_set_group(EC_KEY * key, const EC_GROUP * group)
417{
418 EC_GROUP_free(key->group);
419 key->group = EC_GROUP_dup(group);
420 return (key->group == NULL) ? 0 : 1;
421}
422
423const BIGNUM *
424EC_KEY_get0_private_key(const EC_KEY * key)
425{
426 return key->priv_key;
427}
428
429int
430EC_KEY_set_private_key(EC_KEY * key, const BIGNUM * priv_key)
431{
432 BN_clear_free(key->priv_key);
433 key->priv_key = BN_dup(priv_key);
434 return (key->priv_key == NULL) ? 0 : 1;
435}
436
437const EC_POINT *
438EC_KEY_get0_public_key(const EC_KEY * key)
439{
440 return key->pub_key;
441}
442
443int
444EC_KEY_set_public_key(EC_KEY * key, const EC_POINT * pub_key)
445{
446 EC_POINT_free(key->pub_key);
447 key->pub_key = EC_POINT_dup(pub_key, key->group);
448 return (key->pub_key == NULL) ? 0 : 1;
449}
450
451unsigned int
452EC_KEY_get_enc_flags(const EC_KEY * key)
453{
454 return key->enc_flag;
455}
456
457void
458EC_KEY_set_enc_flags(EC_KEY * key, unsigned int flags)
459{
460 key->enc_flag = flags;
461}
462
463point_conversion_form_t
464EC_KEY_get_conv_form(const EC_KEY * key)
465{
466 return key->conv_form;
467}
468
469void
470EC_KEY_set_conv_form(EC_KEY * key, point_conversion_form_t cform)
471{
472 key->conv_form = cform;
473 if (key->group != NULL)
474 EC_GROUP_set_point_conversion_form(key->group, cform);
475}
476
477void *
478EC_KEY_get_key_method_data(EC_KEY *key,
479 void *(*dup_func) (void *),
480 void (*free_func) (void *),
481 void (*clear_free_func) (void *))
482{
483 void *ret;
484
485 CRYPTO_r_lock(CRYPTO_LOCK_EC);
486 ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
487 CRYPTO_r_unlock(CRYPTO_LOCK_EC);
488
489 return ret;
490}
491
492void *
493EC_KEY_insert_key_method_data(EC_KEY * key, void *data,
494 void *(*dup_func) (void *),
495 void (*free_func) (void *),
496 void (*clear_free_func) (void *))
497{
498 EC_EXTRA_DATA *ex_data;
499
500 CRYPTO_w_lock(CRYPTO_LOCK_EC);
501 ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
502 if (ex_data == NULL)
503 EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
504 CRYPTO_w_unlock(CRYPTO_LOCK_EC);
505
506 return ex_data;
507}
508
509void
510EC_KEY_set_asn1_flag(EC_KEY * key, int flag)
511{
512 if (key->group != NULL)
513 EC_GROUP_set_asn1_flag(key->group, flag);
514}
515
516int
517EC_KEY_precompute_mult(EC_KEY * key, BN_CTX * ctx)
518{
519 if (key->group == NULL)
520 return 0;
521 return EC_GROUP_precompute_mult(key->group, ctx);
522}
523
524int
525EC_KEY_get_flags(const EC_KEY * key)
526{
527 return key->flags;
528}
529
530void
531EC_KEY_set_flags(EC_KEY * key, int flags)
532{
533 key->flags |= flags;
534}
535
536void
537EC_KEY_clear_flags(EC_KEY * key, int flags)
538{
539 key->flags &= ~flags;
540}
diff --git a/src/lib/libcrypto/ec/ec_lcl.h b/src/lib/libcrypto/ec/ec_lcl.h
deleted file mode 100644
index faed33fe56..0000000000
--- a/src/lib/libcrypto/ec/ec_lcl.h
+++ /dev/null
@@ -1,446 +0,0 @@
1/* $OpenBSD: ec_lcl.h,v 1.5 2014/06/12 15:49:29 deraadt Exp $ */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2010 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
73#include <stdlib.h>
74
75#include <openssl/obj_mac.h>
76#include <openssl/ec.h>
77#include <openssl/bn.h>
78
79#if defined(__SUNPRO_C)
80# if __SUNPRO_C >= 0x520
81# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
82# endif
83#endif
84
85/* Use default functions for poin2oct, oct2point and compressed coordinates */
86#define EC_FLAGS_DEFAULT_OCT 0x1
87
88/* Structure details are not part of the exported interface,
89 * so all this may change in future versions. */
90
91struct ec_method_st {
92 /* Various method flags */
93 int flags;
94 /* used by EC_METHOD_get_field_type: */
95 int field_type; /* a NID */
96
97 /* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
98 int (*group_init)(EC_GROUP *);
99 void (*group_finish)(EC_GROUP *);
100 void (*group_clear_finish)(EC_GROUP *);
101 int (*group_copy)(EC_GROUP *, const EC_GROUP *);
102
103 /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
104 /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
105 int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
106 int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
107
108 /* used by EC_GROUP_get_degree: */
109 int (*group_get_degree)(const EC_GROUP *);
110
111 /* used by EC_GROUP_check: */
112 int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
113
114 /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
115 int (*point_init)(EC_POINT *);
116 void (*point_finish)(EC_POINT *);
117 void (*point_clear_finish)(EC_POINT *);
118 int (*point_copy)(EC_POINT *, const EC_POINT *);
119
120 /* used by EC_POINT_set_to_infinity,
121 * EC_POINT_set_Jprojective_coordinates_GFp,
122 * EC_POINT_get_Jprojective_coordinates_GFp,
123 * EC_POINT_set_affine_coordinates_GFp, ..._GF2m,
124 * EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
125 * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
126 */
127 int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
128 int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
129 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
130 int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
131 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
132 int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
133 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
134 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
135 BIGNUM *x, BIGNUM *y, BN_CTX *);
136 int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
137 const BIGNUM *x, int y_bit, BN_CTX *);
138
139 /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
140 size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
141 unsigned char *buf, size_t len, BN_CTX *);
142 int (*oct2point)(const EC_GROUP *, EC_POINT *,
143 const unsigned char *buf, size_t len, BN_CTX *);
144
145 /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
146 int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
147 int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
148 int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
149
150 /* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
151 int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
152 int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
153 int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
154
155 /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
156 int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
157 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
158
159 /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult
160 * (default implementations are used if the 'mul' pointer is 0): */
161 int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
162 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
163 int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
164 int (*have_precompute_mult)(const EC_GROUP *group);
165
166
167 /* internal functions */
168
169 /* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl' so that
170 * the same implementations of point operations can be used with different
171 * optimized implementations of expensive field operations: */
172 int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
173 int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
174 int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
175
176 int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */
177 int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */
178 int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
179} /* EC_METHOD */;
180
181typedef struct ec_extra_data_st {
182 struct ec_extra_data_st *next;
183 void *data;
184 void *(*dup_func)(void *);
185 void (*free_func)(void *);
186 void (*clear_free_func)(void *);
187} EC_EXTRA_DATA; /* used in EC_GROUP */
188
189struct ec_group_st {
190 const EC_METHOD *meth;
191
192 EC_POINT *generator; /* optional */
193 BIGNUM order, cofactor;
194
195 int curve_name;/* optional NID for named curve */
196 int asn1_flag; /* flag to control the asn1 encoding */
197 point_conversion_form_t asn1_form;
198
199 unsigned char *seed; /* optional seed for parameters (appears in ASN1) */
200 size_t seed_len;
201
202 EC_EXTRA_DATA *extra_data; /* linked list */
203
204 /* The following members are handled by the method functions,
205 * even if they appear generic */
206
207 BIGNUM field; /* Field specification.
208 * For curves over GF(p), this is the modulus;
209 * for curves over GF(2^m), this is the
210 * irreducible polynomial defining the field.
211 */
212
213 int poly[6]; /* Field specification for curves over GF(2^m).
214 * The irreducible f(t) is then of the form:
215 * t^poly[0] + t^poly[1] + ... + t^poly[k]
216 * where m = poly[0] > poly[1] > ... > poly[k] = 0.
217 * The array is terminated with poly[k+1]=-1.
218 * All elliptic curve irreducibles have at most 5
219 * non-zero terms.
220 */
221
222 BIGNUM a, b; /* Curve coefficients.
223 * (Here the assumption is that BIGNUMs can be used
224 * or abused for all kinds of fields, not just GF(p).)
225 * For characteristic > 3, the curve is defined
226 * by a Weierstrass equation of the form
227 * y^2 = x^3 + a*x + b.
228 * For characteristic 2, the curve is defined by
229 * an equation of the form
230 * y^2 + x*y = x^3 + a*x^2 + b.
231 */
232
233 int a_is_minus3; /* enable optimized point arithmetics for special case */
234
235 void *field_data1; /* method-specific (e.g., Montgomery structure) */
236 void *field_data2; /* method-specific */
237 int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* method-specific */
238} /* EC_GROUP */;
239
240struct ec_key_st {
241 int version;
242
243 EC_GROUP *group;
244
245 EC_POINT *pub_key;
246 BIGNUM *priv_key;
247
248 unsigned int enc_flag;
249 point_conversion_form_t conv_form;
250
251 int references;
252 int flags;
253
254 EC_EXTRA_DATA *method_data;
255} /* EC_KEY */;
256
257/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
258 * (with visibility limited to 'package' level for now).
259 * We use the function pointers as index for retrieval; this obviates
260 * global ex_data-style index tables.
261 */
262int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
263 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
264void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *,
265 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
266void EC_EX_DATA_free_data(EC_EXTRA_DATA **,
267 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
268void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **,
269 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
270void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
271void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
272
273
274
275struct ec_point_st {
276 const EC_METHOD *meth;
277
278 /* All members except 'meth' are handled by the method functions,
279 * even if they appear generic */
280
281 BIGNUM X;
282 BIGNUM Y;
283 BIGNUM Z; /* Jacobian projective coordinates:
284 * (X, Y, Z) represents (X/Z^2, Y/Z^3) if Z != 0 */
285 int Z_is_one; /* enable optimized point arithmetics for special case */
286} /* EC_POINT */;
287
288
289
290/* method functions in ec_mult.c
291 * (ec_lib.c uses these as defaults if group->method->mul is 0) */
292int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
293 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
294int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
295int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
296
297
298/* method functions in ecp_smpl.c */
299int ec_GFp_simple_group_init(EC_GROUP *);
300void ec_GFp_simple_group_finish(EC_GROUP *);
301void ec_GFp_simple_group_clear_finish(EC_GROUP *);
302int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
303int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
304int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
305int ec_GFp_simple_group_get_degree(const EC_GROUP *);
306int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
307int ec_GFp_simple_point_init(EC_POINT *);
308void ec_GFp_simple_point_finish(EC_POINT *);
309void ec_GFp_simple_point_clear_finish(EC_POINT *);
310int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
311int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
312int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
313 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
314int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
315 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
316int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
317 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
318int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
319 BIGNUM *x, BIGNUM *y, BN_CTX *);
320int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
321 const BIGNUM *x, int y_bit, BN_CTX *);
322size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
323 unsigned char *buf, size_t len, BN_CTX *);
324int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
325 const unsigned char *buf, size_t len, BN_CTX *);
326int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
327int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
328int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
329int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
330int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
331int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
332int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
333int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
334int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
335int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
336
337
338/* method functions in ecp_mont.c */
339int ec_GFp_mont_group_init(EC_GROUP *);
340int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
341void ec_GFp_mont_group_finish(EC_GROUP *);
342void ec_GFp_mont_group_clear_finish(EC_GROUP *);
343int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
344int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
345int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
346int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
347int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
348int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
349
350
351/* method functions in ecp_nist.c */
352int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
353int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
354int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
355int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
356
357
358/* method functions in ec2_smpl.c */
359int ec_GF2m_simple_group_init(EC_GROUP *);
360void ec_GF2m_simple_group_finish(EC_GROUP *);
361void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
362int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
363int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
364int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
365int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
366int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
367int ec_GF2m_simple_point_init(EC_POINT *);
368void ec_GF2m_simple_point_finish(EC_POINT *);
369void ec_GF2m_simple_point_clear_finish(EC_POINT *);
370int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
371int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
372int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
373 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
374int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
375 BIGNUM *x, BIGNUM *y, BN_CTX *);
376int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
377 const BIGNUM *x, int y_bit, BN_CTX *);
378size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
379 unsigned char *buf, size_t len, BN_CTX *);
380int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
381 const unsigned char *buf, size_t len, BN_CTX *);
382int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
383int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
384int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
385int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
386int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
387int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
388int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
389int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
390int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
391int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
392int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
393
394
395/* method functions in ec2_mult.c */
396int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
397 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
398int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
399int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
400
401/* method functions in ec2_mult.c */
402int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
403 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
404int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
405int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
406
407#ifndef OPENSSL_EC_NISTP_64_GCC_128
408/* method functions in ecp_nistp224.c */
409int ec_GFp_nistp224_group_init(EC_GROUP *group);
410int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
411int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
412int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
413int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
414int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
415int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
416
417/* method functions in ecp_nistp256.c */
418int ec_GFp_nistp256_group_init(EC_GROUP *group);
419int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
420int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
421int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
422int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
423int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
424int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
425
426/* method functions in ecp_nistp521.c */
427int ec_GFp_nistp521_group_init(EC_GROUP *group);
428int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
429int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
430int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
431int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
432int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
433int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
434
435/* utility functions in ecp_nistputil.c */
436void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
437 size_t felem_size, void *tmp_felems,
438 void (*felem_one)(void *out),
439 int (*felem_is_zero)(const void *in),
440 void (*felem_assign)(void *out, const void *in),
441 void (*felem_square)(void *out, const void *in),
442 void (*felem_mul)(void *out, const void *in1, const void *in2),
443 void (*felem_inv)(void *out, const void *in),
444 void (*felem_contract)(void *out, const void *in));
445void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in);
446#endif
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
deleted file mode 100644
index 2b5abbd4bb..0000000000
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ /dev/null
@@ -1,1120 +0,0 @@
1/* $OpenBSD: ec_lib.c,v 1.20 2015/10/13 15:25:18 jsing Exp $ */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2003 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 * Binary polynomial ECC support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65
66#include <openssl/opensslconf.h>
67
68#include <openssl/err.h>
69#include <openssl/opensslv.h>
70
71#include "ec_lcl.h"
72
73/* functions for EC_GROUP objects */
74
75EC_GROUP *
76EC_GROUP_new(const EC_METHOD * meth)
77{
78 EC_GROUP *ret;
79
80 if (meth == NULL) {
81 ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
82 return NULL;
83 }
84 if (meth->group_init == 0) {
85 ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
86 return NULL;
87 }
88 ret = malloc(sizeof *ret);
89 if (ret == NULL) {
90 ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
91 return NULL;
92 }
93 ret->meth = meth;
94
95 ret->extra_data = NULL;
96
97 ret->generator = NULL;
98 BN_init(&ret->order);
99 BN_init(&ret->cofactor);
100
101 ret->curve_name = 0;
102 ret->asn1_flag = 0;
103 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
104
105 ret->seed = NULL;
106 ret->seed_len = 0;
107
108 if (!meth->group_init(ret)) {
109 free(ret);
110 return NULL;
111 }
112 return ret;
113}
114
115
116void
117EC_GROUP_free(EC_GROUP * group)
118{
119 if (!group)
120 return;
121
122 if (group->meth->group_finish != 0)
123 group->meth->group_finish(group);
124
125 EC_EX_DATA_free_all_data(&group->extra_data);
126
127 EC_POINT_free(group->generator);
128 BN_free(&group->order);
129 BN_free(&group->cofactor);
130
131 free(group->seed);
132
133 free(group);
134}
135
136
137void
138EC_GROUP_clear_free(EC_GROUP * group)
139{
140 if (!group)
141 return;
142
143 if (group->meth->group_clear_finish != 0)
144 group->meth->group_clear_finish(group);
145 else if (group->meth->group_finish != 0)
146 group->meth->group_finish(group);
147
148 EC_EX_DATA_clear_free_all_data(&group->extra_data);
149
150 EC_POINT_clear_free(group->generator);
151 BN_clear_free(&group->order);
152 BN_clear_free(&group->cofactor);
153
154 if (group->seed) {
155 explicit_bzero(group->seed, group->seed_len);
156 free(group->seed);
157 }
158 explicit_bzero(group, sizeof *group);
159 free(group);
160}
161
162
163int
164EC_GROUP_copy(EC_GROUP * dest, const EC_GROUP * src)
165{
166 EC_EXTRA_DATA *d;
167
168 if (dest->meth->group_copy == 0) {
169 ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
170 return 0;
171 }
172 if (dest->meth != src->meth) {
173 ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
174 return 0;
175 }
176 if (dest == src)
177 return 1;
178
179 EC_EX_DATA_free_all_data(&dest->extra_data);
180
181 for (d = src->extra_data; d != NULL; d = d->next) {
182 void *t = d->dup_func(d->data);
183
184 if (t == NULL)
185 return 0;
186 if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func,
187 d->free_func, d->clear_free_func))
188 return 0;
189 }
190
191 if (src->generator != NULL) {
192 if (dest->generator == NULL) {
193 dest->generator = EC_POINT_new(dest);
194 if (dest->generator == NULL)
195 return 0;
196 }
197 if (!EC_POINT_copy(dest->generator, src->generator))
198 return 0;
199 } else {
200 /* src->generator == NULL */
201 EC_POINT_clear_free(dest->generator);
202 dest->generator = NULL;
203 }
204
205 if (!BN_copy(&dest->order, &src->order))
206 return 0;
207 if (!BN_copy(&dest->cofactor, &src->cofactor))
208 return 0;
209
210 dest->curve_name = src->curve_name;
211 dest->asn1_flag = src->asn1_flag;
212 dest->asn1_form = src->asn1_form;
213
214 if (src->seed) {
215 free(dest->seed);
216 dest->seed = malloc(src->seed_len);
217 if (dest->seed == NULL)
218 return 0;
219 memcpy(dest->seed, src->seed, src->seed_len);
220 dest->seed_len = src->seed_len;
221 } else {
222 free(dest->seed);
223 dest->seed = NULL;
224 dest->seed_len = 0;
225 }
226
227
228 return dest->meth->group_copy(dest, src);
229}
230
231
232EC_GROUP *
233EC_GROUP_dup(const EC_GROUP * a)
234{
235 EC_GROUP *t = NULL;
236 int ok = 0;
237
238 if (a == NULL)
239 return NULL;
240
241 if ((t = EC_GROUP_new(a->meth)) == NULL)
242 return (NULL);
243 if (!EC_GROUP_copy(t, a))
244 goto err;
245
246 ok = 1;
247
248err:
249 if (!ok) {
250 EC_GROUP_free(t);
251 return NULL;
252 } else
253 return t;
254}
255
256
257const EC_METHOD *
258EC_GROUP_method_of(const EC_GROUP *group)
259{
260 return group->meth;
261}
262
263
264int
265EC_METHOD_get_field_type(const EC_METHOD *meth)
266{
267 return meth->field_type;
268}
269
270
271int
272EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
273 const BIGNUM *order, const BIGNUM *cofactor)
274{
275 if (generator == NULL) {
276 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
277 return 0;
278 }
279 if (group->generator == NULL) {
280 group->generator = EC_POINT_new(group);
281 if (group->generator == NULL)
282 return 0;
283 }
284 if (!EC_POINT_copy(group->generator, generator))
285 return 0;
286
287 if (order != NULL) {
288 if (!BN_copy(&group->order, order))
289 return 0;
290 } else
291 BN_zero(&group->order);
292
293 if (cofactor != NULL) {
294 if (!BN_copy(&group->cofactor, cofactor))
295 return 0;
296 } else
297 BN_zero(&group->cofactor);
298
299 return 1;
300}
301
302
303const EC_POINT *
304EC_GROUP_get0_generator(const EC_GROUP *group)
305{
306 return group->generator;
307}
308
309
310int
311EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
312{
313 if (!BN_copy(order, &group->order))
314 return 0;
315
316 return !BN_is_zero(order);
317}
318
319
320int
321EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
322{
323 if (!BN_copy(cofactor, &group->cofactor))
324 return 0;
325
326 return !BN_is_zero(&group->cofactor);
327}
328
329
330void
331EC_GROUP_set_curve_name(EC_GROUP * group, int nid)
332{
333 group->curve_name = nid;
334}
335
336
337int
338EC_GROUP_get_curve_name(const EC_GROUP * group)
339{
340 return group->curve_name;
341}
342
343
344void
345EC_GROUP_set_asn1_flag(EC_GROUP * group, int flag)
346{
347 group->asn1_flag = flag;
348}
349
350
351int
352EC_GROUP_get_asn1_flag(const EC_GROUP * group)
353{
354 return group->asn1_flag;
355}
356
357
358void
359EC_GROUP_set_point_conversion_form(EC_GROUP * group,
360 point_conversion_form_t form)
361{
362 group->asn1_form = form;
363}
364
365
366point_conversion_form_t
367EC_GROUP_get_point_conversion_form(const EC_GROUP * group)
368{
369 return group->asn1_form;
370}
371
372
373size_t
374EC_GROUP_set_seed(EC_GROUP * group, const unsigned char *p, size_t len)
375{
376 if (group->seed) {
377 free(group->seed);
378 group->seed = NULL;
379 group->seed_len = 0;
380 }
381 if (!len || !p)
382 return 1;
383
384 if ((group->seed = malloc(len)) == NULL)
385 return 0;
386 memcpy(group->seed, p, len);
387 group->seed_len = len;
388
389 return len;
390}
391
392
393unsigned char *
394EC_GROUP_get0_seed(const EC_GROUP * group)
395{
396 return group->seed;
397}
398
399
400size_t
401EC_GROUP_get_seed_len(const EC_GROUP * group)
402{
403 return group->seed_len;
404}
405
406
407int
408EC_GROUP_set_curve_GFp(EC_GROUP * group, const BIGNUM * p, const BIGNUM * a,
409 const BIGNUM * b, BN_CTX * ctx)
410{
411 if (group->meth->group_set_curve == 0) {
412 ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
413 return 0;
414 }
415 return group->meth->group_set_curve(group, p, a, b, ctx);
416}
417
418
419int
420EC_GROUP_get_curve_GFp(const EC_GROUP * group, BIGNUM * p, BIGNUM * a,
421 BIGNUM * b, BN_CTX * ctx)
422{
423 if (group->meth->group_get_curve == 0) {
424 ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
425 return 0;
426 }
427 return group->meth->group_get_curve(group, p, a, b, ctx);
428}
429
430#ifndef OPENSSL_NO_EC2M
431int
432EC_GROUP_set_curve_GF2m(EC_GROUP * group, const BIGNUM * p, const BIGNUM * a,
433 const BIGNUM * b, BN_CTX * ctx)
434{
435 if (group->meth->group_set_curve == 0) {
436 ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
437 return 0;
438 }
439 return group->meth->group_set_curve(group, p, a, b, ctx);
440}
441
442
443int
444EC_GROUP_get_curve_GF2m(const EC_GROUP * group, BIGNUM * p, BIGNUM * a,
445 BIGNUM * b, BN_CTX * ctx)
446{
447 if (group->meth->group_get_curve == 0) {
448 ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
449 return 0;
450 }
451 return group->meth->group_get_curve(group, p, a, b, ctx);
452}
453#endif
454
455int
456EC_GROUP_get_degree(const EC_GROUP * group)
457{
458 if (group->meth->group_get_degree == 0) {
459 ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
460 return 0;
461 }
462 return group->meth->group_get_degree(group);
463}
464
465
466int
467EC_GROUP_check_discriminant(const EC_GROUP * group, BN_CTX * ctx)
468{
469 if (group->meth->group_check_discriminant == 0) {
470 ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
471 return 0;
472 }
473 return group->meth->group_check_discriminant(group, ctx);
474}
475
476
477int
478EC_GROUP_cmp(const EC_GROUP * a, const EC_GROUP * b, BN_CTX * ctx)
479{
480 int r = 0;
481 BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
482 BN_CTX *ctx_new = NULL;
483
484 /* compare the field types */
485 if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
486 EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
487 return 1;
488 /* compare the curve name (if present in both) */
489 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
490 EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
491 return 1;
492
493 if (!ctx)
494 ctx_new = ctx = BN_CTX_new();
495 if (!ctx)
496 return -1;
497
498 BN_CTX_start(ctx);
499 if ((a1 = BN_CTX_get(ctx)) == NULL)
500 goto err;
501 if ((a2 = BN_CTX_get(ctx)) == NULL)
502 goto err;
503 if ((a3 = BN_CTX_get(ctx)) == NULL)
504 goto err;
505 if ((b1 = BN_CTX_get(ctx)) == NULL)
506 goto err;
507 if ((b2 = BN_CTX_get(ctx)) == NULL)
508 goto err;
509 if ((b3 = BN_CTX_get(ctx)) == NULL)
510 goto err;
511
512 /*
513 * XXX This approach assumes that the external representation of
514 * curves over the same field type is the same.
515 */
516 if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
517 !b->meth->group_get_curve(b, b1, b2, b3, ctx))
518 r = 1;
519
520 if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
521 r = 1;
522
523 /* XXX EC_POINT_cmp() assumes that the methods are equal */
524 if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
525 EC_GROUP_get0_generator(b), ctx))
526 r = 1;
527
528 if (!r) {
529 /* compare the order and cofactor */
530 if (!EC_GROUP_get_order(a, a1, ctx) ||
531 !EC_GROUP_get_order(b, b1, ctx) ||
532 !EC_GROUP_get_cofactor(a, a2, ctx) ||
533 !EC_GROUP_get_cofactor(b, b2, ctx))
534 goto err;
535 if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
536 r = 1;
537 }
538 BN_CTX_end(ctx);
539 if (ctx_new)
540 BN_CTX_free(ctx);
541
542 return r;
543
544err:
545 BN_CTX_end(ctx);
546 if (ctx_new)
547 BN_CTX_free(ctx);
548 return -1;
549}
550
551
552/* this has 'package' visibility */
553int
554EC_EX_DATA_set_data(EC_EXTRA_DATA ** ex_data, void *data,
555 void *(*dup_func) (void *),
556 void (*free_func) (void *),
557 void (*clear_free_func) (void *))
558{
559 EC_EXTRA_DATA *d;
560
561 if (ex_data == NULL)
562 return 0;
563
564 for (d = *ex_data; d != NULL; d = d->next) {
565 if (d->dup_func == dup_func && d->free_func == free_func &&
566 d->clear_free_func == clear_free_func) {
567 ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
568 return 0;
569 }
570 }
571
572 if (data == NULL)
573 /* no explicit entry needed */
574 return 1;
575
576 d = malloc(sizeof *d);
577 if (d == NULL)
578 return 0;
579
580 d->data = data;
581 d->dup_func = dup_func;
582 d->free_func = free_func;
583 d->clear_free_func = clear_free_func;
584
585 d->next = *ex_data;
586 *ex_data = d;
587
588 return 1;
589}
590
591/* this has 'package' visibility */
592void *
593EC_EX_DATA_get_data(const EC_EXTRA_DATA * ex_data,
594 void *(*dup_func) (void *),
595 void (*free_func) (void *),
596 void (*clear_free_func) (void *))
597{
598 const EC_EXTRA_DATA *d;
599
600 for (d = ex_data; d != NULL; d = d->next) {
601 if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
602 return d->data;
603 }
604
605 return NULL;
606}
607
608/* this has 'package' visibility */
609void
610EC_EX_DATA_free_data(EC_EXTRA_DATA ** ex_data,
611 void *(*dup_func) (void *),
612 void (*free_func) (void *),
613 void (*clear_free_func) (void *))
614{
615 EC_EXTRA_DATA **p;
616
617 if (ex_data == NULL)
618 return;
619
620 for (p = ex_data; *p != NULL; p = &((*p)->next)) {
621 if ((*p)->dup_func == dup_func &&
622 (*p)->free_func == free_func &&
623 (*p)->clear_free_func == clear_free_func) {
624 EC_EXTRA_DATA *next = (*p)->next;
625
626 (*p)->free_func((*p)->data);
627 free(*p);
628
629 *p = next;
630 return;
631 }
632 }
633}
634
635/* this has 'package' visibility */
636void
637EC_EX_DATA_clear_free_data(EC_EXTRA_DATA ** ex_data,
638 void *(*dup_func) (void *),
639 void (*free_func) (void *),
640 void (*clear_free_func) (void *))
641{
642 EC_EXTRA_DATA **p;
643
644 if (ex_data == NULL)
645 return;
646
647 for (p = ex_data; *p != NULL; p = &((*p)->next)) {
648 if ((*p)->dup_func == dup_func &&
649 (*p)->free_func == free_func &&
650 (*p)->clear_free_func == clear_free_func) {
651 EC_EXTRA_DATA *next = (*p)->next;
652
653 (*p)->clear_free_func((*p)->data);
654 free(*p);
655
656 *p = next;
657 return;
658 }
659 }
660}
661
662/* this has 'package' visibility */
663void
664EC_EX_DATA_free_all_data(EC_EXTRA_DATA ** ex_data)
665{
666 EC_EXTRA_DATA *d;
667
668 if (ex_data == NULL)
669 return;
670
671 d = *ex_data;
672 while (d) {
673 EC_EXTRA_DATA *next = d->next;
674
675 d->free_func(d->data);
676 free(d);
677
678 d = next;
679 }
680 *ex_data = NULL;
681}
682
683/* this has 'package' visibility */
684void
685EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA ** ex_data)
686{
687 EC_EXTRA_DATA *d;
688
689 if (ex_data == NULL)
690 return;
691
692 d = *ex_data;
693 while (d) {
694 EC_EXTRA_DATA *next = d->next;
695
696 d->clear_free_func(d->data);
697 free(d);
698
699 d = next;
700 }
701 *ex_data = NULL;
702}
703
704
705/* functions for EC_POINT objects */
706
707EC_POINT *
708EC_POINT_new(const EC_GROUP * group)
709{
710 EC_POINT *ret;
711
712 if (group == NULL) {
713 ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
714 return NULL;
715 }
716 if (group->meth->point_init == 0) {
717 ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
718 return NULL;
719 }
720 ret = malloc(sizeof *ret);
721 if (ret == NULL) {
722 ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
723 return NULL;
724 }
725 ret->meth = group->meth;
726
727 if (!ret->meth->point_init(ret)) {
728 free(ret);
729 return NULL;
730 }
731 return ret;
732}
733
734
735void
736EC_POINT_free(EC_POINT * point)
737{
738 if (!point)
739 return;
740
741 if (point->meth->point_finish != 0)
742 point->meth->point_finish(point);
743 free(point);
744}
745
746
747void
748EC_POINT_clear_free(EC_POINT * point)
749{
750 if (!point)
751 return;
752
753 if (point->meth->point_clear_finish != 0)
754 point->meth->point_clear_finish(point);
755 else if (point->meth->point_finish != 0)
756 point->meth->point_finish(point);
757 explicit_bzero(point, sizeof *point);
758 free(point);
759}
760
761
762int
763EC_POINT_copy(EC_POINT * dest, const EC_POINT * src)
764{
765 if (dest->meth->point_copy == 0) {
766 ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
767 return 0;
768 }
769 if (dest->meth != src->meth) {
770 ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
771 return 0;
772 }
773 if (dest == src)
774 return 1;
775 return dest->meth->point_copy(dest, src);
776}
777
778
779EC_POINT *
780EC_POINT_dup(const EC_POINT * a, const EC_GROUP * group)
781{
782 EC_POINT *t;
783 int r;
784
785 if (a == NULL)
786 return NULL;
787
788 t = EC_POINT_new(group);
789 if (t == NULL)
790 return (NULL);
791 r = EC_POINT_copy(t, a);
792 if (!r) {
793 EC_POINT_free(t);
794 return NULL;
795 } else
796 return t;
797}
798
799
800const EC_METHOD *
801EC_POINT_method_of(const EC_POINT * point)
802{
803 return point->meth;
804}
805
806
807int
808EC_POINT_set_to_infinity(const EC_GROUP * group, EC_POINT * point)
809{
810 if (group->meth->point_set_to_infinity == 0) {
811 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
812 return 0;
813 }
814 if (group->meth != point->meth) {
815 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
816 return 0;
817 }
818 return group->meth->point_set_to_infinity(group, point);
819}
820
821
822int
823EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
824 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
825{
826 if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
827 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
828 return 0;
829 }
830 if (group->meth != point->meth) {
831 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
832 return 0;
833 }
834 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
835}
836
837
838int
839EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
840 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
841{
842 if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
843 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
844 return 0;
845 }
846 if (group->meth != point->meth) {
847 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
848 return 0;
849 }
850 return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
851}
852
853
854int
855EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
856 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
857{
858 if (group->meth->point_set_affine_coordinates == 0) {
859 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
860 return 0;
861 }
862 if (group->meth != point->meth) {
863 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
864 return 0;
865 }
866 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
867}
868
869#ifndef OPENSSL_NO_EC2M
870int
871EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
872 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
873{
874 if (group->meth->point_set_affine_coordinates == 0) {
875 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
876 return 0;
877 }
878 if (group->meth != point->meth) {
879 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
880 return 0;
881 }
882 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
883}
884#endif
885
886int
887EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
888 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
889{
890 if (group->meth->point_get_affine_coordinates == 0) {
891 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
892 return 0;
893 }
894 if (group->meth != point->meth) {
895 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
896 return 0;
897 }
898 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
899}
900
901#ifndef OPENSSL_NO_EC2M
902int
903EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
904 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
905{
906 if (group->meth->point_get_affine_coordinates == 0) {
907 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
908 return 0;
909 }
910 if (group->meth != point->meth) {
911 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
912 return 0;
913 }
914 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
915}
916#endif
917
918int
919EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
920 const EC_POINT *b, BN_CTX *ctx)
921{
922 if (group->meth->add == 0) {
923 ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
924 return 0;
925 }
926 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) {
927 ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
928 return 0;
929 }
930 return group->meth->add(group, r, a, b, ctx);
931}
932
933
934int
935EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
936{
937 if (group->meth->dbl == 0) {
938 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
939 return 0;
940 }
941 if ((group->meth != r->meth) || (r->meth != a->meth)) {
942 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
943 return 0;
944 }
945 return group->meth->dbl(group, r, a, ctx);
946}
947
948
949int
950EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
951{
952 if (group->meth->invert == 0) {
953 ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
954 return 0;
955 }
956 if (group->meth != a->meth) {
957 ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
958 return 0;
959 }
960 return group->meth->invert(group, a, ctx);
961}
962
963
964int
965EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
966{
967 if (group->meth->is_at_infinity == 0) {
968 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
969 return 0;
970 }
971 if (group->meth != point->meth) {
972 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
973 return 0;
974 }
975 return group->meth->is_at_infinity(group, point);
976}
977
978
979int
980EC_POINT_is_on_curve(const EC_GROUP * group, const EC_POINT * point, BN_CTX * ctx)
981{
982 if (group->meth->is_on_curve == 0) {
983 ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
984 return 0;
985 }
986 if (group->meth != point->meth) {
987 ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
988 return 0;
989 }
990 return group->meth->is_on_curve(group, point, ctx);
991}
992
993
994int
995EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
996 BN_CTX * ctx)
997{
998 if (group->meth->point_cmp == 0) {
999 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1000 return -1;
1001 }
1002 if ((group->meth != a->meth) || (a->meth != b->meth)) {
1003 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
1004 return -1;
1005 }
1006 return group->meth->point_cmp(group, a, b, ctx);
1007}
1008
1009
1010int
1011EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1012{
1013 if (group->meth->make_affine == 0) {
1014 ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1015 return 0;
1016 }
1017 if (group->meth != point->meth) {
1018 ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1019 return 0;
1020 }
1021 return group->meth->make_affine(group, point, ctx);
1022}
1023
1024
1025int
1026EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1027 BN_CTX *ctx)
1028{
1029 size_t i;
1030
1031 if (group->meth->points_make_affine == 0) {
1032 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1033 return 0;
1034 }
1035 for (i = 0; i < num; i++) {
1036 if (group->meth != points[i]->meth) {
1037 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1038 return 0;
1039 }
1040 }
1041 return group->meth->points_make_affine(group, num, points, ctx);
1042}
1043
1044
1045/* Functions for point multiplication.
1046 *
1047 * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
1048 * otherwise we dispatch through methods.
1049 */
1050
1051int
1052EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1053 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
1054{
1055 if (group->meth->mul == 0)
1056 /* use default */
1057 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
1058
1059 return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
1060}
1061
1062int
1063EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1064 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
1065{
1066 /* just a convenient interface to EC_POINTs_mul() */
1067
1068 const EC_POINT *points[1];
1069 const BIGNUM *scalars[1];
1070
1071 points[0] = point;
1072 scalars[0] = p_scalar;
1073
1074 return EC_POINTs_mul(group, r, g_scalar,
1075 (point != NULL && p_scalar != NULL),
1076 points, scalars, ctx);
1077}
1078
1079int
1080EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
1081{
1082 if (group->meth->mul == 0)
1083 /* use default */
1084 return ec_wNAF_precompute_mult(group, ctx);
1085
1086 if (group->meth->precompute_mult != 0)
1087 return group->meth->precompute_mult(group, ctx);
1088 else
1089 return 1; /* nothing to do, so report success */
1090}
1091
1092int
1093EC_GROUP_have_precompute_mult(const EC_GROUP * group)
1094{
1095 if (group->meth->mul == 0)
1096 /* use default */
1097 return ec_wNAF_have_precompute_mult(group);
1098
1099 if (group->meth->have_precompute_mult != 0)
1100 return group->meth->have_precompute_mult(group);
1101 else
1102 return 0; /* cannot tell whether precomputation has
1103 * been performed */
1104}
1105
1106EC_KEY *
1107ECParameters_dup(EC_KEY *key)
1108{
1109 unsigned char *p = NULL;
1110 EC_KEY *k = NULL;
1111 int len;
1112
1113 if (key == NULL)
1114 return (NULL);
1115
1116 if ((len = i2d_ECParameters(key, &p)) > 0)
1117 k = d2i_ECParameters(NULL, (const unsigned char **)&p, len);
1118
1119 return (k);
1120}
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
deleted file mode 100644
index e428ac586b..0000000000
--- a/src/lib/libcrypto/ec/ec_mult.c
+++ /dev/null
@@ -1,886 +0,0 @@
1/* $OpenBSD: ec_mult.c,v 1.19 2015/09/10 15:56:25 jsing Exp $ */
2/*
3 * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2007 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 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65
66#include <openssl/err.h>
67
68#include "ec_lcl.h"
69
70
71/*
72 * This file implements the wNAF-based interleaving multi-exponentation method
73 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
74 * for multiplication with precomputation, we use wNAF splitting
75 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
76 */
77
78
79
80
81/* structure for precomputed multiples of the generator */
82typedef struct ec_pre_comp_st {
83 const EC_GROUP *group; /* parent EC_GROUP object */
84 size_t blocksize; /* block size for wNAF splitting */
85 size_t numblocks; /* max. number of blocks for which we have
86 * precomputation */
87 size_t w; /* window size */
88 EC_POINT **points; /* array with pre-calculated multiples of
89 * generator: 'num' pointers to EC_POINT
90 * objects followed by a NULL */
91 size_t num; /* numblocks * 2^(w-1) */
92 int references;
93} EC_PRE_COMP;
94
95/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
96static void *ec_pre_comp_dup(void *);
97static void ec_pre_comp_free(void *);
98static void ec_pre_comp_clear_free(void *);
99
100static EC_PRE_COMP *
101ec_pre_comp_new(const EC_GROUP * group)
102{
103 EC_PRE_COMP *ret = NULL;
104
105 if (!group)
106 return NULL;
107
108 ret = malloc(sizeof(EC_PRE_COMP));
109 if (!ret) {
110 ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
111 return ret;
112 }
113 ret->group = group;
114 ret->blocksize = 8; /* default */
115 ret->numblocks = 0;
116 ret->w = 4; /* default */
117 ret->points = NULL;
118 ret->num = 0;
119 ret->references = 1;
120 return ret;
121}
122
123static void *
124ec_pre_comp_dup(void *src_)
125{
126 EC_PRE_COMP *src = src_;
127
128 /* no need to actually copy, these objects never change! */
129
130 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
131
132 return src_;
133}
134
135static void
136ec_pre_comp_free(void *pre_)
137{
138 int i;
139 EC_PRE_COMP *pre = pre_;
140
141 if (!pre)
142 return;
143
144 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
145 if (i > 0)
146 return;
147
148 if (pre->points) {
149 EC_POINT **p;
150
151 for (p = pre->points; *p != NULL; p++)
152 EC_POINT_free(*p);
153 free(pre->points);
154 }
155 free(pre);
156}
157
158static void
159ec_pre_comp_clear_free(void *pre_)
160{
161 int i;
162 EC_PRE_COMP *pre = pre_;
163
164 if (!pre)
165 return;
166
167 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
168 if (i > 0)
169 return;
170
171 if (pre->points) {
172 EC_POINT **p;
173
174 for (p = pre->points; *p != NULL; p++) {
175 EC_POINT_clear_free(*p);
176 explicit_bzero(p, sizeof *p);
177 }
178 free(pre->points);
179 }
180 explicit_bzero(pre, sizeof *pre);
181 free(pre);
182}
183
184
185
186
187/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
188 * This is an array r[] of values that are either zero or odd with an
189 * absolute value less than 2^w satisfying
190 * scalar = \sum_j r[j]*2^j
191 * where at most one of any w+1 consecutive digits is non-zero
192 * with the exception that the most significant digit may be only
193 * w-1 zeros away from that next non-zero digit.
194 */
195static signed char *
196compute_wNAF(const BIGNUM * scalar, int w, size_t * ret_len)
197{
198 int window_val;
199 int ok = 0;
200 signed char *r = NULL;
201 int sign = 1;
202 int bit, next_bit, mask;
203 size_t len = 0, j;
204
205 if (BN_is_zero(scalar)) {
206 r = malloc(1);
207 if (!r) {
208 ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
209 goto err;
210 }
211 r[0] = 0;
212 *ret_len = 1;
213 return r;
214 }
215 if (w <= 0 || w > 7) {
216 /* 'signed char' can represent integers with
217 * absolute values less than 2^7 */
218 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
219 goto err;
220 }
221 bit = 1 << w; /* at most 128 */
222 next_bit = bit << 1; /* at most 256 */
223 mask = next_bit - 1; /* at most 255 */
224
225 if (BN_is_negative(scalar)) {
226 sign = -1;
227 }
228 if (scalar->d == NULL || scalar->top == 0) {
229 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
230 goto err;
231 }
232 len = BN_num_bits(scalar);
233 r = malloc(len + 1); /* modified wNAF may be one digit longer than
234 * binary representation (*ret_len will be
235 * set to the actual length, i.e. at most
236 * BN_num_bits(scalar) + 1) */
237 if (r == NULL) {
238 ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
239 goto err;
240 }
241 window_val = scalar->d[0] & mask;
242 j = 0;
243 while ((window_val != 0) || (j + w + 1 < len)) {
244 /* if j+w+1 >= len, window_val will not increase */
245 int digit = 0;
246
247 /* 0 <= window_val <= 2^(w+1) */
248 if (window_val & 1) {
249 /* 0 < window_val < 2^(w+1) */
250 if (window_val & bit) {
251 digit = window_val - next_bit; /* -2^w < digit < 0 */
252
253#if 1 /* modified wNAF */
254 if (j + w + 1 >= len) {
255 /*
256 * special case for generating
257 * modified wNAFs: no new bits will
258 * be added into window_val, so using
259 * a positive digit here will
260 * decrease the total length of the
261 * representation
262 */
263
264 digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
265 }
266#endif
267 } else {
268 digit = window_val; /* 0 < digit < 2^w */
269 }
270
271 if (digit <= -bit || digit >= bit || !(digit & 1)) {
272 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
273 goto err;
274 }
275 window_val -= digit;
276
277 /*
278 * now window_val is 0 or 2^(w+1) in standard wNAF
279 * generation; for modified window NAFs, it may also
280 * be 2^w
281 */
282 if (window_val != 0 && window_val != next_bit && window_val != bit) {
283 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
284 goto err;
285 }
286 }
287 r[j++] = sign * digit;
288
289 window_val >>= 1;
290 window_val += bit * BN_is_bit_set(scalar, j + w);
291
292 if (window_val > next_bit) {
293 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
294 goto err;
295 }
296 }
297
298 if (j > len + 1) {
299 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
300 goto err;
301 }
302 len = j;
303 ok = 1;
304
305err:
306 if (!ok) {
307 free(r);
308 r = NULL;
309 }
310 if (ok)
311 *ret_len = len;
312 return r;
313}
314
315
316/* TODO: table should be optimised for the wNAF-based implementation,
317 * sometimes smaller windows will give better performance
318 * (thus the boundaries should be increased)
319 */
320#define EC_window_bits_for_scalar_size(b) \
321 ((size_t) \
322 ((b) >= 2000 ? 6 : \
323 (b) >= 800 ? 5 : \
324 (b) >= 300 ? 4 : \
325 (b) >= 70 ? 3 : \
326 (b) >= 20 ? 2 : \
327 1))
328
329/* Compute
330 * \sum scalars[i]*points[i],
331 * also including
332 * scalar*generator
333 * in the addition if scalar != NULL
334 */
335int
336ec_wNAF_mul(const EC_GROUP * group, EC_POINT * r, const BIGNUM * scalar,
337 size_t num, const EC_POINT * points[], const BIGNUM * scalars[], BN_CTX * ctx)
338{
339 BN_CTX *new_ctx = NULL;
340 const EC_POINT *generator = NULL;
341 EC_POINT *tmp = NULL;
342 size_t totalnum;
343 size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
344 size_t pre_points_per_block = 0;
345 size_t i, j;
346 int k;
347 int r_is_inverted = 0;
348 int r_is_at_infinity = 1;
349 size_t *wsize = NULL; /* individual window sizes */
350 signed char **wNAF = NULL; /* individual wNAFs */
351 signed char *tmp_wNAF = NULL;
352 size_t *wNAF_len = NULL;
353 size_t max_len = 0;
354 size_t num_val;
355 EC_POINT **val = NULL; /* precomputation */
356 EC_POINT **v;
357 EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or
358 * 'pre_comp->points' */
359 const EC_PRE_COMP *pre_comp = NULL;
360 int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be
361 * treated like other scalars, i.e.
362 * precomputation is not available */
363 int ret = 0;
364
365 if (group->meth != r->meth) {
366 ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
367 return 0;
368 }
369 if ((scalar == NULL) && (num == 0)) {
370 return EC_POINT_set_to_infinity(group, r);
371 }
372 for (i = 0; i < num; i++) {
373 if (group->meth != points[i]->meth) {
374 ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
375 return 0;
376 }
377 }
378
379 if (ctx == NULL) {
380 ctx = new_ctx = BN_CTX_new();
381 if (ctx == NULL)
382 goto err;
383 }
384 if (scalar != NULL) {
385 generator = EC_GROUP_get0_generator(group);
386 if (generator == NULL) {
387 ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
388 goto err;
389 }
390 /* look if we can use precomputed multiples of generator */
391
392 pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
393
394 if (pre_comp && pre_comp->numblocks &&
395 (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) {
396 blocksize = pre_comp->blocksize;
397
398 /*
399 * determine maximum number of blocks that wNAF
400 * splitting may yield (NB: maximum wNAF length is
401 * bit length plus one)
402 */
403 numblocks = (BN_num_bits(scalar) / blocksize) + 1;
404
405 /*
406 * we cannot use more blocks than we have
407 * precomputation for
408 */
409 if (numblocks > pre_comp->numblocks)
410 numblocks = pre_comp->numblocks;
411
412 pre_points_per_block = (size_t) 1 << (pre_comp->w - 1);
413
414 /* check that pre_comp looks sane */
415 if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
416 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
417 goto err;
418 }
419 } else {
420 /* can't use precomputation */
421 pre_comp = NULL;
422 numblocks = 1;
423 num_scalar = 1; /* treat 'scalar' like 'num'-th
424 * element of 'scalars' */
425 }
426 }
427 totalnum = num + numblocks;
428
429 /* includes space for pivot */
430 wNAF = reallocarray(NULL, (totalnum + 1), sizeof wNAF[0]);
431 if (wNAF == NULL) {
432 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
433 goto err;
434 }
435
436 wNAF[0] = NULL; /* preliminary pivot */
437
438 wsize = reallocarray(NULL, totalnum, sizeof wsize[0]);
439 wNAF_len = reallocarray(NULL, totalnum, sizeof wNAF_len[0]);
440 val_sub = reallocarray(NULL, totalnum, sizeof val_sub[0]);
441
442 if (wsize == NULL || wNAF_len == NULL || val_sub == NULL) {
443 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
444 goto err;
445 }
446
447 /* num_val will be the total number of temporarily precomputed points */
448 num_val = 0;
449
450 for (i = 0; i < num + num_scalar; i++) {
451 size_t bits;
452
453 bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
454 wsize[i] = EC_window_bits_for_scalar_size(bits);
455 num_val += (size_t) 1 << (wsize[i] - 1);
456 wNAF[i + 1] = NULL; /* make sure we always have a pivot */
457 wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
458 if (wNAF[i] == NULL)
459 goto err;
460 if (wNAF_len[i] > max_len)
461 max_len = wNAF_len[i];
462 }
463
464 if (numblocks) {
465 /* we go here iff scalar != NULL */
466
467 if (pre_comp == NULL) {
468 if (num_scalar != 1) {
469 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
470 goto err;
471 }
472 /* we have already generated a wNAF for 'scalar' */
473 } else {
474 size_t tmp_len = 0;
475
476 if (num_scalar != 0) {
477 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
478 goto err;
479 }
480 /*
481 * use the window size for which we have
482 * precomputation
483 */
484 wsize[num] = pre_comp->w;
485 tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
486 if (tmp_wNAF == NULL)
487 goto err;
488
489 if (tmp_len <= max_len) {
490 /*
491 * One of the other wNAFs is at least as long
492 * as the wNAF belonging to the generator, so
493 * wNAF splitting will not buy us anything.
494 */
495
496 numblocks = 1;
497 totalnum = num + 1; /* don't use wNAF
498 * splitting */
499 wNAF[num] = tmp_wNAF;
500 tmp_wNAF = NULL;
501 wNAF[num + 1] = NULL;
502 wNAF_len[num] = tmp_len;
503 if (tmp_len > max_len)
504 max_len = tmp_len;
505 /*
506 * pre_comp->points starts with the points
507 * that we need here:
508 */
509 val_sub[num] = pre_comp->points;
510 } else {
511 /*
512 * don't include tmp_wNAF directly into wNAF
513 * array - use wNAF splitting and include the
514 * blocks
515 */
516
517 signed char *pp;
518 EC_POINT **tmp_points;
519
520 if (tmp_len < numblocks * blocksize) {
521 /*
522 * possibly we can do with fewer
523 * blocks than estimated
524 */
525 numblocks = (tmp_len + blocksize - 1) / blocksize;
526 if (numblocks > pre_comp->numblocks) {
527 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
528 goto err;
529 }
530 totalnum = num + numblocks;
531 }
532 /* split wNAF in 'numblocks' parts */
533 pp = tmp_wNAF;
534 tmp_points = pre_comp->points;
535
536 for (i = num; i < totalnum; i++) {
537 if (i < totalnum - 1) {
538 wNAF_len[i] = blocksize;
539 if (tmp_len < blocksize) {
540 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
541 goto err;
542 }
543 tmp_len -= blocksize;
544 } else
545 /*
546 * last block gets whatever
547 * is left (this could be
548 * more or less than
549 * 'blocksize'!)
550 */
551 wNAF_len[i] = tmp_len;
552
553 wNAF[i + 1] = NULL;
554 wNAF[i] = malloc(wNAF_len[i]);
555 if (wNAF[i] == NULL) {
556 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
557 goto err;
558 }
559 memcpy(wNAF[i], pp, wNAF_len[i]);
560 if (wNAF_len[i] > max_len)
561 max_len = wNAF_len[i];
562
563 if (*tmp_points == NULL) {
564 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
565 goto err;
566 }
567 val_sub[i] = tmp_points;
568 tmp_points += pre_points_per_block;
569 pp += blocksize;
570 }
571 }
572 }
573 }
574 /*
575 * All points we precompute now go into a single array 'val'.
576 * 'val_sub[i]' is a pointer to the subarray for the i-th point, or
577 * to a subarray of 'pre_comp->points' if we already have
578 * precomputation.
579 */
580 val = reallocarray(NULL, (num_val + 1), sizeof val[0]);
581 if (val == NULL) {
582 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
583 goto err;
584 }
585 val[num_val] = NULL; /* pivot element */
586
587 /* allocate points for precomputation */
588 v = val;
589 for (i = 0; i < num + num_scalar; i++) {
590 val_sub[i] = v;
591 for (j = 0; j < ((size_t) 1 << (wsize[i] - 1)); j++) {
592 *v = EC_POINT_new(group);
593 if (*v == NULL)
594 goto err;
595 v++;
596 }
597 }
598 if (!(v == val + num_val)) {
599 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
600 goto err;
601 }
602 if (!(tmp = EC_POINT_new(group)))
603 goto err;
604
605 /*
606 * prepare precomputed values: val_sub[i][0] := points[i]
607 * val_sub[i][1] := 3 * points[i] val_sub[i][2] := 5 * points[i] ...
608 */
609 for (i = 0; i < num + num_scalar; i++) {
610 if (i < num) {
611 if (!EC_POINT_copy(val_sub[i][0], points[i]))
612 goto err;
613 } else {
614 if (!EC_POINT_copy(val_sub[i][0], generator))
615 goto err;
616 }
617
618 if (wsize[i] > 1) {
619 if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))
620 goto err;
621 for (j = 1; j < ((size_t) 1 << (wsize[i] - 1)); j++) {
622 if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))
623 goto err;
624 }
625 }
626 }
627
628 if (!EC_POINTs_make_affine(group, num_val, val, ctx))
629 goto err;
630
631 r_is_at_infinity = 1;
632
633 for (k = max_len - 1; k >= 0; k--) {
634 if (!r_is_at_infinity) {
635 if (!EC_POINT_dbl(group, r, r, ctx))
636 goto err;
637 }
638 for (i = 0; i < totalnum; i++) {
639 if (wNAF_len[i] > (size_t) k) {
640 int digit = wNAF[i][k];
641 int is_neg;
642
643 if (digit) {
644 is_neg = digit < 0;
645
646 if (is_neg)
647 digit = -digit;
648
649 if (is_neg != r_is_inverted) {
650 if (!r_is_at_infinity) {
651 if (!EC_POINT_invert(group, r, ctx))
652 goto err;
653 }
654 r_is_inverted = !r_is_inverted;
655 }
656 /* digit > 0 */
657
658 if (r_is_at_infinity) {
659 if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
660 goto err;
661 r_is_at_infinity = 0;
662 } else {
663 if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx))
664 goto err;
665 }
666 }
667 }
668 }
669 }
670
671 if (r_is_at_infinity) {
672 if (!EC_POINT_set_to_infinity(group, r))
673 goto err;
674 } else {
675 if (r_is_inverted)
676 if (!EC_POINT_invert(group, r, ctx))
677 goto err;
678 }
679
680 ret = 1;
681
682err:
683 BN_CTX_free(new_ctx);
684 EC_POINT_free(tmp);
685 free(wsize);
686 free(wNAF_len);
687 free(tmp_wNAF);
688 if (wNAF != NULL) {
689 signed char **w;
690
691 for (w = wNAF; *w != NULL; w++)
692 free(*w);
693
694 free(wNAF);
695 }
696 if (val != NULL) {
697 for (v = val; *v != NULL; v++)
698 EC_POINT_clear_free(*v);
699 free(val);
700 }
701 free(val_sub);
702 return ret;
703}
704
705
706/* ec_wNAF_precompute_mult()
707 * creates an EC_PRE_COMP object with preprecomputed multiples of the generator
708 * for use with wNAF splitting as implemented in ec_wNAF_mul().
709 *
710 * 'pre_comp->points' is an array of multiples of the generator
711 * of the following form:
712 * points[0] = generator;
713 * points[1] = 3 * generator;
714 * ...
715 * points[2^(w-1)-1] = (2^(w-1)-1) * generator;
716 * points[2^(w-1)] = 2^blocksize * generator;
717 * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
718 * ...
719 * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator
720 * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator
721 * ...
722 * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator
723 * points[2^(w-1)*numblocks] = NULL
724 */
725int
726ec_wNAF_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
727{
728 const EC_POINT *generator;
729 EC_POINT *tmp_point = NULL, *base = NULL, **var;
730 BN_CTX *new_ctx = NULL;
731 BIGNUM *order;
732 size_t i, bits, w, pre_points_per_block, blocksize, numblocks,
733 num;
734 EC_POINT **points = NULL;
735 EC_PRE_COMP *pre_comp;
736 int ret = 0;
737
738 /* if there is an old EC_PRE_COMP object, throw it away */
739 EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
740
741 if ((pre_comp = ec_pre_comp_new(group)) == NULL)
742 return 0;
743
744 generator = EC_GROUP_get0_generator(group);
745 if (generator == NULL) {
746 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
747 goto err;
748 }
749 if (ctx == NULL) {
750 ctx = new_ctx = BN_CTX_new();
751 if (ctx == NULL)
752 goto err;
753 }
754 BN_CTX_start(ctx);
755 if ((order = BN_CTX_get(ctx)) == NULL)
756 goto err;
757
758 if (!EC_GROUP_get_order(group, order, ctx))
759 goto err;
760 if (BN_is_zero(order)) {
761 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
762 goto err;
763 }
764 bits = BN_num_bits(order);
765 /*
766 * The following parameters mean we precompute (approximately) one
767 * point per bit.
768 *
769 * TBD: The combination 8, 4 is perfect for 160 bits; for other bit
770 * lengths, other parameter combinations might provide better
771 * efficiency.
772 */
773 blocksize = 8;
774 w = 4;
775 if (EC_window_bits_for_scalar_size(bits) > w) {
776 /* let's not make the window too small ... */
777 w = EC_window_bits_for_scalar_size(bits);
778 }
779 numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks
780 * to use for wNAF
781 * splitting */
782
783 pre_points_per_block = (size_t) 1 << (w - 1);
784 num = pre_points_per_block * numblocks; /* number of points to
785 * compute and store */
786
787 points = reallocarray(NULL, (num + 1), sizeof(EC_POINT *));
788 if (!points) {
789 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
790 goto err;
791 }
792 var = points;
793 var[num] = NULL; /* pivot */
794 for (i = 0; i < num; i++) {
795 if ((var[i] = EC_POINT_new(group)) == NULL) {
796 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
797 goto err;
798 }
799 }
800
801 if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
802 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
803 goto err;
804 }
805 if (!EC_POINT_copy(base, generator))
806 goto err;
807
808 /* do the precomputation */
809 for (i = 0; i < numblocks; i++) {
810 size_t j;
811
812 if (!EC_POINT_dbl(group, tmp_point, base, ctx))
813 goto err;
814
815 if (!EC_POINT_copy(*var++, base))
816 goto err;
817
818 for (j = 1; j < pre_points_per_block; j++, var++) {
819 /* calculate odd multiples of the current base point */
820 if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
821 goto err;
822 }
823
824 if (i < numblocks - 1) {
825 /*
826 * get the next base (multiply current one by
827 * 2^blocksize)
828 */
829 size_t k;
830
831 if (blocksize <= 2) {
832 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
833 goto err;
834 }
835 if (!EC_POINT_dbl(group, base, tmp_point, ctx))
836 goto err;
837 for (k = 2; k < blocksize; k++) {
838 if (!EC_POINT_dbl(group, base, base, ctx))
839 goto err;
840 }
841 }
842 }
843
844 if (!EC_POINTs_make_affine(group, num, points, ctx))
845 goto err;
846
847 pre_comp->group = group;
848 pre_comp->blocksize = blocksize;
849 pre_comp->numblocks = numblocks;
850 pre_comp->w = w;
851 pre_comp->points = points;
852 points = NULL;
853 pre_comp->num = num;
854
855 if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
856 ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free))
857 goto err;
858 pre_comp = NULL;
859
860 ret = 1;
861err:
862 if (ctx != NULL)
863 BN_CTX_end(ctx);
864 BN_CTX_free(new_ctx);
865 ec_pre_comp_free(pre_comp);
866 if (points) {
867 EC_POINT **p;
868
869 for (p = points; *p != NULL; p++)
870 EC_POINT_free(*p);
871 free(points);
872 }
873 EC_POINT_free(tmp_point);
874 EC_POINT_free(base);
875 return ret;
876}
877
878
879int
880ec_wNAF_have_precompute_mult(const EC_GROUP * group)
881{
882 if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)
883 return 1;
884 else
885 return 0;
886}
diff --git a/src/lib/libcrypto/ec/ec_oct.c b/src/lib/libcrypto/ec/ec_oct.c
deleted file mode 100644
index 82124a8f80..0000000000
--- a/src/lib/libcrypto/ec/ec_oct.c
+++ /dev/null
@@ -1,192 +0,0 @@
1/* $OpenBSD: ec_oct.c,v 1.4 2014/07/10 22:45:57 jsing Exp $ */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2003 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 * Binary polynomial ECC support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65
66#include <openssl/opensslconf.h>
67
68#include <openssl/err.h>
69#include <openssl/opensslv.h>
70
71#include "ec_lcl.h"
72
73int
74EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP * group, EC_POINT * point,
75 const BIGNUM * x, int y_bit, BN_CTX * ctx)
76{
77 if (group->meth->point_set_compressed_coordinates == 0
78 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
79 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
80 return 0;
81 }
82 if (group->meth != point->meth) {
83 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
84 return 0;
85 }
86 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
87 if (group->meth->field_type == NID_X9_62_prime_field)
88 return ec_GFp_simple_set_compressed_coordinates(
89 group, point, x, y_bit, ctx);
90 else
91#ifdef OPENSSL_NO_EC2M
92 {
93 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_GF2M_NOT_SUPPORTED);
94 return 0;
95 }
96#else
97 return ec_GF2m_simple_set_compressed_coordinates(
98 group, point, x, y_bit, ctx);
99#endif
100 }
101 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
102}
103
104#ifndef OPENSSL_NO_EC2M
105int
106EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP * group, EC_POINT * point,
107 const BIGNUM * x, int y_bit, BN_CTX * ctx)
108{
109 if (group->meth->point_set_compressed_coordinates == 0
110 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
111 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
112 return 0;
113 }
114 if (group->meth != point->meth) {
115 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
116 return 0;
117 }
118 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
119 if (group->meth->field_type == NID_X9_62_prime_field)
120 return ec_GFp_simple_set_compressed_coordinates(
121 group, point, x, y_bit, ctx);
122 else
123 return ec_GF2m_simple_set_compressed_coordinates(
124 group, point, x, y_bit, ctx);
125 }
126 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
127}
128#endif
129
130size_t
131EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
132 point_conversion_form_t form,
133 unsigned char *buf, size_t len, BN_CTX *ctx)
134{
135 if (group->meth->point2oct == 0
136 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
137 ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
138 return 0;
139 }
140 if (group->meth != point->meth) {
141 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
142 return 0;
143 }
144 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
145 if (group->meth->field_type == NID_X9_62_prime_field)
146 return ec_GFp_simple_point2oct(group, point,
147 form, buf, len, ctx);
148 else
149#ifdef OPENSSL_NO_EC2M
150 {
151 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
152 return 0;
153 }
154#else
155 return ec_GF2m_simple_point2oct(group, point,
156 form, buf, len, ctx);
157#endif
158 }
159 return group->meth->point2oct(group, point, form, buf, len, ctx);
160}
161
162
163int
164EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
165 const unsigned char *buf, size_t len, BN_CTX *ctx)
166{
167 if (group->meth->oct2point == 0 &&
168 !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
169 ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
170 return 0;
171 }
172 if (group->meth != point->meth) {
173 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
174 return 0;
175 }
176 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
177 if (group->meth->field_type == NID_X9_62_prime_field)
178 return ec_GFp_simple_oct2point(group, point,
179 buf, len, ctx);
180 else
181#ifdef OPENSSL_NO_EC2M
182 {
183 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
184 return 0;
185 }
186#else
187 return ec_GF2m_simple_oct2point(group, point,
188 buf, len, ctx);
189#endif
190 }
191 return group->meth->oct2point(group, point, buf, len, ctx);
192}
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c
deleted file mode 100644
index a52bff1f2f..0000000000
--- a/src/lib/libcrypto/ec/ec_pmeth.c
+++ /dev/null
@@ -1,323 +0,0 @@
1/* $OpenBSD: ec_pmeth.c,v 1.9 2015/06/20 14:19:39 jsing Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 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 * licensing@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#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1t.h>
63#include <openssl/ec.h>
64#include <openssl/ecdsa.h>
65#include <openssl/err.h>
66#include <openssl/evp.h>
67#include <openssl/x509.h>
68
69#include "evp_locl.h"
70
71/* EC pkey context structure */
72
73typedef struct {
74 /* Key and paramgen group */
75 EC_GROUP *gen_group;
76 /* message digest */
77 const EVP_MD *md;
78} EC_PKEY_CTX;
79
80static int
81pkey_ec_init(EVP_PKEY_CTX * ctx)
82{
83 EC_PKEY_CTX *dctx;
84 dctx = malloc(sizeof(EC_PKEY_CTX));
85 if (!dctx)
86 return 0;
87 dctx->gen_group = NULL;
88 dctx->md = NULL;
89
90 ctx->data = dctx;
91
92 return 1;
93}
94
95static int
96pkey_ec_copy(EVP_PKEY_CTX * dst, EVP_PKEY_CTX * src)
97{
98 EC_PKEY_CTX *dctx, *sctx;
99 if (!pkey_ec_init(dst))
100 return 0;
101 sctx = src->data;
102 dctx = dst->data;
103 if (sctx->gen_group) {
104 dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
105 if (!dctx->gen_group)
106 return 0;
107 }
108 dctx->md = sctx->md;
109 return 1;
110}
111
112static void
113pkey_ec_cleanup(EVP_PKEY_CTX * ctx)
114{
115 EC_PKEY_CTX *dctx = ctx->data;
116 if (dctx) {
117 EC_GROUP_free(dctx->gen_group);
118 free(dctx);
119 }
120}
121
122static int
123pkey_ec_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, size_t * siglen,
124 const unsigned char *tbs, size_t tbslen)
125{
126 int ret, type;
127 unsigned int sltmp;
128 EC_PKEY_CTX *dctx = ctx->data;
129 EC_KEY *ec = ctx->pkey->pkey.ec;
130
131 if (!sig) {
132 *siglen = ECDSA_size(ec);
133 return 1;
134 } else if (*siglen < (size_t) ECDSA_size(ec)) {
135 ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
136 return 0;
137 }
138 if (dctx->md)
139 type = EVP_MD_type(dctx->md);
140 else
141 type = NID_sha1;
142
143
144 ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
145
146 if (ret <= 0)
147 return ret;
148 *siglen = (size_t) sltmp;
149 return 1;
150}
151
152static int
153pkey_ec_verify(EVP_PKEY_CTX * ctx,
154 const unsigned char *sig, size_t siglen,
155 const unsigned char *tbs, size_t tbslen)
156{
157 int ret, type;
158 EC_PKEY_CTX *dctx = ctx->data;
159 EC_KEY *ec = ctx->pkey->pkey.ec;
160
161 if (dctx->md)
162 type = EVP_MD_type(dctx->md);
163 else
164 type = NID_sha1;
165
166 ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
167
168 return ret;
169}
170
171static int
172pkey_ec_derive(EVP_PKEY_CTX * ctx, unsigned char *key, size_t * keylen)
173{
174 int ret;
175 size_t outlen;
176 const EC_POINT *pubkey = NULL;
177 if (!ctx->pkey || !ctx->peerkey) {
178 ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
179 return 0;
180 }
181 if (!key) {
182 const EC_GROUP *group;
183 group = EC_KEY_get0_group(ctx->pkey->pkey.ec);
184 *keylen = (EC_GROUP_get_degree(group) + 7) / 8;
185 return 1;
186 }
187 pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
188
189 /*
190 * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
191 * not an error, the result is truncated.
192 */
193
194 outlen = *keylen;
195
196 ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0);
197 if (ret < 0)
198 return ret;
199 *keylen = ret;
200 return 1;
201}
202
203static int
204pkey_ec_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2)
205{
206 EC_PKEY_CTX *dctx = ctx->data;
207 EC_GROUP *group;
208 switch (type) {
209 case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
210 group = EC_GROUP_new_by_curve_name(p1);
211 if (group == NULL) {
212 ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
213 return 0;
214 }
215 EC_GROUP_free(dctx->gen_group);
216 dctx->gen_group = group;
217 return 1;
218
219 case EVP_PKEY_CTRL_MD:
220 if (EVP_MD_type((const EVP_MD *) p2) != NID_sha1 &&
221 EVP_MD_type((const EVP_MD *) p2) != NID_ecdsa_with_SHA1 &&
222 EVP_MD_type((const EVP_MD *) p2) != NID_sha224 &&
223 EVP_MD_type((const EVP_MD *) p2) != NID_sha256 &&
224 EVP_MD_type((const EVP_MD *) p2) != NID_sha384 &&
225 EVP_MD_type((const EVP_MD *) p2) != NID_sha512) {
226 ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
227 return 0;
228 }
229 dctx->md = p2;
230 return 1;
231
232 case EVP_PKEY_CTRL_PEER_KEY:
233 /* Default behaviour is OK */
234 case EVP_PKEY_CTRL_DIGESTINIT:
235 case EVP_PKEY_CTRL_PKCS7_SIGN:
236 case EVP_PKEY_CTRL_CMS_SIGN:
237 return 1;
238
239 default:
240 return -2;
241
242 }
243}
244
245static int
246pkey_ec_ctrl_str(EVP_PKEY_CTX * ctx,
247 const char *type, const char *value)
248{
249 if (!strcmp(type, "ec_paramgen_curve")) {
250 int nid;
251 nid = EC_curve_nist2nid(value);
252 if (nid == NID_undef)
253 nid = OBJ_sn2nid(value);
254 if (nid == NID_undef)
255 nid = OBJ_ln2nid(value);
256 if (nid == NID_undef) {
257 ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
258 return 0;
259 }
260 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
261 }
262 return -2;
263}
264
265static int
266pkey_ec_paramgen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey)
267{
268 EC_KEY *ec = NULL;
269 EC_PKEY_CTX *dctx = ctx->data;
270 int ret = 0;
271 if (dctx->gen_group == NULL) {
272 ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
273 return 0;
274 }
275 ec = EC_KEY_new();
276 if (!ec)
277 return 0;
278 ret = EC_KEY_set_group(ec, dctx->gen_group);
279 if (ret)
280 EVP_PKEY_assign_EC_KEY(pkey, ec);
281 else
282 EC_KEY_free(ec);
283 return ret;
284}
285
286static int
287pkey_ec_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey)
288{
289 EC_KEY *ec = NULL;
290 if (ctx->pkey == NULL) {
291 ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
292 return 0;
293 }
294 ec = EC_KEY_new();
295 if (!ec)
296 return 0;
297 EVP_PKEY_assign_EC_KEY(pkey, ec);
298 /* Note: if error return, pkey is freed by parent routine */
299 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
300 return 0;
301 return EC_KEY_generate_key(pkey->pkey.ec);
302}
303
304const EVP_PKEY_METHOD ec_pkey_meth = {
305 .pkey_id = EVP_PKEY_EC,
306
307 .init = pkey_ec_init,
308 .copy = pkey_ec_copy,
309 .cleanup = pkey_ec_cleanup,
310
311 .paramgen = pkey_ec_paramgen,
312
313 .keygen = pkey_ec_keygen,
314
315 .sign = pkey_ec_sign,
316
317 .verify = pkey_ec_verify,
318
319 .derive = pkey_ec_derive,
320
321 .ctrl = pkey_ec_ctrl,
322 .ctrl_str = pkey_ec_ctrl_str
323};
diff --git a/src/lib/libcrypto/ec/ec_print.c b/src/lib/libcrypto/ec/ec_print.c
deleted file mode 100644
index af4d1996c0..0000000000
--- a/src/lib/libcrypto/ec/ec_print.c
+++ /dev/null
@@ -1,178 +0,0 @@
1/* $OpenBSD: ec_print.c,v 1.7 2014/12/03 19:53:20 deraadt Exp $ */
2/* ====================================================================
3 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/crypto.h>
57#include "ec_lcl.h"
58
59BIGNUM *
60EC_POINT_point2bn(const EC_GROUP * group, const EC_POINT * point,
61 point_conversion_form_t form, BIGNUM * ret, BN_CTX * ctx)
62{
63 size_t buf_len = 0;
64 unsigned char *buf;
65
66 buf_len = EC_POINT_point2oct(group, point, form,
67 NULL, 0, ctx);
68 if (buf_len == 0)
69 return NULL;
70
71 if ((buf = malloc(buf_len)) == NULL)
72 return NULL;
73
74 if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
75 free(buf);
76 return NULL;
77 }
78 ret = BN_bin2bn(buf, buf_len, ret);
79
80 free(buf);
81
82 return ret;
83}
84
85EC_POINT *
86EC_POINT_bn2point(const EC_GROUP * group,
87 const BIGNUM * bn, EC_POINT * point, BN_CTX * ctx)
88{
89 size_t buf_len = 0;
90 unsigned char *buf;
91 EC_POINT *ret;
92
93 if ((buf_len = BN_num_bytes(bn)) == 0)
94 return NULL;
95 buf = malloc(buf_len);
96 if (buf == NULL)
97 return NULL;
98
99 if (!BN_bn2bin(bn, buf)) {
100 free(buf);
101 return NULL;
102 }
103 if (point == NULL) {
104 if ((ret = EC_POINT_new(group)) == NULL) {
105 free(buf);
106 return NULL;
107 }
108 } else
109 ret = point;
110
111 if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
112 if (point == NULL)
113 EC_POINT_clear_free(ret);
114 free(buf);
115 return NULL;
116 }
117 free(buf);
118 return ret;
119}
120
121static const char *HEX_DIGITS = "0123456789ABCDEF";
122
123/* the return value must be freed (using free()) */
124char *
125EC_POINT_point2hex(const EC_GROUP * group, const EC_POINT * point,
126 point_conversion_form_t form, BN_CTX * ctx)
127{
128 char *ret, *p;
129 size_t buf_len = 0, i;
130 unsigned char *buf, *pbuf;
131
132 buf_len = EC_POINT_point2oct(group, point, form,
133 NULL, 0, ctx);
134 if (buf_len == 0 || buf_len + 1 == 0)
135 return NULL;
136
137 if ((buf = malloc(buf_len)) == NULL)
138 return NULL;
139
140 if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
141 free(buf);
142 return NULL;
143 }
144 ret = reallocarray(NULL, buf_len + 1, 2);
145 if (ret == NULL) {
146 free(buf);
147 return NULL;
148 }
149 p = ret;
150 pbuf = buf;
151 for (i = buf_len; i > 0; i--) {
152 int v = (int) *(pbuf++);
153 *(p++) = HEX_DIGITS[v >> 4];
154 *(p++) = HEX_DIGITS[v & 0x0F];
155 }
156 *p = '\0';
157
158 free(buf);
159
160 return ret;
161}
162
163EC_POINT *
164EC_POINT_hex2point(const EC_GROUP * group, const char *buf,
165 EC_POINT * point, BN_CTX * ctx)
166{
167 EC_POINT *ret = NULL;
168 BIGNUM *tmp_bn = NULL;
169
170 if (!BN_hex2bn(&tmp_bn, buf))
171 return NULL;
172
173 ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
174
175 BN_clear_free(tmp_bn);
176
177 return ret;
178}
diff --git a/src/lib/libcrypto/ec/eck_prn.c b/src/lib/libcrypto/ec/eck_prn.c
deleted file mode 100644
index 06cdd69591..0000000000
--- a/src/lib/libcrypto/ec/eck_prn.c
+++ /dev/null
@@ -1,371 +0,0 @@
1/* $OpenBSD: eck_prn.c,v 1.11 2015/06/20 14:17:07 jsing Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2005 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 * Portions originally developed by SUN MICROSYSTEMS, INC., and
61 * contributed to the OpenSSL project.
62 */
63
64#include <stdio.h>
65#include <string.h>
66
67#include <openssl/opensslconf.h>
68
69#include <openssl/bn.h>
70#include <openssl/ec.h>
71#include <openssl/err.h>
72#include <openssl/evp.h>
73
74int
75ECPKParameters_print_fp(FILE * fp, const EC_GROUP * x, int off)
76{
77 BIO *b;
78 int ret;
79
80 if ((b = BIO_new(BIO_s_file())) == NULL) {
81 ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
82 return (0);
83 }
84 BIO_set_fp(b, fp, BIO_NOCLOSE);
85 ret = ECPKParameters_print(b, x, off);
86 BIO_free(b);
87 return (ret);
88}
89
90int
91EC_KEY_print_fp(FILE * fp, const EC_KEY * x, int off)
92{
93 BIO *b;
94 int ret;
95
96 if ((b = BIO_new(BIO_s_file())) == NULL) {
97 ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
98 return (0);
99 }
100 BIO_set_fp(b, fp, BIO_NOCLOSE);
101 ret = EC_KEY_print(b, x, off);
102 BIO_free(b);
103 return (ret);
104}
105
106int
107ECParameters_print_fp(FILE * fp, const EC_KEY * x)
108{
109 BIO *b;
110 int ret;
111
112 if ((b = BIO_new(BIO_s_file())) == NULL) {
113 ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
114 return (0);
115 }
116 BIO_set_fp(b, fp, BIO_NOCLOSE);
117 ret = ECParameters_print(b, x);
118 BIO_free(b);
119 return (ret);
120}
121
122int
123EC_KEY_print(BIO * bp, const EC_KEY * x, int off)
124{
125 EVP_PKEY *pk;
126 int ret;
127 pk = EVP_PKEY_new();
128 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *) x))
129 return 0;
130 ret = EVP_PKEY_print_private(bp, pk, off, NULL);
131 EVP_PKEY_free(pk);
132 return ret;
133}
134
135int
136ECParameters_print(BIO * bp, const EC_KEY * x)
137{
138 EVP_PKEY *pk;
139 int ret;
140 pk = EVP_PKEY_new();
141 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *) x))
142 return 0;
143 ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
144 EVP_PKEY_free(pk);
145 return ret;
146}
147
148static int
149print_bin(BIO * fp, const char *str, const unsigned char *num,
150 size_t len, int off);
151
152int
153ECPKParameters_print(BIO * bp, const EC_GROUP * x, int off)
154{
155 unsigned char *buffer = NULL;
156 size_t buf_len = 0, i;
157 int ret = 0, reason = ERR_R_BIO_LIB;
158 BN_CTX *ctx = NULL;
159 const EC_POINT *point = NULL;
160 BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, *order = NULL,
161 *cofactor = NULL;
162 const unsigned char *seed;
163 size_t seed_len = 0;
164 const char *nname;
165
166 static const char *gen_compressed = "Generator (compressed):";
167 static const char *gen_uncompressed = "Generator (uncompressed):";
168 static const char *gen_hybrid = "Generator (hybrid):";
169
170 if (!x) {
171 reason = ERR_R_PASSED_NULL_PARAMETER;
172 goto err;
173 }
174 ctx = BN_CTX_new();
175 if (ctx == NULL) {
176 reason = ERR_R_MALLOC_FAILURE;
177 goto err;
178 }
179 if (EC_GROUP_get_asn1_flag(x)) {
180 /* the curve parameter are given by an asn1 OID */
181 int nid;
182
183 if (!BIO_indent(bp, off, 128))
184 goto err;
185
186 nid = EC_GROUP_get_curve_name(x);
187 if (nid == 0)
188 goto err;
189
190 if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
191 goto err;
192 if (BIO_printf(bp, "\n") <= 0)
193 goto err;
194
195 nname = EC_curve_nid2nist(nid);
196 if (nname) {
197 if (!BIO_indent(bp, off, 128))
198 goto err;
199 if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0)
200 goto err;
201 }
202 } else {
203 /* explicit parameters */
204 int is_char_two = 0;
205 point_conversion_form_t form;
206 int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
207
208 if (tmp_nid == NID_X9_62_characteristic_two_field)
209 is_char_two = 1;
210
211 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
212 (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
213 (cofactor = BN_new()) == NULL) {
214 reason = ERR_R_MALLOC_FAILURE;
215 goto err;
216 }
217#ifndef OPENSSL_NO_EC2M
218 if (is_char_two) {
219 if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
220 reason = ERR_R_EC_LIB;
221 goto err;
222 }
223 } else /* prime field */
224#endif
225 {
226 if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
227 reason = ERR_R_EC_LIB;
228 goto err;
229 }
230 }
231
232 if ((point = EC_GROUP_get0_generator(x)) == NULL) {
233 reason = ERR_R_EC_LIB;
234 goto err;
235 }
236 if (!EC_GROUP_get_order(x, order, NULL) ||
237 !EC_GROUP_get_cofactor(x, cofactor, NULL)) {
238 reason = ERR_R_EC_LIB;
239 goto err;
240 }
241 form = EC_GROUP_get_point_conversion_form(x);
242
243 if ((gen = EC_POINT_point2bn(x, point,
244 form, NULL, ctx)) == NULL) {
245 reason = ERR_R_EC_LIB;
246 goto err;
247 }
248 buf_len = (size_t) BN_num_bytes(p);
249 if (buf_len < (i = (size_t) BN_num_bytes(a)))
250 buf_len = i;
251 if (buf_len < (i = (size_t) BN_num_bytes(b)))
252 buf_len = i;
253 if (buf_len < (i = (size_t) BN_num_bytes(gen)))
254 buf_len = i;
255 if (buf_len < (i = (size_t) BN_num_bytes(order)))
256 buf_len = i;
257 if (buf_len < (i = (size_t) BN_num_bytes(cofactor)))
258 buf_len = i;
259
260 if ((seed = EC_GROUP_get0_seed(x)) != NULL)
261 seed_len = EC_GROUP_get_seed_len(x);
262
263 buf_len += 10;
264 if ((buffer = malloc(buf_len)) == NULL) {
265 reason = ERR_R_MALLOC_FAILURE;
266 goto err;
267 }
268 if (!BIO_indent(bp, off, 128))
269 goto err;
270
271 /* print the 'short name' of the field type */
272 if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
273 <= 0)
274 goto err;
275
276 if (is_char_two) {
277 /* print the 'short name' of the base type OID */
278 int basis_type = EC_GROUP_get_basis_type(x);
279 if (basis_type == 0)
280 goto err;
281
282 if (!BIO_indent(bp, off, 128))
283 goto err;
284
285 if (BIO_printf(bp, "Basis Type: %s\n",
286 OBJ_nid2sn(basis_type)) <= 0)
287 goto err;
288
289 /* print the polynomial */
290 if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
291 off))
292 goto err;
293 } else {
294 if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off))
295 goto err;
296 }
297 if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
298 goto err;
299 if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
300 goto err;
301 if (form == POINT_CONVERSION_COMPRESSED) {
302 if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
303 buffer, off))
304 goto err;
305 } else if (form == POINT_CONVERSION_UNCOMPRESSED) {
306 if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
307 buffer, off))
308 goto err;
309 } else { /* form == POINT_CONVERSION_HYBRID */
310 if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
311 buffer, off))
312 goto err;
313 }
314 if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
315 buffer, off))
316 goto err;
317 if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
318 buffer, off))
319 goto err;
320 if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
321 goto err;
322 }
323 ret = 1;
324err:
325 if (!ret)
326 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
327 BN_free(p);
328 BN_free(a);
329 BN_free(b);
330 BN_free(gen);
331 BN_free(order);
332 BN_free(cofactor);
333 BN_CTX_free(ctx);
334 free(buffer);
335 return (ret);
336}
337
338static int
339print_bin(BIO * fp, const char *name, const unsigned char *buf,
340 size_t len, int off)
341{
342 size_t i;
343 char str[128];
344
345 if (buf == NULL)
346 return 1;
347 if (off) {
348 if (off > 128)
349 off = 128;
350 memset(str, ' ', off);
351 if (BIO_write(fp, str, off) <= 0)
352 return 0;
353 }
354 if (BIO_printf(fp, "%s", name) <= 0)
355 return 0;
356
357 for (i = 0; i < len; i++) {
358 if ((i % 15) == 0) {
359 str[0] = '\n';
360 memset(&(str[1]), ' ', off + 4);
361 if (BIO_write(fp, str, off + 1 + 4) <= 0)
362 return 0;
363 }
364 if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= 0)
365 return 0;
366 }
367 if (BIO_write(fp, "\n", 1) <= 0)
368 return 0;
369
370 return 1;
371}
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c
deleted file mode 100644
index a3ad4e1ce9..0000000000
--- a/src/lib/libcrypto/ec/ecp_mont.c
+++ /dev/null
@@ -1,294 +0,0 @@
1/* $OpenBSD: ecp_mont.c,v 1.10 2015/02/13 00:46:03 beck Exp $ */
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 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63
64#include <openssl/err.h>
65
66#include "ec_lcl.h"
67
68
69const EC_METHOD *
70EC_GFp_mont_method(void)
71{
72 static const EC_METHOD ret = {
73 .flags = EC_FLAGS_DEFAULT_OCT,
74 .field_type = NID_X9_62_prime_field,
75 .group_init = ec_GFp_mont_group_init,
76 .group_finish = ec_GFp_mont_group_finish,
77 .group_clear_finish = ec_GFp_mont_group_clear_finish,
78 .group_copy = ec_GFp_mont_group_copy,
79 .group_set_curve = ec_GFp_mont_group_set_curve,
80 .group_get_curve = ec_GFp_simple_group_get_curve,
81 .group_get_degree = ec_GFp_simple_group_get_degree,
82 .group_check_discriminant =
83 ec_GFp_simple_group_check_discriminant,
84 .point_init = ec_GFp_simple_point_init,
85 .point_finish = ec_GFp_simple_point_finish,
86 .point_clear_finish = ec_GFp_simple_point_clear_finish,
87 .point_copy = ec_GFp_simple_point_copy,
88 .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
89 .point_set_Jprojective_coordinates_GFp =
90 ec_GFp_simple_set_Jprojective_coordinates_GFp,
91 .point_get_Jprojective_coordinates_GFp =
92 ec_GFp_simple_get_Jprojective_coordinates_GFp,
93 .point_set_affine_coordinates =
94 ec_GFp_simple_point_set_affine_coordinates,
95 .point_get_affine_coordinates =
96 ec_GFp_simple_point_get_affine_coordinates,
97 .add = ec_GFp_simple_add,
98 .dbl = ec_GFp_simple_dbl,
99 .invert = ec_GFp_simple_invert,
100 .is_at_infinity = ec_GFp_simple_is_at_infinity,
101 .is_on_curve = ec_GFp_simple_is_on_curve,
102 .point_cmp = ec_GFp_simple_cmp,
103 .make_affine = ec_GFp_simple_make_affine,
104 .points_make_affine = ec_GFp_simple_points_make_affine,
105 .field_mul = ec_GFp_mont_field_mul,
106 .field_sqr = ec_GFp_mont_field_sqr,
107 .field_encode = ec_GFp_mont_field_encode,
108 .field_decode = ec_GFp_mont_field_decode,
109 .field_set_to_one = ec_GFp_mont_field_set_to_one
110 };
111
112 return &ret;
113}
114
115
116int
117ec_GFp_mont_group_init(EC_GROUP * group)
118{
119 int ok;
120
121 ok = ec_GFp_simple_group_init(group);
122 group->field_data1 = NULL;
123 group->field_data2 = NULL;
124 return ok;
125}
126
127
128void
129ec_GFp_mont_group_finish(EC_GROUP * group)
130{
131 BN_MONT_CTX_free(group->field_data1);
132 group->field_data1 = NULL;
133 BN_free(group->field_data2);
134 group->field_data2 = NULL;
135 ec_GFp_simple_group_finish(group);
136}
137
138
139void
140ec_GFp_mont_group_clear_finish(EC_GROUP * group)
141{
142 BN_MONT_CTX_free(group->field_data1);
143 group->field_data1 = NULL;
144 BN_clear_free(group->field_data2);
145 group->field_data2 = NULL;
146 ec_GFp_simple_group_clear_finish(group);
147}
148
149
150int
151ec_GFp_mont_group_copy(EC_GROUP * dest, const EC_GROUP * src)
152{
153 BN_MONT_CTX_free(dest->field_data1);
154 dest->field_data1 = NULL;
155 BN_clear_free(dest->field_data2);
156 dest->field_data2 = NULL;
157
158 if (!ec_GFp_simple_group_copy(dest, src))
159 return 0;
160
161 if (src->field_data1 != NULL) {
162 dest->field_data1 = BN_MONT_CTX_new();
163 if (dest->field_data1 == NULL)
164 return 0;
165 if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1))
166 goto err;
167 }
168 if (src->field_data2 != NULL) {
169 dest->field_data2 = BN_dup(src->field_data2);
170 if (dest->field_data2 == NULL)
171 goto err;
172 }
173 return 1;
174
175err:
176 if (dest->field_data1 != NULL) {
177 BN_MONT_CTX_free(dest->field_data1);
178 dest->field_data1 = NULL;
179 }
180 return 0;
181}
182
183
184int
185ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
186 const BIGNUM *b, BN_CTX *ctx)
187{
188 BN_CTX *new_ctx = NULL;
189 BN_MONT_CTX *mont = NULL;
190 BIGNUM *one = NULL;
191 int ret = 0;
192
193 BN_MONT_CTX_free(group->field_data1);
194 group->field_data1 = NULL;
195 BN_free(group->field_data2);
196 group->field_data2 = NULL;
197 if (ctx == NULL) {
198 ctx = new_ctx = BN_CTX_new();
199 if (ctx == NULL)
200 return 0;
201 }
202 mont = BN_MONT_CTX_new();
203 if (mont == NULL)
204 goto err;
205 if (!BN_MONT_CTX_set(mont, p, ctx)) {
206 ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
207 goto err;
208 }
209 one = BN_new();
210 if (one == NULL)
211 goto err;
212 if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
213 goto err;
214
215 group->field_data1 = mont;
216 mont = NULL;
217 group->field_data2 = one;
218 one = NULL;
219
220 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
221
222 if (!ret) {
223 BN_MONT_CTX_free(group->field_data1);
224 group->field_data1 = NULL;
225 BN_free(group->field_data2);
226 group->field_data2 = NULL;
227 }
228err:
229 BN_CTX_free(new_ctx);
230 BN_MONT_CTX_free(mont);
231 BN_free(one);
232 return ret;
233}
234
235
236int
237ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
238 const BIGNUM *b, BN_CTX *ctx)
239{
240 if (group->field_data1 == NULL) {
241 ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
242 return 0;
243 }
244 return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
245}
246
247
248int
249ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
250 BN_CTX *ctx)
251{
252 if (group->field_data1 == NULL) {
253 ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
254 return 0;
255 }
256 return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
257}
258
259
260int
261ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
262 BN_CTX *ctx)
263{
264 if (group->field_data1 == NULL) {
265 ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
266 return 0;
267 }
268 return BN_to_montgomery(r, a, (BN_MONT_CTX *) group->field_data1, ctx);
269}
270
271
272int
273ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
274 BN_CTX *ctx)
275{
276 if (group->field_data1 == NULL) {
277 ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
278 return 0;
279 }
280 return BN_from_montgomery(r, a, group->field_data1, ctx);
281}
282
283
284int
285ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
286{
287 if (group->field_data2 == NULL) {
288 ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
289 return 0;
290 }
291 if (!BN_copy(r, group->field_data2))
292 return 0;
293 return 1;
294}
diff --git a/src/lib/libcrypto/ec/ecp_nist.c b/src/lib/libcrypto/ec/ecp_nist.c
deleted file mode 100644
index a33f9d9e39..0000000000
--- a/src/lib/libcrypto/ec/ecp_nist.c
+++ /dev/null
@@ -1,212 +0,0 @@
1/* $OpenBSD: ecp_nist.c,v 1.9 2014/07/12 16:03:37 miod Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2003 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 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63
64#include <limits.h>
65
66#include <openssl/err.h>
67#include <openssl/obj_mac.h>
68#include "ec_lcl.h"
69
70const EC_METHOD *
71EC_GFp_nist_method(void)
72{
73 static const EC_METHOD ret = {
74 .flags = EC_FLAGS_DEFAULT_OCT,
75 .field_type = NID_X9_62_prime_field,
76 .group_init = ec_GFp_simple_group_init,
77 .group_finish = ec_GFp_simple_group_finish,
78 .group_clear_finish = ec_GFp_simple_group_clear_finish,
79 .group_copy = ec_GFp_nist_group_copy,
80 .group_set_curve = ec_GFp_nist_group_set_curve,
81 .group_get_curve = ec_GFp_simple_group_get_curve,
82 .group_get_degree = ec_GFp_simple_group_get_degree,
83 .group_check_discriminant =
84 ec_GFp_simple_group_check_discriminant,
85 .point_init = ec_GFp_simple_point_init,
86 .point_finish = ec_GFp_simple_point_finish,
87 .point_clear_finish = ec_GFp_simple_point_clear_finish,
88 .point_copy = ec_GFp_simple_point_copy,
89 .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
90 .point_set_Jprojective_coordinates_GFp =
91 ec_GFp_simple_set_Jprojective_coordinates_GFp,
92 .point_get_Jprojective_coordinates_GFp =
93 ec_GFp_simple_get_Jprojective_coordinates_GFp,
94 .point_set_affine_coordinates =
95 ec_GFp_simple_point_set_affine_coordinates,
96 .point_get_affine_coordinates =
97 ec_GFp_simple_point_get_affine_coordinates,
98 .add = ec_GFp_simple_add,
99 .dbl = ec_GFp_simple_dbl,
100 .invert = ec_GFp_simple_invert,
101 .is_at_infinity = ec_GFp_simple_is_at_infinity,
102 .is_on_curve = ec_GFp_simple_is_on_curve,
103 .point_cmp = ec_GFp_simple_cmp,
104 .make_affine = ec_GFp_simple_make_affine,
105 .points_make_affine = ec_GFp_simple_points_make_affine,
106 .field_mul = ec_GFp_nist_field_mul,
107 .field_sqr = ec_GFp_nist_field_sqr
108 };
109
110 return &ret;
111}
112
113int
114ec_GFp_nist_group_copy(EC_GROUP * dest, const EC_GROUP * src)
115{
116 dest->field_mod_func = src->field_mod_func;
117
118 return ec_GFp_simple_group_copy(dest, src);
119}
120
121int
122ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
123 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
124{
125 int ret = 0;
126 BN_CTX *new_ctx = NULL;
127 BIGNUM *tmp_bn;
128
129 if (ctx == NULL)
130 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
131 return 0;
132
133 BN_CTX_start(ctx);
134 if ((tmp_bn = BN_CTX_get(ctx)) == NULL)
135 goto err;
136
137 if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
138 group->field_mod_func = BN_nist_mod_192;
139 else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
140 group->field_mod_func = BN_nist_mod_224;
141 else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
142 group->field_mod_func = BN_nist_mod_256;
143 else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
144 group->field_mod_func = BN_nist_mod_384;
145 else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
146 group->field_mod_func = BN_nist_mod_521;
147 else {
148 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
149 goto err;
150 }
151
152 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
153
154err:
155 BN_CTX_end(ctx);
156 BN_CTX_free(new_ctx);
157 return ret;
158}
159
160
161int
162ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
163 const BIGNUM *b, BN_CTX *ctx)
164{
165 int ret = 0;
166 BN_CTX *ctx_new = NULL;
167
168 if (!group || !r || !a || !b) {
169 ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
170 goto err;
171 }
172 if (!ctx)
173 if ((ctx_new = ctx = BN_CTX_new()) == NULL)
174 goto err;
175
176 if (!BN_mul(r, a, b, ctx))
177 goto err;
178 if (!group->field_mod_func(r, r, &group->field, ctx))
179 goto err;
180
181 ret = 1;
182err:
183 BN_CTX_free(ctx_new);
184 return ret;
185}
186
187
188int
189ec_GFp_nist_field_sqr(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a,
190 BN_CTX * ctx)
191{
192 int ret = 0;
193 BN_CTX *ctx_new = NULL;
194
195 if (!group || !r || !a) {
196 ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
197 goto err;
198 }
199 if (!ctx)
200 if ((ctx_new = ctx = BN_CTX_new()) == NULL)
201 goto err;
202
203 if (!BN_sqr(r, a, ctx))
204 goto err;
205 if (!group->field_mod_func(r, r, &group->field, ctx))
206 goto err;
207
208 ret = 1;
209err:
210 BN_CTX_free(ctx_new);
211 return ret;
212}
diff --git a/src/lib/libcrypto/ec/ecp_nistp224.c b/src/lib/libcrypto/ec/ecp_nistp224.c
deleted file mode 100644
index 0976f24a9f..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistp224.c
+++ /dev/null
@@ -1,1693 +0,0 @@
1/* $OpenBSD: ecp_nistp224.c,v 1.17 2015/09/10 15:56:25 jsing Exp $ */
2/*
3 * Written by Emilia Kasper (Google) for the OpenSSL project.
4 */
5/*
6 * Copyright (c) 2011 Google Inc.
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/*
22 * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
23 *
24 * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
25 * and Adam Langley's public domain 64-bit C implementation of curve25519
26 */
27
28#include <stdint.h>
29#include <string.h>
30
31#include <openssl/opensslconf.h>
32
33#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
34
35#include <openssl/err.h>
36#include "ec_lcl.h"
37
38#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
39 /* even with gcc, the typedef won't work for 32-bit platforms */
40 typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
41#else
42 #error "Need GCC 3.1 or later to define type uint128_t"
43#endif
44
45typedef uint8_t u8;
46typedef uint64_t u64;
47typedef int64_t s64;
48
49
50/******************************************************************************/
51/* INTERNAL REPRESENTATION OF FIELD ELEMENTS
52 *
53 * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
54 * using 64-bit coefficients called 'limbs',
55 * and sometimes (for multiplication results) as
56 * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6
57 * using 128-bit coefficients called 'widelimbs'.
58 * A 4-limb representation is an 'felem';
59 * a 7-widelimb representation is a 'widefelem'.
60 * Even within felems, bits of adjacent limbs overlap, and we don't always
61 * reduce the representations: we ensure that inputs to each felem
62 * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60,
63 * and fit into a 128-bit word without overflow. The coefficients are then
64 * again partially reduced to obtain an felem satisfying a_i < 2^57.
65 * We only reduce to the unique minimal representation at the end of the
66 * computation.
67 */
68
69typedef uint64_t limb;
70typedef uint128_t widelimb;
71
72typedef limb felem[4];
73typedef widelimb widefelem[7];
74
75/* Field element represented as a byte arrary.
76 * 28*8 = 224 bits is also the group order size for the elliptic curve,
77 * and we also use this type for scalars for point multiplication.
78 */
79typedef u8 felem_bytearray[28];
80
81static const felem_bytearray nistp224_curve_params[5] = {
82 {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
83 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
84 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
85 {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
86 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
87 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE},
88 {0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */
89 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
90 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4},
91 {0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */
92 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
93 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21},
94 {0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */
95 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
96 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34}
97};
98
99/* Precomputed multiples of the standard generator
100 * Points are given in coordinates (X, Y, Z) where Z normally is 1
101 * (0 for the point at infinity).
102 * For each field element, slice a_0 is word 0, etc.
103 *
104 * The table has 2 * 16 elements, starting with the following:
105 * index | bits | point
106 * ------+---------+------------------------------
107 * 0 | 0 0 0 0 | 0G
108 * 1 | 0 0 0 1 | 1G
109 * 2 | 0 0 1 0 | 2^56G
110 * 3 | 0 0 1 1 | (2^56 + 1)G
111 * 4 | 0 1 0 0 | 2^112G
112 * 5 | 0 1 0 1 | (2^112 + 1)G
113 * 6 | 0 1 1 0 | (2^112 + 2^56)G
114 * 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
115 * 8 | 1 0 0 0 | 2^168G
116 * 9 | 1 0 0 1 | (2^168 + 1)G
117 * 10 | 1 0 1 0 | (2^168 + 2^56)G
118 * 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
119 * 12 | 1 1 0 0 | (2^168 + 2^112)G
120 * 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
121 * 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
122 * 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
123 * followed by a copy of this with each element multiplied by 2^28.
124 *
125 * The reason for this is so that we can clock bits into four different
126 * locations when doing simple scalar multiplies against the base point,
127 * and then another four locations using the second 16 elements.
128 */
129static const felem gmul[2][16][3] =
130{{{{0, 0, 0, 0},
131 {0, 0, 0, 0},
132 {0, 0, 0, 0}},
133 {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
134 {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
135 {1, 0, 0, 0}},
136 {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
137 {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
138 {1, 0, 0, 0}},
139 {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
140 {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
141 {1, 0, 0, 0}},
142 {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
143 {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
144 {1, 0, 0, 0}},
145 {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
146 {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
147 {1, 0, 0, 0}},
148 {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
149 {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
150 {1, 0, 0, 0}},
151 {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
152 {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
153 {1, 0, 0, 0}},
154 {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
155 {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
156 {1, 0, 0, 0}},
157 {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
158 {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
159 {1, 0, 0, 0}},
160 {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
161 {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
162 {1, 0, 0, 0}},
163 {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
164 {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
165 {1, 0, 0, 0}},
166 {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
167 {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
168 {1, 0, 0, 0}},
169 {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
170 {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
171 {1, 0, 0, 0}},
172 {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
173 {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
174 {1, 0, 0, 0}},
175 {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
176 {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
177 {1, 0, 0, 0}}},
178 {{{0, 0, 0, 0},
179 {0, 0, 0, 0},
180 {0, 0, 0, 0}},
181 {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
182 {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
183 {1, 0, 0, 0}},
184 {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
185 {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
186 {1, 0, 0, 0}},
187 {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
188 {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
189 {1, 0, 0, 0}},
190 {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
191 {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
192 {1, 0, 0, 0}},
193 {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
194 {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
195 {1, 0, 0, 0}},
196 {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
197 {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
198 {1, 0, 0, 0}},
199 {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
200 {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
201 {1, 0, 0, 0}},
202 {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
203 {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
204 {1, 0, 0, 0}},
205 {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
206 {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
207 {1, 0, 0, 0}},
208 {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
209 {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
210 {1, 0, 0, 0}},
211 {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
212 {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
213 {1, 0, 0, 0}},
214 {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
215 {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
216 {1, 0, 0, 0}},
217 {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
218 {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
219 {1, 0, 0, 0}},
220 {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
221 {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
222 {1, 0, 0, 0}},
223 {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
224 {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
225 {1, 0, 0, 0}}}};
226
227/* Precomputation for the group generator. */
228typedef struct {
229 felem g_pre_comp[2][16][3];
230 int references;
231} NISTP224_PRE_COMP;
232
233const EC_METHOD *
234EC_GFp_nistp224_method(void)
235{
236 static const EC_METHOD ret = {
237 .flags = EC_FLAGS_DEFAULT_OCT,
238 .field_type = NID_X9_62_prime_field,
239 .group_init = ec_GFp_nistp224_group_init,
240 .group_finish = ec_GFp_simple_group_finish,
241 .group_clear_finish = ec_GFp_simple_group_clear_finish,
242 .group_copy = ec_GFp_nist_group_copy,
243 .group_set_curve = ec_GFp_nistp224_group_set_curve,
244 .group_get_curve = ec_GFp_simple_group_get_curve,
245 .group_get_degree = ec_GFp_simple_group_get_degree,
246 .group_check_discriminant =
247 ec_GFp_simple_group_check_discriminant,
248 .point_init = ec_GFp_simple_point_init,
249 .point_finish = ec_GFp_simple_point_finish,
250 .point_clear_finish = ec_GFp_simple_point_clear_finish,
251 .point_copy = ec_GFp_simple_point_copy,
252 .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
253 .point_set_Jprojective_coordinates_GFp =
254 ec_GFp_simple_set_Jprojective_coordinates_GFp,
255 .point_get_Jprojective_coordinates_GFp =
256 ec_GFp_simple_get_Jprojective_coordinates_GFp,
257 .point_set_affine_coordinates =
258 ec_GFp_simple_point_set_affine_coordinates,
259 .point_get_affine_coordinates =
260 ec_GFp_nistp224_point_get_affine_coordinates,
261 .add = ec_GFp_simple_add,
262 .dbl = ec_GFp_simple_dbl,
263 .invert = ec_GFp_simple_invert,
264 .is_at_infinity = ec_GFp_simple_is_at_infinity,
265 .is_on_curve = ec_GFp_simple_is_on_curve,
266 .point_cmp = ec_GFp_simple_cmp,
267 .make_affine = ec_GFp_simple_make_affine,
268 .points_make_affine = ec_GFp_simple_points_make_affine,
269 .mul = ec_GFp_nistp224_points_mul,
270 .precompute_mult = ec_GFp_nistp224_precompute_mult,
271 .have_precompute_mult = ec_GFp_nistp224_have_precompute_mult,
272 .field_mul = ec_GFp_nist_field_mul,
273 .field_sqr = ec_GFp_nist_field_sqr
274 };
275
276 return &ret;
277}
278
279/* Helper functions to convert field elements to/from internal representation */
280static void
281bin28_to_felem(felem out, const u8 in[28])
282{
283 out[0] = *((const uint64_t *) (in)) & 0x00ffffffffffffff;
284 out[1] = (*((const uint64_t *) (in + 7))) & 0x00ffffffffffffff;
285 out[2] = (*((const uint64_t *) (in + 14))) & 0x00ffffffffffffff;
286 out[3] = (*((const uint64_t *) (in + 21))) & 0x00ffffffffffffff;
287}
288
289static void
290felem_to_bin28(u8 out[28], const felem in)
291{
292 unsigned i;
293 for (i = 0; i < 7; ++i) {
294 out[i] = in[0] >> (8 * i);
295 out[i + 7] = in[1] >> (8 * i);
296 out[i + 14] = in[2] >> (8 * i);
297 out[i + 21] = in[3] >> (8 * i);
298 }
299}
300
301/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
302static void
303flip_endian(u8 * out, const u8 * in, unsigned len)
304{
305 unsigned i;
306 for (i = 0; i < len; ++i)
307 out[i] = in[len - 1 - i];
308}
309
310/* From OpenSSL BIGNUM to internal representation */
311static int
312BN_to_felem(felem out, const BIGNUM * bn)
313{
314 felem_bytearray b_in;
315 felem_bytearray b_out;
316 unsigned num_bytes;
317
318 /* BN_bn2bin eats leading zeroes */
319 memset(b_out, 0, sizeof b_out);
320 num_bytes = BN_num_bytes(bn);
321 if (num_bytes > sizeof b_out) {
322 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
323 return 0;
324 }
325 if (BN_is_negative(bn)) {
326 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
327 return 0;
328 }
329 num_bytes = BN_bn2bin(bn, b_in);
330 flip_endian(b_out, b_in, num_bytes);
331 bin28_to_felem(out, b_out);
332 return 1;
333}
334
335/* From internal representation to OpenSSL BIGNUM */
336static BIGNUM *
337felem_to_BN(BIGNUM * out, const felem in)
338{
339 felem_bytearray b_in, b_out;
340 felem_to_bin28(b_in, in);
341 flip_endian(b_out, b_in, sizeof b_out);
342 return BN_bin2bn(b_out, sizeof b_out, out);
343}
344
345/******************************************************************************/
346/* FIELD OPERATIONS
347 *
348 * Field operations, using the internal representation of field elements.
349 * NB! These operations are specific to our point multiplication and cannot be
350 * expected to be correct in general - e.g., multiplication with a large scalar
351 * will cause an overflow.
352 *
353 */
354
355static void
356felem_one(felem out)
357{
358 out[0] = 1;
359 out[1] = 0;
360 out[2] = 0;
361 out[3] = 0;
362}
363
364static void
365felem_assign(felem out, const felem in)
366{
367 out[0] = in[0];
368 out[1] = in[1];
369 out[2] = in[2];
370 out[3] = in[3];
371}
372
373/* Sum two field elements: out += in */
374static void
375felem_sum(felem out, const felem in)
376{
377 out[0] += in[0];
378 out[1] += in[1];
379 out[2] += in[2];
380 out[3] += in[3];
381}
382
383/* Get negative value: out = -in */
384/* Assumes in[i] < 2^57 */
385static void
386felem_neg(felem out, const felem in)
387{
388 static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
389 static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
390 static const limb two58m42m2 = (((limb) 1) << 58) -
391 (((limb) 1) << 42) - (((limb) 1) << 2);
392
393 /* Set to 0 mod 2^224-2^96+1 to ensure out > in */
394 out[0] = two58p2 - in[0];
395 out[1] = two58m42m2 - in[1];
396 out[2] = two58m2 - in[2];
397 out[3] = two58m2 - in[3];
398}
399
400/* Subtract field elements: out -= in */
401/* Assumes in[i] < 2^57 */
402static void
403felem_diff(felem out, const felem in)
404{
405 static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
406 static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
407 static const limb two58m42m2 = (((limb) 1) << 58) -
408 (((limb) 1) << 42) - (((limb) 1) << 2);
409
410 /* Add 0 mod 2^224-2^96+1 to ensure out > in */
411 out[0] += two58p2;
412 out[1] += two58m42m2;
413 out[2] += two58m2;
414 out[3] += two58m2;
415
416 out[0] -= in[0];
417 out[1] -= in[1];
418 out[2] -= in[2];
419 out[3] -= in[3];
420}
421
422/* Subtract in unreduced 128-bit mode: out -= in */
423/* Assumes in[i] < 2^119 */
424static void
425widefelem_diff(widefelem out, const widefelem in)
426{
427 static const widelimb two120 = ((widelimb) 1) << 120;
428 static const widelimb two120m64 = (((widelimb) 1) << 120) -
429 (((widelimb) 1) << 64);
430 static const widelimb two120m104m64 = (((widelimb) 1) << 120) -
431 (((widelimb) 1) << 104) - (((widelimb) 1) << 64);
432
433 /* Add 0 mod 2^224-2^96+1 to ensure out > in */
434 out[0] += two120;
435 out[1] += two120m64;
436 out[2] += two120m64;
437 out[3] += two120;
438 out[4] += two120m104m64;
439 out[5] += two120m64;
440 out[6] += two120m64;
441
442 out[0] -= in[0];
443 out[1] -= in[1];
444 out[2] -= in[2];
445 out[3] -= in[3];
446 out[4] -= in[4];
447 out[5] -= in[5];
448 out[6] -= in[6];
449}
450
451/* Subtract in mixed mode: out128 -= in64 */
452/* in[i] < 2^63 */
453static void
454felem_diff_128_64(widefelem out, const felem in)
455{
456 static const widelimb two64p8 = (((widelimb) 1) << 64) +
457 (((widelimb) 1) << 8);
458 static const widelimb two64m8 = (((widelimb) 1) << 64) -
459 (((widelimb) 1) << 8);
460 static const widelimb two64m48m8 = (((widelimb) 1) << 64) -
461 (((widelimb) 1) << 48) - (((widelimb) 1) << 8);
462
463 /* Add 0 mod 2^224-2^96+1 to ensure out > in */
464 out[0] += two64p8;
465 out[1] += two64m48m8;
466 out[2] += two64m8;
467 out[3] += two64m8;
468
469 out[0] -= in[0];
470 out[1] -= in[1];
471 out[2] -= in[2];
472 out[3] -= in[3];
473}
474
475/* Multiply a field element by a scalar: out = out * scalar
476 * The scalars we actually use are small, so results fit without overflow */
477static void
478felem_scalar(felem out, const limb scalar)
479{
480 out[0] *= scalar;
481 out[1] *= scalar;
482 out[2] *= scalar;
483 out[3] *= scalar;
484}
485
486/* Multiply an unreduced field element by a scalar: out = out * scalar
487 * The scalars we actually use are small, so results fit without overflow */
488static void
489widefelem_scalar(widefelem out, const widelimb scalar)
490{
491 out[0] *= scalar;
492 out[1] *= scalar;
493 out[2] *= scalar;
494 out[3] *= scalar;
495 out[4] *= scalar;
496 out[5] *= scalar;
497 out[6] *= scalar;
498}
499
500/* Square a field element: out = in^2 */
501static void
502felem_square(widefelem out, const felem in)
503{
504 limb tmp0, tmp1, tmp2;
505 tmp0 = 2 * in[0];
506 tmp1 = 2 * in[1];
507 tmp2 = 2 * in[2];
508 out[0] = ((widelimb) in[0]) * in[0];
509 out[1] = ((widelimb) in[0]) * tmp1;
510 out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1];
511 out[3] = ((widelimb) in[3]) * tmp0 +
512 ((widelimb) in[1]) * tmp2;
513 out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2];
514 out[5] = ((widelimb) in[3]) * tmp2;
515 out[6] = ((widelimb) in[3]) * in[3];
516}
517
518/* Multiply two field elements: out = in1 * in2 */
519static void
520felem_mul(widefelem out, const felem in1, const felem in2)
521{
522 out[0] = ((widelimb) in1[0]) * in2[0];
523 out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0];
524 out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] +
525 ((widelimb) in1[2]) * in2[0];
526 out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] +
527 ((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0];
528 out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] +
529 ((widelimb) in1[3]) * in2[1];
530 out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2];
531 out[6] = ((widelimb) in1[3]) * in2[3];
532}
533
534/* Reduce seven 128-bit coefficients to four 64-bit coefficients.
535 * Requires in[i] < 2^126,
536 * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */
537static void
538felem_reduce(felem out, const widefelem in)
539{
540 static const widelimb two127p15 = (((widelimb) 1) << 127) +
541 (((widelimb) 1) << 15);
542 static const widelimb two127m71 = (((widelimb) 1) << 127) -
543 (((widelimb) 1) << 71);
544 static const widelimb two127m71m55 = (((widelimb) 1) << 127) -
545 (((widelimb) 1) << 71) - (((widelimb) 1) << 55);
546 widelimb output[5];
547
548 /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */
549 output[0] = in[0] + two127p15;
550 output[1] = in[1] + two127m71m55;
551 output[2] = in[2] + two127m71;
552 output[3] = in[3];
553 output[4] = in[4];
554
555 /* Eliminate in[4], in[5], in[6] */
556 output[4] += in[6] >> 16;
557 output[3] += (in[6] & 0xffff) << 40;
558 output[2] -= in[6];
559
560 output[3] += in[5] >> 16;
561 output[2] += (in[5] & 0xffff) << 40;
562 output[1] -= in[5];
563
564 output[2] += output[4] >> 16;
565 output[1] += (output[4] & 0xffff) << 40;
566 output[0] -= output[4];
567
568 /* Carry 2 -> 3 -> 4 */
569 output[3] += output[2] >> 56;
570 output[2] &= 0x00ffffffffffffff;
571
572 output[4] = output[3] >> 56;
573 output[3] &= 0x00ffffffffffffff;
574
575 /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */
576
577 /* Eliminate output[4] */
578 output[2] += output[4] >> 16;
579 /* output[2] < 2^56 + 2^56 = 2^57 */
580 output[1] += (output[4] & 0xffff) << 40;
581 output[0] -= output[4];
582
583 /* Carry 0 -> 1 -> 2 -> 3 */
584 output[1] += output[0] >> 56;
585 out[0] = output[0] & 0x00ffffffffffffff;
586
587 output[2] += output[1] >> 56;
588 /* output[2] < 2^57 + 2^72 */
589 out[1] = output[1] & 0x00ffffffffffffff;
590 output[3] += output[2] >> 56;
591 /* output[3] <= 2^56 + 2^16 */
592 out[2] = output[2] & 0x00ffffffffffffff;
593
594 /*
595 * out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16
596 * (due to final carry), so out < 2*p
597 */
598 out[3] = output[3];
599}
600
601static void
602felem_square_reduce(felem out, const felem in)
603{
604 widefelem tmp;
605 felem_square(tmp, in);
606 felem_reduce(out, tmp);
607}
608
609static void
610felem_mul_reduce(felem out, const felem in1, const felem in2)
611{
612 widefelem tmp;
613 felem_mul(tmp, in1, in2);
614 felem_reduce(out, tmp);
615}
616
617/* Reduce to unique minimal representation.
618 * Requires 0 <= in < 2*p (always call felem_reduce first) */
619static void
620felem_contract(felem out, const felem in)
621{
622 static const int64_t two56 = ((limb) 1) << 56;
623 /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */
624 /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */
625 int64_t tmp[4], a;
626 tmp[0] = in[0];
627 tmp[1] = in[1];
628 tmp[2] = in[2];
629 tmp[3] = in[3];
630 /* Case 1: a = 1 iff in >= 2^224 */
631 a = (in[3] >> 56);
632 tmp[0] -= a;
633 tmp[1] += a << 40;
634 tmp[3] &= 0x00ffffffffffffff;
635 /*
636 * Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all
637 * 1 and the lower part is non-zero
638 */
639 a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
640 (((int64_t) (in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
641 a &= 0x00ffffffffffffff;
642 /* turn a into an all-one mask (if a = 0) or an all-zero mask */
643 a = (a - 1) >> 63;
644 /* subtract 2^224 - 2^96 + 1 if a is all-one */
645 tmp[3] &= a ^ 0xffffffffffffffff;
646 tmp[2] &= a ^ 0xffffffffffffffff;
647 tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
648 tmp[0] -= 1 & a;
649
650 /*
651 * eliminate negative coefficients: if tmp[0] is negative, tmp[1]
652 * must be non-zero, so we only need one step
653 */
654 a = tmp[0] >> 63;
655 tmp[0] += two56 & a;
656 tmp[1] -= 1 & a;
657
658 /* carry 1 -> 2 -> 3 */
659 tmp[2] += tmp[1] >> 56;
660 tmp[1] &= 0x00ffffffffffffff;
661
662 tmp[3] += tmp[2] >> 56;
663 tmp[2] &= 0x00ffffffffffffff;
664
665 /* Now 0 <= out < p */
666 out[0] = tmp[0];
667 out[1] = tmp[1];
668 out[2] = tmp[2];
669 out[3] = tmp[3];
670}
671
672/* Zero-check: returns 1 if input is 0, and 0 otherwise.
673 * We know that field elements are reduced to in < 2^225,
674 * so we only need to check three cases: 0, 2^224 - 2^96 + 1,
675 * and 2^225 - 2^97 + 2 */
676static limb
677felem_is_zero(const felem in)
678{
679 limb zero, two224m96p1, two225m97p2;
680
681 zero = in[0] | in[1] | in[2] | in[3];
682 zero = (((int64_t) (zero) - 1) >> 63) & 1;
683 two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000)
684 | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff);
685 two224m96p1 = (((int64_t) (two224m96p1) - 1) >> 63) & 1;
686 two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000)
687 | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff);
688 two225m97p2 = (((int64_t) (two225m97p2) - 1) >> 63) & 1;
689 return (zero | two224m96p1 | two225m97p2);
690}
691
692static limb
693felem_is_zero_int(const felem in)
694{
695 return (int) (felem_is_zero(in) & ((limb) 1));
696}
697
698/* Invert a field element */
699/* Computation chain copied from djb's code */
700static void
701felem_inv(felem out, const felem in)
702{
703 felem ftmp, ftmp2, ftmp3, ftmp4;
704 widefelem tmp;
705 unsigned i;
706
707 felem_square(tmp, in);
708 felem_reduce(ftmp, tmp);/* 2 */
709 felem_mul(tmp, in, ftmp);
710 felem_reduce(ftmp, tmp);/* 2^2 - 1 */
711 felem_square(tmp, ftmp);
712 felem_reduce(ftmp, tmp);/* 2^3 - 2 */
713 felem_mul(tmp, in, ftmp);
714 felem_reduce(ftmp, tmp);/* 2^3 - 1 */
715 felem_square(tmp, ftmp);
716 felem_reduce(ftmp2, tmp); /* 2^4 - 2 */
717 felem_square(tmp, ftmp2);
718 felem_reduce(ftmp2, tmp); /* 2^5 - 4 */
719 felem_square(tmp, ftmp2);
720 felem_reduce(ftmp2, tmp); /* 2^6 - 8 */
721 felem_mul(tmp, ftmp2, ftmp);
722 felem_reduce(ftmp, tmp);/* 2^6 - 1 */
723 felem_square(tmp, ftmp);
724 felem_reduce(ftmp2, tmp); /* 2^7 - 2 */
725 for (i = 0; i < 5; ++i) { /* 2^12 - 2^6 */
726 felem_square(tmp, ftmp2);
727 felem_reduce(ftmp2, tmp);
728 }
729 felem_mul(tmp, ftmp2, ftmp);
730 felem_reduce(ftmp2, tmp); /* 2^12 - 1 */
731 felem_square(tmp, ftmp2);
732 felem_reduce(ftmp3, tmp); /* 2^13 - 2 */
733 for (i = 0; i < 11; ++i) { /* 2^24 - 2^12 */
734 felem_square(tmp, ftmp3);
735 felem_reduce(ftmp3, tmp);
736 }
737 felem_mul(tmp, ftmp3, ftmp2);
738 felem_reduce(ftmp2, tmp); /* 2^24 - 1 */
739 felem_square(tmp, ftmp2);
740 felem_reduce(ftmp3, tmp); /* 2^25 - 2 */
741 for (i = 0; i < 23; ++i) { /* 2^48 - 2^24 */
742 felem_square(tmp, ftmp3);
743 felem_reduce(ftmp3, tmp);
744 }
745 felem_mul(tmp, ftmp3, ftmp2);
746 felem_reduce(ftmp3, tmp); /* 2^48 - 1 */
747 felem_square(tmp, ftmp3);
748 felem_reduce(ftmp4, tmp); /* 2^49 - 2 */
749 for (i = 0; i < 47; ++i) { /* 2^96 - 2^48 */
750 felem_square(tmp, ftmp4);
751 felem_reduce(ftmp4, tmp);
752 }
753 felem_mul(tmp, ftmp3, ftmp4);
754 felem_reduce(ftmp3, tmp); /* 2^96 - 1 */
755 felem_square(tmp, ftmp3);
756 felem_reduce(ftmp4, tmp); /* 2^97 - 2 */
757 for (i = 0; i < 23; ++i) { /* 2^120 - 2^24 */
758 felem_square(tmp, ftmp4);
759 felem_reduce(ftmp4, tmp);
760 }
761 felem_mul(tmp, ftmp2, ftmp4);
762 felem_reduce(ftmp2, tmp); /* 2^120 - 1 */
763 for (i = 0; i < 6; ++i) { /* 2^126 - 2^6 */
764 felem_square(tmp, ftmp2);
765 felem_reduce(ftmp2, tmp);
766 }
767 felem_mul(tmp, ftmp2, ftmp);
768 felem_reduce(ftmp, tmp);/* 2^126 - 1 */
769 felem_square(tmp, ftmp);
770 felem_reduce(ftmp, tmp);/* 2^127 - 2 */
771 felem_mul(tmp, ftmp, in);
772 felem_reduce(ftmp, tmp);/* 2^127 - 1 */
773 for (i = 0; i < 97; ++i) { /* 2^224 - 2^97 */
774 felem_square(tmp, ftmp);
775 felem_reduce(ftmp, tmp);
776 }
777 felem_mul(tmp, ftmp, ftmp3);
778 felem_reduce(out, tmp); /* 2^224 - 2^96 - 1 */
779}
780
781/* Copy in constant time:
782 * if icopy == 1, copy in to out,
783 * if icopy == 0, copy out to itself. */
784static void
785copy_conditional(felem out, const felem in, limb icopy)
786{
787 unsigned i;
788 /* icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one */
789 const limb copy = -icopy;
790 for (i = 0; i < 4; ++i) {
791 const limb tmp = copy & (in[i] ^ out[i]);
792 out[i] ^= tmp;
793 }
794}
795
796/******************************************************************************/
797/* ELLIPTIC CURVE POINT OPERATIONS
798 *
799 * Points are represented in Jacobian projective coordinates:
800 * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
801 * or to the point at infinity if Z == 0.
802 *
803 */
804
805/* Double an elliptic curve point:
806 * (X', Y', Z') = 2 * (X, Y, Z), where
807 * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
808 * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
809 * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
810 * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
811 * while x_out == y_in is not (maybe this works, but it's not tested). */
812static void
813point_double(felem x_out, felem y_out, felem z_out,
814 const felem x_in, const felem y_in, const felem z_in)
815{
816 widefelem tmp, tmp2;
817 felem delta, gamma, beta, alpha, ftmp, ftmp2;
818
819 felem_assign(ftmp, x_in);
820 felem_assign(ftmp2, x_in);
821
822 /* delta = z^2 */
823 felem_square(tmp, z_in);
824 felem_reduce(delta, tmp);
825
826 /* gamma = y^2 */
827 felem_square(tmp, y_in);
828 felem_reduce(gamma, tmp);
829
830 /* beta = x*gamma */
831 felem_mul(tmp, x_in, gamma);
832 felem_reduce(beta, tmp);
833
834 /* alpha = 3*(x-delta)*(x+delta) */
835 felem_diff(ftmp, delta);
836 /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */
837 felem_sum(ftmp2, delta);
838 /* ftmp2[i] < 2^57 + 2^57 = 2^58 */
839 felem_scalar(ftmp2, 3);
840 /* ftmp2[i] < 3 * 2^58 < 2^60 */
841 felem_mul(tmp, ftmp, ftmp2);
842 /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */
843 felem_reduce(alpha, tmp);
844
845 /* x' = alpha^2 - 8*beta */
846 felem_square(tmp, alpha);
847 /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
848 felem_assign(ftmp, beta);
849 felem_scalar(ftmp, 8);
850 /* ftmp[i] < 8 * 2^57 = 2^60 */
851 felem_diff_128_64(tmp, ftmp);
852 /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
853 felem_reduce(x_out, tmp);
854
855 /* z' = (y + z)^2 - gamma - delta */
856 felem_sum(delta, gamma);
857 /* delta[i] < 2^57 + 2^57 = 2^58 */
858 felem_assign(ftmp, y_in);
859 felem_sum(ftmp, z_in);
860 /* ftmp[i] < 2^57 + 2^57 = 2^58 */
861 felem_square(tmp, ftmp);
862 /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */
863 felem_diff_128_64(tmp, delta);
864 /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */
865 felem_reduce(z_out, tmp);
866
867 /* y' = alpha*(4*beta - x') - 8*gamma^2 */
868 felem_scalar(beta, 4);
869 /* beta[i] < 4 * 2^57 = 2^59 */
870 felem_diff(beta, x_out);
871 /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */
872 felem_mul(tmp, alpha, beta);
873 /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */
874 felem_square(tmp2, gamma);
875 /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */
876 widefelem_scalar(tmp2, 8);
877 /* tmp2[i] < 8 * 2^116 = 2^119 */
878 widefelem_diff(tmp, tmp2);
879 /* tmp[i] < 2^119 + 2^120 < 2^121 */
880 felem_reduce(y_out, tmp);
881}
882
883/* Add two elliptic curve points:
884 * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
885 * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
886 * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
887 * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) -
888 * Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
889 * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
890 *
891 * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
892 */
893
894/* This function is not entirely constant-time:
895 * it includes a branch for checking whether the two input points are equal,
896 * (while not equal to the point at infinity).
897 * This case never happens during single point multiplication,
898 * so there is no timing leak for ECDH or ECDSA signing. */
899static void
900point_add(felem x3, felem y3, felem z3,
901 const felem x1, const felem y1, const felem z1,
902 const int mixed, const felem x2, const felem y2, const felem z2)
903{
904 felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
905 widefelem tmp, tmp2;
906 limb z1_is_zero, z2_is_zero, x_equal, y_equal;
907
908 if (!mixed) {
909 /* ftmp2 = z2^2 */
910 felem_square(tmp, z2);
911 felem_reduce(ftmp2, tmp);
912
913 /* ftmp4 = z2^3 */
914 felem_mul(tmp, ftmp2, z2);
915 felem_reduce(ftmp4, tmp);
916
917 /* ftmp4 = z2^3*y1 */
918 felem_mul(tmp2, ftmp4, y1);
919 felem_reduce(ftmp4, tmp2);
920
921 /* ftmp2 = z2^2*x1 */
922 felem_mul(tmp2, ftmp2, x1);
923 felem_reduce(ftmp2, tmp2);
924 } else {
925 /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
926
927 /* ftmp4 = z2^3*y1 */
928 felem_assign(ftmp4, y1);
929
930 /* ftmp2 = z2^2*x1 */
931 felem_assign(ftmp2, x1);
932 }
933
934 /* ftmp = z1^2 */
935 felem_square(tmp, z1);
936 felem_reduce(ftmp, tmp);
937
938 /* ftmp3 = z1^3 */
939 felem_mul(tmp, ftmp, z1);
940 felem_reduce(ftmp3, tmp);
941
942 /* tmp = z1^3*y2 */
943 felem_mul(tmp, ftmp3, y2);
944 /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
945
946 /* ftmp3 = z1^3*y2 - z2^3*y1 */
947 felem_diff_128_64(tmp, ftmp4);
948 /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
949 felem_reduce(ftmp3, tmp);
950
951 /* tmp = z1^2*x2 */
952 felem_mul(tmp, ftmp, x2);
953 /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
954
955 /* ftmp = z1^2*x2 - z2^2*x1 */
956 felem_diff_128_64(tmp, ftmp2);
957 /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
958 felem_reduce(ftmp, tmp);
959
960 /*
961 * the formulae are incorrect if the points are equal so we check for
962 * this and do doubling if this happens
963 */
964 x_equal = felem_is_zero(ftmp);
965 y_equal = felem_is_zero(ftmp3);
966 z1_is_zero = felem_is_zero(z1);
967 z2_is_zero = felem_is_zero(z2);
968 /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
969 if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
970 point_double(x3, y3, z3, x1, y1, z1);
971 return;
972 }
973 /* ftmp5 = z1*z2 */
974 if (!mixed) {
975 felem_mul(tmp, z1, z2);
976 felem_reduce(ftmp5, tmp);
977 } else {
978 /* special case z2 = 0 is handled later */
979 felem_assign(ftmp5, z1);
980 }
981
982 /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */
983 felem_mul(tmp, ftmp, ftmp5);
984 felem_reduce(z_out, tmp);
985
986 /* ftmp = (z1^2*x2 - z2^2*x1)^2 */
987 felem_assign(ftmp5, ftmp);
988 felem_square(tmp, ftmp);
989 felem_reduce(ftmp, tmp);
990
991 /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */
992 felem_mul(tmp, ftmp, ftmp5);
993 felem_reduce(ftmp5, tmp);
994
995 /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
996 felem_mul(tmp, ftmp2, ftmp);
997 felem_reduce(ftmp2, tmp);
998
999 /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
1000 felem_mul(tmp, ftmp4, ftmp5);
1001 /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
1002
1003 /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */
1004 felem_square(tmp2, ftmp3);
1005 /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */
1006
1007 /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */
1008 felem_diff_128_64(tmp2, ftmp5);
1009 /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */
1010
1011 /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
1012 felem_assign(ftmp5, ftmp2);
1013 felem_scalar(ftmp5, 2);
1014 /* ftmp5[i] < 2 * 2^57 = 2^58 */
1015
1016 /*
1017 * x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
1018 * 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2
1019 */
1020 felem_diff_128_64(tmp2, ftmp5);
1021 /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */
1022 felem_reduce(x_out, tmp2);
1023
1024 /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */
1025 felem_diff(ftmp2, x_out);
1026 /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */
1027
1028 /* tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) */
1029 felem_mul(tmp2, ftmp3, ftmp2);
1030 /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */
1031
1032 /*
1033 * y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 -
1034 * x_out) - z2^3*y1*(z1^2*x2 - z2^2*x1)^3
1035 */
1036 widefelem_diff(tmp2, tmp);
1037 /* tmp2[i] < 2^118 + 2^120 < 2^121 */
1038 felem_reduce(y_out, tmp2);
1039
1040 /*
1041 * the result (x_out, y_out, z_out) is incorrect if one of the inputs
1042 * is the point at infinity, so we need to check for this separately
1043 */
1044
1045 /* if point 1 is at infinity, copy point 2 to output, and vice versa */
1046 copy_conditional(x_out, x2, z1_is_zero);
1047 copy_conditional(x_out, x1, z2_is_zero);
1048 copy_conditional(y_out, y2, z1_is_zero);
1049 copy_conditional(y_out, y1, z2_is_zero);
1050 copy_conditional(z_out, z2, z1_is_zero);
1051 copy_conditional(z_out, z1, z2_is_zero);
1052 felem_assign(x3, x_out);
1053 felem_assign(y3, y_out);
1054 felem_assign(z3, z_out);
1055}
1056
1057/* select_point selects the |idx|th point from a precomputation table and
1058 * copies it to out. */
1059static void
1060select_point(const u64 idx, unsigned int size, const felem pre_comp[ /* size */ ][3], felem out[3])
1061{
1062 unsigned i, j;
1063 limb *outlimbs = &out[0][0];
1064 memset(outlimbs, 0, 3 * sizeof(felem));
1065
1066 for (i = 0; i < size; i++) {
1067 const limb *inlimbs = &pre_comp[i][0][0];
1068 u64 mask = i ^ idx;
1069 mask |= mask >> 4;
1070 mask |= mask >> 2;
1071 mask |= mask >> 1;
1072 mask &= 1;
1073 mask--;
1074 for (j = 0; j < 4 * 3; j++)
1075 outlimbs[j] |= inlimbs[j] & mask;
1076 }
1077}
1078
1079/* get_bit returns the |i|th bit in |in| */
1080static char
1081get_bit(const felem_bytearray in, unsigned i)
1082{
1083 if (i >= 224)
1084 return 0;
1085 return (in[i >> 3] >> (i & 7)) & 1;
1086}
1087
1088/* Interleaved point multiplication using precomputed point multiples:
1089 * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
1090 * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
1091 * of the generator, using certain (large) precomputed multiples in g_pre_comp.
1092 * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
1093static void
1094batch_mul(felem x_out, felem y_out, felem z_out,
1095 const felem_bytearray scalars[], const unsigned num_points, const u8 * g_scalar,
1096 const int mixed, const felem pre_comp[][17][3], const felem g_pre_comp[2][16][3])
1097{
1098 int i, skip;
1099 unsigned num;
1100 unsigned gen_mul = (g_scalar != NULL);
1101 felem nq[3], tmp[4];
1102 u64 bits;
1103 u8 sign, digit;
1104
1105 /* set nq to the point at infinity */
1106 memset(nq, 0, 3 * sizeof(felem));
1107
1108 /*
1109 * Loop over all scalars msb-to-lsb, interleaving additions of
1110 * multiples of the generator (two in each of the last 28 rounds) and
1111 * additions of other points multiples (every 5th round).
1112 */
1113 skip = 1; /* save two point operations in the first
1114 * round */
1115 for (i = (num_points ? 220 : 27); i >= 0; --i) {
1116 /* double */
1117 if (!skip)
1118 point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1119
1120 /* add multiples of the generator */
1121 if (gen_mul && (i <= 27)) {
1122 /* first, look 28 bits upwards */
1123 bits = get_bit(g_scalar, i + 196) << 3;
1124 bits |= get_bit(g_scalar, i + 140) << 2;
1125 bits |= get_bit(g_scalar, i + 84) << 1;
1126 bits |= get_bit(g_scalar, i + 28);
1127 /* select the point to add, in constant time */
1128 select_point(bits, 16, g_pre_comp[1], tmp);
1129
1130 if (!skip) {
1131 point_add(nq[0], nq[1], nq[2],
1132 nq[0], nq[1], nq[2],
1133 1 /* mixed */ , tmp[0], tmp[1], tmp[2]);
1134 } else {
1135 memcpy(nq, tmp, 3 * sizeof(felem));
1136 skip = 0;
1137 }
1138
1139 /* second, look at the current position */
1140 bits = get_bit(g_scalar, i + 168) << 3;
1141 bits |= get_bit(g_scalar, i + 112) << 2;
1142 bits |= get_bit(g_scalar, i + 56) << 1;
1143 bits |= get_bit(g_scalar, i);
1144 /* select the point to add, in constant time */
1145 select_point(bits, 16, g_pre_comp[0], tmp);
1146 point_add(nq[0], nq[1], nq[2],
1147 nq[0], nq[1], nq[2],
1148 1 /* mixed */ , tmp[0], tmp[1], tmp[2]);
1149 }
1150 /* do other additions every 5 doublings */
1151 if (num_points && (i % 5 == 0)) {
1152 /* loop over all scalars */
1153 for (num = 0; num < num_points; ++num) {
1154 bits = get_bit(scalars[num], i + 4) << 5;
1155 bits |= get_bit(scalars[num], i + 3) << 4;
1156 bits |= get_bit(scalars[num], i + 2) << 3;
1157 bits |= get_bit(scalars[num], i + 1) << 2;
1158 bits |= get_bit(scalars[num], i) << 1;
1159 bits |= get_bit(scalars[num], i - 1);
1160 ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
1161
1162 /* select the point to add or subtract */
1163 select_point(digit, 17, pre_comp[num], tmp);
1164 felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the
1165 * negative point */
1166 copy_conditional(tmp[1], tmp[3], sign);
1167
1168 if (!skip) {
1169 point_add(nq[0], nq[1], nq[2],
1170 nq[0], nq[1], nq[2],
1171 mixed, tmp[0], tmp[1], tmp[2]);
1172 } else {
1173 memcpy(nq, tmp, 3 * sizeof(felem));
1174 skip = 0;
1175 }
1176 }
1177 }
1178 }
1179 felem_assign(x_out, nq[0]);
1180 felem_assign(y_out, nq[1]);
1181 felem_assign(z_out, nq[2]);
1182}
1183
1184/******************************************************************************/
1185/* FUNCTIONS TO MANAGE PRECOMPUTATION
1186 */
1187
1188static NISTP224_PRE_COMP *
1189nistp224_pre_comp_new()
1190{
1191 NISTP224_PRE_COMP *ret = NULL;
1192 ret = malloc(sizeof *ret);
1193 if (!ret) {
1194 ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
1195 return ret;
1196 }
1197 memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
1198 ret->references = 1;
1199 return ret;
1200}
1201
1202static void *
1203nistp224_pre_comp_dup(void *src_)
1204{
1205 NISTP224_PRE_COMP *src = src_;
1206
1207 /* no need to actually copy, these objects never change! */
1208 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
1209
1210 return src_;
1211}
1212
1213static void
1214nistp224_pre_comp_free(void *pre_)
1215{
1216 int i;
1217 NISTP224_PRE_COMP *pre = pre_;
1218
1219 if (!pre)
1220 return;
1221
1222 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1223 if (i > 0)
1224 return;
1225
1226 free(pre);
1227}
1228
1229static void
1230nistp224_pre_comp_clear_free(void *pre_)
1231{
1232 int i;
1233 NISTP224_PRE_COMP *pre = pre_;
1234
1235 if (!pre)
1236 return;
1237
1238 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1239 if (i > 0)
1240 return;
1241
1242 explicit_bzero(pre, sizeof *pre);
1243 free(pre);
1244}
1245
1246/******************************************************************************/
1247/* OPENSSL EC_METHOD FUNCTIONS
1248 */
1249
1250int
1251ec_GFp_nistp224_group_init(EC_GROUP * group)
1252{
1253 int ret;
1254 ret = ec_GFp_simple_group_init(group);
1255 group->a_is_minus3 = 1;
1256 return ret;
1257}
1258
1259int
1260ec_GFp_nistp224_group_set_curve(EC_GROUP * group, const BIGNUM * p,
1261 const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
1262{
1263 int ret = 0;
1264 BN_CTX *new_ctx = NULL;
1265 BIGNUM *curve_p, *curve_a, *curve_b;
1266
1267 if (ctx == NULL)
1268 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
1269 return 0;
1270 BN_CTX_start(ctx);
1271 if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
1272 ((curve_a = BN_CTX_get(ctx)) == NULL) ||
1273 ((curve_b = BN_CTX_get(ctx)) == NULL))
1274 goto err;
1275 BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
1276 BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
1277 BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
1278 if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
1279 (BN_cmp(curve_b, b))) {
1280 ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE,
1281 EC_R_WRONG_CURVE_PARAMETERS);
1282 goto err;
1283 }
1284 group->field_mod_func = BN_nist_mod_224;
1285 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
1286err:
1287 BN_CTX_end(ctx);
1288 BN_CTX_free(new_ctx);
1289 return ret;
1290}
1291
1292/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
1293 * (X', Y') = (X/Z^2, Y/Z^3) */
1294int
1295ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP * group,
1296 const EC_POINT * point, BIGNUM * x, BIGNUM * y, BN_CTX * ctx)
1297{
1298 felem z1, z2, x_in, y_in, x_out, y_out;
1299 widefelem tmp;
1300
1301 if (EC_POINT_is_at_infinity(group, point) > 0) {
1302 ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
1303 EC_R_POINT_AT_INFINITY);
1304 return 0;
1305 }
1306 if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
1307 (!BN_to_felem(z1, &point->Z)))
1308 return 0;
1309 felem_inv(z2, z1);
1310 felem_square(tmp, z2);
1311 felem_reduce(z1, tmp);
1312 felem_mul(tmp, x_in, z1);
1313 felem_reduce(x_in, tmp);
1314 felem_contract(x_out, x_in);
1315 if (x != NULL) {
1316 if (!felem_to_BN(x, x_out)) {
1317 ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
1318 ERR_R_BN_LIB);
1319 return 0;
1320 }
1321 }
1322 felem_mul(tmp, z1, z2);
1323 felem_reduce(z1, tmp);
1324 felem_mul(tmp, y_in, z1);
1325 felem_reduce(y_in, tmp);
1326 felem_contract(y_out, y_in);
1327 if (y != NULL) {
1328 if (!felem_to_BN(y, y_out)) {
1329 ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
1330 ERR_R_BN_LIB);
1331 return 0;
1332 }
1333 }
1334 return 1;
1335}
1336
1337static void
1338make_points_affine(size_t num, felem points[ /* num */ ][3], felem tmp_felems[ /* num+1 */ ])
1339{
1340 /*
1341 * Runs in constant time, unless an input is the point at infinity
1342 * (which normally shouldn't happen).
1343 */
1344 ec_GFp_nistp_points_make_affine_internal(
1345 num,
1346 points,
1347 sizeof(felem),
1348 tmp_felems,
1349 (void (*) (void *)) felem_one,
1350 (int (*) (const void *)) felem_is_zero_int,
1351 (void (*) (void *, const void *)) felem_assign,
1352 (void (*) (void *, const void *)) felem_square_reduce,
1353 (void (*) (void *, const void *, const void *)) felem_mul_reduce,
1354 (void (*) (void *, const void *)) felem_inv,
1355 (void (*) (void *, const void *)) felem_contract);
1356}
1357
1358/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
1359 * Result is stored in r (r can equal one of the inputs). */
1360int
1361ec_GFp_nistp224_points_mul(const EC_GROUP * group, EC_POINT * r,
1362 const BIGNUM * scalar, size_t num, const EC_POINT * points[],
1363 const BIGNUM * scalars[], BN_CTX * ctx)
1364{
1365 int ret = 0;
1366 int j;
1367 unsigned i;
1368 int mixed = 0;
1369 BN_CTX *new_ctx = NULL;
1370 BIGNUM *x, *y, *z, *tmp_scalar;
1371 felem_bytearray g_secret;
1372 felem_bytearray *secrets = NULL;
1373 felem(*pre_comp)[17][3] = NULL;
1374 felem *tmp_felems = NULL;
1375 felem_bytearray tmp;
1376 unsigned num_bytes;
1377 int have_pre_comp = 0;
1378 size_t num_points = num;
1379 felem x_in, y_in, z_in, x_out, y_out, z_out;
1380 NISTP224_PRE_COMP *pre = NULL;
1381 const felem(*g_pre_comp)[16][3] = NULL;
1382 EC_POINT *generator = NULL;
1383 const EC_POINT *p = NULL;
1384 const BIGNUM *p_scalar = NULL;
1385
1386 if (ctx == NULL)
1387 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
1388 return 0;
1389 BN_CTX_start(ctx);
1390 if (((x = BN_CTX_get(ctx)) == NULL) ||
1391 ((y = BN_CTX_get(ctx)) == NULL) ||
1392 ((z = BN_CTX_get(ctx)) == NULL) ||
1393 ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
1394 goto err;
1395
1396 if (scalar != NULL) {
1397 pre = EC_EX_DATA_get_data(group->extra_data,
1398 nistp224_pre_comp_dup, nistp224_pre_comp_free,
1399 nistp224_pre_comp_clear_free);
1400 if (pre)
1401 /* we have precomputation, try to use it */
1402 g_pre_comp = (const felem(*)[16][3]) pre->g_pre_comp;
1403 else
1404 /* try to use the standard precomputation */
1405 g_pre_comp = &gmul[0];
1406 generator = EC_POINT_new(group);
1407 if (generator == NULL)
1408 goto err;
1409 /* get the generator from precomputation */
1410 if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
1411 !felem_to_BN(y, g_pre_comp[0][1][1]) ||
1412 !felem_to_BN(z, g_pre_comp[0][1][2])) {
1413 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
1414 goto err;
1415 }
1416 if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
1417 generator, x, y, z, ctx))
1418 goto err;
1419 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
1420 /* precomputation matches generator */
1421 have_pre_comp = 1;
1422 else
1423 /*
1424 * we don't have valid precomputation: treat the
1425 * generator as a random point
1426 */
1427 num_points = num_points + 1;
1428 }
1429 if (num_points > 0) {
1430 if (num_points >= 3) {
1431 /*
1432 * unless we precompute multiples for just one or two
1433 * points, converting those into affine form is time
1434 * well spent
1435 */
1436 mixed = 1;
1437 }
1438 secrets = calloc(num_points, sizeof(felem_bytearray));
1439 pre_comp = calloc(num_points, 17 * 3 * sizeof(felem));
1440 if (mixed) {
1441 /* XXX should do more int overflow checking */
1442 tmp_felems = reallocarray(NULL,
1443 (num_points * 17 + 1), sizeof(felem));
1444 }
1445 if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL))) {
1446 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE);
1447 goto err;
1448 }
1449 /*
1450 * we treat NULL scalars as 0, and NULL points as points at
1451 * infinity, i.e., they contribute nothing to the linear
1452 * combination
1453 */
1454 for (i = 0; i < num_points; ++i) {
1455 if (i == num)
1456 /* the generator */
1457 {
1458 p = EC_GROUP_get0_generator(group);
1459 p_scalar = scalar;
1460 } else
1461 /* the i^th point */
1462 {
1463 p = points[i];
1464 p_scalar = scalars[i];
1465 }
1466 if ((p_scalar != NULL) && (p != NULL)) {
1467 /* reduce scalar to 0 <= scalar < 2^224 */
1468 if ((BN_num_bits(p_scalar) > 224) || (BN_is_negative(p_scalar))) {
1469 /*
1470 * this is an unusual input, and we
1471 * don't guarantee constant-timeness
1472 */
1473 if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
1474 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
1475 goto err;
1476 }
1477 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1478 } else
1479 num_bytes = BN_bn2bin(p_scalar, tmp);
1480 flip_endian(secrets[i], tmp, num_bytes);
1481 /* precompute multiples */
1482 if ((!BN_to_felem(x_out, &p->X)) ||
1483 (!BN_to_felem(y_out, &p->Y)) ||
1484 (!BN_to_felem(z_out, &p->Z)))
1485 goto err;
1486 felem_assign(pre_comp[i][1][0], x_out);
1487 felem_assign(pre_comp[i][1][1], y_out);
1488 felem_assign(pre_comp[i][1][2], z_out);
1489 for (j = 2; j <= 16; ++j) {
1490 if (j & 1) {
1491 point_add(
1492 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1493 pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
1494 0, pre_comp[i][j - 1][0], pre_comp[i][j - 1][1], pre_comp[i][j - 1][2]);
1495 } else {
1496 point_double(
1497 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1498 pre_comp[i][j / 2][0], pre_comp[i][j / 2][1], pre_comp[i][j / 2][2]);
1499 }
1500 }
1501 }
1502 }
1503 if (mixed)
1504 make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
1505 }
1506 /* the scalar for the generator */
1507 if ((scalar != NULL) && (have_pre_comp)) {
1508 memset(g_secret, 0, sizeof g_secret);
1509 /* reduce scalar to 0 <= scalar < 2^224 */
1510 if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar))) {
1511 /*
1512 * this is an unusual input, and we don't guarantee
1513 * constant-timeness
1514 */
1515 if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
1516 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
1517 goto err;
1518 }
1519 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1520 } else
1521 num_bytes = BN_bn2bin(scalar, tmp);
1522 flip_endian(g_secret, tmp, num_bytes);
1523 /* do the multiplication with generator precomputation */
1524 batch_mul(x_out, y_out, z_out,
1525 (const felem_bytearray(*)) secrets, num_points,
1526 g_secret,
1527 mixed, (const felem(*)[17][3]) pre_comp,
1528 g_pre_comp);
1529 } else
1530 /* do the multiplication without generator precomputation */
1531 batch_mul(x_out, y_out, z_out,
1532 (const felem_bytearray(*)) secrets, num_points,
1533 NULL, mixed, (const felem(*)[17][3]) pre_comp, NULL);
1534 /* reduce the output to its unique minimal representation */
1535 felem_contract(x_in, x_out);
1536 felem_contract(y_in, y_out);
1537 felem_contract(z_in, z_out);
1538 if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
1539 (!felem_to_BN(z, z_in))) {
1540 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
1541 goto err;
1542 }
1543 ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
1544
1545err:
1546 BN_CTX_end(ctx);
1547 EC_POINT_free(generator);
1548 BN_CTX_free(new_ctx);
1549 free(secrets);
1550 free(pre_comp);
1551 free(tmp_felems);
1552 return ret;
1553}
1554
1555int
1556ec_GFp_nistp224_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
1557{
1558 int ret = 0;
1559 NISTP224_PRE_COMP *pre = NULL;
1560 int i, j;
1561 BN_CTX *new_ctx = NULL;
1562 BIGNUM *x, *y;
1563 EC_POINT *generator = NULL;
1564 felem tmp_felems[32];
1565
1566 /* throw away old precomputation */
1567 EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup,
1568 nistp224_pre_comp_free, nistp224_pre_comp_clear_free);
1569 if (ctx == NULL)
1570 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
1571 return 0;
1572 BN_CTX_start(ctx);
1573 if (((x = BN_CTX_get(ctx)) == NULL) ||
1574 ((y = BN_CTX_get(ctx)) == NULL))
1575 goto err;
1576 /* get the generator */
1577 if (group->generator == NULL)
1578 goto err;
1579 generator = EC_POINT_new(group);
1580 if (generator == NULL)
1581 goto err;
1582 BN_bin2bn(nistp224_curve_params[3], sizeof(felem_bytearray), x);
1583 BN_bin2bn(nistp224_curve_params[4], sizeof(felem_bytearray), y);
1584 if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
1585 goto err;
1586 if ((pre = nistp224_pre_comp_new()) == NULL)
1587 goto err;
1588 /* if the generator is the standard one, use built-in precomputation */
1589 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
1590 memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
1591 ret = 1;
1592 goto err;
1593 }
1594 if ((!BN_to_felem(pre->g_pre_comp[0][1][0], &group->generator->X)) ||
1595 (!BN_to_felem(pre->g_pre_comp[0][1][1], &group->generator->Y)) ||
1596 (!BN_to_felem(pre->g_pre_comp[0][1][2], &group->generator->Z)))
1597 goto err;
1598 /*
1599 * compute 2^56*G, 2^112*G, 2^168*G for the first table, 2^28*G,
1600 * 2^84*G, 2^140*G, 2^196*G for the second one
1601 */
1602 for (i = 1; i <= 8; i <<= 1) {
1603 point_double(
1604 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
1605 pre->g_pre_comp[0][i][0], pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
1606 for (j = 0; j < 27; ++j) {
1607 point_double(
1608 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
1609 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
1610 }
1611 if (i == 8)
1612 break;
1613 point_double(
1614 pre->g_pre_comp[0][2 * i][0], pre->g_pre_comp[0][2 * i][1], pre->g_pre_comp[0][2 * i][2],
1615 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
1616 for (j = 0; j < 27; ++j) {
1617 point_double(
1618 pre->g_pre_comp[0][2 * i][0], pre->g_pre_comp[0][2 * i][1], pre->g_pre_comp[0][2 * i][2],
1619 pre->g_pre_comp[0][2 * i][0], pre->g_pre_comp[0][2 * i][1], pre->g_pre_comp[0][2 * i][2]);
1620 }
1621 }
1622 for (i = 0; i < 2; i++) {
1623 /* g_pre_comp[i][0] is the point at infinity */
1624 memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
1625 /* the remaining multiples */
1626 /* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */
1627 point_add(
1628 pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
1629 pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
1630 pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
1631 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
1632 pre->g_pre_comp[i][2][2]);
1633 /* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */
1634 point_add(
1635 pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
1636 pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
1637 pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
1638 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
1639 pre->g_pre_comp[i][2][2]);
1640 /* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */
1641 point_add(
1642 pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
1643 pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
1644 pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
1645 0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
1646 pre->g_pre_comp[i][4][2]);
1647 /*
1648 * 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G +
1649 * 2^196*G
1650 */
1651 point_add(
1652 pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
1653 pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
1654 pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
1655 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
1656 pre->g_pre_comp[i][2][2]);
1657 for (j = 1; j < 8; ++j) {
1658 /* odd multiples: add G resp. 2^28*G */
1659 point_add(
1660 pre->g_pre_comp[i][2 * j + 1][0], pre->g_pre_comp[i][2 * j + 1][1],
1661 pre->g_pre_comp[i][2 * j + 1][2], pre->g_pre_comp[i][2 * j][0],
1662 pre->g_pre_comp[i][2 * j][1], pre->g_pre_comp[i][2 * j][2],
1663 0, pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1],
1664 pre->g_pre_comp[i][1][2]);
1665 }
1666 }
1667 make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems);
1668
1669 if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup,
1670 nistp224_pre_comp_free, nistp224_pre_comp_clear_free))
1671 goto err;
1672 ret = 1;
1673 pre = NULL;
1674err:
1675 BN_CTX_end(ctx);
1676 EC_POINT_free(generator);
1677 BN_CTX_free(new_ctx);
1678 nistp224_pre_comp_free(pre);
1679 return ret;
1680}
1681
1682int
1683ec_GFp_nistp224_have_precompute_mult(const EC_GROUP * group)
1684{
1685 if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup,
1686 nistp224_pre_comp_free, nistp224_pre_comp_clear_free)
1687 != NULL)
1688 return 1;
1689 else
1690 return 0;
1691}
1692
1693#endif
diff --git a/src/lib/libcrypto/ec/ecp_nistp256.c b/src/lib/libcrypto/ec/ecp_nistp256.c
deleted file mode 100644
index be1d2a5402..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistp256.c
+++ /dev/null
@@ -1,2239 +0,0 @@
1/* $OpenBSD: ecp_nistp256.c,v 1.16 2015/09/10 15:56:25 jsing Exp $ */
2/*
3 * Written by Adam Langley (Google) for the OpenSSL project
4 */
5/*
6 * Copyright (c) 2011 Google Inc.
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/*
22 * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication
23 *
24 * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
25 * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
26 * work which got its smarts from Daniel J. Bernstein's work on the same.
27 */
28
29#include <stdint.h>
30#include <string.h>
31
32#include <openssl/opensslconf.h>
33
34#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
35
36#include <openssl/err.h>
37#include "ec_lcl.h"
38
39#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
40 /* even with gcc, the typedef won't work for 32-bit platforms */
41 typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
42 typedef __int128_t int128_t;
43#else
44 #error "Need GCC 3.1 or later to define type uint128_t"
45#endif
46
47typedef uint8_t u8;
48typedef uint32_t u32;
49typedef uint64_t u64;
50typedef int64_t s64;
51
52/* The underlying field.
53 *
54 * P256 operates over GF(2^256-2^224+2^192+2^96-1). We can serialise an element
55 * of this field into 32 bytes. We call this an felem_bytearray. */
56
57typedef u8 felem_bytearray[32];
58
59/* These are the parameters of P256, taken from FIPS 186-3, page 86. These
60 * values are big-endian. */
61static const felem_bytearray nistp256_curve_params[5] = {
62 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
66 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
69 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */
70 {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
71 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
72 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
73 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
74 {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */
75 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
76 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
77 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96},
78 {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */
79 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
80 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
81 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5}
82};
83
84/* The representation of field elements.
85 * ------------------------------------
86 *
87 * We represent field elements with either four 128-bit values, eight 128-bit
88 * values, or four 64-bit values. The field element represented is:
89 * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192 (mod p)
90 * or:
91 * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512 (mod p)
92 *
93 * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits
94 * apart, but are 128-bits wide, the most significant bits of each limb overlap
95 * with the least significant bits of the next.
96 *
97 * A field element with four limbs is an 'felem'. One with eight limbs is a
98 * 'longfelem'
99 *
100 * A field element with four, 64-bit values is called a 'smallfelem'. Small
101 * values are used as intermediate values before multiplication.
102 */
103
104#define NLIMBS 4
105
106typedef uint128_t limb;
107typedef limb felem[NLIMBS];
108typedef limb longfelem[NLIMBS * 2];
109typedef u64 smallfelem[NLIMBS];
110
111/* This is the value of the prime as four 64-bit words, little-endian. */
112static const u64 kPrime[4] = {0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul};
113static const limb bottom32bits = 0xffffffff;
114static const u64 bottom63bits = 0x7ffffffffffffffful;
115
116/* bin32_to_felem takes a little-endian byte array and converts it into felem
117 * form. This assumes that the CPU is little-endian. */
118static void
119bin32_to_felem(felem out, const u8 in[32])
120{
121 out[0] = *((u64 *) & in[0]);
122 out[1] = *((u64 *) & in[8]);
123 out[2] = *((u64 *) & in[16]);
124 out[3] = *((u64 *) & in[24]);
125}
126
127/* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian,
128 * 32 byte array. This assumes that the CPU is little-endian. */
129static void
130smallfelem_to_bin32(u8 out[32], const smallfelem in)
131{
132 *((u64 *) & out[0]) = in[0];
133 *((u64 *) & out[8]) = in[1];
134 *((u64 *) & out[16]) = in[2];
135 *((u64 *) & out[24]) = in[3];
136}
137
138/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
139static void
140flip_endian(u8 * out, const u8 * in, unsigned len)
141{
142 unsigned i;
143 for (i = 0; i < len; ++i)
144 out[i] = in[len - 1 - i];
145}
146
147/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
148static int
149BN_to_felem(felem out, const BIGNUM * bn)
150{
151 felem_bytearray b_in;
152 felem_bytearray b_out;
153 unsigned num_bytes;
154
155 /* BN_bn2bin eats leading zeroes */
156 memset(b_out, 0, sizeof b_out);
157 num_bytes = BN_num_bytes(bn);
158 if (num_bytes > sizeof b_out) {
159 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
160 return 0;
161 }
162 if (BN_is_negative(bn)) {
163 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
164 return 0;
165 }
166 num_bytes = BN_bn2bin(bn, b_in);
167 flip_endian(b_out, b_in, num_bytes);
168 bin32_to_felem(out, b_out);
169 return 1;
170}
171
172/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
173static BIGNUM *
174smallfelem_to_BN(BIGNUM * out, const smallfelem in)
175{
176 felem_bytearray b_in, b_out;
177 smallfelem_to_bin32(b_in, in);
178 flip_endian(b_out, b_in, sizeof b_out);
179 return BN_bin2bn(b_out, sizeof b_out, out);
180}
181
182
183/* Field operations
184 * ---------------- */
185
186static void
187smallfelem_one(smallfelem out)
188{
189 out[0] = 1;
190 out[1] = 0;
191 out[2] = 0;
192 out[3] = 0;
193}
194
195static void
196smallfelem_assign(smallfelem out, const smallfelem in)
197{
198 out[0] = in[0];
199 out[1] = in[1];
200 out[2] = in[2];
201 out[3] = in[3];
202}
203
204static void
205felem_assign(felem out, const felem in)
206{
207 out[0] = in[0];
208 out[1] = in[1];
209 out[2] = in[2];
210 out[3] = in[3];
211}
212
213/* felem_sum sets out = out + in. */
214static void
215felem_sum(felem out, const felem in)
216{
217 out[0] += in[0];
218 out[1] += in[1];
219 out[2] += in[2];
220 out[3] += in[3];
221}
222
223/* felem_small_sum sets out = out + in. */
224static void
225felem_small_sum(felem out, const smallfelem in)
226{
227 out[0] += in[0];
228 out[1] += in[1];
229 out[2] += in[2];
230 out[3] += in[3];
231}
232
233/* felem_scalar sets out = out * scalar */
234static void
235felem_scalar(felem out, const u64 scalar)
236{
237 out[0] *= scalar;
238 out[1] *= scalar;
239 out[2] *= scalar;
240 out[3] *= scalar;
241}
242
243/* longfelem_scalar sets out = out * scalar */
244static void
245longfelem_scalar(longfelem out, const u64 scalar)
246{
247 out[0] *= scalar;
248 out[1] *= scalar;
249 out[2] *= scalar;
250 out[3] *= scalar;
251 out[4] *= scalar;
252 out[5] *= scalar;
253 out[6] *= scalar;
254 out[7] *= scalar;
255}
256
257#define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
258#define two105 (((limb)1) << 105)
259#define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
260
261/* zero105 is 0 mod p */
262static const felem zero105 = {two105m41m9, two105, two105m41p9, two105m41p9};
263
264/* smallfelem_neg sets |out| to |-small|
265 * On exit:
266 * out[i] < out[i] + 2^105
267 */
268static void
269smallfelem_neg(felem out, const smallfelem small)
270{
271 /* In order to prevent underflow, we subtract from 0 mod p. */
272 out[0] = zero105[0] - small[0];
273 out[1] = zero105[1] - small[1];
274 out[2] = zero105[2] - small[2];
275 out[3] = zero105[3] - small[3];
276}
277
278/* felem_diff subtracts |in| from |out|
279 * On entry:
280 * in[i] < 2^104
281 * On exit:
282 * out[i] < out[i] + 2^105
283 */
284static void
285felem_diff(felem out, const felem in)
286{
287 /* In order to prevent underflow, we add 0 mod p before subtracting. */
288 out[0] += zero105[0];
289 out[1] += zero105[1];
290 out[2] += zero105[2];
291 out[3] += zero105[3];
292
293 out[0] -= in[0];
294 out[1] -= in[1];
295 out[2] -= in[2];
296 out[3] -= in[3];
297}
298
299#define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
300#define two107 (((limb)1) << 107)
301#define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
302
303/* zero107 is 0 mod p */
304static const felem zero107 = {two107m43m11, two107, two107m43p11, two107m43p11};
305
306/* An alternative felem_diff for larger inputs |in|
307 * felem_diff_zero107 subtracts |in| from |out|
308 * On entry:
309 * in[i] < 2^106
310 * On exit:
311 * out[i] < out[i] + 2^107
312 */
313static void
314felem_diff_zero107(felem out, const felem in)
315{
316 /* In order to prevent underflow, we add 0 mod p before subtracting. */
317 out[0] += zero107[0];
318 out[1] += zero107[1];
319 out[2] += zero107[2];
320 out[3] += zero107[3];
321
322 out[0] -= in[0];
323 out[1] -= in[1];
324 out[2] -= in[2];
325 out[3] -= in[3];
326}
327
328/* longfelem_diff subtracts |in| from |out|
329 * On entry:
330 * in[i] < 7*2^67
331 * On exit:
332 * out[i] < out[i] + 2^70 + 2^40
333 */
334static void
335longfelem_diff(longfelem out, const longfelem in)
336{
337 static const limb two70m8p6 = (((limb) 1) << 70) - (((limb) 1) << 8) + (((limb) 1) << 6);
338 static const limb two70p40 = (((limb) 1) << 70) + (((limb) 1) << 40);
339 static const limb two70 = (((limb) 1) << 70);
340 static const limb two70m40m38p6 = (((limb) 1) << 70) - (((limb) 1) << 40) - (((limb) 1) << 38) + (((limb) 1) << 6);
341 static const limb two70m6 = (((limb) 1) << 70) - (((limb) 1) << 6);
342
343 /* add 0 mod p to avoid underflow */
344 out[0] += two70m8p6;
345 out[1] += two70p40;
346 out[2] += two70;
347 out[3] += two70m40m38p6;
348 out[4] += two70m6;
349 out[5] += two70m6;
350 out[6] += two70m6;
351 out[7] += two70m6;
352
353 /* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */
354 out[0] -= in[0];
355 out[1] -= in[1];
356 out[2] -= in[2];
357 out[3] -= in[3];
358 out[4] -= in[4];
359 out[5] -= in[5];
360 out[6] -= in[6];
361 out[7] -= in[7];
362}
363
364#define two64m0 (((limb)1) << 64) - 1
365#define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
366#define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
367#define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
368
369/* zero110 is 0 mod p */
370static const felem zero110 = {two64m0, two110p32m0, two64m46, two64m32};
371
372/* felem_shrink converts an felem into a smallfelem. The result isn't quite
373 * minimal as the value may be greater than p.
374 *
375 * On entry:
376 * in[i] < 2^109
377 * On exit:
378 * out[i] < 2^64
379 */
380static void
381felem_shrink(smallfelem out, const felem in)
382{
383 felem tmp;
384 u64 a, b, mask;
385 s64 high, low;
386 static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */
387
388 /* Carry 2->3 */
389 tmp[3] = zero110[3] + in[3] + ((u64) (in[2] >> 64));
390 /* tmp[3] < 2^110 */
391
392 tmp[2] = zero110[2] + (u64) in[2];
393 tmp[0] = zero110[0] + in[0];
394 tmp[1] = zero110[1] + in[1];
395 /* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */
396
397 /*
398 * We perform two partial reductions where we eliminate the high-word
399 * of tmp[3]. We don't update the other words till the end.
400 */
401 a = tmp[3] >> 64; /* a < 2^46 */
402 tmp[3] = (u64) tmp[3];
403 tmp[3] -= a;
404 tmp[3] += ((limb) a) << 32;
405 /* tmp[3] < 2^79 */
406
407 b = a;
408 a = tmp[3] >> 64; /* a < 2^15 */
409 b += a; /* b < 2^46 + 2^15 < 2^47 */
410 tmp[3] = (u64) tmp[3];
411 tmp[3] -= a;
412 tmp[3] += ((limb) a) << 32;
413 /* tmp[3] < 2^64 + 2^47 */
414
415 /*
416 * This adjusts the other two words to complete the two partial
417 * reductions.
418 */
419 tmp[0] += b;
420 tmp[1] -= (((limb) b) << 32);
421
422 /*
423 * In order to make space in tmp[3] for the carry from 2 -> 3, we
424 * conditionally subtract kPrime if tmp[3] is large enough.
425 */
426 high = tmp[3] >> 64;
427 /* As tmp[3] < 2^65, high is either 1 or 0 */
428 high <<= 63;
429 high >>= 63;
430 /*
431 * high is: all ones if the high word of tmp[3] is 1 all zeros if
432 * the high word of tmp[3] if 0
433 */
434 low = tmp[3];
435 mask = low >> 63;
436 /*
437 * mask is: all ones if the MSB of low is 1 all zeros if the MSB
438 * of low if 0
439 */
440 low &= bottom63bits;
441 low -= kPrime3Test;
442 /* if low was greater than kPrime3Test then the MSB is zero */
443 low = ~low;
444 low >>= 63;
445 /*
446 * low is: all ones if low was > kPrime3Test all zeros if low was
447 * <= kPrime3Test
448 */
449 mask = (mask & low) | high;
450 tmp[0] -= mask & kPrime[0];
451 tmp[1] -= mask & kPrime[1];
452 /* kPrime[2] is zero, so omitted */
453 tmp[3] -= mask & kPrime[3];
454 /* tmp[3] < 2**64 - 2**32 + 1 */
455
456 tmp[1] += ((u64) (tmp[0] >> 64));
457 tmp[0] = (u64) tmp[0];
458 tmp[2] += ((u64) (tmp[1] >> 64));
459 tmp[1] = (u64) tmp[1];
460 tmp[3] += ((u64) (tmp[2] >> 64));
461 tmp[2] = (u64) tmp[2];
462 /* tmp[i] < 2^64 */
463
464 out[0] = tmp[0];
465 out[1] = tmp[1];
466 out[2] = tmp[2];
467 out[3] = tmp[3];
468}
469
470/* smallfelem_expand converts a smallfelem to an felem */
471static void
472smallfelem_expand(felem out, const smallfelem in)
473{
474 out[0] = in[0];
475 out[1] = in[1];
476 out[2] = in[2];
477 out[3] = in[3];
478}
479
480/* smallfelem_square sets |out| = |small|^2
481 * On entry:
482 * small[i] < 2^64
483 * On exit:
484 * out[i] < 7 * 2^64 < 2^67
485 */
486static void
487smallfelem_square(longfelem out, const smallfelem small)
488{
489 limb a;
490 u64 high, low;
491
492 a = ((uint128_t) small[0]) * small[0];
493 low = a;
494 high = a >> 64;
495 out[0] = low;
496 out[1] = high;
497
498 a = ((uint128_t) small[0]) * small[1];
499 low = a;
500 high = a >> 64;
501 out[1] += low;
502 out[1] += low;
503 out[2] = high;
504
505 a = ((uint128_t) small[0]) * small[2];
506 low = a;
507 high = a >> 64;
508 out[2] += low;
509 out[2] *= 2;
510 out[3] = high;
511
512 a = ((uint128_t) small[0]) * small[3];
513 low = a;
514 high = a >> 64;
515 out[3] += low;
516 out[4] = high;
517
518 a = ((uint128_t) small[1]) * small[2];
519 low = a;
520 high = a >> 64;
521 out[3] += low;
522 out[3] *= 2;
523 out[4] += high;
524
525 a = ((uint128_t) small[1]) * small[1];
526 low = a;
527 high = a >> 64;
528 out[2] += low;
529 out[3] += high;
530
531 a = ((uint128_t) small[1]) * small[3];
532 low = a;
533 high = a >> 64;
534 out[4] += low;
535 out[4] *= 2;
536 out[5] = high;
537
538 a = ((uint128_t) small[2]) * small[3];
539 low = a;
540 high = a >> 64;
541 out[5] += low;
542 out[5] *= 2;
543 out[6] = high;
544 out[6] += high;
545
546 a = ((uint128_t) small[2]) * small[2];
547 low = a;
548 high = a >> 64;
549 out[4] += low;
550 out[5] += high;
551
552 a = ((uint128_t) small[3]) * small[3];
553 low = a;
554 high = a >> 64;
555 out[6] += low;
556 out[7] = high;
557}
558
559/* felem_square sets |out| = |in|^2
560 * On entry:
561 * in[i] < 2^109
562 * On exit:
563 * out[i] < 7 * 2^64 < 2^67
564 */
565static void
566felem_square(longfelem out, const felem in)
567{
568 u64 small[4];
569 felem_shrink(small, in);
570 smallfelem_square(out, small);
571}
572
573/* smallfelem_mul sets |out| = |small1| * |small2|
574 * On entry:
575 * small1[i] < 2^64
576 * small2[i] < 2^64
577 * On exit:
578 * out[i] < 7 * 2^64 < 2^67
579 */
580static void
581smallfelem_mul(longfelem out, const smallfelem small1, const smallfelem small2)
582{
583 limb a;
584 u64 high, low;
585
586 a = ((uint128_t) small1[0]) * small2[0];
587 low = a;
588 high = a >> 64;
589 out[0] = low;
590 out[1] = high;
591
592
593 a = ((uint128_t) small1[0]) * small2[1];
594 low = a;
595 high = a >> 64;
596 out[1] += low;
597 out[2] = high;
598
599 a = ((uint128_t) small1[1]) * small2[0];
600 low = a;
601 high = a >> 64;
602 out[1] += low;
603 out[2] += high;
604
605
606 a = ((uint128_t) small1[0]) * small2[2];
607 low = a;
608 high = a >> 64;
609 out[2] += low;
610 out[3] = high;
611
612 a = ((uint128_t) small1[1]) * small2[1];
613 low = a;
614 high = a >> 64;
615 out[2] += low;
616 out[3] += high;
617
618 a = ((uint128_t) small1[2]) * small2[0];
619 low = a;
620 high = a >> 64;
621 out[2] += low;
622 out[3] += high;
623
624
625 a = ((uint128_t) small1[0]) * small2[3];
626 low = a;
627 high = a >> 64;
628 out[3] += low;
629 out[4] = high;
630
631 a = ((uint128_t) small1[1]) * small2[2];
632 low = a;
633 high = a >> 64;
634 out[3] += low;
635 out[4] += high;
636
637 a = ((uint128_t) small1[2]) * small2[1];
638 low = a;
639 high = a >> 64;
640 out[3] += low;
641 out[4] += high;
642
643 a = ((uint128_t) small1[3]) * small2[0];
644 low = a;
645 high = a >> 64;
646 out[3] += low;
647 out[4] += high;
648
649
650 a = ((uint128_t) small1[1]) * small2[3];
651 low = a;
652 high = a >> 64;
653 out[4] += low;
654 out[5] = high;
655
656 a = ((uint128_t) small1[2]) * small2[2];
657 low = a;
658 high = a >> 64;
659 out[4] += low;
660 out[5] += high;
661
662 a = ((uint128_t) small1[3]) * small2[1];
663 low = a;
664 high = a >> 64;
665 out[4] += low;
666 out[5] += high;
667
668
669 a = ((uint128_t) small1[2]) * small2[3];
670 low = a;
671 high = a >> 64;
672 out[5] += low;
673 out[6] = high;
674
675 a = ((uint128_t) small1[3]) * small2[2];
676 low = a;
677 high = a >> 64;
678 out[5] += low;
679 out[6] += high;
680
681
682 a = ((uint128_t) small1[3]) * small2[3];
683 low = a;
684 high = a >> 64;
685 out[6] += low;
686 out[7] = high;
687}
688
689/* felem_mul sets |out| = |in1| * |in2|
690 * On entry:
691 * in1[i] < 2^109
692 * in2[i] < 2^109
693 * On exit:
694 * out[i] < 7 * 2^64 < 2^67
695 */
696static void
697felem_mul(longfelem out, const felem in1, const felem in2)
698{
699 smallfelem small1, small2;
700 felem_shrink(small1, in1);
701 felem_shrink(small2, in2);
702 smallfelem_mul(out, small1, small2);
703}
704
705/* felem_small_mul sets |out| = |small1| * |in2|
706 * On entry:
707 * small1[i] < 2^64
708 * in2[i] < 2^109
709 * On exit:
710 * out[i] < 7 * 2^64 < 2^67
711 */
712static void
713felem_small_mul(longfelem out, const smallfelem small1, const felem in2)
714{
715 smallfelem small2;
716 felem_shrink(small2, in2);
717 smallfelem_mul(out, small1, small2);
718}
719
720#define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
721#define two100 (((limb)1) << 100)
722#define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
723/* zero100 is 0 mod p */
724static const felem zero100 = {two100m36m4, two100, two100m36p4, two100m36p4};
725
726/* Internal function for the different flavours of felem_reduce.
727 * felem_reduce_ reduces the higher coefficients in[4]-in[7].
728 * On entry:
729 * out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7]
730 * out[1] >= in[7] + 2^32*in[4]
731 * out[2] >= in[5] + 2^32*in[5]
732 * out[3] >= in[4] + 2^32*in[5] + 2^32*in[6]
733 * On exit:
734 * out[0] <= out[0] + in[4] + 2^32*in[5]
735 * out[1] <= out[1] + in[5] + 2^33*in[6]
736 * out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7]
737 * out[3] <= out[3] + 2^32*in[4] + 3*in[7]
738 */
739static void
740felem_reduce_(felem out, const longfelem in)
741{
742 int128_t c;
743 /* combine common terms from below */
744 c = in[4] + (in[5] << 32);
745 out[0] += c;
746 out[3] -= c;
747
748 c = in[5] - in[7];
749 out[1] += c;
750 out[2] -= c;
751
752 /* the remaining terms */
753 /* 256: [(0,1),(96,-1),(192,-1),(224,1)] */
754 out[1] -= (in[4] << 32);
755 out[3] += (in[4] << 32);
756
757 /* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */
758 out[2] -= (in[5] << 32);
759
760 /* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */
761 out[0] -= in[6];
762 out[0] -= (in[6] << 32);
763 out[1] += (in[6] << 33);
764 out[2] += (in[6] * 2);
765 out[3] -= (in[6] << 32);
766
767 /* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */
768 out[0] -= in[7];
769 out[0] -= (in[7] << 32);
770 out[2] += (in[7] << 33);
771 out[3] += (in[7] * 3);
772}
773
774/* felem_reduce converts a longfelem into an felem.
775 * To be called directly after felem_square or felem_mul.
776 * On entry:
777 * in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64
778 * in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64
779 * On exit:
780 * out[i] < 2^101
781 */
782static void
783felem_reduce(felem out, const longfelem in)
784{
785 out[0] = zero100[0] + in[0];
786 out[1] = zero100[1] + in[1];
787 out[2] = zero100[2] + in[2];
788 out[3] = zero100[3] + in[3];
789
790 felem_reduce_(out, in);
791
792 /*
793 * out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0
794 * out[1] > 2^100 - 2^64 - 7*2^96 > 0 out[2] > 2^100 - 2^36 + 2^4 -
795 * 5*2^64 - 5*2^96 > 0 out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96
796 * - 3*2^96 > 0
797 *
798 * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101 out[1] < 2^100 +
799 * 3*2^64 + 5*2^64 + 3*2^97 < 2^101 out[2] < 2^100 + 5*2^64 + 2^64 +
800 * 3*2^65 + 2^97 < 2^101 out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 <
801 * 2^101
802 */
803}
804
805/* felem_reduce_zero105 converts a larger longfelem into an felem.
806 * On entry:
807 * in[0] < 2^71
808 * On exit:
809 * out[i] < 2^106
810 */
811static void
812felem_reduce_zero105(felem out, const longfelem in)
813{
814 out[0] = zero105[0] + in[0];
815 out[1] = zero105[1] + in[1];
816 out[2] = zero105[2] + in[2];
817 out[3] = zero105[3] + in[3];
818
819 felem_reduce_(out, in);
820
821 /*
822 * out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0
823 * out[1] > 2^105 - 2^71 - 2^103 > 0 out[2] > 2^105 - 2^41 + 2^9 -
824 * 2^71 - 2^103 > 0 out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 -
825 * 2^103 > 0
826 *
827 * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106 out[1] < 2^105 + 2^71 +
828 * 2^71 + 2^103 < 2^106 out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 <
829 * 2^106 out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106
830 */
831}
832
833/* subtract_u64 sets *result = *result - v and *carry to one if the subtraction
834 * underflowed. */
835static void
836subtract_u64(u64 * result, u64 * carry, u64 v)
837{
838 uint128_t r = *result;
839 r -= v;
840 *carry = (r >> 64) & 1;
841 *result = (u64) r;
842}
843
844/* felem_contract converts |in| to its unique, minimal representation.
845 * On entry:
846 * in[i] < 2^109
847 */
848static void
849felem_contract(smallfelem out, const felem in)
850{
851 unsigned i;
852 u64 all_equal_so_far = 0, result = 0, carry;
853
854 felem_shrink(out, in);
855 /* small is minimal except that the value might be > p */
856
857 all_equal_so_far--;
858 /*
859 * We are doing a constant time test if out >= kPrime. We need to
860 * compare each u64, from most-significant to least significant. For
861 * each one, if all words so far have been equal (m is all ones) then
862 * a non-equal result is the answer. Otherwise we continue.
863 */
864 for (i = 3; i < 4; i--) {
865 u64 equal;
866 uint128_t a = ((uint128_t) kPrime[i]) - out[i];
867 /*
868 * if out[i] > kPrime[i] then a will underflow and the high
869 * 64-bits will all be set.
870 */
871 result |= all_equal_so_far & ((u64) (a >> 64));
872
873 /*
874 * if kPrime[i] == out[i] then |equal| will be all zeros and
875 * the decrement will make it all ones.
876 */
877 equal = kPrime[i] ^ out[i];
878 equal--;
879 equal &= equal << 32;
880 equal &= equal << 16;
881 equal &= equal << 8;
882 equal &= equal << 4;
883 equal &= equal << 2;
884 equal &= equal << 1;
885 equal = ((s64) equal) >> 63;
886
887 all_equal_so_far &= equal;
888 }
889
890 /*
891 * if all_equal_so_far is still all ones then the two values are
892 * equal and so out >= kPrime is true.
893 */
894 result |= all_equal_so_far;
895
896 /* if out >= kPrime then we subtract kPrime. */
897 subtract_u64(&out[0], &carry, result & kPrime[0]);
898 subtract_u64(&out[1], &carry, carry);
899 subtract_u64(&out[2], &carry, carry);
900 subtract_u64(&out[3], &carry, carry);
901
902 subtract_u64(&out[1], &carry, result & kPrime[1]);
903 subtract_u64(&out[2], &carry, carry);
904 subtract_u64(&out[3], &carry, carry);
905
906 subtract_u64(&out[2], &carry, result & kPrime[2]);
907 subtract_u64(&out[3], &carry, carry);
908
909 subtract_u64(&out[3], &carry, result & kPrime[3]);
910}
911
912static void
913smallfelem_square_contract(smallfelem out, const smallfelem in)
914{
915 longfelem longtmp;
916 felem tmp;
917
918 smallfelem_square(longtmp, in);
919 felem_reduce(tmp, longtmp);
920 felem_contract(out, tmp);
921}
922
923static void
924smallfelem_mul_contract(smallfelem out, const smallfelem in1, const smallfelem in2)
925{
926 longfelem longtmp;
927 felem tmp;
928
929 smallfelem_mul(longtmp, in1, in2);
930 felem_reduce(tmp, longtmp);
931 felem_contract(out, tmp);
932}
933
934/* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
935 * otherwise.
936 * On entry:
937 * small[i] < 2^64
938 */
939static limb
940smallfelem_is_zero(const smallfelem small)
941{
942 limb result;
943 u64 is_p;
944
945 u64 is_zero = small[0] | small[1] | small[2] | small[3];
946 is_zero--;
947 is_zero &= is_zero << 32;
948 is_zero &= is_zero << 16;
949 is_zero &= is_zero << 8;
950 is_zero &= is_zero << 4;
951 is_zero &= is_zero << 2;
952 is_zero &= is_zero << 1;
953 is_zero = ((s64) is_zero) >> 63;
954
955 is_p = (small[0] ^ kPrime[0]) |
956 (small[1] ^ kPrime[1]) |
957 (small[2] ^ kPrime[2]) |
958 (small[3] ^ kPrime[3]);
959 is_p--;
960 is_p &= is_p << 32;
961 is_p &= is_p << 16;
962 is_p &= is_p << 8;
963 is_p &= is_p << 4;
964 is_p &= is_p << 2;
965 is_p &= is_p << 1;
966 is_p = ((s64) is_p) >> 63;
967
968 is_zero |= is_p;
969
970 result = is_zero;
971 result |= ((limb) is_zero) << 64;
972 return result;
973}
974
975static int
976smallfelem_is_zero_int(const smallfelem small)
977{
978 return (int) (smallfelem_is_zero(small) & ((limb) 1));
979}
980
981/* felem_inv calculates |out| = |in|^{-1}
982 *
983 * Based on Fermat's Little Theorem:
984 * a^p = a (mod p)
985 * a^{p-1} = 1 (mod p)
986 * a^{p-2} = a^{-1} (mod p)
987 */
988static void
989felem_inv(felem out, const felem in)
990{
991 felem ftmp, ftmp2;
992 /* each e_I will hold |in|^{2^I - 1} */
993 felem e2, e4, e8, e16, e32, e64;
994 longfelem tmp;
995 unsigned i;
996
997 felem_square(tmp, in);
998 felem_reduce(ftmp, tmp);/* 2^1 */
999 felem_mul(tmp, in, ftmp);
1000 felem_reduce(ftmp, tmp);/* 2^2 - 2^0 */
1001 felem_assign(e2, ftmp);
1002 felem_square(tmp, ftmp);
1003 felem_reduce(ftmp, tmp);/* 2^3 - 2^1 */
1004 felem_square(tmp, ftmp);
1005 felem_reduce(ftmp, tmp);/* 2^4 - 2^2 */
1006 felem_mul(tmp, ftmp, e2);
1007 felem_reduce(ftmp, tmp);/* 2^4 - 2^0 */
1008 felem_assign(e4, ftmp);
1009 felem_square(tmp, ftmp);
1010 felem_reduce(ftmp, tmp);/* 2^5 - 2^1 */
1011 felem_square(tmp, ftmp);
1012 felem_reduce(ftmp, tmp);/* 2^6 - 2^2 */
1013 felem_square(tmp, ftmp);
1014 felem_reduce(ftmp, tmp);/* 2^7 - 2^3 */
1015 felem_square(tmp, ftmp);
1016 felem_reduce(ftmp, tmp);/* 2^8 - 2^4 */
1017 felem_mul(tmp, ftmp, e4);
1018 felem_reduce(ftmp, tmp);/* 2^8 - 2^0 */
1019 felem_assign(e8, ftmp);
1020 for (i = 0; i < 8; i++) {
1021 felem_square(tmp, ftmp);
1022 felem_reduce(ftmp, tmp);
1023 } /* 2^16 - 2^8 */
1024 felem_mul(tmp, ftmp, e8);
1025 felem_reduce(ftmp, tmp);/* 2^16 - 2^0 */
1026 felem_assign(e16, ftmp);
1027 for (i = 0; i < 16; i++) {
1028 felem_square(tmp, ftmp);
1029 felem_reduce(ftmp, tmp);
1030 } /* 2^32 - 2^16 */
1031 felem_mul(tmp, ftmp, e16);
1032 felem_reduce(ftmp, tmp);/* 2^32 - 2^0 */
1033 felem_assign(e32, ftmp);
1034 for (i = 0; i < 32; i++) {
1035 felem_square(tmp, ftmp);
1036 felem_reduce(ftmp, tmp);
1037 } /* 2^64 - 2^32 */
1038 felem_assign(e64, ftmp);
1039 felem_mul(tmp, ftmp, in);
1040 felem_reduce(ftmp, tmp);/* 2^64 - 2^32 + 2^0 */
1041 for (i = 0; i < 192; i++) {
1042 felem_square(tmp, ftmp);
1043 felem_reduce(ftmp, tmp);
1044 } /* 2^256 - 2^224 + 2^192 */
1045
1046 felem_mul(tmp, e64, e32);
1047 felem_reduce(ftmp2, tmp); /* 2^64 - 2^0 */
1048 for (i = 0; i < 16; i++) {
1049 felem_square(tmp, ftmp2);
1050 felem_reduce(ftmp2, tmp);
1051 } /* 2^80 - 2^16 */
1052 felem_mul(tmp, ftmp2, e16);
1053 felem_reduce(ftmp2, tmp); /* 2^80 - 2^0 */
1054 for (i = 0; i < 8; i++) {
1055 felem_square(tmp, ftmp2);
1056 felem_reduce(ftmp2, tmp);
1057 } /* 2^88 - 2^8 */
1058 felem_mul(tmp, ftmp2, e8);
1059 felem_reduce(ftmp2, tmp); /* 2^88 - 2^0 */
1060 for (i = 0; i < 4; i++) {
1061 felem_square(tmp, ftmp2);
1062 felem_reduce(ftmp2, tmp);
1063 } /* 2^92 - 2^4 */
1064 felem_mul(tmp, ftmp2, e4);
1065 felem_reduce(ftmp2, tmp); /* 2^92 - 2^0 */
1066 felem_square(tmp, ftmp2);
1067 felem_reduce(ftmp2, tmp); /* 2^93 - 2^1 */
1068 felem_square(tmp, ftmp2);
1069 felem_reduce(ftmp2, tmp); /* 2^94 - 2^2 */
1070 felem_mul(tmp, ftmp2, e2);
1071 felem_reduce(ftmp2, tmp); /* 2^94 - 2^0 */
1072 felem_square(tmp, ftmp2);
1073 felem_reduce(ftmp2, tmp); /* 2^95 - 2^1 */
1074 felem_square(tmp, ftmp2);
1075 felem_reduce(ftmp2, tmp); /* 2^96 - 2^2 */
1076 felem_mul(tmp, ftmp2, in);
1077 felem_reduce(ftmp2, tmp); /* 2^96 - 3 */
1078
1079 felem_mul(tmp, ftmp2, ftmp);
1080 felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
1081}
1082
1083static void
1084smallfelem_inv_contract(smallfelem out, const smallfelem in)
1085{
1086 felem tmp;
1087
1088 smallfelem_expand(tmp, in);
1089 felem_inv(tmp, tmp);
1090 felem_contract(out, tmp);
1091}
1092
1093/* Group operations
1094 * ----------------
1095 *
1096 * Building on top of the field operations we have the operations on the
1097 * elliptic curve group itself. Points on the curve are represented in Jacobian
1098 * coordinates */
1099
1100/* point_double calculates 2*(x_in, y_in, z_in)
1101 *
1102 * The method is taken from:
1103 * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
1104 *
1105 * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
1106 * while x_out == y_in is not (maybe this works, but it's not tested). */
1107static void
1108point_double(felem x_out, felem y_out, felem z_out,
1109 const felem x_in, const felem y_in, const felem z_in)
1110{
1111 longfelem tmp, tmp2;
1112 felem delta, gamma, beta, alpha, ftmp, ftmp2;
1113 smallfelem small1, small2;
1114
1115 felem_assign(ftmp, x_in);
1116 /* ftmp[i] < 2^106 */
1117 felem_assign(ftmp2, x_in);
1118 /* ftmp2[i] < 2^106 */
1119
1120 /* delta = z^2 */
1121 felem_square(tmp, z_in);
1122 felem_reduce(delta, tmp);
1123 /* delta[i] < 2^101 */
1124
1125 /* gamma = y^2 */
1126 felem_square(tmp, y_in);
1127 felem_reduce(gamma, tmp);
1128 /* gamma[i] < 2^101 */
1129 felem_shrink(small1, gamma);
1130
1131 /* beta = x*gamma */
1132 felem_small_mul(tmp, small1, x_in);
1133 felem_reduce(beta, tmp);
1134 /* beta[i] < 2^101 */
1135
1136 /* alpha = 3*(x-delta)*(x+delta) */
1137 felem_diff(ftmp, delta);
1138 /* ftmp[i] < 2^105 + 2^106 < 2^107 */
1139 felem_sum(ftmp2, delta);
1140 /* ftmp2[i] < 2^105 + 2^106 < 2^107 */
1141 felem_scalar(ftmp2, 3);
1142 /* ftmp2[i] < 3 * 2^107 < 2^109 */
1143 felem_mul(tmp, ftmp, ftmp2);
1144 felem_reduce(alpha, tmp);
1145 /* alpha[i] < 2^101 */
1146 felem_shrink(small2, alpha);
1147
1148 /* x' = alpha^2 - 8*beta */
1149 smallfelem_square(tmp, small2);
1150 felem_reduce(x_out, tmp);
1151 felem_assign(ftmp, beta);
1152 felem_scalar(ftmp, 8);
1153 /* ftmp[i] < 8 * 2^101 = 2^104 */
1154 felem_diff(x_out, ftmp);
1155 /* x_out[i] < 2^105 + 2^101 < 2^106 */
1156
1157 /* z' = (y + z)^2 - gamma - delta */
1158 felem_sum(delta, gamma);
1159 /* delta[i] < 2^101 + 2^101 = 2^102 */
1160 felem_assign(ftmp, y_in);
1161 felem_sum(ftmp, z_in);
1162 /* ftmp[i] < 2^106 + 2^106 = 2^107 */
1163 felem_square(tmp, ftmp);
1164 felem_reduce(z_out, tmp);
1165 felem_diff(z_out, delta);
1166 /* z_out[i] < 2^105 + 2^101 < 2^106 */
1167
1168 /* y' = alpha*(4*beta - x') - 8*gamma^2 */
1169 felem_scalar(beta, 4);
1170 /* beta[i] < 4 * 2^101 = 2^103 */
1171 felem_diff_zero107(beta, x_out);
1172 /* beta[i] < 2^107 + 2^103 < 2^108 */
1173 felem_small_mul(tmp, small2, beta);
1174 /* tmp[i] < 7 * 2^64 < 2^67 */
1175 smallfelem_square(tmp2, small1);
1176 /* tmp2[i] < 7 * 2^64 */
1177 longfelem_scalar(tmp2, 8);
1178 /* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */
1179 longfelem_diff(tmp, tmp2);
1180 /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
1181 felem_reduce_zero105(y_out, tmp);
1182 /* y_out[i] < 2^106 */
1183}
1184
1185/* point_double_small is the same as point_double, except that it operates on
1186 * smallfelems */
1187static void
1188point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out,
1189 const smallfelem x_in, const smallfelem y_in, const smallfelem z_in)
1190{
1191 felem felem_x_out, felem_y_out, felem_z_out;
1192 felem felem_x_in, felem_y_in, felem_z_in;
1193
1194 smallfelem_expand(felem_x_in, x_in);
1195 smallfelem_expand(felem_y_in, y_in);
1196 smallfelem_expand(felem_z_in, z_in);
1197 point_double(felem_x_out, felem_y_out, felem_z_out,
1198 felem_x_in, felem_y_in, felem_z_in);
1199 felem_shrink(x_out, felem_x_out);
1200 felem_shrink(y_out, felem_y_out);
1201 felem_shrink(z_out, felem_z_out);
1202}
1203
1204/* copy_conditional copies in to out iff mask is all ones. */
1205static void
1206copy_conditional(felem out, const felem in, limb mask)
1207{
1208 unsigned i;
1209 for (i = 0; i < NLIMBS; ++i) {
1210 const limb tmp = mask & (in[i] ^ out[i]);
1211 out[i] ^= tmp;
1212 }
1213}
1214
1215/* copy_small_conditional copies in to out iff mask is all ones. */
1216static void
1217copy_small_conditional(felem out, const smallfelem in, limb mask)
1218{
1219 unsigned i;
1220 const u64 mask64 = mask;
1221 for (i = 0; i < NLIMBS; ++i) {
1222 out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask);
1223 }
1224}
1225
1226/* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
1227 *
1228 * The method is taken from:
1229 * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
1230 * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
1231 *
1232 * This function includes a branch for checking whether the two input points
1233 * are equal, (while not equal to the point at infinity). This case never
1234 * happens during single point multiplication, so there is no timing leak for
1235 * ECDH or ECDSA signing. */
1236static void
1237point_add(felem x3, felem y3, felem z3,
1238 const felem x1, const felem y1, const felem z1,
1239 const int mixed, const smallfelem x2, const smallfelem y2, const smallfelem z2)
1240{
1241 felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
1242 longfelem tmp, tmp2;
1243 smallfelem small1, small2, small3, small4, small5;
1244 limb x_equal, y_equal, z1_is_zero, z2_is_zero;
1245
1246 felem_shrink(small3, z1);
1247
1248 z1_is_zero = smallfelem_is_zero(small3);
1249 z2_is_zero = smallfelem_is_zero(z2);
1250
1251 /* ftmp = z1z1 = z1**2 */
1252 smallfelem_square(tmp, small3);
1253 felem_reduce(ftmp, tmp);
1254 /* ftmp[i] < 2^101 */
1255 felem_shrink(small1, ftmp);
1256
1257 if (!mixed) {
1258 /* ftmp2 = z2z2 = z2**2 */
1259 smallfelem_square(tmp, z2);
1260 felem_reduce(ftmp2, tmp);
1261 /* ftmp2[i] < 2^101 */
1262 felem_shrink(small2, ftmp2);
1263
1264 felem_shrink(small5, x1);
1265
1266 /* u1 = ftmp3 = x1*z2z2 */
1267 smallfelem_mul(tmp, small5, small2);
1268 felem_reduce(ftmp3, tmp);
1269 /* ftmp3[i] < 2^101 */
1270
1271 /* ftmp5 = z1 + z2 */
1272 felem_assign(ftmp5, z1);
1273 felem_small_sum(ftmp5, z2);
1274 /* ftmp5[i] < 2^107 */
1275
1276 /* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */
1277 felem_square(tmp, ftmp5);
1278 felem_reduce(ftmp5, tmp);
1279 /* ftmp2 = z2z2 + z1z1 */
1280 felem_sum(ftmp2, ftmp);
1281 /* ftmp2[i] < 2^101 + 2^101 = 2^102 */
1282 felem_diff(ftmp5, ftmp2);
1283 /* ftmp5[i] < 2^105 + 2^101 < 2^106 */
1284
1285 /* ftmp2 = z2 * z2z2 */
1286 smallfelem_mul(tmp, small2, z2);
1287 felem_reduce(ftmp2, tmp);
1288
1289 /* s1 = ftmp2 = y1 * z2**3 */
1290 felem_mul(tmp, y1, ftmp2);
1291 felem_reduce(ftmp6, tmp);
1292 /* ftmp6[i] < 2^101 */
1293 } else {
1294 /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
1295
1296 /* u1 = ftmp3 = x1*z2z2 */
1297 felem_assign(ftmp3, x1);
1298 /* ftmp3[i] < 2^106 */
1299
1300 /* ftmp5 = 2z1z2 */
1301 felem_assign(ftmp5, z1);
1302 felem_scalar(ftmp5, 2);
1303 /* ftmp5[i] < 2*2^106 = 2^107 */
1304
1305 /* s1 = ftmp2 = y1 * z2**3 */
1306 felem_assign(ftmp6, y1);
1307 /* ftmp6[i] < 2^106 */
1308 }
1309
1310 /* u2 = x2*z1z1 */
1311 smallfelem_mul(tmp, x2, small1);
1312 felem_reduce(ftmp4, tmp);
1313
1314 /* h = ftmp4 = u2 - u1 */
1315 felem_diff_zero107(ftmp4, ftmp3);
1316 /* ftmp4[i] < 2^107 + 2^101 < 2^108 */
1317 felem_shrink(small4, ftmp4);
1318
1319 x_equal = smallfelem_is_zero(small4);
1320
1321 /* z_out = ftmp5 * h */
1322 felem_small_mul(tmp, small4, ftmp5);
1323 felem_reduce(z_out, tmp);
1324 /* z_out[i] < 2^101 */
1325
1326 /* ftmp = z1 * z1z1 */
1327 smallfelem_mul(tmp, small1, small3);
1328 felem_reduce(ftmp, tmp);
1329
1330 /* s2 = tmp = y2 * z1**3 */
1331 felem_small_mul(tmp, y2, ftmp);
1332 felem_reduce(ftmp5, tmp);
1333
1334 /* r = ftmp5 = (s2 - s1)*2 */
1335 felem_diff_zero107(ftmp5, ftmp6);
1336 /* ftmp5[i] < 2^107 + 2^107 = 2^108 */
1337 felem_scalar(ftmp5, 2);
1338 /* ftmp5[i] < 2^109 */
1339 felem_shrink(small1, ftmp5);
1340 y_equal = smallfelem_is_zero(small1);
1341
1342 if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
1343 point_double(x3, y3, z3, x1, y1, z1);
1344 return;
1345 }
1346 /* I = ftmp = (2h)**2 */
1347 felem_assign(ftmp, ftmp4);
1348 felem_scalar(ftmp, 2);
1349 /* ftmp[i] < 2*2^108 = 2^109 */
1350 felem_square(tmp, ftmp);
1351 felem_reduce(ftmp, tmp);
1352
1353 /* J = ftmp2 = h * I */
1354 felem_mul(tmp, ftmp4, ftmp);
1355 felem_reduce(ftmp2, tmp);
1356
1357 /* V = ftmp4 = U1 * I */
1358 felem_mul(tmp, ftmp3, ftmp);
1359 felem_reduce(ftmp4, tmp);
1360
1361 /* x_out = r**2 - J - 2V */
1362 smallfelem_square(tmp, small1);
1363 felem_reduce(x_out, tmp);
1364 felem_assign(ftmp3, ftmp4);
1365 felem_scalar(ftmp4, 2);
1366 felem_sum(ftmp4, ftmp2);
1367 /* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */
1368 felem_diff(x_out, ftmp4);
1369 /* x_out[i] < 2^105 + 2^101 */
1370
1371 /* y_out = r(V-x_out) - 2 * s1 * J */
1372 felem_diff_zero107(ftmp3, x_out);
1373 /* ftmp3[i] < 2^107 + 2^101 < 2^108 */
1374 felem_small_mul(tmp, small1, ftmp3);
1375 felem_mul(tmp2, ftmp6, ftmp2);
1376 longfelem_scalar(tmp2, 2);
1377 /* tmp2[i] < 2*2^67 = 2^68 */
1378 longfelem_diff(tmp, tmp2);
1379 /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
1380 felem_reduce_zero105(y_out, tmp);
1381 /* y_out[i] < 2^106 */
1382
1383 copy_small_conditional(x_out, x2, z1_is_zero);
1384 copy_conditional(x_out, x1, z2_is_zero);
1385 copy_small_conditional(y_out, y2, z1_is_zero);
1386 copy_conditional(y_out, y1, z2_is_zero);
1387 copy_small_conditional(z_out, z2, z1_is_zero);
1388 copy_conditional(z_out, z1, z2_is_zero);
1389 felem_assign(x3, x_out);
1390 felem_assign(y3, y_out);
1391 felem_assign(z3, z_out);
1392}
1393
1394/* point_add_small is the same as point_add, except that it operates on
1395 * smallfelems */
1396static void
1397point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
1398 smallfelem x1, smallfelem y1, smallfelem z1,
1399 smallfelem x2, smallfelem y2, smallfelem z2)
1400{
1401 felem felem_x3, felem_y3, felem_z3;
1402 felem felem_x1, felem_y1, felem_z1;
1403 smallfelem_expand(felem_x1, x1);
1404 smallfelem_expand(felem_y1, y1);
1405 smallfelem_expand(felem_z1, z1);
1406 point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0, x2, y2, z2);
1407 felem_shrink(x3, felem_x3);
1408 felem_shrink(y3, felem_y3);
1409 felem_shrink(z3, felem_z3);
1410}
1411
1412/* Base point pre computation
1413 * --------------------------
1414 *
1415 * Two different sorts of precomputed tables are used in the following code.
1416 * Each contain various points on the curve, where each point is three field
1417 * elements (x, y, z).
1418 *
1419 * For the base point table, z is usually 1 (0 for the point at infinity).
1420 * This table has 2 * 16 elements, starting with the following:
1421 * index | bits | point
1422 * ------+---------+------------------------------
1423 * 0 | 0 0 0 0 | 0G
1424 * 1 | 0 0 0 1 | 1G
1425 * 2 | 0 0 1 0 | 2^64G
1426 * 3 | 0 0 1 1 | (2^64 + 1)G
1427 * 4 | 0 1 0 0 | 2^128G
1428 * 5 | 0 1 0 1 | (2^128 + 1)G
1429 * 6 | 0 1 1 0 | (2^128 + 2^64)G
1430 * 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
1431 * 8 | 1 0 0 0 | 2^192G
1432 * 9 | 1 0 0 1 | (2^192 + 1)G
1433 * 10 | 1 0 1 0 | (2^192 + 2^64)G
1434 * 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
1435 * 12 | 1 1 0 0 | (2^192 + 2^128)G
1436 * 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
1437 * 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
1438 * 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
1439 * followed by a copy of this with each element multiplied by 2^32.
1440 *
1441 * The reason for this is so that we can clock bits into four different
1442 * locations when doing simple scalar multiplies against the base point,
1443 * and then another four locations using the second 16 elements.
1444 *
1445 * Tables for other points have table[i] = iG for i in 0 .. 16. */
1446
1447/* gmul is the table of precomputed base points */
1448static const smallfelem gmul[2][16][3] =
1449{{{{0, 0, 0, 0},
1450{0, 0, 0, 0},
1451{0, 0, 0, 0}},
1452{{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2, 0x6b17d1f2e12c4247},
1453{0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16, 0x4fe342e2fe1a7f9b},
1454{1, 0, 0, 0}},
1455{{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de, 0x0fa822bc2811aaa5},
1456{0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b, 0xbff44ae8f5dba80d},
1457{1, 0, 0, 0}},
1458{{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789, 0x300a4bbc89d6726f},
1459{0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f, 0x72aac7e0d09b4644},
1460{1, 0, 0, 0}},
1461{{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e, 0x447d739beedb5e67},
1462{0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7, 0x2d4825ab834131ee},
1463{1, 0, 0, 0}},
1464{{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60, 0xef9519328a9c72ff},
1465{0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c, 0x611e9fc37dbb2c9b},
1466{1, 0, 0, 0}},
1467{{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf, 0x550663797b51f5d8},
1468{0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5, 0x157164848aecb851},
1469{1, 0, 0, 0}},
1470{{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391, 0xeb5d7745b21141ea},
1471{0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee, 0xeafd72ebdbecc17b},
1472{1, 0, 0, 0}},
1473{{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5, 0xa6d39677a7849276},
1474{0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf, 0x674f84749b0b8816},
1475{1, 0, 0, 0}},
1476{{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb, 0x4e769e7672c9ddad},
1477{0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281, 0x42b99082de830663},
1478{1, 0, 0, 0}},
1479{{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478, 0x78878ef61c6ce04d},
1480{0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def, 0xb6cb3f5d7b72c321},
1481{1, 0, 0, 0}},
1482{{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae, 0x0c88bc4d716b1287},
1483{0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa, 0xdd5ddea3f3901dc6},
1484{1, 0, 0, 0}},
1485{{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3, 0x68f344af6b317466},
1486{0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3, 0x31b9c405f8540a20},
1487{1, 0, 0, 0}},
1488{{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0, 0x4052bf4b6f461db9},
1489{0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8, 0xfecf4d5190b0fc61},
1490{1, 0, 0, 0}},
1491{{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a, 0x1eddbae2c802e41a},
1492{0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0, 0x43104d86560ebcfc},
1493{1, 0, 0, 0}},
1494{{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a, 0xb48e26b484f7a21c},
1495{0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668, 0xfac015404d4d3dab},
1496{1, 0, 0, 0}}},
1497{{{0, 0, 0, 0},
1498{0, 0, 0, 0},
1499{0, 0, 0, 0}},
1500{{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da, 0x7fe36b40af22af89},
1501{0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1, 0xe697d45825b63624},
1502{1, 0, 0, 0}},
1503{{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902, 0x4a5b506612a677a6},
1504{0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40, 0xeb13461ceac089f1},
1505{1, 0, 0, 0}},
1506{{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857, 0x0781b8291c6a220a},
1507{0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434, 0x690cde8df0151593},
1508{1, 0, 0, 0}},
1509{{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326, 0x8a535f566ec73617},
1510{0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf, 0x0455c08468b08bd7},
1511{1, 0, 0, 0}},
1512{{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279, 0x06bada7ab77f8276},
1513{0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70, 0x5b476dfd0e6cb18a},
1514{1, 0, 0, 0}},
1515{{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8, 0x3e29864e8a2ec908},
1516{0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed, 0x239b90ea3dc31e7e},
1517{1, 0, 0, 0}},
1518{{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4, 0x820f4dd949f72ff7},
1519{0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3, 0x140406ec783a05ec},
1520{1, 0, 0, 0}},
1521{{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe, 0x68f6b8542783dfee},
1522{0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028, 0xcbe1feba92e40ce6},
1523{1, 0, 0, 0}},
1524{{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927, 0xd0b2f94d2f420109},
1525{0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a, 0x971459828b0719e5},
1526{1, 0, 0, 0}},
1527{{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687, 0x961610004a866aba},
1528{0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c, 0x7acb9fadcee75e44},
1529{1, 0, 0, 0}},
1530{{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea, 0x24eb9acca333bf5b},
1531{0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d, 0x69f891c5acd079cc},
1532{1, 0, 0, 0}},
1533{{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514, 0xe51f547c5972a107},
1534{0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06, 0x1c309a2b25bb1387},
1535{1, 0, 0, 0}},
1536{{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828, 0x20b87b8aa2c4e503},
1537{0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044, 0xf5c6fa49919776be},
1538{1, 0, 0, 0}},
1539{{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56, 0x1ed7d1b9332010b9},
1540{0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24, 0x3a2b03f03217257a},
1541{1, 0, 0, 0}},
1542{{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b, 0x15fee545c78dd9f6},
1543{0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, 0x4ab5b6b2b8753f81},
1544{1, 0, 0, 0}}}};
1545
1546/* select_point selects the |idx|th point from a precomputation table and
1547 * copies it to out. */
1548static void
1549select_point(const u64 idx, unsigned int size, const smallfelem pre_comp[16][3], smallfelem out[3])
1550{
1551 unsigned i, j;
1552 u64 *outlimbs = &out[0][0];
1553 memset(outlimbs, 0, 3 * sizeof(smallfelem));
1554
1555 for (i = 0; i < size; i++) {
1556 const u64 *inlimbs = (u64 *) & pre_comp[i][0][0];
1557 u64 mask = i ^ idx;
1558 mask |= mask >> 4;
1559 mask |= mask >> 2;
1560 mask |= mask >> 1;
1561 mask &= 1;
1562 mask--;
1563 for (j = 0; j < NLIMBS * 3; j++)
1564 outlimbs[j] |= inlimbs[j] & mask;
1565 }
1566}
1567
1568/* get_bit returns the |i|th bit in |in| */
1569static char
1570get_bit(const felem_bytearray in, int i)
1571{
1572 if ((i < 0) || (i >= 256))
1573 return 0;
1574 return (in[i >> 3] >> (i & 7)) & 1;
1575}
1576
1577/* Interleaved point multiplication using precomputed point multiples:
1578 * The small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[],
1579 * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
1580 * of the generator, using certain (large) precomputed multiples in g_pre_comp.
1581 * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
1582static void
1583batch_mul(felem x_out, felem y_out, felem z_out,
1584 const felem_bytearray scalars[], const unsigned num_points, const u8 * g_scalar,
1585 const int mixed, const smallfelem pre_comp[][17][3], const smallfelem g_pre_comp[2][16][3])
1586{
1587 int i, skip;
1588 unsigned num, gen_mul = (g_scalar != NULL);
1589 felem nq[3], ftmp;
1590 smallfelem tmp[3];
1591 u64 bits;
1592 u8 sign, digit;
1593
1594 /* set nq to the point at infinity */
1595 memset(nq, 0, 3 * sizeof(felem));
1596
1597 /*
1598 * Loop over all scalars msb-to-lsb, interleaving additions of
1599 * multiples of the generator (two in each of the last 32 rounds) and
1600 * additions of other points multiples (every 5th round).
1601 */
1602 skip = 1; /* save two point operations in the first
1603 * round */
1604 for (i = (num_points ? 255 : 31); i >= 0; --i) {
1605 /* double */
1606 if (!skip)
1607 point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1608
1609 /* add multiples of the generator */
1610 if (gen_mul && (i <= 31)) {
1611 /* first, look 32 bits upwards */
1612 bits = get_bit(g_scalar, i + 224) << 3;
1613 bits |= get_bit(g_scalar, i + 160) << 2;
1614 bits |= get_bit(g_scalar, i + 96) << 1;
1615 bits |= get_bit(g_scalar, i + 32);
1616 /* select the point to add, in constant time */
1617 select_point(bits, 16, g_pre_comp[1], tmp);
1618
1619 if (!skip) {
1620 point_add(nq[0], nq[1], nq[2],
1621 nq[0], nq[1], nq[2],
1622 1 /* mixed */ , tmp[0], tmp[1], tmp[2]);
1623 } else {
1624 smallfelem_expand(nq[0], tmp[0]);
1625 smallfelem_expand(nq[1], tmp[1]);
1626 smallfelem_expand(nq[2], tmp[2]);
1627 skip = 0;
1628 }
1629
1630 /* second, look at the current position */
1631 bits = get_bit(g_scalar, i + 192) << 3;
1632 bits |= get_bit(g_scalar, i + 128) << 2;
1633 bits |= get_bit(g_scalar, i + 64) << 1;
1634 bits |= get_bit(g_scalar, i);
1635 /* select the point to add, in constant time */
1636 select_point(bits, 16, g_pre_comp[0], tmp);
1637 point_add(nq[0], nq[1], nq[2],
1638 nq[0], nq[1], nq[2],
1639 1 /* mixed */ , tmp[0], tmp[1], tmp[2]);
1640 }
1641 /* do other additions every 5 doublings */
1642 if (num_points && (i % 5 == 0)) {
1643 /* loop over all scalars */
1644 for (num = 0; num < num_points; ++num) {
1645 bits = get_bit(scalars[num], i + 4) << 5;
1646 bits |= get_bit(scalars[num], i + 3) << 4;
1647 bits |= get_bit(scalars[num], i + 2) << 3;
1648 bits |= get_bit(scalars[num], i + 1) << 2;
1649 bits |= get_bit(scalars[num], i) << 1;
1650 bits |= get_bit(scalars[num], i - 1);
1651 ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
1652
1653 /*
1654 * select the point to add or subtract, in
1655 * constant time
1656 */
1657 select_point(digit, 17, pre_comp[num], tmp);
1658 smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the
1659 * negative point */
1660 copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1));
1661 felem_contract(tmp[1], ftmp);
1662
1663 if (!skip) {
1664 point_add(nq[0], nq[1], nq[2],
1665 nq[0], nq[1], nq[2],
1666 mixed, tmp[0], tmp[1], tmp[2]);
1667 } else {
1668 smallfelem_expand(nq[0], tmp[0]);
1669 smallfelem_expand(nq[1], tmp[1]);
1670 smallfelem_expand(nq[2], tmp[2]);
1671 skip = 0;
1672 }
1673 }
1674 }
1675 }
1676 felem_assign(x_out, nq[0]);
1677 felem_assign(y_out, nq[1]);
1678 felem_assign(z_out, nq[2]);
1679}
1680
1681/* Precomputation for the group generator. */
1682typedef struct {
1683 smallfelem g_pre_comp[2][16][3];
1684 int references;
1685} NISTP256_PRE_COMP;
1686
1687const EC_METHOD *
1688EC_GFp_nistp256_method(void)
1689{
1690 static const EC_METHOD ret = {
1691 .flags = EC_FLAGS_DEFAULT_OCT,
1692 .field_type = NID_X9_62_prime_field,
1693 .group_init = ec_GFp_nistp256_group_init,
1694 .group_finish = ec_GFp_simple_group_finish,
1695 .group_clear_finish = ec_GFp_simple_group_clear_finish,
1696 .group_copy = ec_GFp_nist_group_copy,
1697 .group_set_curve = ec_GFp_nistp256_group_set_curve,
1698 .group_get_curve = ec_GFp_simple_group_get_curve,
1699 .group_get_degree = ec_GFp_simple_group_get_degree,
1700 .group_check_discriminant =
1701 ec_GFp_simple_group_check_discriminant,
1702 .point_init = ec_GFp_simple_point_init,
1703 .point_finish = ec_GFp_simple_point_finish,
1704 .point_clear_finish = ec_GFp_simple_point_clear_finish,
1705 .point_copy = ec_GFp_simple_point_copy,
1706 .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
1707 .point_set_Jprojective_coordinates_GFp =
1708 ec_GFp_simple_set_Jprojective_coordinates_GFp,
1709 .point_get_Jprojective_coordinates_GFp =
1710 ec_GFp_simple_get_Jprojective_coordinates_GFp,
1711 .point_set_affine_coordinates =
1712 ec_GFp_simple_point_set_affine_coordinates,
1713 .point_get_affine_coordinates =
1714 ec_GFp_nistp256_point_get_affine_coordinates,
1715 .add = ec_GFp_simple_add,
1716 .dbl = ec_GFp_simple_dbl,
1717 .invert = ec_GFp_simple_invert,
1718 .is_at_infinity = ec_GFp_simple_is_at_infinity,
1719 .is_on_curve = ec_GFp_simple_is_on_curve,
1720 .point_cmp = ec_GFp_simple_cmp,
1721 .make_affine = ec_GFp_simple_make_affine,
1722 .points_make_affine = ec_GFp_simple_points_make_affine,
1723 .mul = ec_GFp_nistp256_points_mul,
1724 .precompute_mult = ec_GFp_nistp256_precompute_mult,
1725 .have_precompute_mult = ec_GFp_nistp256_have_precompute_mult,
1726 .field_mul = ec_GFp_nist_field_mul,
1727 .field_sqr = ec_GFp_nist_field_sqr
1728 };
1729
1730 return &ret;
1731}
1732
1733/******************************************************************************/
1734/* FUNCTIONS TO MANAGE PRECOMPUTATION
1735 */
1736
1737static NISTP256_PRE_COMP *
1738nistp256_pre_comp_new()
1739{
1740 NISTP256_PRE_COMP *ret = NULL;
1741 ret = malloc(sizeof *ret);
1742 if (!ret) {
1743 ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
1744 return ret;
1745 }
1746 memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
1747 ret->references = 1;
1748 return ret;
1749}
1750
1751static void *
1752nistp256_pre_comp_dup(void *src_)
1753{
1754 NISTP256_PRE_COMP *src = src_;
1755
1756 /* no need to actually copy, these objects never change! */
1757 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
1758
1759 return src_;
1760}
1761
1762static void
1763nistp256_pre_comp_free(void *pre_)
1764{
1765 int i;
1766 NISTP256_PRE_COMP *pre = pre_;
1767
1768 if (!pre)
1769 return;
1770
1771 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1772 if (i > 0)
1773 return;
1774
1775 free(pre);
1776}
1777
1778static void
1779nistp256_pre_comp_clear_free(void *pre_)
1780{
1781 int i;
1782 NISTP256_PRE_COMP *pre = pre_;
1783
1784 if (!pre)
1785 return;
1786
1787 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1788 if (i > 0)
1789 return;
1790
1791 explicit_bzero(pre, sizeof *pre);
1792 free(pre);
1793}
1794
1795/******************************************************************************/
1796/* OPENSSL EC_METHOD FUNCTIONS
1797 */
1798
1799int
1800ec_GFp_nistp256_group_init(EC_GROUP * group)
1801{
1802 int ret;
1803 ret = ec_GFp_simple_group_init(group);
1804 group->a_is_minus3 = 1;
1805 return ret;
1806}
1807
1808int
1809ec_GFp_nistp256_group_set_curve(EC_GROUP * group, const BIGNUM * p,
1810 const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
1811{
1812 int ret = 0;
1813 BN_CTX *new_ctx = NULL;
1814 BIGNUM *curve_p, *curve_a, *curve_b;
1815
1816 if (ctx == NULL)
1817 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
1818 return 0;
1819 BN_CTX_start(ctx);
1820 if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
1821 ((curve_a = BN_CTX_get(ctx)) == NULL) ||
1822 ((curve_b = BN_CTX_get(ctx)) == NULL))
1823 goto err;
1824 BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
1825 BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
1826 BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
1827 if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
1828 (BN_cmp(curve_b, b))) {
1829 ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE,
1830 EC_R_WRONG_CURVE_PARAMETERS);
1831 goto err;
1832 }
1833 group->field_mod_func = BN_nist_mod_256;
1834 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
1835err:
1836 BN_CTX_end(ctx);
1837 BN_CTX_free(new_ctx);
1838 return ret;
1839}
1840
1841/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
1842 * (X', Y') = (X/Z^2, Y/Z^3) */
1843int
1844ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP * group,
1845 const EC_POINT * point, BIGNUM * x, BIGNUM * y, BN_CTX * ctx)
1846{
1847 felem z1, z2, x_in, y_in;
1848 smallfelem x_out, y_out;
1849 longfelem tmp;
1850
1851 if (EC_POINT_is_at_infinity(group, point) > 0) {
1852 ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
1853 EC_R_POINT_AT_INFINITY);
1854 return 0;
1855 }
1856 if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
1857 (!BN_to_felem(z1, &point->Z)))
1858 return 0;
1859 felem_inv(z2, z1);
1860 felem_square(tmp, z2);
1861 felem_reduce(z1, tmp);
1862 felem_mul(tmp, x_in, z1);
1863 felem_reduce(x_in, tmp);
1864 felem_contract(x_out, x_in);
1865 if (x != NULL) {
1866 if (!smallfelem_to_BN(x, x_out)) {
1867 ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
1868 ERR_R_BN_LIB);
1869 return 0;
1870 }
1871 }
1872 felem_mul(tmp, z1, z2);
1873 felem_reduce(z1, tmp);
1874 felem_mul(tmp, y_in, z1);
1875 felem_reduce(y_in, tmp);
1876 felem_contract(y_out, y_in);
1877 if (y != NULL) {
1878 if (!smallfelem_to_BN(y, y_out)) {
1879 ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
1880 ERR_R_BN_LIB);
1881 return 0;
1882 }
1883 }
1884 return 1;
1885}
1886
1887static void
1888make_points_affine(size_t num, smallfelem points[ /* num */ ][3], smallfelem tmp_smallfelems[ /* num+1 */ ])
1889{
1890 /*
1891 * Runs in constant time, unless an input is the point at infinity
1892 * (which normally shouldn't happen).
1893 */
1894 ec_GFp_nistp_points_make_affine_internal(
1895 num,
1896 points,
1897 sizeof(smallfelem),
1898 tmp_smallfelems,
1899 (void (*) (void *)) smallfelem_one,
1900 (int (*) (const void *)) smallfelem_is_zero_int,
1901 (void (*) (void *, const void *)) smallfelem_assign,
1902 (void (*) (void *, const void *)) smallfelem_square_contract,
1903 (void (*) (void *, const void *, const void *)) smallfelem_mul_contract,
1904 (void (*) (void *, const void *)) smallfelem_inv_contract,
1905 (void (*) (void *, const void *)) smallfelem_assign /* nothing to contract */ );
1906}
1907
1908/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
1909 * Result is stored in r (r can equal one of the inputs). */
1910int
1911ec_GFp_nistp256_points_mul(const EC_GROUP * group, EC_POINT * r,
1912 const BIGNUM * scalar, size_t num, const EC_POINT * points[],
1913 const BIGNUM * scalars[], BN_CTX * ctx)
1914{
1915 int ret = 0;
1916 int j;
1917 int mixed = 0;
1918 BN_CTX *new_ctx = NULL;
1919 BIGNUM *x, *y, *z, *tmp_scalar;
1920 felem_bytearray g_secret;
1921 felem_bytearray *secrets = NULL;
1922 smallfelem(*pre_comp)[17][3] = NULL;
1923 smallfelem *tmp_smallfelems = NULL;
1924 felem_bytearray tmp;
1925 unsigned i, num_bytes;
1926 int have_pre_comp = 0;
1927 size_t num_points = num;
1928 smallfelem x_in, y_in, z_in;
1929 felem x_out, y_out, z_out;
1930 NISTP256_PRE_COMP *pre = NULL;
1931 const smallfelem(*g_pre_comp)[16][3] = NULL;
1932 EC_POINT *generator = NULL;
1933 const EC_POINT *p = NULL;
1934 const BIGNUM *p_scalar = NULL;
1935
1936 if (ctx == NULL)
1937 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
1938 return 0;
1939 BN_CTX_start(ctx);
1940 if (((x = BN_CTX_get(ctx)) == NULL) ||
1941 ((y = BN_CTX_get(ctx)) == NULL) ||
1942 ((z = BN_CTX_get(ctx)) == NULL) ||
1943 ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
1944 goto err;
1945
1946 if (scalar != NULL) {
1947 pre = EC_EX_DATA_get_data(group->extra_data,
1948 nistp256_pre_comp_dup, nistp256_pre_comp_free,
1949 nistp256_pre_comp_clear_free);
1950 if (pre)
1951 /* we have precomputation, try to use it */
1952 g_pre_comp = (const smallfelem(*)[16][3]) pre->g_pre_comp;
1953 else
1954 /* try to use the standard precomputation */
1955 g_pre_comp = &gmul[0];
1956 generator = EC_POINT_new(group);
1957 if (generator == NULL)
1958 goto err;
1959 /* get the generator from precomputation */
1960 if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
1961 !smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
1962 !smallfelem_to_BN(z, g_pre_comp[0][1][2])) {
1963 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
1964 goto err;
1965 }
1966 if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
1967 generator, x, y, z, ctx))
1968 goto err;
1969 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
1970 /* precomputation matches generator */
1971 have_pre_comp = 1;
1972 else
1973 /*
1974 * we don't have valid precomputation: treat the
1975 * generator as a random point
1976 */
1977 num_points++;
1978 }
1979 if (num_points > 0) {
1980 if (num_points >= 3) {
1981 /*
1982 * unless we precompute multiples for just one or two
1983 * points, converting those into affine form is time
1984 * well spent
1985 */
1986 mixed = 1;
1987 }
1988 secrets = calloc(num_points, sizeof(felem_bytearray));
1989 pre_comp = calloc(num_points, 17 * 3 * sizeof(smallfelem));
1990 if (mixed) {
1991 /* XXX should do more int overflow checking */
1992 tmp_smallfelems = reallocarray(NULL,
1993 (num_points * 17 + 1), sizeof(smallfelem));
1994 }
1995 if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_smallfelems == NULL))) {
1996 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
1997 goto err;
1998 }
1999 /*
2000 * we treat NULL scalars as 0, and NULL points as points at
2001 * infinity, i.e., they contribute nothing to the linear
2002 * combination
2003 */
2004 for (i = 0; i < num_points; ++i) {
2005 if (i == num)
2006 /*
2007 * we didn't have a valid precomputation, so
2008 * we pick the generator
2009 */
2010 {
2011 p = EC_GROUP_get0_generator(group);
2012 p_scalar = scalar;
2013 } else
2014 /* the i^th point */
2015 {
2016 p = points[i];
2017 p_scalar = scalars[i];
2018 }
2019 if ((p_scalar != NULL) && (p != NULL)) {
2020 /* reduce scalar to 0 <= scalar < 2^256 */
2021 if ((BN_num_bits(p_scalar) > 256) || (BN_is_negative(p_scalar))) {
2022 /*
2023 * this is an unusual input, and we
2024 * don't guarantee constant-timeness
2025 */
2026 if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
2027 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
2028 goto err;
2029 }
2030 num_bytes = BN_bn2bin(tmp_scalar, tmp);
2031 } else
2032 num_bytes = BN_bn2bin(p_scalar, tmp);
2033 flip_endian(secrets[i], tmp, num_bytes);
2034 /* precompute multiples */
2035 if ((!BN_to_felem(x_out, &p->X)) ||
2036 (!BN_to_felem(y_out, &p->Y)) ||
2037 (!BN_to_felem(z_out, &p->Z)))
2038 goto err;
2039 felem_shrink(pre_comp[i][1][0], x_out);
2040 felem_shrink(pre_comp[i][1][1], y_out);
2041 felem_shrink(pre_comp[i][1][2], z_out);
2042 for (j = 2; j <= 16; ++j) {
2043 if (j & 1) {
2044 point_add_small(
2045 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
2046 pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
2047 pre_comp[i][j - 1][0], pre_comp[i][j - 1][1], pre_comp[i][j - 1][2]);
2048 } else {
2049 point_double_small(
2050 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
2051 pre_comp[i][j / 2][0], pre_comp[i][j / 2][1], pre_comp[i][j / 2][2]);
2052 }
2053 }
2054 }
2055 }
2056 if (mixed)
2057 make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems);
2058 }
2059 /* the scalar for the generator */
2060 if ((scalar != NULL) && (have_pre_comp)) {
2061 memset(g_secret, 0, sizeof(g_secret));
2062 /* reduce scalar to 0 <= scalar < 2^256 */
2063 if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar))) {
2064 /*
2065 * this is an unusual input, and we don't guarantee
2066 * constant-timeness
2067 */
2068 if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
2069 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
2070 goto err;
2071 }
2072 num_bytes = BN_bn2bin(tmp_scalar, tmp);
2073 } else
2074 num_bytes = BN_bn2bin(scalar, tmp);
2075 flip_endian(g_secret, tmp, num_bytes);
2076 /* do the multiplication with generator precomputation */
2077 batch_mul(x_out, y_out, z_out,
2078 (const felem_bytearray(*)) secrets, num_points,
2079 g_secret,
2080 mixed, (const smallfelem(*)[17][3]) pre_comp,
2081 g_pre_comp);
2082 } else
2083 /* do the multiplication without generator precomputation */
2084 batch_mul(x_out, y_out, z_out,
2085 (const felem_bytearray(*)) secrets, num_points,
2086 NULL, mixed, (const smallfelem(*)[17][3]) pre_comp, NULL);
2087 /* reduce the output to its unique minimal representation */
2088 felem_contract(x_in, x_out);
2089 felem_contract(y_in, y_out);
2090 felem_contract(z_in, z_out);
2091 if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) ||
2092 (!smallfelem_to_BN(z, z_in))) {
2093 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
2094 goto err;
2095 }
2096 ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
2097
2098err:
2099 BN_CTX_end(ctx);
2100 EC_POINT_free(generator);
2101 BN_CTX_free(new_ctx);
2102 free(secrets);
2103 free(pre_comp);
2104 free(tmp_smallfelems);
2105 return ret;
2106}
2107
2108int
2109ec_GFp_nistp256_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
2110{
2111 int ret = 0;
2112 NISTP256_PRE_COMP *pre = NULL;
2113 int i, j;
2114 BN_CTX *new_ctx = NULL;
2115 BIGNUM *x, *y;
2116 EC_POINT *generator = NULL;
2117 smallfelem tmp_smallfelems[32];
2118 felem x_tmp, y_tmp, z_tmp;
2119
2120 /* throw away old precomputation */
2121 EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup,
2122 nistp256_pre_comp_free, nistp256_pre_comp_clear_free);
2123 if (ctx == NULL)
2124 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
2125 return 0;
2126 BN_CTX_start(ctx);
2127 if (((x = BN_CTX_get(ctx)) == NULL) ||
2128 ((y = BN_CTX_get(ctx)) == NULL))
2129 goto err;
2130 /* get the generator */
2131 if (group->generator == NULL)
2132 goto err;
2133 generator = EC_POINT_new(group);
2134 if (generator == NULL)
2135 goto err;
2136 BN_bin2bn(nistp256_curve_params[3], sizeof(felem_bytearray), x);
2137 BN_bin2bn(nistp256_curve_params[4], sizeof(felem_bytearray), y);
2138 if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
2139 goto err;
2140 if ((pre = nistp256_pre_comp_new()) == NULL)
2141 goto err;
2142 /* if the generator is the standard one, use built-in precomputation */
2143 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
2144 memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
2145 ret = 1;
2146 goto err;
2147 }
2148 if ((!BN_to_felem(x_tmp, &group->generator->X)) ||
2149 (!BN_to_felem(y_tmp, &group->generator->Y)) ||
2150 (!BN_to_felem(z_tmp, &group->generator->Z)))
2151 goto err;
2152 felem_shrink(pre->g_pre_comp[0][1][0], x_tmp);
2153 felem_shrink(pre->g_pre_comp[0][1][1], y_tmp);
2154 felem_shrink(pre->g_pre_comp[0][1][2], z_tmp);
2155 /*
2156 * compute 2^64*G, 2^128*G, 2^192*G for the first table, 2^32*G,
2157 * 2^96*G, 2^160*G, 2^224*G for the second one
2158 */
2159 for (i = 1; i <= 8; i <<= 1) {
2160 point_double_small(
2161 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
2162 pre->g_pre_comp[0][i][0], pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
2163 for (j = 0; j < 31; ++j) {
2164 point_double_small(
2165 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
2166 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
2167 }
2168 if (i == 8)
2169 break;
2170 point_double_small(
2171 pre->g_pre_comp[0][2 * i][0], pre->g_pre_comp[0][2 * i][1], pre->g_pre_comp[0][2 * i][2],
2172 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
2173 for (j = 0; j < 31; ++j) {
2174 point_double_small(
2175 pre->g_pre_comp[0][2 * i][0], pre->g_pre_comp[0][2 * i][1], pre->g_pre_comp[0][2 * i][2],
2176 pre->g_pre_comp[0][2 * i][0], pre->g_pre_comp[0][2 * i][1], pre->g_pre_comp[0][2 * i][2]);
2177 }
2178 }
2179 for (i = 0; i < 2; i++) {
2180 /* g_pre_comp[i][0] is the point at infinity */
2181 memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
2182 /* the remaining multiples */
2183 /* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */
2184 point_add_small(
2185 pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], pre->g_pre_comp[i][6][2],
2186 pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
2187 pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
2188 /* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */
2189 point_add_small(
2190 pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], pre->g_pre_comp[i][10][2],
2191 pre->g_pre_comp[i][8][0], pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
2192 pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
2193 /* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */
2194 point_add_small(
2195 pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
2196 pre->g_pre_comp[i][8][0], pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
2197 pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2]);
2198 /*
2199 * 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G +
2200 * 2^224*G
2201 */
2202 point_add_small(
2203 pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], pre->g_pre_comp[i][14][2],
2204 pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
2205 pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
2206 for (j = 1; j < 8; ++j) {
2207 /* odd multiples: add G resp. 2^32*G */
2208 point_add_small(
2209 pre->g_pre_comp[i][2 * j + 1][0], pre->g_pre_comp[i][2 * j + 1][1], pre->g_pre_comp[i][2 * j + 1][2],
2210 pre->g_pre_comp[i][2 * j][0], pre->g_pre_comp[i][2 * j][1], pre->g_pre_comp[i][2 * j][2],
2211 pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1], pre->g_pre_comp[i][1][2]);
2212 }
2213 }
2214 make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems);
2215
2216 if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup,
2217 nistp256_pre_comp_free, nistp256_pre_comp_clear_free))
2218 goto err;
2219 ret = 1;
2220 pre = NULL;
2221err:
2222 BN_CTX_end(ctx);
2223 EC_POINT_free(generator);
2224 BN_CTX_free(new_ctx);
2225 nistp256_pre_comp_free(pre);
2226 return ret;
2227}
2228
2229int
2230ec_GFp_nistp256_have_precompute_mult(const EC_GROUP * group)
2231{
2232 if (EC_EX_DATA_get_data(group->extra_data, nistp256_pre_comp_dup,
2233 nistp256_pre_comp_free, nistp256_pre_comp_clear_free)
2234 != NULL)
2235 return 1;
2236 else
2237 return 0;
2238}
2239#endif
diff --git a/src/lib/libcrypto/ec/ecp_nistp521.c b/src/lib/libcrypto/ec/ecp_nistp521.c
deleted file mode 100644
index cfa13b41f8..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistp521.c
+++ /dev/null
@@ -1,2113 +0,0 @@
1/* $OpenBSD: ecp_nistp521.c,v 1.17 2015/09/10 15:56:25 jsing Exp $ */
2/*
3 * Written by Adam Langley (Google) for the OpenSSL project
4 */
5/*
6 * Copyright (c) 2011 Google Inc.
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/*
22 * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication
23 *
24 * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
25 * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
26 * work which got its smarts from Daniel J. Bernstein's work on the same.
27 */
28
29#include <stdint.h>
30#include <string.h>
31
32#include <openssl/opensslconf.h>
33
34#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
35
36#include <openssl/err.h>
37#include "ec_lcl.h"
38
39#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
40 /* even with gcc, the typedef won't work for 32-bit platforms */
41 typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
42#else
43 #error "Need GCC 3.1 or later to define type uint128_t"
44#endif
45
46typedef uint8_t u8;
47typedef uint64_t u64;
48typedef int64_t s64;
49
50/* The underlying field.
51 *
52 * P521 operates over GF(2^521-1). We can serialise an element of this field
53 * into 66 bytes where the most significant byte contains only a single bit. We
54 * call this an felem_bytearray. */
55
56typedef u8 felem_bytearray[66];
57
58/* These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5.
59 * These values are big-endian. */
60static const felem_bytearray nistp521_curve_params[5] =
61 {
62 {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */
63 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
64 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
66 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
68 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
69 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
70 0xff, 0xff},
71 {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a = -3 */
72 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
73 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
74 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
75 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
76 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
77 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79 0xff, 0xfc},
80 {0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, /* b */
81 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
82 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
83 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
84 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
85 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
86 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
87 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
88 0x3f, 0x00},
89 {0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, /* x */
90 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
91 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
92 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
93 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
94 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
95 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
96 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
97 0xbd, 0x66},
98 {0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, /* y */
99 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
100 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
101 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
102 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
103 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
104 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
105 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
106 0x66, 0x50}
107 };
108
109/* The representation of field elements.
110 * ------------------------------------
111 *
112 * We represent field elements with nine values. These values are either 64 or
113 * 128 bits and the field element represented is:
114 * v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464 (mod p)
115 * Each of the nine values is called a 'limb'. Since the limbs are spaced only
116 * 58 bits apart, but are greater than 58 bits in length, the most significant
117 * bits of each limb overlap with the least significant bits of the next.
118 *
119 * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a
120 * 'largefelem' */
121
122#define NLIMBS 9
123
124typedef uint64_t limb;
125typedef limb felem[NLIMBS];
126typedef uint128_t largefelem[NLIMBS];
127
128static const limb bottom57bits = 0x1ffffffffffffff;
129static const limb bottom58bits = 0x3ffffffffffffff;
130
131/* bin66_to_felem takes a little-endian byte array and converts it into felem
132 * form. This assumes that the CPU is little-endian. */
133static void
134bin66_to_felem(felem out, const u8 in[66])
135{
136 out[0] = (*((limb *) & in[0])) & bottom58bits;
137 out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits;
138 out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits;
139 out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits;
140 out[4] = (*((limb *) & in[29])) & bottom58bits;
141 out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits;
142 out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits;
143 out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits;
144 out[8] = (*((limb *) & in[58])) & bottom57bits;
145}
146
147/* felem_to_bin66 takes an felem and serialises into a little endian, 66 byte
148 * array. This assumes that the CPU is little-endian. */
149static void
150felem_to_bin66(u8 out[66], const felem in)
151{
152 memset(out, 0, 66);
153 (*((limb *) & out[0])) = in[0];
154 (*((limb *) & out[7])) |= in[1] << 2;
155 (*((limb *) & out[14])) |= in[2] << 4;
156 (*((limb *) & out[21])) |= in[3] << 6;
157 (*((limb *) & out[29])) = in[4];
158 (*((limb *) & out[36])) |= in[5] << 2;
159 (*((limb *) & out[43])) |= in[6] << 4;
160 (*((limb *) & out[50])) |= in[7] << 6;
161 (*((limb *) & out[58])) = in[8];
162}
163
164/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
165static void
166flip_endian(u8 * out, const u8 * in, unsigned len)
167{
168 unsigned i;
169 for (i = 0; i < len; ++i)
170 out[i] = in[len - 1 - i];
171}
172
173/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
174static int
175BN_to_felem(felem out, const BIGNUM * bn)
176{
177 felem_bytearray b_in;
178 felem_bytearray b_out;
179 unsigned num_bytes;
180
181 /* BN_bn2bin eats leading zeroes */
182 memset(b_out, 0, sizeof b_out);
183 num_bytes = BN_num_bytes(bn);
184 if (num_bytes > sizeof b_out) {
185 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
186 return 0;
187 }
188 if (BN_is_negative(bn)) {
189 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
190 return 0;
191 }
192 num_bytes = BN_bn2bin(bn, b_in);
193 flip_endian(b_out, b_in, num_bytes);
194 bin66_to_felem(out, b_out);
195 return 1;
196}
197
198/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
199static BIGNUM *
200felem_to_BN(BIGNUM * out, const felem in)
201{
202 felem_bytearray b_in, b_out;
203 felem_to_bin66(b_in, in);
204 flip_endian(b_out, b_in, sizeof b_out);
205 return BN_bin2bn(b_out, sizeof b_out, out);
206}
207
208
209/* Field operations
210 * ---------------- */
211
212static void
213felem_one(felem out)
214{
215 out[0] = 1;
216 out[1] = 0;
217 out[2] = 0;
218 out[3] = 0;
219 out[4] = 0;
220 out[5] = 0;
221 out[6] = 0;
222 out[7] = 0;
223 out[8] = 0;
224}
225
226static void
227felem_assign(felem out, const felem in)
228{
229 out[0] = in[0];
230 out[1] = in[1];
231 out[2] = in[2];
232 out[3] = in[3];
233 out[4] = in[4];
234 out[5] = in[5];
235 out[6] = in[6];
236 out[7] = in[7];
237 out[8] = in[8];
238}
239
240/* felem_sum64 sets out = out + in. */
241static void
242felem_sum64(felem out, const felem in)
243{
244 out[0] += in[0];
245 out[1] += in[1];
246 out[2] += in[2];
247 out[3] += in[3];
248 out[4] += in[4];
249 out[5] += in[5];
250 out[6] += in[6];
251 out[7] += in[7];
252 out[8] += in[8];
253}
254
255/* felem_scalar sets out = in * scalar */
256static void
257felem_scalar(felem out, const felem in, limb scalar)
258{
259 out[0] = in[0] * scalar;
260 out[1] = in[1] * scalar;
261 out[2] = in[2] * scalar;
262 out[3] = in[3] * scalar;
263 out[4] = in[4] * scalar;
264 out[5] = in[5] * scalar;
265 out[6] = in[6] * scalar;
266 out[7] = in[7] * scalar;
267 out[8] = in[8] * scalar;
268}
269
270/* felem_scalar64 sets out = out * scalar */
271static void
272felem_scalar64(felem out, limb scalar)
273{
274 out[0] *= scalar;
275 out[1] *= scalar;
276 out[2] *= scalar;
277 out[3] *= scalar;
278 out[4] *= scalar;
279 out[5] *= scalar;
280 out[6] *= scalar;
281 out[7] *= scalar;
282 out[8] *= scalar;
283}
284
285/* felem_scalar128 sets out = out * scalar */
286static void
287felem_scalar128(largefelem out, limb scalar)
288{
289 out[0] *= scalar;
290 out[1] *= scalar;
291 out[2] *= scalar;
292 out[3] *= scalar;
293 out[4] *= scalar;
294 out[5] *= scalar;
295 out[6] *= scalar;
296 out[7] *= scalar;
297 out[8] *= scalar;
298}
299
300/* felem_neg sets |out| to |-in|
301 * On entry:
302 * in[i] < 2^59 + 2^14
303 * On exit:
304 * out[i] < 2^62
305 */
306static void
307felem_neg(felem out, const felem in)
308{
309 /* In order to prevent underflow, we subtract from 0 mod p. */
310 static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5);
311 static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4);
312
313 out[0] = two62m3 - in[0];
314 out[1] = two62m2 - in[1];
315 out[2] = two62m2 - in[2];
316 out[3] = two62m2 - in[3];
317 out[4] = two62m2 - in[4];
318 out[5] = two62m2 - in[5];
319 out[6] = two62m2 - in[6];
320 out[7] = two62m2 - in[7];
321 out[8] = two62m2 - in[8];
322}
323
324/* felem_diff64 subtracts |in| from |out|
325 * On entry:
326 * in[i] < 2^59 + 2^14
327 * On exit:
328 * out[i] < out[i] + 2^62
329 */
330static void
331felem_diff64(felem out, const felem in)
332{
333 /* In order to prevent underflow, we add 0 mod p before subtracting. */
334 static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5);
335 static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4);
336
337 out[0] += two62m3 - in[0];
338 out[1] += two62m2 - in[1];
339 out[2] += two62m2 - in[2];
340 out[3] += two62m2 - in[3];
341 out[4] += two62m2 - in[4];
342 out[5] += two62m2 - in[5];
343 out[6] += two62m2 - in[6];
344 out[7] += two62m2 - in[7];
345 out[8] += two62m2 - in[8];
346}
347
348/* felem_diff_128_64 subtracts |in| from |out|
349 * On entry:
350 * in[i] < 2^62 + 2^17
351 * On exit:
352 * out[i] < out[i] + 2^63
353 */
354static void
355felem_diff_128_64(largefelem out, const felem in)
356{
357 /* In order to prevent underflow, we add 0 mod p before subtracting. */
358 static const limb two63m6 = (((limb) 1) << 62) - (((limb) 1) << 5);
359 static const limb two63m5 = (((limb) 1) << 62) - (((limb) 1) << 4);
360
361 out[0] += two63m6 - in[0];
362 out[1] += two63m5 - in[1];
363 out[2] += two63m5 - in[2];
364 out[3] += two63m5 - in[3];
365 out[4] += two63m5 - in[4];
366 out[5] += two63m5 - in[5];
367 out[6] += two63m5 - in[6];
368 out[7] += two63m5 - in[7];
369 out[8] += two63m5 - in[8];
370}
371
372/* felem_diff_128_64 subtracts |in| from |out|
373 * On entry:
374 * in[i] < 2^126
375 * On exit:
376 * out[i] < out[i] + 2^127 - 2^69
377 */
378static void
379felem_diff128(largefelem out, const largefelem in)
380{
381 /* In order to prevent underflow, we add 0 mod p before subtracting. */
382 static const uint128_t two127m70 = (((uint128_t) 1) << 127) - (((uint128_t) 1) << 70);
383 static const uint128_t two127m69 = (((uint128_t) 1) << 127) - (((uint128_t) 1) << 69);
384
385 out[0] += (two127m70 - in[0]);
386 out[1] += (two127m69 - in[1]);
387 out[2] += (two127m69 - in[2]);
388 out[3] += (two127m69 - in[3]);
389 out[4] += (two127m69 - in[4]);
390 out[5] += (two127m69 - in[5]);
391 out[6] += (two127m69 - in[6]);
392 out[7] += (two127m69 - in[7]);
393 out[8] += (two127m69 - in[8]);
394}
395
396/* felem_square sets |out| = |in|^2
397 * On entry:
398 * in[i] < 2^62
399 * On exit:
400 * out[i] < 17 * max(in[i]) * max(in[i])
401 */
402static void
403felem_square(largefelem out, const felem in)
404{
405 felem inx2, inx4;
406 felem_scalar(inx2, in, 2);
407 felem_scalar(inx4, in, 4);
408
409 /*
410 * We have many cases were we want to do in[x] * in[y] + in[y] *
411 * in[x] This is obviously just 2 * in[x] * in[y] However, rather
412 * than do the doubling on the 128 bit result, we double one of the
413 * inputs to the multiplication by reading from |inx2|
414 */
415
416 out[0] = ((uint128_t) in[0]) * in[0];
417 out[1] = ((uint128_t) in[0]) * inx2[1];
418 out[2] = ((uint128_t) in[0]) * inx2[2] +
419 ((uint128_t) in[1]) * in[1];
420 out[3] = ((uint128_t) in[0]) * inx2[3] +
421 ((uint128_t) in[1]) * inx2[2];
422 out[4] = ((uint128_t) in[0]) * inx2[4] +
423 ((uint128_t) in[1]) * inx2[3] +
424 ((uint128_t) in[2]) * in[2];
425 out[5] = ((uint128_t) in[0]) * inx2[5] +
426 ((uint128_t) in[1]) * inx2[4] +
427 ((uint128_t) in[2]) * inx2[3];
428 out[6] = ((uint128_t) in[0]) * inx2[6] +
429 ((uint128_t) in[1]) * inx2[5] +
430 ((uint128_t) in[2]) * inx2[4] +
431 ((uint128_t) in[3]) * in[3];
432 out[7] = ((uint128_t) in[0]) * inx2[7] +
433 ((uint128_t) in[1]) * inx2[6] +
434 ((uint128_t) in[2]) * inx2[5] +
435 ((uint128_t) in[3]) * inx2[4];
436 out[8] = ((uint128_t) in[0]) * inx2[8] +
437 ((uint128_t) in[1]) * inx2[7] +
438 ((uint128_t) in[2]) * inx2[6] +
439 ((uint128_t) in[3]) * inx2[5] +
440 ((uint128_t) in[4]) * in[4];
441
442 /*
443 * The remaining limbs fall above 2^521, with the first falling at
444 * 2^522. They correspond to locations one bit up from the limbs
445 * produced above so we would have to multiply by two to align them.
446 * Again, rather than operate on the 128-bit result, we double one of
447 * the inputs to the multiplication. If we want to double for both
448 * this reason, and the reason above, then we end up multiplying by
449 * four.
450 */
451
452 /* 9 */
453 out[0] += ((uint128_t) in[1]) * inx4[8] +
454 ((uint128_t) in[2]) * inx4[7] +
455 ((uint128_t) in[3]) * inx4[6] +
456 ((uint128_t) in[4]) * inx4[5];
457
458 /* 10 */
459 out[1] += ((uint128_t) in[2]) * inx4[8] +
460 ((uint128_t) in[3]) * inx4[7] +
461 ((uint128_t) in[4]) * inx4[6] +
462 ((uint128_t) in[5]) * inx2[5];
463
464 /* 11 */
465 out[2] += ((uint128_t) in[3]) * inx4[8] +
466 ((uint128_t) in[4]) * inx4[7] +
467 ((uint128_t) in[5]) * inx4[6];
468
469 /* 12 */
470 out[3] += ((uint128_t) in[4]) * inx4[8] +
471 ((uint128_t) in[5]) * inx4[7] +
472 ((uint128_t) in[6]) * inx2[6];
473
474 /* 13 */
475 out[4] += ((uint128_t) in[5]) * inx4[8] +
476 ((uint128_t) in[6]) * inx4[7];
477
478 /* 14 */
479 out[5] += ((uint128_t) in[6]) * inx4[8] +
480 ((uint128_t) in[7]) * inx2[7];
481
482 /* 15 */
483 out[6] += ((uint128_t) in[7]) * inx4[8];
484
485 /* 16 */
486 out[7] += ((uint128_t) in[8]) * inx2[8];
487}
488
489/* felem_mul sets |out| = |in1| * |in2|
490 * On entry:
491 * in1[i] < 2^64
492 * in2[i] < 2^63
493 * On exit:
494 * out[i] < 17 * max(in1[i]) * max(in2[i])
495 */
496static void
497felem_mul(largefelem out, const felem in1, const felem in2)
498{
499 felem in2x2;
500 felem_scalar(in2x2, in2, 2);
501
502 out[0] = ((uint128_t) in1[0]) * in2[0];
503
504 out[1] = ((uint128_t) in1[0]) * in2[1] +
505 ((uint128_t) in1[1]) * in2[0];
506
507 out[2] = ((uint128_t) in1[0]) * in2[2] +
508 ((uint128_t) in1[1]) * in2[1] +
509 ((uint128_t) in1[2]) * in2[0];
510
511 out[3] = ((uint128_t) in1[0]) * in2[3] +
512 ((uint128_t) in1[1]) * in2[2] +
513 ((uint128_t) in1[2]) * in2[1] +
514 ((uint128_t) in1[3]) * in2[0];
515
516 out[4] = ((uint128_t) in1[0]) * in2[4] +
517 ((uint128_t) in1[1]) * in2[3] +
518 ((uint128_t) in1[2]) * in2[2] +
519 ((uint128_t) in1[3]) * in2[1] +
520 ((uint128_t) in1[4]) * in2[0];
521
522 out[5] = ((uint128_t) in1[0]) * in2[5] +
523 ((uint128_t) in1[1]) * in2[4] +
524 ((uint128_t) in1[2]) * in2[3] +
525 ((uint128_t) in1[3]) * in2[2] +
526 ((uint128_t) in1[4]) * in2[1] +
527 ((uint128_t) in1[5]) * in2[0];
528
529 out[6] = ((uint128_t) in1[0]) * in2[6] +
530 ((uint128_t) in1[1]) * in2[5] +
531 ((uint128_t) in1[2]) * in2[4] +
532 ((uint128_t) in1[3]) * in2[3] +
533 ((uint128_t) in1[4]) * in2[2] +
534 ((uint128_t) in1[5]) * in2[1] +
535 ((uint128_t) in1[6]) * in2[0];
536
537 out[7] = ((uint128_t) in1[0]) * in2[7] +
538 ((uint128_t) in1[1]) * in2[6] +
539 ((uint128_t) in1[2]) * in2[5] +
540 ((uint128_t) in1[3]) * in2[4] +
541 ((uint128_t) in1[4]) * in2[3] +
542 ((uint128_t) in1[5]) * in2[2] +
543 ((uint128_t) in1[6]) * in2[1] +
544 ((uint128_t) in1[7]) * in2[0];
545
546 out[8] = ((uint128_t) in1[0]) * in2[8] +
547 ((uint128_t) in1[1]) * in2[7] +
548 ((uint128_t) in1[2]) * in2[6] +
549 ((uint128_t) in1[3]) * in2[5] +
550 ((uint128_t) in1[4]) * in2[4] +
551 ((uint128_t) in1[5]) * in2[3] +
552 ((uint128_t) in1[6]) * in2[2] +
553 ((uint128_t) in1[7]) * in2[1] +
554 ((uint128_t) in1[8]) * in2[0];
555
556 /* See comment in felem_square about the use of in2x2 here */
557
558 out[0] += ((uint128_t) in1[1]) * in2x2[8] +
559 ((uint128_t) in1[2]) * in2x2[7] +
560 ((uint128_t) in1[3]) * in2x2[6] +
561 ((uint128_t) in1[4]) * in2x2[5] +
562 ((uint128_t) in1[5]) * in2x2[4] +
563 ((uint128_t) in1[6]) * in2x2[3] +
564 ((uint128_t) in1[7]) * in2x2[2] +
565 ((uint128_t) in1[8]) * in2x2[1];
566
567 out[1] += ((uint128_t) in1[2]) * in2x2[8] +
568 ((uint128_t) in1[3]) * in2x2[7] +
569 ((uint128_t) in1[4]) * in2x2[6] +
570 ((uint128_t) in1[5]) * in2x2[5] +
571 ((uint128_t) in1[6]) * in2x2[4] +
572 ((uint128_t) in1[7]) * in2x2[3] +
573 ((uint128_t) in1[8]) * in2x2[2];
574
575 out[2] += ((uint128_t) in1[3]) * in2x2[8] +
576 ((uint128_t) in1[4]) * in2x2[7] +
577 ((uint128_t) in1[5]) * in2x2[6] +
578 ((uint128_t) in1[6]) * in2x2[5] +
579 ((uint128_t) in1[7]) * in2x2[4] +
580 ((uint128_t) in1[8]) * in2x2[3];
581
582 out[3] += ((uint128_t) in1[4]) * in2x2[8] +
583 ((uint128_t) in1[5]) * in2x2[7] +
584 ((uint128_t) in1[6]) * in2x2[6] +
585 ((uint128_t) in1[7]) * in2x2[5] +
586 ((uint128_t) in1[8]) * in2x2[4];
587
588 out[4] += ((uint128_t) in1[5]) * in2x2[8] +
589 ((uint128_t) in1[6]) * in2x2[7] +
590 ((uint128_t) in1[7]) * in2x2[6] +
591 ((uint128_t) in1[8]) * in2x2[5];
592
593 out[5] += ((uint128_t) in1[6]) * in2x2[8] +
594 ((uint128_t) in1[7]) * in2x2[7] +
595 ((uint128_t) in1[8]) * in2x2[6];
596
597 out[6] += ((uint128_t) in1[7]) * in2x2[8] +
598 ((uint128_t) in1[8]) * in2x2[7];
599
600 out[7] += ((uint128_t) in1[8]) * in2x2[8];
601}
602
603static const limb bottom52bits = 0xfffffffffffff;
604
605/* felem_reduce converts a largefelem to an felem.
606 * On entry:
607 * in[i] < 2^128
608 * On exit:
609 * out[i] < 2^59 + 2^14
610 */
611static void
612felem_reduce(felem out, const largefelem in)
613{
614 u64 overflow1, overflow2;
615
616 out[0] = ((limb) in[0]) & bottom58bits;
617 out[1] = ((limb) in[1]) & bottom58bits;
618 out[2] = ((limb) in[2]) & bottom58bits;
619 out[3] = ((limb) in[3]) & bottom58bits;
620 out[4] = ((limb) in[4]) & bottom58bits;
621 out[5] = ((limb) in[5]) & bottom58bits;
622 out[6] = ((limb) in[6]) & bottom58bits;
623 out[7] = ((limb) in[7]) & bottom58bits;
624 out[8] = ((limb) in[8]) & bottom58bits;
625
626 /* out[i] < 2^58 */
627
628 out[1] += ((limb) in[0]) >> 58;
629 out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6;
630 /*
631 * out[1] < 2^58 + 2^6 + 2^58 = 2^59 + 2^6
632 */
633 out[2] += ((limb) (in[0] >> 64)) >> 52;
634
635 out[2] += ((limb) in[1]) >> 58;
636 out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6;
637 out[3] += ((limb) (in[1] >> 64)) >> 52;
638
639 out[3] += ((limb) in[2]) >> 58;
640 out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6;
641 out[4] += ((limb) (in[2] >> 64)) >> 52;
642
643 out[4] += ((limb) in[3]) >> 58;
644 out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6;
645 out[5] += ((limb) (in[3] >> 64)) >> 52;
646
647 out[5] += ((limb) in[4]) >> 58;
648 out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6;
649 out[6] += ((limb) (in[4] >> 64)) >> 52;
650
651 out[6] += ((limb) in[5]) >> 58;
652 out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6;
653 out[7] += ((limb) (in[5] >> 64)) >> 52;
654
655 out[7] += ((limb) in[6]) >> 58;
656 out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6;
657 out[8] += ((limb) (in[6] >> 64)) >> 52;
658
659 out[8] += ((limb) in[7]) >> 58;
660 out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6;
661 /*
662 * out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12 < 2^59 + 2^13
663 */
664 overflow1 = ((limb) (in[7] >> 64)) >> 52;
665
666 overflow1 += ((limb) in[8]) >> 58;
667 overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6;
668 overflow2 = ((limb) (in[8] >> 64)) >> 52;
669
670 overflow1 <<= 1; /* overflow1 < 2^13 + 2^7 + 2^59 */
671 overflow2 <<= 1; /* overflow2 < 2^13 */
672
673 out[0] += overflow1; /* out[0] < 2^60 */
674 out[1] += overflow2; /* out[1] < 2^59 + 2^6 + 2^13 */
675
676 out[1] += out[0] >> 58;
677 out[0] &= bottom58bits;
678 /*
679 * out[0] < 2^58 out[1] < 2^59 + 2^6 + 2^13 + 2^2 < 2^59 + 2^14
680 */
681}
682
683static void
684felem_square_reduce(felem out, const felem in)
685{
686 largefelem tmp;
687 felem_square(tmp, in);
688 felem_reduce(out, tmp);
689}
690
691static void
692felem_mul_reduce(felem out, const felem in1, const felem in2)
693{
694 largefelem tmp;
695 felem_mul(tmp, in1, in2);
696 felem_reduce(out, tmp);
697}
698
699/* felem_inv calculates |out| = |in|^{-1}
700 *
701 * Based on Fermat's Little Theorem:
702 * a^p = a (mod p)
703 * a^{p-1} = 1 (mod p)
704 * a^{p-2} = a^{-1} (mod p)
705 */
706static void
707felem_inv(felem out, const felem in)
708{
709 felem ftmp, ftmp2, ftmp3, ftmp4;
710 largefelem tmp;
711 unsigned i;
712
713 felem_square(tmp, in);
714 felem_reduce(ftmp, tmp);/* 2^1 */
715 felem_mul(tmp, in, ftmp);
716 felem_reduce(ftmp, tmp);/* 2^2 - 2^0 */
717 felem_assign(ftmp2, ftmp);
718 felem_square(tmp, ftmp);
719 felem_reduce(ftmp, tmp);/* 2^3 - 2^1 */
720 felem_mul(tmp, in, ftmp);
721 felem_reduce(ftmp, tmp);/* 2^3 - 2^0 */
722 felem_square(tmp, ftmp);
723 felem_reduce(ftmp, tmp);/* 2^4 - 2^1 */
724
725 felem_square(tmp, ftmp2);
726 felem_reduce(ftmp3, tmp); /* 2^3 - 2^1 */
727 felem_square(tmp, ftmp3);
728 felem_reduce(ftmp3, tmp); /* 2^4 - 2^2 */
729 felem_mul(tmp, ftmp3, ftmp2);
730 felem_reduce(ftmp3, tmp); /* 2^4 - 2^0 */
731
732 felem_assign(ftmp2, ftmp3);
733 felem_square(tmp, ftmp3);
734 felem_reduce(ftmp3, tmp); /* 2^5 - 2^1 */
735 felem_square(tmp, ftmp3);
736 felem_reduce(ftmp3, tmp); /* 2^6 - 2^2 */
737 felem_square(tmp, ftmp3);
738 felem_reduce(ftmp3, tmp); /* 2^7 - 2^3 */
739 felem_square(tmp, ftmp3);
740 felem_reduce(ftmp3, tmp); /* 2^8 - 2^4 */
741 felem_assign(ftmp4, ftmp3);
742 felem_mul(tmp, ftmp3, ftmp);
743 felem_reduce(ftmp4, tmp); /* 2^8 - 2^1 */
744 felem_square(tmp, ftmp4);
745 felem_reduce(ftmp4, tmp); /* 2^9 - 2^2 */
746 felem_mul(tmp, ftmp3, ftmp2);
747 felem_reduce(ftmp3, tmp); /* 2^8 - 2^0 */
748 felem_assign(ftmp2, ftmp3);
749
750 for (i = 0; i < 8; i++) {
751 felem_square(tmp, ftmp3);
752 felem_reduce(ftmp3, tmp); /* 2^16 - 2^8 */
753 }
754 felem_mul(tmp, ftmp3, ftmp2);
755 felem_reduce(ftmp3, tmp); /* 2^16 - 2^0 */
756 felem_assign(ftmp2, ftmp3);
757
758 for (i = 0; i < 16; i++) {
759 felem_square(tmp, ftmp3);
760 felem_reduce(ftmp3, tmp); /* 2^32 - 2^16 */
761 }
762 felem_mul(tmp, ftmp3, ftmp2);
763 felem_reduce(ftmp3, tmp); /* 2^32 - 2^0 */
764 felem_assign(ftmp2, ftmp3);
765
766 for (i = 0; i < 32; i++) {
767 felem_square(tmp, ftmp3);
768 felem_reduce(ftmp3, tmp); /* 2^64 - 2^32 */
769 }
770 felem_mul(tmp, ftmp3, ftmp2);
771 felem_reduce(ftmp3, tmp); /* 2^64 - 2^0 */
772 felem_assign(ftmp2, ftmp3);
773
774 for (i = 0; i < 64; i++) {
775 felem_square(tmp, ftmp3);
776 felem_reduce(ftmp3, tmp); /* 2^128 - 2^64 */
777 }
778 felem_mul(tmp, ftmp3, ftmp2);
779 felem_reduce(ftmp3, tmp); /* 2^128 - 2^0 */
780 felem_assign(ftmp2, ftmp3);
781
782 for (i = 0; i < 128; i++) {
783 felem_square(tmp, ftmp3);
784 felem_reduce(ftmp3, tmp); /* 2^256 - 2^128 */
785 }
786 felem_mul(tmp, ftmp3, ftmp2);
787 felem_reduce(ftmp3, tmp); /* 2^256 - 2^0 */
788 felem_assign(ftmp2, ftmp3);
789
790 for (i = 0; i < 256; i++) {
791 felem_square(tmp, ftmp3);
792 felem_reduce(ftmp3, tmp); /* 2^512 - 2^256 */
793 }
794 felem_mul(tmp, ftmp3, ftmp2);
795 felem_reduce(ftmp3, tmp); /* 2^512 - 2^0 */
796
797 for (i = 0; i < 9; i++) {
798 felem_square(tmp, ftmp3);
799 felem_reduce(ftmp3, tmp); /* 2^521 - 2^9 */
800 }
801 felem_mul(tmp, ftmp3, ftmp4);
802 felem_reduce(ftmp3, tmp); /* 2^512 - 2^2 */
803 felem_mul(tmp, ftmp3, in);
804 felem_reduce(out, tmp); /* 2^512 - 3 */
805}
806
807/* This is 2^521-1, expressed as an felem */
808static const felem kPrime =
809{
810 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
811 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
812 0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff
813};
814
815/* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
816 * otherwise.
817 * On entry:
818 * in[i] < 2^59 + 2^14
819 */
820static limb
821felem_is_zero(const felem in)
822{
823 felem ftmp;
824 limb is_zero, is_p;
825 felem_assign(ftmp, in);
826
827 ftmp[0] += ftmp[8] >> 57;
828 ftmp[8] &= bottom57bits;
829 /* ftmp[8] < 2^57 */
830 ftmp[1] += ftmp[0] >> 58;
831 ftmp[0] &= bottom58bits;
832 ftmp[2] += ftmp[1] >> 58;
833 ftmp[1] &= bottom58bits;
834 ftmp[3] += ftmp[2] >> 58;
835 ftmp[2] &= bottom58bits;
836 ftmp[4] += ftmp[3] >> 58;
837 ftmp[3] &= bottom58bits;
838 ftmp[5] += ftmp[4] >> 58;
839 ftmp[4] &= bottom58bits;
840 ftmp[6] += ftmp[5] >> 58;
841 ftmp[5] &= bottom58bits;
842 ftmp[7] += ftmp[6] >> 58;
843 ftmp[6] &= bottom58bits;
844 ftmp[8] += ftmp[7] >> 58;
845 ftmp[7] &= bottom58bits;
846 /* ftmp[8] < 2^57 + 4 */
847
848 /*
849 * The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is
850 * greater than our bound for ftmp[8]. Therefore we only have to
851 * check if the zero is zero or 2^521-1.
852 */
853
854 is_zero = 0;
855 is_zero |= ftmp[0];
856 is_zero |= ftmp[1];
857 is_zero |= ftmp[2];
858 is_zero |= ftmp[3];
859 is_zero |= ftmp[4];
860 is_zero |= ftmp[5];
861 is_zero |= ftmp[6];
862 is_zero |= ftmp[7];
863 is_zero |= ftmp[8];
864
865 is_zero--;
866 /*
867 * We know that ftmp[i] < 2^63, therefore the only way that the top
868 * bit can be set is if is_zero was 0 before the decrement.
869 */
870 is_zero = ((s64) is_zero) >> 63;
871
872 is_p = ftmp[0] ^ kPrime[0];
873 is_p |= ftmp[1] ^ kPrime[1];
874 is_p |= ftmp[2] ^ kPrime[2];
875 is_p |= ftmp[3] ^ kPrime[3];
876 is_p |= ftmp[4] ^ kPrime[4];
877 is_p |= ftmp[5] ^ kPrime[5];
878 is_p |= ftmp[6] ^ kPrime[6];
879 is_p |= ftmp[7] ^ kPrime[7];
880 is_p |= ftmp[8] ^ kPrime[8];
881
882 is_p--;
883 is_p = ((s64) is_p) >> 63;
884
885 is_zero |= is_p;
886 return is_zero;
887}
888
889static int
890felem_is_zero_int(const felem in)
891{
892 return (int) (felem_is_zero(in) & ((limb) 1));
893}
894
895/* felem_contract converts |in| to its unique, minimal representation.
896 * On entry:
897 * in[i] < 2^59 + 2^14
898 */
899static void
900felem_contract(felem out, const felem in)
901{
902 limb is_p, is_greater, sign;
903 static const limb two58 = ((limb) 1) << 58;
904
905 felem_assign(out, in);
906
907 out[0] += out[8] >> 57;
908 out[8] &= bottom57bits;
909 /* out[8] < 2^57 */
910 out[1] += out[0] >> 58;
911 out[0] &= bottom58bits;
912 out[2] += out[1] >> 58;
913 out[1] &= bottom58bits;
914 out[3] += out[2] >> 58;
915 out[2] &= bottom58bits;
916 out[4] += out[3] >> 58;
917 out[3] &= bottom58bits;
918 out[5] += out[4] >> 58;
919 out[4] &= bottom58bits;
920 out[6] += out[5] >> 58;
921 out[5] &= bottom58bits;
922 out[7] += out[6] >> 58;
923 out[6] &= bottom58bits;
924 out[8] += out[7] >> 58;
925 out[7] &= bottom58bits;
926 /* out[8] < 2^57 + 4 */
927
928 /*
929 * If the value is greater than 2^521-1 then we have to subtract
930 * 2^521-1 out. See the comments in felem_is_zero regarding why we
931 * don't test for other multiples of the prime.
932 */
933
934 /*
935 * First, if |out| is equal to 2^521-1, we subtract it out to get
936 * zero.
937 */
938
939 is_p = out[0] ^ kPrime[0];
940 is_p |= out[1] ^ kPrime[1];
941 is_p |= out[2] ^ kPrime[2];
942 is_p |= out[3] ^ kPrime[3];
943 is_p |= out[4] ^ kPrime[4];
944 is_p |= out[5] ^ kPrime[5];
945 is_p |= out[6] ^ kPrime[6];
946 is_p |= out[7] ^ kPrime[7];
947 is_p |= out[8] ^ kPrime[8];
948
949 is_p--;
950 is_p &= is_p << 32;
951 is_p &= is_p << 16;
952 is_p &= is_p << 8;
953 is_p &= is_p << 4;
954 is_p &= is_p << 2;
955 is_p &= is_p << 1;
956 is_p = ((s64) is_p) >> 63;
957 is_p = ~is_p;
958
959 /* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */
960
961 out[0] &= is_p;
962 out[1] &= is_p;
963 out[2] &= is_p;
964 out[3] &= is_p;
965 out[4] &= is_p;
966 out[5] &= is_p;
967 out[6] &= is_p;
968 out[7] &= is_p;
969 out[8] &= is_p;
970
971 /*
972 * In order to test that |out| >= 2^521-1 we need only test if out[8]
973 * >> 57 is greater than zero as (2^521-1) + x >= 2^522
974 */
975 is_greater = out[8] >> 57;
976 is_greater |= is_greater << 32;
977 is_greater |= is_greater << 16;
978 is_greater |= is_greater << 8;
979 is_greater |= is_greater << 4;
980 is_greater |= is_greater << 2;
981 is_greater |= is_greater << 1;
982 is_greater = ((s64) is_greater) >> 63;
983
984 out[0] -= kPrime[0] & is_greater;
985 out[1] -= kPrime[1] & is_greater;
986 out[2] -= kPrime[2] & is_greater;
987 out[3] -= kPrime[3] & is_greater;
988 out[4] -= kPrime[4] & is_greater;
989 out[5] -= kPrime[5] & is_greater;
990 out[6] -= kPrime[6] & is_greater;
991 out[7] -= kPrime[7] & is_greater;
992 out[8] -= kPrime[8] & is_greater;
993
994 /* Eliminate negative coefficients */
995 sign = -(out[0] >> 63);
996 out[0] += (two58 & sign);
997 out[1] -= (1 & sign);
998 sign = -(out[1] >> 63);
999 out[1] += (two58 & sign);
1000 out[2] -= (1 & sign);
1001 sign = -(out[2] >> 63);
1002 out[2] += (two58 & sign);
1003 out[3] -= (1 & sign);
1004 sign = -(out[3] >> 63);
1005 out[3] += (two58 & sign);
1006 out[4] -= (1 & sign);
1007 sign = -(out[4] >> 63);
1008 out[4] += (two58 & sign);
1009 out[5] -= (1 & sign);
1010 sign = -(out[0] >> 63);
1011 out[5] += (two58 & sign);
1012 out[6] -= (1 & sign);
1013 sign = -(out[6] >> 63);
1014 out[6] += (two58 & sign);
1015 out[7] -= (1 & sign);
1016 sign = -(out[7] >> 63);
1017 out[7] += (two58 & sign);
1018 out[8] -= (1 & sign);
1019 sign = -(out[5] >> 63);
1020 out[5] += (two58 & sign);
1021 out[6] -= (1 & sign);
1022 sign = -(out[6] >> 63);
1023 out[6] += (two58 & sign);
1024 out[7] -= (1 & sign);
1025 sign = -(out[7] >> 63);
1026 out[7] += (two58 & sign);
1027 out[8] -= (1 & sign);
1028}
1029
1030/* Group operations
1031 * ----------------
1032 *
1033 * Building on top of the field operations we have the operations on the
1034 * elliptic curve group itself. Points on the curve are represented in Jacobian
1035 * coordinates */
1036
1037/* point_double calcuates 2*(x_in, y_in, z_in)
1038 *
1039 * The method is taken from:
1040 * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
1041 *
1042 * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
1043 * while x_out == y_in is not (maybe this works, but it's not tested). */
1044static void
1045point_double(felem x_out, felem y_out, felem z_out,
1046 const felem x_in, const felem y_in, const felem z_in)
1047{
1048 largefelem tmp, tmp2;
1049 felem delta, gamma, beta, alpha, ftmp, ftmp2;
1050
1051 felem_assign(ftmp, x_in);
1052 felem_assign(ftmp2, x_in);
1053
1054 /* delta = z^2 */
1055 felem_square(tmp, z_in);
1056 felem_reduce(delta, tmp); /* delta[i] < 2^59 + 2^14 */
1057
1058 /* gamma = y^2 */
1059 felem_square(tmp, y_in);
1060 felem_reduce(gamma, tmp); /* gamma[i] < 2^59 + 2^14 */
1061
1062 /* beta = x*gamma */
1063 felem_mul(tmp, x_in, gamma);
1064 felem_reduce(beta, tmp);/* beta[i] < 2^59 + 2^14 */
1065
1066 /* alpha = 3*(x-delta)*(x+delta) */
1067 felem_diff64(ftmp, delta);
1068 /* ftmp[i] < 2^61 */
1069 felem_sum64(ftmp2, delta);
1070 /* ftmp2[i] < 2^60 + 2^15 */
1071 felem_scalar64(ftmp2, 3);
1072 /* ftmp2[i] < 3*2^60 + 3*2^15 */
1073 felem_mul(tmp, ftmp, ftmp2);
1074 /*
1075 * tmp[i] < 17(3*2^121 + 3*2^76) = 61*2^121 + 61*2^76 < 64*2^121 +
1076 * 64*2^76 = 2^127 + 2^82 < 2^128
1077 */
1078 felem_reduce(alpha, tmp);
1079
1080 /* x' = alpha^2 - 8*beta */
1081 felem_square(tmp, alpha);
1082 /*
1083 * tmp[i] < 17*2^120 < 2^125
1084 */
1085 felem_assign(ftmp, beta);
1086 felem_scalar64(ftmp, 8);
1087 /* ftmp[i] < 2^62 + 2^17 */
1088 felem_diff_128_64(tmp, ftmp);
1089 /* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */
1090 felem_reduce(x_out, tmp);
1091
1092 /* z' = (y + z)^2 - gamma - delta */
1093 felem_sum64(delta, gamma);
1094 /* delta[i] < 2^60 + 2^15 */
1095 felem_assign(ftmp, y_in);
1096 felem_sum64(ftmp, z_in);
1097 /* ftmp[i] < 2^60 + 2^15 */
1098 felem_square(tmp, ftmp);
1099 /*
1100 * tmp[i] < 17(2^122) < 2^127
1101 */
1102 felem_diff_128_64(tmp, delta);
1103 /* tmp[i] < 2^127 + 2^63 */
1104 felem_reduce(z_out, tmp);
1105
1106 /* y' = alpha*(4*beta - x') - 8*gamma^2 */
1107 felem_scalar64(beta, 4);
1108 /* beta[i] < 2^61 + 2^16 */
1109 felem_diff64(beta, x_out);
1110 /* beta[i] < 2^61 + 2^60 + 2^16 */
1111 felem_mul(tmp, alpha, beta);
1112 /*
1113 * tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16)) = 17*(2^120 + 2^75
1114 * + 2^119 + 2^74 + 2^75 + 2^30) = 17*(2^120 + 2^119 + 2^76 + 2^74 +
1115 * 2^30) < 2^128
1116 */
1117 felem_square(tmp2, gamma);
1118 /*
1119 * tmp2[i] < 17*(2^59 + 2^14)^2 = 17*(2^118 + 2^74 + 2^28)
1120 */
1121 felem_scalar128(tmp2, 8);
1122 /*
1123 * tmp2[i] < 8*17*(2^118 + 2^74 + 2^28) = 2^125 + 2^121 + 2^81 + 2^77
1124 * + 2^35 + 2^31 < 2^126
1125 */
1126 felem_diff128(tmp, tmp2);
1127 /*
1128 * tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30) =
1129 * 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 + 2^74
1130 * + 2^69 + 2^34 + 2^30 < 2^128
1131 */
1132 felem_reduce(y_out, tmp);
1133}
1134
1135/* copy_conditional copies in to out iff mask is all ones. */
1136static void
1137copy_conditional(felem out, const felem in, limb mask)
1138{
1139 unsigned i;
1140 for (i = 0; i < NLIMBS; ++i) {
1141 const limb tmp = mask & (in[i] ^ out[i]);
1142 out[i] ^= tmp;
1143 }
1144}
1145
1146/* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
1147 *
1148 * The method is taken from
1149 * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
1150 * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
1151 *
1152 * This function includes a branch for checking whether the two input points
1153 * are equal (while not equal to the point at infinity). This case never
1154 * happens during single point multiplication, so there is no timing leak for
1155 * ECDH or ECDSA signing. */
1156static void
1157point_add(felem x3, felem y3, felem z3,
1158 const felem x1, const felem y1, const felem z1,
1159 const int mixed, const felem x2, const felem y2, const felem z2)
1160{
1161 felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
1162 largefelem tmp, tmp2;
1163 limb x_equal, y_equal, z1_is_zero, z2_is_zero;
1164
1165 z1_is_zero = felem_is_zero(z1);
1166 z2_is_zero = felem_is_zero(z2);
1167
1168 /* ftmp = z1z1 = z1**2 */
1169 felem_square(tmp, z1);
1170 felem_reduce(ftmp, tmp);
1171
1172 if (!mixed) {
1173 /* ftmp2 = z2z2 = z2**2 */
1174 felem_square(tmp, z2);
1175 felem_reduce(ftmp2, tmp);
1176
1177 /* u1 = ftmp3 = x1*z2z2 */
1178 felem_mul(tmp, x1, ftmp2);
1179 felem_reduce(ftmp3, tmp);
1180
1181 /* ftmp5 = z1 + z2 */
1182 felem_assign(ftmp5, z1);
1183 felem_sum64(ftmp5, z2);
1184 /* ftmp5[i] < 2^61 */
1185
1186 /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */
1187 felem_square(tmp, ftmp5);
1188 /* tmp[i] < 17*2^122 */
1189 felem_diff_128_64(tmp, ftmp);
1190 /* tmp[i] < 17*2^122 + 2^63 */
1191 felem_diff_128_64(tmp, ftmp2);
1192 /* tmp[i] < 17*2^122 + 2^64 */
1193 felem_reduce(ftmp5, tmp);
1194
1195 /* ftmp2 = z2 * z2z2 */
1196 felem_mul(tmp, ftmp2, z2);
1197 felem_reduce(ftmp2, tmp);
1198
1199 /* s1 = ftmp6 = y1 * z2**3 */
1200 felem_mul(tmp, y1, ftmp2);
1201 felem_reduce(ftmp6, tmp);
1202 } else {
1203 /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
1204
1205 /* u1 = ftmp3 = x1*z2z2 */
1206 felem_assign(ftmp3, x1);
1207
1208 /* ftmp5 = 2*z1z2 */
1209 felem_scalar(ftmp5, z1, 2);
1210
1211 /* s1 = ftmp6 = y1 * z2**3 */
1212 felem_assign(ftmp6, y1);
1213 }
1214
1215 /* u2 = x2*z1z1 */
1216 felem_mul(tmp, x2, ftmp);
1217 /* tmp[i] < 17*2^120 */
1218
1219 /* h = ftmp4 = u2 - u1 */
1220 felem_diff_128_64(tmp, ftmp3);
1221 /* tmp[i] < 17*2^120 + 2^63 */
1222 felem_reduce(ftmp4, tmp);
1223
1224 x_equal = felem_is_zero(ftmp4);
1225
1226 /* z_out = ftmp5 * h */
1227 felem_mul(tmp, ftmp5, ftmp4);
1228 felem_reduce(z_out, tmp);
1229
1230 /* ftmp = z1 * z1z1 */
1231 felem_mul(tmp, ftmp, z1);
1232 felem_reduce(ftmp, tmp);
1233
1234 /* s2 = tmp = y2 * z1**3 */
1235 felem_mul(tmp, y2, ftmp);
1236 /* tmp[i] < 17*2^120 */
1237
1238 /* r = ftmp5 = (s2 - s1)*2 */
1239 felem_diff_128_64(tmp, ftmp6);
1240 /* tmp[i] < 17*2^120 + 2^63 */
1241 felem_reduce(ftmp5, tmp);
1242 y_equal = felem_is_zero(ftmp5);
1243 felem_scalar64(ftmp5, 2);
1244 /* ftmp5[i] < 2^61 */
1245
1246 if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
1247 point_double(x3, y3, z3, x1, y1, z1);
1248 return;
1249 }
1250 /* I = ftmp = (2h)**2 */
1251 felem_assign(ftmp, ftmp4);
1252 felem_scalar64(ftmp, 2);
1253 /* ftmp[i] < 2^61 */
1254 felem_square(tmp, ftmp);
1255 /* tmp[i] < 17*2^122 */
1256 felem_reduce(ftmp, tmp);
1257
1258 /* J = ftmp2 = h * I */
1259 felem_mul(tmp, ftmp4, ftmp);
1260 felem_reduce(ftmp2, tmp);
1261
1262 /* V = ftmp4 = U1 * I */
1263 felem_mul(tmp, ftmp3, ftmp);
1264 felem_reduce(ftmp4, tmp);
1265
1266 /* x_out = r**2 - J - 2V */
1267 felem_square(tmp, ftmp5);
1268 /* tmp[i] < 17*2^122 */
1269 felem_diff_128_64(tmp, ftmp2);
1270 /* tmp[i] < 17*2^122 + 2^63 */
1271 felem_assign(ftmp3, ftmp4);
1272 felem_scalar64(ftmp4, 2);
1273 /* ftmp4[i] < 2^61 */
1274 felem_diff_128_64(tmp, ftmp4);
1275 /* tmp[i] < 17*2^122 + 2^64 */
1276 felem_reduce(x_out, tmp);
1277
1278 /* y_out = r(V-x_out) - 2 * s1 * J */
1279 felem_diff64(ftmp3, x_out);
1280 /*
1281 * ftmp3[i] < 2^60 + 2^60 = 2^61
1282 */
1283 felem_mul(tmp, ftmp5, ftmp3);
1284 /* tmp[i] < 17*2^122 */
1285 felem_mul(tmp2, ftmp6, ftmp2);
1286 /* tmp2[i] < 17*2^120 */
1287 felem_scalar128(tmp2, 2);
1288 /* tmp2[i] < 17*2^121 */
1289 felem_diff128(tmp, tmp2);
1290 /*
1291 * tmp[i] < 2^127 - 2^69 + 17*2^122 = 2^126 - 2^122 - 2^6 - 2^2 - 1 <
1292 * 2^127
1293 */
1294 felem_reduce(y_out, tmp);
1295
1296 copy_conditional(x_out, x2, z1_is_zero);
1297 copy_conditional(x_out, x1, z2_is_zero);
1298 copy_conditional(y_out, y2, z1_is_zero);
1299 copy_conditional(y_out, y1, z2_is_zero);
1300 copy_conditional(z_out, z2, z1_is_zero);
1301 copy_conditional(z_out, z1, z2_is_zero);
1302 felem_assign(x3, x_out);
1303 felem_assign(y3, y_out);
1304 felem_assign(z3, z_out);
1305}
1306
1307/* Base point pre computation
1308 * --------------------------
1309 *
1310 * Two different sorts of precomputed tables are used in the following code.
1311 * Each contain various points on the curve, where each point is three field
1312 * elements (x, y, z).
1313 *
1314 * For the base point table, z is usually 1 (0 for the point at infinity).
1315 * This table has 16 elements:
1316 * index | bits | point
1317 * ------+---------+------------------------------
1318 * 0 | 0 0 0 0 | 0G
1319 * 1 | 0 0 0 1 | 1G
1320 * 2 | 0 0 1 0 | 2^130G
1321 * 3 | 0 0 1 1 | (2^130 + 1)G
1322 * 4 | 0 1 0 0 | 2^260G
1323 * 5 | 0 1 0 1 | (2^260 + 1)G
1324 * 6 | 0 1 1 0 | (2^260 + 2^130)G
1325 * 7 | 0 1 1 1 | (2^260 + 2^130 + 1)G
1326 * 8 | 1 0 0 0 | 2^390G
1327 * 9 | 1 0 0 1 | (2^390 + 1)G
1328 * 10 | 1 0 1 0 | (2^390 + 2^130)G
1329 * 11 | 1 0 1 1 | (2^390 + 2^130 + 1)G
1330 * 12 | 1 1 0 0 | (2^390 + 2^260)G
1331 * 13 | 1 1 0 1 | (2^390 + 2^260 + 1)G
1332 * 14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G
1333 * 15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G
1334 *
1335 * The reason for this is so that we can clock bits into four different
1336 * locations when doing simple scalar multiplies against the base point.
1337 *
1338 * Tables for other points have table[i] = iG for i in 0 .. 16. */
1339
1340/* gmul is the table of precomputed base points */
1341static const felem gmul[16][3] =
1342{{{0, 0, 0, 0, 0, 0, 0, 0, 0},
1343{0, 0, 0, 0, 0, 0, 0, 0, 0},
1344{0, 0, 0, 0, 0, 0, 0, 0, 0}},
1345{{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334,
1346 0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8,
13470x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404},
1348{0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353,
1349 0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45,
13500x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b},
1351{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1352{{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad,
1353 0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e,
13540x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5},
1355{0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58,
1356 0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c,
13570x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7},
1358{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1359{{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873,
1360 0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c,
13610x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9},
1362{0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52,
1363 0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e,
13640x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe},
1365{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1366{{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2,
1367 0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561,
13680x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065},
1369{0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a,
1370 0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e,
13710x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524},
1372{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1373{{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6,
1374 0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51,
13750x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe},
1376{0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d,
1377 0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c,
13780x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7},
1379{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1380{{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27,
1381 0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f,
13820x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256},
1383{0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa,
1384 0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2,
13850x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd},
1386{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1387{{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890,
1388 0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74,
13890x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23},
1390{0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516,
1391 0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1,
13920x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e},
1393{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1394{{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce,
1395 0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7,
13960x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5},
1397{0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318,
1398 0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83,
13990x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242},
1400{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1401{{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae,
1402 0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef,
14030x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203},
1404{0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447,
1405 0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283,
14060x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f},
1407{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1408{{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5,
1409 0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c,
14100x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a},
1411{0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df,
1412 0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645,
14130x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a},
1414{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1415{{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292,
1416 0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422,
14170x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b},
1418{0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30,
1419 0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb,
14200x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f},
1421{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1422{{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767,
1423 0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3,
14240x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf},
1425{0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2,
1426 0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692,
14270x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d},
1428{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1429{{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3,
1430 0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade,
14310x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684},
1432{0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8,
1433 0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a,
14340x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81},
1435{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1436{{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608,
1437 0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610,
14380x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d},
1439{0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006,
1440 0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86,
14410x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42},
1442{1, 0, 0, 0, 0, 0, 0, 0, 0}},
1443{{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c,
1444 0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9,
14450x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f},
1446{0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7,
1447 0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c,
14480x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055},
1449{1, 0, 0, 0, 0, 0, 0, 0, 0}}};
1450
1451/* select_point selects the |idx|th point from a precomputation table and
1452 * copies it to out. */
1453static void
1454select_point(const limb idx, unsigned int size, const felem pre_comp[ /* size */ ][3],
1455 felem out[3])
1456{
1457 unsigned i, j;
1458 limb *outlimbs = &out[0][0];
1459 memset(outlimbs, 0, 3 * sizeof(felem));
1460
1461 for (i = 0; i < size; i++) {
1462 const limb *inlimbs = &pre_comp[i][0][0];
1463 limb mask = i ^ idx;
1464 mask |= mask >> 4;
1465 mask |= mask >> 2;
1466 mask |= mask >> 1;
1467 mask &= 1;
1468 mask--;
1469 for (j = 0; j < NLIMBS * 3; j++)
1470 outlimbs[j] |= inlimbs[j] & mask;
1471 }
1472}
1473
1474/* get_bit returns the |i|th bit in |in| */
1475static char
1476get_bit(const felem_bytearray in, int i)
1477{
1478 if (i < 0)
1479 return 0;
1480 return (in[i >> 3] >> (i & 7)) & 1;
1481}
1482
1483/* Interleaved point multiplication using precomputed point multiples:
1484 * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
1485 * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
1486 * of the generator, using certain (large) precomputed multiples in g_pre_comp.
1487 * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
1488static void
1489batch_mul(felem x_out, felem y_out, felem z_out,
1490 const felem_bytearray scalars[], const unsigned num_points, const u8 * g_scalar,
1491 const int mixed, const felem pre_comp[][17][3], const felem g_pre_comp[16][3])
1492{
1493 int i, skip;
1494 unsigned num, gen_mul = (g_scalar != NULL);
1495 felem nq[3], tmp[4];
1496 limb bits;
1497 u8 sign, digit;
1498
1499 /* set nq to the point at infinity */
1500 memset(nq, 0, 3 * sizeof(felem));
1501
1502 /*
1503 * Loop over all scalars msb-to-lsb, interleaving additions of
1504 * multiples of the generator (last quarter of rounds) and additions
1505 * of other points multiples (every 5th round).
1506 */
1507 skip = 1; /* save two point operations in the first
1508 * round */
1509 for (i = (num_points ? 520 : 130); i >= 0; --i) {
1510 /* double */
1511 if (!skip)
1512 point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1513
1514 /* add multiples of the generator */
1515 if (gen_mul && (i <= 130)) {
1516 bits = get_bit(g_scalar, i + 390) << 3;
1517 if (i < 130) {
1518 bits |= get_bit(g_scalar, i + 260) << 2;
1519 bits |= get_bit(g_scalar, i + 130) << 1;
1520 bits |= get_bit(g_scalar, i);
1521 }
1522 /* select the point to add, in constant time */
1523 select_point(bits, 16, g_pre_comp, tmp);
1524 if (!skip) {
1525 point_add(nq[0], nq[1], nq[2],
1526 nq[0], nq[1], nq[2],
1527 1 /* mixed */ , tmp[0], tmp[1], tmp[2]);
1528 } else {
1529 memcpy(nq, tmp, 3 * sizeof(felem));
1530 skip = 0;
1531 }
1532 }
1533 /* do other additions every 5 doublings */
1534 if (num_points && (i % 5 == 0)) {
1535 /* loop over all scalars */
1536 for (num = 0; num < num_points; ++num) {
1537 bits = get_bit(scalars[num], i + 4) << 5;
1538 bits |= get_bit(scalars[num], i + 3) << 4;
1539 bits |= get_bit(scalars[num], i + 2) << 3;
1540 bits |= get_bit(scalars[num], i + 1) << 2;
1541 bits |= get_bit(scalars[num], i) << 1;
1542 bits |= get_bit(scalars[num], i - 1);
1543 ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
1544
1545 /*
1546 * select the point to add or subtract, in
1547 * constant time
1548 */
1549 select_point(digit, 17, pre_comp[num], tmp);
1550 felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the
1551 * negative point */
1552 copy_conditional(tmp[1], tmp[3], (-(limb) sign));
1553
1554 if (!skip) {
1555 point_add(nq[0], nq[1], nq[2],
1556 nq[0], nq[1], nq[2],
1557 mixed, tmp[0], tmp[1], tmp[2]);
1558 } else {
1559 memcpy(nq, tmp, 3 * sizeof(felem));
1560 skip = 0;
1561 }
1562 }
1563 }
1564 }
1565 felem_assign(x_out, nq[0]);
1566 felem_assign(y_out, nq[1]);
1567 felem_assign(z_out, nq[2]);
1568}
1569
1570
1571/* Precomputation for the group generator. */
1572typedef struct {
1573 felem g_pre_comp[16][3];
1574 int references;
1575} NISTP521_PRE_COMP;
1576
1577const EC_METHOD *
1578EC_GFp_nistp521_method(void)
1579{
1580 static const EC_METHOD ret = {
1581 .flags = EC_FLAGS_DEFAULT_OCT,
1582 .field_type = NID_X9_62_prime_field,
1583 .group_init = ec_GFp_nistp521_group_init,
1584 .group_finish = ec_GFp_simple_group_finish,
1585 .group_clear_finish = ec_GFp_simple_group_clear_finish,
1586 .group_copy = ec_GFp_nist_group_copy,
1587 .group_set_curve = ec_GFp_nistp521_group_set_curve,
1588 .group_get_curve = ec_GFp_simple_group_get_curve,
1589 .group_get_degree = ec_GFp_simple_group_get_degree,
1590 .group_check_discriminant =
1591 ec_GFp_simple_group_check_discriminant,
1592 .point_init = ec_GFp_simple_point_init,
1593 .point_finish = ec_GFp_simple_point_finish,
1594 .point_clear_finish = ec_GFp_simple_point_clear_finish,
1595 .point_copy = ec_GFp_simple_point_copy,
1596 .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
1597 .point_set_Jprojective_coordinates_GFp =
1598 ec_GFp_simple_set_Jprojective_coordinates_GFp,
1599 .point_get_Jprojective_coordinates_GFp =
1600 ec_GFp_simple_get_Jprojective_coordinates_GFp,
1601 .point_set_affine_coordinates =
1602 ec_GFp_simple_point_set_affine_coordinates,
1603 .point_get_affine_coordinates =
1604 ec_GFp_nistp521_point_get_affine_coordinates,
1605 .add = ec_GFp_simple_add,
1606 .dbl = ec_GFp_simple_dbl,
1607 .invert = ec_GFp_simple_invert,
1608 .is_at_infinity = ec_GFp_simple_is_at_infinity,
1609 .is_on_curve = ec_GFp_simple_is_on_curve,
1610 .point_cmp = ec_GFp_simple_cmp,
1611 .make_affine = ec_GFp_simple_make_affine,
1612 .points_make_affine = ec_GFp_simple_points_make_affine,
1613 .mul = ec_GFp_nistp521_points_mul,
1614 .precompute_mult = ec_GFp_nistp521_precompute_mult,
1615 .have_precompute_mult = ec_GFp_nistp521_have_precompute_mult,
1616 .field_mul = ec_GFp_nist_field_mul,
1617 .field_sqr = ec_GFp_nist_field_sqr
1618 };
1619
1620 return &ret;
1621}
1622
1623
1624/******************************************************************************/
1625/* FUNCTIONS TO MANAGE PRECOMPUTATION
1626 */
1627
1628static NISTP521_PRE_COMP *
1629nistp521_pre_comp_new()
1630{
1631 NISTP521_PRE_COMP *ret = NULL;
1632 ret = malloc(sizeof(NISTP521_PRE_COMP));
1633 if (!ret) {
1634 ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
1635 return ret;
1636 }
1637 memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
1638 ret->references = 1;
1639 return ret;
1640}
1641
1642static void *
1643nistp521_pre_comp_dup(void *src_)
1644{
1645 NISTP521_PRE_COMP *src = src_;
1646
1647 /* no need to actually copy, these objects never change! */
1648 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
1649
1650 return src_;
1651}
1652
1653static void
1654nistp521_pre_comp_free(void *pre_)
1655{
1656 int i;
1657 NISTP521_PRE_COMP *pre = pre_;
1658
1659 if (!pre)
1660 return;
1661
1662 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1663 if (i > 0)
1664 return;
1665
1666 free(pre);
1667}
1668
1669static void
1670nistp521_pre_comp_clear_free(void *pre_)
1671{
1672 int i;
1673 NISTP521_PRE_COMP *pre = pre_;
1674
1675 if (!pre)
1676 return;
1677
1678 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1679 if (i > 0)
1680 return;
1681
1682 explicit_bzero(pre, sizeof(*pre));
1683 free(pre);
1684}
1685
1686/******************************************************************************/
1687/* OPENSSL EC_METHOD FUNCTIONS
1688 */
1689
1690int
1691ec_GFp_nistp521_group_init(EC_GROUP * group)
1692{
1693 int ret;
1694 ret = ec_GFp_simple_group_init(group);
1695 group->a_is_minus3 = 1;
1696 return ret;
1697}
1698
1699int
1700ec_GFp_nistp521_group_set_curve(EC_GROUP * group, const BIGNUM * p,
1701 const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
1702{
1703 int ret = 0;
1704 BN_CTX *new_ctx = NULL;
1705 BIGNUM *curve_p, *curve_a, *curve_b;
1706
1707 if (ctx == NULL)
1708 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
1709 return 0;
1710 BN_CTX_start(ctx);
1711 if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
1712 ((curve_a = BN_CTX_get(ctx)) == NULL) ||
1713 ((curve_b = BN_CTX_get(ctx)) == NULL))
1714 goto err;
1715 BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p);
1716 BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a);
1717 BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b);
1718 if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
1719 (BN_cmp(curve_b, b))) {
1720 ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE,
1721 EC_R_WRONG_CURVE_PARAMETERS);
1722 goto err;
1723 }
1724 group->field_mod_func = BN_nist_mod_521;
1725 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
1726err:
1727 BN_CTX_end(ctx);
1728 BN_CTX_free(new_ctx);
1729 return ret;
1730}
1731
1732/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
1733 * (X', Y') = (X/Z^2, Y/Z^3) */
1734int
1735ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP * group,
1736 const EC_POINT * point, BIGNUM * x, BIGNUM * y, BN_CTX * ctx)
1737{
1738 felem z1, z2, x_in, y_in, x_out, y_out;
1739 largefelem tmp;
1740
1741 if (EC_POINT_is_at_infinity(group, point) > 0) {
1742 ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
1743 EC_R_POINT_AT_INFINITY);
1744 return 0;
1745 }
1746 if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
1747 (!BN_to_felem(z1, &point->Z)))
1748 return 0;
1749 felem_inv(z2, z1);
1750 felem_square(tmp, z2);
1751 felem_reduce(z1, tmp);
1752 felem_mul(tmp, x_in, z1);
1753 felem_reduce(x_in, tmp);
1754 felem_contract(x_out, x_in);
1755 if (x != NULL) {
1756 if (!felem_to_BN(x, x_out)) {
1757 ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
1758 return 0;
1759 }
1760 }
1761 felem_mul(tmp, z1, z2);
1762 felem_reduce(z1, tmp);
1763 felem_mul(tmp, y_in, z1);
1764 felem_reduce(y_in, tmp);
1765 felem_contract(y_out, y_in);
1766 if (y != NULL) {
1767 if (!felem_to_BN(y, y_out)) {
1768 ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
1769 return 0;
1770 }
1771 }
1772 return 1;
1773}
1774
1775static void
1776make_points_affine(size_t num, felem points[ /* num */ ][3], felem tmp_felems[ /* num+1 */ ])
1777{
1778 /*
1779 * Runs in constant time, unless an input is the point at infinity
1780 * (which normally shouldn't happen).
1781 */
1782 ec_GFp_nistp_points_make_affine_internal(
1783 num,
1784 points,
1785 sizeof(felem),
1786 tmp_felems,
1787 (void (*) (void *)) felem_one,
1788 (int (*) (const void *)) felem_is_zero_int,
1789 (void (*) (void *, const void *)) felem_assign,
1790 (void (*) (void *, const void *)) felem_square_reduce,
1791 (void (*) (void *, const void *, const void *)) felem_mul_reduce,
1792 (void (*) (void *, const void *)) felem_inv,
1793 (void (*) (void *, const void *)) felem_contract);
1794}
1795
1796/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
1797 * Result is stored in r (r can equal one of the inputs). */
1798int
1799ec_GFp_nistp521_points_mul(const EC_GROUP * group, EC_POINT * r,
1800 const BIGNUM * scalar, size_t num, const EC_POINT * points[],
1801 const BIGNUM * scalars[], BN_CTX * ctx)
1802{
1803 int ret = 0;
1804 int j;
1805 int mixed = 0;
1806 BN_CTX *new_ctx = NULL;
1807 BIGNUM *x, *y, *z, *tmp_scalar;
1808 felem_bytearray g_secret;
1809 felem_bytearray *secrets = NULL;
1810 felem(*pre_comp)[17][3] = NULL;
1811 felem *tmp_felems = NULL;
1812 felem_bytearray tmp;
1813 unsigned i, num_bytes;
1814 int have_pre_comp = 0;
1815 size_t num_points = num;
1816 felem x_in, y_in, z_in, x_out, y_out, z_out;
1817 NISTP521_PRE_COMP *pre = NULL;
1818 felem(*g_pre_comp)[3] = NULL;
1819 EC_POINT *generator = NULL;
1820 const EC_POINT *p = NULL;
1821 const BIGNUM *p_scalar = NULL;
1822
1823 if (ctx == NULL)
1824 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
1825 return 0;
1826 BN_CTX_start(ctx);
1827 if (((x = BN_CTX_get(ctx)) == NULL) ||
1828 ((y = BN_CTX_get(ctx)) == NULL) ||
1829 ((z = BN_CTX_get(ctx)) == NULL) ||
1830 ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
1831 goto err;
1832
1833 if (scalar != NULL) {
1834 pre = EC_EX_DATA_get_data(group->extra_data,
1835 nistp521_pre_comp_dup, nistp521_pre_comp_free,
1836 nistp521_pre_comp_clear_free);
1837 if (pre)
1838 /* we have precomputation, try to use it */
1839 g_pre_comp = &pre->g_pre_comp[0];
1840 else
1841 /* try to use the standard precomputation */
1842 g_pre_comp = (felem(*)[3]) gmul;
1843 generator = EC_POINT_new(group);
1844 if (generator == NULL)
1845 goto err;
1846 /* get the generator from precomputation */
1847 if (!felem_to_BN(x, g_pre_comp[1][0]) ||
1848 !felem_to_BN(y, g_pre_comp[1][1]) ||
1849 !felem_to_BN(z, g_pre_comp[1][2])) {
1850 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
1851 goto err;
1852 }
1853 if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
1854 generator, x, y, z, ctx))
1855 goto err;
1856 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
1857 /* precomputation matches generator */
1858 have_pre_comp = 1;
1859 else
1860 /*
1861 * we don't have valid precomputation: treat the
1862 * generator as a random point
1863 */
1864 num_points++;
1865 }
1866 if (num_points > 0) {
1867 if (num_points >= 2) {
1868 /*
1869 * unless we precompute multiples for just one point,
1870 * converting those into affine form is time well
1871 * spent
1872 */
1873 mixed = 1;
1874 }
1875 secrets = calloc(num_points, sizeof(felem_bytearray));
1876 pre_comp = calloc(num_points, 17 * 3 * sizeof(felem));
1877 if (mixed) {
1878 /* XXX should do more int overflow checking */
1879 tmp_felems = reallocarray(NULL,
1880 (num_points * 17 + 1), sizeof(felem));
1881 }
1882 if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL))) {
1883 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE);
1884 goto err;
1885 }
1886 /*
1887 * we treat NULL scalars as 0, and NULL points as points at
1888 * infinity, i.e., they contribute nothing to the linear
1889 * combination
1890 */
1891 for (i = 0; i < num_points; ++i) {
1892 if (i == num)
1893 /*
1894 * we didn't have a valid precomputation, so
1895 * we pick the generator
1896 */
1897 {
1898 p = EC_GROUP_get0_generator(group);
1899 p_scalar = scalar;
1900 } else
1901 /* the i^th point */
1902 {
1903 p = points[i];
1904 p_scalar = scalars[i];
1905 }
1906 if ((p_scalar != NULL) && (p != NULL)) {
1907 /* reduce scalar to 0 <= scalar < 2^521 */
1908 if ((BN_num_bits(p_scalar) > 521) || (BN_is_negative(p_scalar))) {
1909 /*
1910 * this is an unusual input, and we
1911 * don't guarantee constant-timeness
1912 */
1913 if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
1914 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
1915 goto err;
1916 }
1917 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1918 } else
1919 num_bytes = BN_bn2bin(p_scalar, tmp);
1920 flip_endian(secrets[i], tmp, num_bytes);
1921 /* precompute multiples */
1922 if ((!BN_to_felem(x_out, &p->X)) ||
1923 (!BN_to_felem(y_out, &p->Y)) ||
1924 (!BN_to_felem(z_out, &p->Z)))
1925 goto err;
1926 memcpy(pre_comp[i][1][0], x_out, sizeof(felem));
1927 memcpy(pre_comp[i][1][1], y_out, sizeof(felem));
1928 memcpy(pre_comp[i][1][2], z_out, sizeof(felem));
1929 for (j = 2; j <= 16; ++j) {
1930 if (j & 1) {
1931 point_add(
1932 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1933 pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
1934 0, pre_comp[i][j - 1][0], pre_comp[i][j - 1][1], pre_comp[i][j - 1][2]);
1935 } else {
1936 point_double(
1937 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1938 pre_comp[i][j / 2][0], pre_comp[i][j / 2][1], pre_comp[i][j / 2][2]);
1939 }
1940 }
1941 }
1942 }
1943 if (mixed)
1944 make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
1945 }
1946 /* the scalar for the generator */
1947 if ((scalar != NULL) && (have_pre_comp)) {
1948 memset(g_secret, 0, sizeof(g_secret));
1949 /* reduce scalar to 0 <= scalar < 2^521 */
1950 if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar))) {
1951 /*
1952 * this is an unusual input, and we don't guarantee
1953 * constant-timeness
1954 */
1955 if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
1956 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
1957 goto err;
1958 }
1959 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1960 } else
1961 num_bytes = BN_bn2bin(scalar, tmp);
1962 flip_endian(g_secret, tmp, num_bytes);
1963 /* do the multiplication with generator precomputation */
1964 batch_mul(x_out, y_out, z_out,
1965 (const felem_bytearray(*)) secrets, num_points,
1966 g_secret,
1967 mixed, (const felem(*)[17][3]) pre_comp,
1968 (const felem(*)[3]) g_pre_comp);
1969 } else
1970 /* do the multiplication without generator precomputation */
1971 batch_mul(x_out, y_out, z_out,
1972 (const felem_bytearray(*)) secrets, num_points,
1973 NULL, mixed, (const felem(*)[17][3]) pre_comp, NULL);
1974 /* reduce the output to its unique minimal representation */
1975 felem_contract(x_in, x_out);
1976 felem_contract(y_in, y_out);
1977 felem_contract(z_in, z_out);
1978 if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
1979 (!felem_to_BN(z, z_in))) {
1980 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
1981 goto err;
1982 }
1983 ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
1984
1985err:
1986 BN_CTX_end(ctx);
1987 EC_POINT_free(generator);
1988 BN_CTX_free(new_ctx);
1989 free(secrets);
1990 free(pre_comp);
1991 free(tmp_felems);
1992 return ret;
1993}
1994
1995int
1996ec_GFp_nistp521_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
1997{
1998 int ret = 0;
1999 NISTP521_PRE_COMP *pre = NULL;
2000 int i, j;
2001 BN_CTX *new_ctx = NULL;
2002 BIGNUM *x, *y;
2003 EC_POINT *generator = NULL;
2004 felem tmp_felems[16];
2005
2006 /* throw away old precomputation */
2007 EC_EX_DATA_free_data(&group->extra_data, nistp521_pre_comp_dup,
2008 nistp521_pre_comp_free, nistp521_pre_comp_clear_free);
2009 if (ctx == NULL)
2010 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
2011 return 0;
2012 BN_CTX_start(ctx);
2013 if (((x = BN_CTX_get(ctx)) == NULL) ||
2014 ((y = BN_CTX_get(ctx)) == NULL))
2015 goto err;
2016 /* get the generator */
2017 if (group->generator == NULL)
2018 goto err;
2019 generator = EC_POINT_new(group);
2020 if (generator == NULL)
2021 goto err;
2022 BN_bin2bn(nistp521_curve_params[3], sizeof(felem_bytearray), x);
2023 BN_bin2bn(nistp521_curve_params[4], sizeof(felem_bytearray), y);
2024 if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
2025 goto err;
2026 if ((pre = nistp521_pre_comp_new()) == NULL)
2027 goto err;
2028 /* if the generator is the standard one, use built-in precomputation */
2029 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
2030 memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
2031 ret = 1;
2032 goto err;
2033 }
2034 if ((!BN_to_felem(pre->g_pre_comp[1][0], &group->generator->X)) ||
2035 (!BN_to_felem(pre->g_pre_comp[1][1], &group->generator->Y)) ||
2036 (!BN_to_felem(pre->g_pre_comp[1][2], &group->generator->Z)))
2037 goto err;
2038 /* compute 2^130*G, 2^260*G, 2^390*G */
2039 for (i = 1; i <= 4; i <<= 1) {
2040 point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1],
2041 pre->g_pre_comp[2 * i][2], pre->g_pre_comp[i][0],
2042 pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]);
2043 for (j = 0; j < 129; ++j) {
2044 point_double(pre->g_pre_comp[2 * i][0],
2045 pre->g_pre_comp[2 * i][1],
2046 pre->g_pre_comp[2 * i][2],
2047 pre->g_pre_comp[2 * i][0],
2048 pre->g_pre_comp[2 * i][1],
2049 pre->g_pre_comp[2 * i][2]);
2050 }
2051 }
2052 /* g_pre_comp[0] is the point at infinity */
2053 memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0]));
2054 /* the remaining multiples */
2055 /* 2^130*G + 2^260*G */
2056 point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1],
2057 pre->g_pre_comp[6][2], pre->g_pre_comp[4][0],
2058 pre->g_pre_comp[4][1], pre->g_pre_comp[4][2],
2059 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
2060 pre->g_pre_comp[2][2]);
2061 /* 2^130*G + 2^390*G */
2062 point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1],
2063 pre->g_pre_comp[10][2], pre->g_pre_comp[8][0],
2064 pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
2065 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
2066 pre->g_pre_comp[2][2]);
2067 /* 2^260*G + 2^390*G */
2068 point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1],
2069 pre->g_pre_comp[12][2], pre->g_pre_comp[8][0],
2070 pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
2071 0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1],
2072 pre->g_pre_comp[4][2]);
2073 /* 2^130*G + 2^260*G + 2^390*G */
2074 point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1],
2075 pre->g_pre_comp[14][2], pre->g_pre_comp[12][0],
2076 pre->g_pre_comp[12][1], pre->g_pre_comp[12][2],
2077 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
2078 pre->g_pre_comp[2][2]);
2079 for (i = 1; i < 8; ++i) {
2080 /* odd multiples: add G */
2081 point_add(pre->g_pre_comp[2 * i + 1][0], pre->g_pre_comp[2 * i + 1][1],
2082 pre->g_pre_comp[2 * i + 1][2], pre->g_pre_comp[2 * i][0],
2083 pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2],
2084 0, pre->g_pre_comp[1][0], pre->g_pre_comp[1][1],
2085 pre->g_pre_comp[1][2]);
2086 }
2087 make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems);
2088
2089 if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp521_pre_comp_dup,
2090 nistp521_pre_comp_free, nistp521_pre_comp_clear_free))
2091 goto err;
2092 ret = 1;
2093 pre = NULL;
2094err:
2095 BN_CTX_end(ctx);
2096 EC_POINT_free(generator);
2097 BN_CTX_free(new_ctx);
2098 nistp521_pre_comp_free(pre);
2099 return ret;
2100}
2101
2102int
2103ec_GFp_nistp521_have_precompute_mult(const EC_GROUP * group)
2104{
2105 if (EC_EX_DATA_get_data(group->extra_data, nistp521_pre_comp_dup,
2106 nistp521_pre_comp_free, nistp521_pre_comp_clear_free)
2107 != NULL)
2108 return 1;
2109 else
2110 return 0;
2111}
2112
2113#endif
diff --git a/src/lib/libcrypto/ec/ecp_nistputil.c b/src/lib/libcrypto/ec/ecp_nistputil.c
deleted file mode 100644
index ca55b49ba2..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistputil.c
+++ /dev/null
@@ -1,209 +0,0 @@
1/* $OpenBSD: ecp_nistputil.c,v 1.6 2014/07/10 22:45:57 jsing Exp $ */
2/*
3 * Written by Bodo Moeller for the OpenSSL project.
4 */
5/*
6 * Copyright (c) 2011 Google Inc.
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <stddef.h>
22
23#include <openssl/opensslconf.h>
24
25#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
26
27/*
28 * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
29 */
30
31#include "ec_lcl.h"
32
33/* Convert an array of points into affine coordinates.
34 * (If the point at infinity is found (Z = 0), it remains unchanged.)
35 * This function is essentially an equivalent to EC_POINTs_make_affine(), but
36 * works with the internal representation of points as used by ecp_nistp###.c
37 * rather than with (BIGNUM-based) EC_POINT data structures.
38 *
39 * point_array is the input/output buffer ('num' points in projective form,
40 * i.e. three coordinates each), based on an internal representation of
41 * field elements of size 'felem_size'.
42 *
43 * tmp_felems needs to point to a temporary array of 'num'+1 field elements
44 * for storage of intermediate values.
45 */
46void
47ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
48 size_t felem_size, void *tmp_felems,
49 void (*felem_one) (void *out),
50 int (*felem_is_zero) (const void *in),
51 void (*felem_assign) (void *out, const void *in),
52 void (*felem_square) (void *out, const void *in),
53 void (*felem_mul) (void *out, const void *in1, const void *in2),
54 void (*felem_inv) (void *out, const void *in),
55 void (*felem_contract) (void *out, const void *in))
56{
57 int i = 0;
58
59#define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
60#define X(I) (&((char *)point_array)[3*(I) * felem_size])
61#define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
62#define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
63
64 if (!felem_is_zero(Z(0)))
65 felem_assign(tmp_felem(0), Z(0));
66 else
67 felem_one(tmp_felem(0));
68 for (i = 1; i < (int) num; i++) {
69 if (!felem_is_zero(Z(i)))
70 felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i));
71 else
72 felem_assign(tmp_felem(i), tmp_felem(i - 1));
73 }
74 /*
75 * Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any
76 * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i)
77 * = 1
78 */
79
80 felem_inv(tmp_felem(num - 1), tmp_felem(num - 1));
81 for (i = num - 1; i >= 0; i--) {
82 if (i > 0)
83 /*
84 * tmp_felem(i-1) is the product of Z(0) .. Z(i-1),
85 * tmp_felem(i) is the inverse of the product of Z(0)
86 * .. Z(i)
87 */
88 felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i)); /* 1/Z(i) */
89 else
90 felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
91
92 if (!felem_is_zero(Z(i))) {
93 if (i > 0)
94 /*
95 * For next iteration, replace tmp_felem(i-1)
96 * by its inverse
97 */
98 felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i));
99
100 /*
101 * Convert point (X, Y, Z) into affine form (X/(Z^2),
102 * Y/(Z^3), 1)
103 */
104 felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
105 felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
106 felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
107 felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
108 felem_contract(X(i), X(i));
109 felem_contract(Y(i), Y(i));
110 felem_one(Z(i));
111 } else {
112 if (i > 0)
113 /*
114 * For next iteration, replace tmp_felem(i-1)
115 * by its inverse
116 */
117 felem_assign(tmp_felem(i - 1), tmp_felem(i));
118 }
119 }
120}
121
122/*
123 * This function looks at 5+1 scalar bits (5 current, 1 adjacent less
124 * significant bit), and recodes them into a signed digit for use in fast point
125 * multiplication: the use of signed rather than unsigned digits means that
126 * fewer points need to be precomputed, given that point inversion is easy
127 * (a precomputed point dP makes -dP available as well).
128 *
129 * BACKGROUND:
130 *
131 * Signed digits for multiplication were introduced by Booth ("A signed binary
132 * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
133 * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
134 * Booth's original encoding did not generally improve the density of nonzero
135 * digits over the binary representation, and was merely meant to simplify the
136 * handling of signed factors given in two's complement; but it has since been
137 * shown to be the basis of various signed-digit representations that do have
138 * further advantages, including the wNAF, using the following general approach:
139 *
140 * (1) Given a binary representation
141 *
142 * b_k ... b_2 b_1 b_0,
143 *
144 * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
145 * by using bit-wise subtraction as follows:
146 *
147 * b_k b_(k-1) ... b_2 b_1 b_0
148 * - b_k ... b_3 b_2 b_1 b_0
149 * -------------------------------------
150 * s_k b_(k-1) ... s_3 s_2 s_1 s_0
151 *
152 * A left-shift followed by subtraction of the original value yields a new
153 * representation of the same value, using signed bits s_i = b_(i+1) - b_i.
154 * This representation from Booth's paper has since appeared in the
155 * literature under a variety of different names including "reversed binary
156 * form", "alternating greedy expansion", "mutual opposite form", and
157 * "sign-alternating {+-1}-representation".
158 *
159 * An interesting property is that among the nonzero bits, values 1 and -1
160 * strictly alternate.
161 *
162 * (2) Various window schemes can be applied to the Booth representation of
163 * integers: for example, right-to-left sliding windows yield the wNAF
164 * (a signed-digit encoding independently discovered by various researchers
165 * in the 1990s), and left-to-right sliding windows yield a left-to-right
166 * equivalent of the wNAF (independently discovered by various researchers
167 * around 2004).
168 *
169 * To prevent leaking information through side channels in point multiplication,
170 * we need to recode the given integer into a regular pattern: sliding windows
171 * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
172 * decades older: we'll be using the so-called "modified Booth encoding" due to
173 * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
174 * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five
175 * signed bits into a signed digit:
176 *
177 * s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
178 *
179 * The sign-alternating property implies that the resulting digit values are
180 * integers from -16 to 16.
181 *
182 * Of course, we don't actually need to compute the signed digits s_i as an
183 * intermediate step (that's just a nice way to see how this scheme relates
184 * to the wNAF): a direct computation obtains the recoded digit from the
185 * six bits b_(4j + 4) ... b_(4j - 1).
186 *
187 * This function takes those five bits as an integer (0 .. 63), writing the
188 * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
189 * value, in the range 0 .. 8). Note that this integer essentially provides the
190 * input bits "shifted to the left" by one position: for example, the input to
191 * compute the least significant recoded digit, given that there's no bit b_-1,
192 * has to be b_4 b_3 b_2 b_1 b_0 0.
193 *
194 */
195void
196ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in)
197{
198 unsigned char s, d;
199
200 s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as
201 * 6-bit value */
202 d = (1 << 6) - in - 1;
203 d = (d & s) | (in & ~s);
204 d = (d >> 1) + (d & 1);
205
206 *sign = s & 1;
207 *digit = d;
208}
209#endif
diff --git a/src/lib/libcrypto/ec/ecp_oct.c b/src/lib/libcrypto/ec/ecp_oct.c
deleted file mode 100644
index 994f0b08b1..0000000000
--- a/src/lib/libcrypto/ec/ecp_oct.c
+++ /dev/null
@@ -1,395 +0,0 @@
1/* $OpenBSD: ecp_oct.c,v 1.7 2015/02/09 15:49:22 jsing Exp $ */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project.
5*/
6/* ====================================================================
7 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@openssl.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* ====================================================================
60 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
61 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
62 * and contributed to the OpenSSL project.
63 */
64
65#include <openssl/err.h>
66
67#include "ec_lcl.h"
68
69int
70ec_GFp_simple_set_compressed_coordinates(const EC_GROUP * group,
71 EC_POINT * point, const BIGNUM * x_, int y_bit, BN_CTX * ctx)
72{
73 BN_CTX *new_ctx = NULL;
74 BIGNUM *tmp1, *tmp2, *x, *y;
75 int ret = 0;
76
77 /* clear error queue */
78 ERR_clear_error();
79
80 if (ctx == NULL) {
81 ctx = new_ctx = BN_CTX_new();
82 if (ctx == NULL)
83 return 0;
84 }
85 y_bit = (y_bit != 0);
86
87 BN_CTX_start(ctx);
88 if ((tmp1 = BN_CTX_get(ctx)) == NULL)
89 goto err;
90 if ((tmp2 = BN_CTX_get(ctx)) == NULL)
91 goto err;
92 if ((x = BN_CTX_get(ctx)) == NULL)
93 goto err;
94 if ((y = BN_CTX_get(ctx)) == NULL)
95 goto err;
96
97 /*
98 * Recover y. We have a Weierstrass equation y^2 = x^3 + a*x + b, so
99 * y is one of the square roots of x^3 + a*x + b.
100 */
101
102 /* tmp1 := x^3 */
103 if (!BN_nnmod(x, x_, &group->field, ctx))
104 goto err;
105 if (group->meth->field_decode == 0) {
106 /* field_{sqr,mul} work on standard representation */
107 if (!group->meth->field_sqr(group, tmp2, x_, ctx))
108 goto err;
109 if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
110 goto err;
111 } else {
112 if (!BN_mod_sqr(tmp2, x_, &group->field, ctx))
113 goto err;
114 if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx))
115 goto err;
116 }
117
118 /* tmp1 := tmp1 + a*x */
119 if (group->a_is_minus3) {
120 if (!BN_mod_lshift1_quick(tmp2, x, &group->field))
121 goto err;
122 if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field))
123 goto err;
124 if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field))
125 goto err;
126 } else {
127 if (group->meth->field_decode) {
128 if (!group->meth->field_decode(group, tmp2, &group->a, ctx))
129 goto err;
130 if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx))
131 goto err;
132 } else {
133 /* field_mul works on standard representation */
134 if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx))
135 goto err;
136 }
137
138 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
139 goto err;
140 }
141
142 /* tmp1 := tmp1 + b */
143 if (group->meth->field_decode) {
144 if (!group->meth->field_decode(group, tmp2, &group->b, ctx))
145 goto err;
146 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
147 goto err;
148 } else {
149 if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field))
150 goto err;
151 }
152
153 if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
154 unsigned long err = ERR_peek_last_error();
155
156 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
157 ERR_clear_error();
158 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
159 } else
160 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
161 goto err;
162 }
163 if (y_bit != BN_is_odd(y)) {
164 if (BN_is_zero(y)) {
165 int kron;
166
167 kron = BN_kronecker(x, &group->field, ctx);
168 if (kron == -2)
169 goto err;
170
171 if (kron == 1)
172 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
173 else
174 /*
175 * BN_mod_sqrt() should have cought this
176 * error (not a square)
177 */
178 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
179 goto err;
180 }
181 if (!BN_usub(y, &group->field, y))
182 goto err;
183 }
184 if (y_bit != BN_is_odd(y)) {
185 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
186 goto err;
187 }
188 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
189 goto err;
190
191 ret = 1;
192
193err:
194 BN_CTX_end(ctx);
195 BN_CTX_free(new_ctx);
196 return ret;
197}
198
199
200size_t
201ec_GFp_simple_point2oct(const EC_GROUP * group, const EC_POINT * point, point_conversion_form_t form,
202 unsigned char *buf, size_t len, BN_CTX * ctx)
203{
204 size_t ret;
205 BN_CTX *new_ctx = NULL;
206 int used_ctx = 0;
207 BIGNUM *x, *y;
208 size_t field_len, i, skip;
209
210 if ((form != POINT_CONVERSION_COMPRESSED)
211 && (form != POINT_CONVERSION_UNCOMPRESSED)
212 && (form != POINT_CONVERSION_HYBRID)) {
213 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
214 goto err;
215 }
216 if (EC_POINT_is_at_infinity(group, point) > 0) {
217 /* encodes to a single 0 octet */
218 if (buf != NULL) {
219 if (len < 1) {
220 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
221 return 0;
222 }
223 buf[0] = 0;
224 }
225 return 1;
226 }
227 /* ret := required output buffer length */
228 field_len = BN_num_bytes(&group->field);
229 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
230
231 /* if 'buf' is NULL, just return required length */
232 if (buf != NULL) {
233 if (len < ret) {
234 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
235 goto err;
236 }
237 if (ctx == NULL) {
238 ctx = new_ctx = BN_CTX_new();
239 if (ctx == NULL)
240 return 0;
241 }
242 BN_CTX_start(ctx);
243 used_ctx = 1;
244 if ((x = BN_CTX_get(ctx)) == NULL)
245 goto err;
246 if ((y = BN_CTX_get(ctx)) == NULL)
247 goto err;
248
249 if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
250 goto err;
251
252 if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
253 buf[0] = form + 1;
254 else
255 buf[0] = form;
256
257 i = 1;
258
259 skip = field_len - BN_num_bytes(x);
260 if (skip > field_len) {
261 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
262 goto err;
263 }
264 while (skip > 0) {
265 buf[i++] = 0;
266 skip--;
267 }
268 skip = BN_bn2bin(x, buf + i);
269 i += skip;
270 if (i != 1 + field_len) {
271 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
272 goto err;
273 }
274 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID) {
275 skip = field_len - BN_num_bytes(y);
276 if (skip > field_len) {
277 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
278 goto err;
279 }
280 while (skip > 0) {
281 buf[i++] = 0;
282 skip--;
283 }
284 skip = BN_bn2bin(y, buf + i);
285 i += skip;
286 }
287 if (i != ret) {
288 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
289 goto err;
290 }
291 }
292 if (used_ctx)
293 BN_CTX_end(ctx);
294 BN_CTX_free(new_ctx);
295 return ret;
296
297err:
298 if (used_ctx)
299 BN_CTX_end(ctx);
300 BN_CTX_free(new_ctx);
301 return 0;
302}
303
304
305int
306ec_GFp_simple_oct2point(const EC_GROUP * group, EC_POINT * point,
307 const unsigned char *buf, size_t len, BN_CTX * ctx)
308{
309 point_conversion_form_t form;
310 int y_bit;
311 BN_CTX *new_ctx = NULL;
312 BIGNUM *x, *y;
313 size_t field_len, enc_len;
314 int ret = 0;
315
316 if (len == 0) {
317 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
318 return 0;
319 }
320 form = buf[0];
321 y_bit = form & 1;
322 form = form & ~1U;
323 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
324 && (form != POINT_CONVERSION_UNCOMPRESSED)
325 && (form != POINT_CONVERSION_HYBRID)) {
326 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
327 return 0;
328 }
329 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
330 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
331 return 0;
332 }
333 if (form == 0) {
334 if (len != 1) {
335 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
336 return 0;
337 }
338 return EC_POINT_set_to_infinity(group, point);
339 }
340 field_len = BN_num_bytes(&group->field);
341 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
342
343 if (len != enc_len) {
344 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
345 return 0;
346 }
347 if (ctx == NULL) {
348 ctx = new_ctx = BN_CTX_new();
349 if (ctx == NULL)
350 return 0;
351 }
352 BN_CTX_start(ctx);
353 if ((x = BN_CTX_get(ctx)) == NULL)
354 goto err;
355 if ((y = BN_CTX_get(ctx)) == NULL)
356 goto err;
357
358 if (!BN_bin2bn(buf + 1, field_len, x))
359 goto err;
360 if (BN_ucmp(x, &group->field) >= 0) {
361 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
362 goto err;
363 }
364 if (form == POINT_CONVERSION_COMPRESSED) {
365 if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx))
366 goto err;
367 } else {
368 if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
369 goto err;
370 if (BN_ucmp(y, &group->field) >= 0) {
371 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
372 goto err;
373 }
374 if (form == POINT_CONVERSION_HYBRID) {
375 if (y_bit != BN_is_odd(y)) {
376 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
377 goto err;
378 }
379 }
380 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
381 goto err;
382 }
383
384 /* test required by X9.62 */
385 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
386 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
387 goto err;
388 }
389 ret = 1;
390
391err:
392 BN_CTX_end(ctx);
393 BN_CTX_free(new_ctx);
394 return ret;
395}
diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c
deleted file mode 100644
index f6db4dc9b1..0000000000
--- a/src/lib/libcrypto/ec/ecp_smpl.c
+++ /dev/null
@@ -1,1410 +0,0 @@
1/* $OpenBSD: ecp_smpl.c,v 1.15 2015/02/09 15:49:22 jsing Exp $ */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project.
5*/
6/* ====================================================================
7 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@openssl.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* ====================================================================
60 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
61 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
62 * and contributed to the OpenSSL project.
63 */
64
65#include <openssl/err.h>
66
67#include "ec_lcl.h"
68
69const EC_METHOD *
70EC_GFp_simple_method(void)
71{
72 static const EC_METHOD ret = {
73 .flags = EC_FLAGS_DEFAULT_OCT,
74 .field_type = NID_X9_62_prime_field,
75 .group_init = ec_GFp_simple_group_init,
76 .group_finish = ec_GFp_simple_group_finish,
77 .group_clear_finish = ec_GFp_simple_group_clear_finish,
78 .group_copy = ec_GFp_simple_group_copy,
79 .group_set_curve = ec_GFp_simple_group_set_curve,
80 .group_get_curve = ec_GFp_simple_group_get_curve,
81 .group_get_degree = ec_GFp_simple_group_get_degree,
82 .group_check_discriminant =
83 ec_GFp_simple_group_check_discriminant,
84 .point_init = ec_GFp_simple_point_init,
85 .point_finish = ec_GFp_simple_point_finish,
86 .point_clear_finish = ec_GFp_simple_point_clear_finish,
87 .point_copy = ec_GFp_simple_point_copy,
88 .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
89 .point_set_Jprojective_coordinates_GFp =
90 ec_GFp_simple_set_Jprojective_coordinates_GFp,
91 .point_get_Jprojective_coordinates_GFp =
92 ec_GFp_simple_get_Jprojective_coordinates_GFp,
93 .point_set_affine_coordinates =
94 ec_GFp_simple_point_set_affine_coordinates,
95 .point_get_affine_coordinates =
96 ec_GFp_simple_point_get_affine_coordinates,
97 .add = ec_GFp_simple_add,
98 .dbl = ec_GFp_simple_dbl,
99 .invert = ec_GFp_simple_invert,
100 .is_at_infinity = ec_GFp_simple_is_at_infinity,
101 .is_on_curve = ec_GFp_simple_is_on_curve,
102 .point_cmp = ec_GFp_simple_cmp,
103 .make_affine = ec_GFp_simple_make_affine,
104 .points_make_affine = ec_GFp_simple_points_make_affine,
105 .field_mul = ec_GFp_simple_field_mul,
106 .field_sqr = ec_GFp_simple_field_sqr
107 };
108
109 return &ret;
110}
111
112
113/* Most method functions in this file are designed to work with
114 * non-trivial representations of field elements if necessary
115 * (see ecp_mont.c): while standard modular addition and subtraction
116 * are used, the field_mul and field_sqr methods will be used for
117 * multiplication, and field_encode and field_decode (if defined)
118 * will be used for converting between representations.
119
120 * Functions ec_GFp_simple_points_make_affine() and
121 * ec_GFp_simple_point_get_affine_coordinates() specifically assume
122 * that if a non-trivial representation is used, it is a Montgomery
123 * representation (i.e. 'encoding' means multiplying by some factor R).
124 */
125
126
127int
128ec_GFp_simple_group_init(EC_GROUP * group)
129{
130 BN_init(&group->field);
131 BN_init(&group->a);
132 BN_init(&group->b);
133 group->a_is_minus3 = 0;
134 return 1;
135}
136
137
138void
139ec_GFp_simple_group_finish(EC_GROUP * group)
140{
141 BN_free(&group->field);
142 BN_free(&group->a);
143 BN_free(&group->b);
144}
145
146
147void
148ec_GFp_simple_group_clear_finish(EC_GROUP * group)
149{
150 BN_clear_free(&group->field);
151 BN_clear_free(&group->a);
152 BN_clear_free(&group->b);
153}
154
155
156int
157ec_GFp_simple_group_copy(EC_GROUP * dest, const EC_GROUP * src)
158{
159 if (!BN_copy(&dest->field, &src->field))
160 return 0;
161 if (!BN_copy(&dest->a, &src->a))
162 return 0;
163 if (!BN_copy(&dest->b, &src->b))
164 return 0;
165
166 dest->a_is_minus3 = src->a_is_minus3;
167
168 return 1;
169}
170
171
172int
173ec_GFp_simple_group_set_curve(EC_GROUP * group,
174 const BIGNUM * p, const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
175{
176 int ret = 0;
177 BN_CTX *new_ctx = NULL;
178 BIGNUM *tmp_a;
179
180 /* p must be a prime > 3 */
181 if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
182 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
183 return 0;
184 }
185 if (ctx == NULL) {
186 ctx = new_ctx = BN_CTX_new();
187 if (ctx == NULL)
188 return 0;
189 }
190 BN_CTX_start(ctx);
191 if ((tmp_a = BN_CTX_get(ctx)) == NULL)
192 goto err;
193
194 /* group->field */
195 if (!BN_copy(&group->field, p))
196 goto err;
197 BN_set_negative(&group->field, 0);
198
199 /* group->a */
200 if (!BN_nnmod(tmp_a, a, p, ctx))
201 goto err;
202 if (group->meth->field_encode) {
203 if (!group->meth->field_encode(group, &group->a, tmp_a, ctx))
204 goto err;
205 } else if (!BN_copy(&group->a, tmp_a))
206 goto err;
207
208 /* group->b */
209 if (!BN_nnmod(&group->b, b, p, ctx))
210 goto err;
211 if (group->meth->field_encode)
212 if (!group->meth->field_encode(group, &group->b, &group->b, ctx))
213 goto err;
214
215 /* group->a_is_minus3 */
216 if (!BN_add_word(tmp_a, 3))
217 goto err;
218 group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
219
220 ret = 1;
221
222err:
223 BN_CTX_end(ctx);
224 BN_CTX_free(new_ctx);
225 return ret;
226}
227
228
229int
230ec_GFp_simple_group_get_curve(const EC_GROUP * group, BIGNUM * p, BIGNUM * a, BIGNUM * b, BN_CTX * ctx)
231{
232 int ret = 0;
233 BN_CTX *new_ctx = NULL;
234
235 if (p != NULL) {
236 if (!BN_copy(p, &group->field))
237 return 0;
238 }
239 if (a != NULL || b != NULL) {
240 if (group->meth->field_decode) {
241 if (ctx == NULL) {
242 ctx = new_ctx = BN_CTX_new();
243 if (ctx == NULL)
244 return 0;
245 }
246 if (a != NULL) {
247 if (!group->meth->field_decode(group, a, &group->a, ctx))
248 goto err;
249 }
250 if (b != NULL) {
251 if (!group->meth->field_decode(group, b, &group->b, ctx))
252 goto err;
253 }
254 } else {
255 if (a != NULL) {
256 if (!BN_copy(a, &group->a))
257 goto err;
258 }
259 if (b != NULL) {
260 if (!BN_copy(b, &group->b))
261 goto err;
262 }
263 }
264 }
265 ret = 1;
266
267err:
268 BN_CTX_free(new_ctx);
269 return ret;
270}
271
272
273int
274ec_GFp_simple_group_get_degree(const EC_GROUP * group)
275{
276 return BN_num_bits(&group->field);
277}
278
279
280int
281ec_GFp_simple_group_check_discriminant(const EC_GROUP * group, BN_CTX * ctx)
282{
283 int ret = 0;
284 BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
285 const BIGNUM *p = &group->field;
286 BN_CTX *new_ctx = NULL;
287
288 if (ctx == NULL) {
289 ctx = new_ctx = BN_CTX_new();
290 if (ctx == NULL) {
291 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
292 goto err;
293 }
294 }
295 BN_CTX_start(ctx);
296 if ((a = BN_CTX_get(ctx)) == NULL)
297 goto err;
298 if ((b = BN_CTX_get(ctx)) == NULL)
299 goto err;
300 if ((tmp_1 = BN_CTX_get(ctx)) == NULL)
301 goto err;
302 if ((tmp_2 = BN_CTX_get(ctx)) == NULL)
303 goto err;
304 if ((order = BN_CTX_get(ctx)) == NULL)
305 goto err;
306
307 if (group->meth->field_decode) {
308 if (!group->meth->field_decode(group, a, &group->a, ctx))
309 goto err;
310 if (!group->meth->field_decode(group, b, &group->b, ctx))
311 goto err;
312 } else {
313 if (!BN_copy(a, &group->a))
314 goto err;
315 if (!BN_copy(b, &group->b))
316 goto err;
317 }
318
319 /*
320 * check the discriminant: y^2 = x^3 + a*x + b is an elliptic curve
321 * <=> 4*a^3 + 27*b^2 != 0 (mod p) 0 =< a, b < p
322 */
323 if (BN_is_zero(a)) {
324 if (BN_is_zero(b))
325 goto err;
326 } else if (!BN_is_zero(b)) {
327 if (!BN_mod_sqr(tmp_1, a, p, ctx))
328 goto err;
329 if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
330 goto err;
331 if (!BN_lshift(tmp_1, tmp_2, 2))
332 goto err;
333 /* tmp_1 = 4*a^3 */
334
335 if (!BN_mod_sqr(tmp_2, b, p, ctx))
336 goto err;
337 if (!BN_mul_word(tmp_2, 27))
338 goto err;
339 /* tmp_2 = 27*b^2 */
340
341 if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
342 goto err;
343 if (BN_is_zero(a))
344 goto err;
345 }
346 ret = 1;
347
348err:
349 if (ctx != NULL)
350 BN_CTX_end(ctx);
351 BN_CTX_free(new_ctx);
352 return ret;
353}
354
355
356int
357ec_GFp_simple_point_init(EC_POINT * point)
358{
359 BN_init(&point->X);
360 BN_init(&point->Y);
361 BN_init(&point->Z);
362 point->Z_is_one = 0;
363
364 return 1;
365}
366
367
368void
369ec_GFp_simple_point_finish(EC_POINT * point)
370{
371 BN_free(&point->X);
372 BN_free(&point->Y);
373 BN_free(&point->Z);
374}
375
376
377void
378ec_GFp_simple_point_clear_finish(EC_POINT * point)
379{
380 BN_clear_free(&point->X);
381 BN_clear_free(&point->Y);
382 BN_clear_free(&point->Z);
383 point->Z_is_one = 0;
384}
385
386
387int
388ec_GFp_simple_point_copy(EC_POINT * dest, const EC_POINT * src)
389{
390 if (!BN_copy(&dest->X, &src->X))
391 return 0;
392 if (!BN_copy(&dest->Y, &src->Y))
393 return 0;
394 if (!BN_copy(&dest->Z, &src->Z))
395 return 0;
396 dest->Z_is_one = src->Z_is_one;
397
398 return 1;
399}
400
401
402int
403ec_GFp_simple_point_set_to_infinity(const EC_GROUP * group, EC_POINT * point)
404{
405 point->Z_is_one = 0;
406 BN_zero(&point->Z);
407 return 1;
408}
409
410
411int
412ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP * group, EC_POINT * point,
413 const BIGNUM * x, const BIGNUM * y, const BIGNUM * z, BN_CTX * ctx)
414{
415 BN_CTX *new_ctx = NULL;
416 int ret = 0;
417
418 if (ctx == NULL) {
419 ctx = new_ctx = BN_CTX_new();
420 if (ctx == NULL)
421 return 0;
422 }
423 if (x != NULL) {
424 if (!BN_nnmod(&point->X, x, &group->field, ctx))
425 goto err;
426 if (group->meth->field_encode) {
427 if (!group->meth->field_encode(group, &point->X, &point->X, ctx))
428 goto err;
429 }
430 }
431 if (y != NULL) {
432 if (!BN_nnmod(&point->Y, y, &group->field, ctx))
433 goto err;
434 if (group->meth->field_encode) {
435 if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx))
436 goto err;
437 }
438 }
439 if (z != NULL) {
440 int Z_is_one;
441
442 if (!BN_nnmod(&point->Z, z, &group->field, ctx))
443 goto err;
444 Z_is_one = BN_is_one(&point->Z);
445 if (group->meth->field_encode) {
446 if (Z_is_one && (group->meth->field_set_to_one != 0)) {
447 if (!group->meth->field_set_to_one(group, &point->Z, ctx))
448 goto err;
449 } else {
450 if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx))
451 goto err;
452 }
453 }
454 point->Z_is_one = Z_is_one;
455 }
456 ret = 1;
457
458err:
459 BN_CTX_free(new_ctx);
460 return ret;
461}
462
463
464int
465ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP * group, const EC_POINT * point,
466 BIGNUM * x, BIGNUM * y, BIGNUM * z, BN_CTX * ctx)
467{
468 BN_CTX *new_ctx = NULL;
469 int ret = 0;
470
471 if (group->meth->field_decode != 0) {
472 if (ctx == NULL) {
473 ctx = new_ctx = BN_CTX_new();
474 if (ctx == NULL)
475 return 0;
476 }
477 if (x != NULL) {
478 if (!group->meth->field_decode(group, x, &point->X, ctx))
479 goto err;
480 }
481 if (y != NULL) {
482 if (!group->meth->field_decode(group, y, &point->Y, ctx))
483 goto err;
484 }
485 if (z != NULL) {
486 if (!group->meth->field_decode(group, z, &point->Z, ctx))
487 goto err;
488 }
489 } else {
490 if (x != NULL) {
491 if (!BN_copy(x, &point->X))
492 goto err;
493 }
494 if (y != NULL) {
495 if (!BN_copy(y, &point->Y))
496 goto err;
497 }
498 if (z != NULL) {
499 if (!BN_copy(z, &point->Z))
500 goto err;
501 }
502 }
503
504 ret = 1;
505
506err:
507 BN_CTX_free(new_ctx);
508 return ret;
509}
510
511
512int
513ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP * group, EC_POINT * point,
514 const BIGNUM * x, const BIGNUM * y, BN_CTX * ctx)
515{
516 if (x == NULL || y == NULL) {
517 /* unlike for projective coordinates, we do not tolerate this */
518 ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
519 return 0;
520 }
521 return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
522}
523
524
525int
526ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP * group, const EC_POINT * point,
527 BIGNUM * x, BIGNUM * y, BN_CTX * ctx)
528{
529 BN_CTX *new_ctx = NULL;
530 BIGNUM *Z, *Z_1, *Z_2, *Z_3;
531 const BIGNUM *Z_;
532 int ret = 0;
533
534 if (EC_POINT_is_at_infinity(group, point) > 0) {
535 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
536 return 0;
537 }
538 if (ctx == NULL) {
539 ctx = new_ctx = BN_CTX_new();
540 if (ctx == NULL)
541 return 0;
542 }
543 BN_CTX_start(ctx);
544 if ((Z = BN_CTX_get(ctx)) == NULL)
545 goto err;
546 if ((Z_1 = BN_CTX_get(ctx)) == NULL)
547 goto err;
548 if ((Z_2 = BN_CTX_get(ctx)) == NULL)
549 goto err;
550 if ((Z_3 = BN_CTX_get(ctx)) == NULL)
551 goto err;
552
553 /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
554
555 if (group->meth->field_decode) {
556 if (!group->meth->field_decode(group, Z, &point->Z, ctx))
557 goto err;
558 Z_ = Z;
559 } else {
560 Z_ = &point->Z;
561 }
562
563 if (BN_is_one(Z_)) {
564 if (group->meth->field_decode) {
565 if (x != NULL) {
566 if (!group->meth->field_decode(group, x, &point->X, ctx))
567 goto err;
568 }
569 if (y != NULL) {
570 if (!group->meth->field_decode(group, y, &point->Y, ctx))
571 goto err;
572 }
573 } else {
574 if (x != NULL) {
575 if (!BN_copy(x, &point->X))
576 goto err;
577 }
578 if (y != NULL) {
579 if (!BN_copy(y, &point->Y))
580 goto err;
581 }
582 }
583 } else {
584 if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) {
585 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
586 goto err;
587 }
588 if (group->meth->field_encode == 0) {
589 /* field_sqr works on standard representation */
590 if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
591 goto err;
592 } else {
593 if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx))
594 goto err;
595 }
596
597 if (x != NULL) {
598 /*
599 * in the Montgomery case, field_mul will cancel out
600 * Montgomery factor in X:
601 */
602 if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx))
603 goto err;
604 }
605 if (y != NULL) {
606 if (group->meth->field_encode == 0) {
607 /* field_mul works on standard representation */
608 if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
609 goto err;
610 } else {
611 if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx))
612 goto err;
613 }
614
615 /*
616 * in the Montgomery case, field_mul will cancel out
617 * Montgomery factor in Y:
618 */
619 if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx))
620 goto err;
621 }
622 }
623
624 ret = 1;
625
626err:
627 BN_CTX_end(ctx);
628 BN_CTX_free(new_ctx);
629 return ret;
630}
631
632int
633ec_GFp_simple_add(const EC_GROUP * group, EC_POINT * r, const EC_POINT * a, const EC_POINT * b, BN_CTX * ctx)
634{
635 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
636 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
637 const BIGNUM *p;
638 BN_CTX *new_ctx = NULL;
639 BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
640 int ret = 0;
641
642 if (a == b)
643 return EC_POINT_dbl(group, r, a, ctx);
644 if (EC_POINT_is_at_infinity(group, a) > 0)
645 return EC_POINT_copy(r, b);
646 if (EC_POINT_is_at_infinity(group, b) > 0)
647 return EC_POINT_copy(r, a);
648
649 field_mul = group->meth->field_mul;
650 field_sqr = group->meth->field_sqr;
651 p = &group->field;
652
653 if (ctx == NULL) {
654 ctx = new_ctx = BN_CTX_new();
655 if (ctx == NULL)
656 return 0;
657 }
658 BN_CTX_start(ctx);
659 if ((n0 = BN_CTX_get(ctx)) == NULL)
660 goto end;
661 if ((n1 = BN_CTX_get(ctx)) == NULL)
662 goto end;
663 if ((n2 = BN_CTX_get(ctx)) == NULL)
664 goto end;
665 if ((n3 = BN_CTX_get(ctx)) == NULL)
666 goto end;
667 if ((n4 = BN_CTX_get(ctx)) == NULL)
668 goto end;
669 if ((n5 = BN_CTX_get(ctx)) == NULL)
670 goto end;
671 if ((n6 = BN_CTX_get(ctx)) == NULL)
672 goto end;
673
674 /*
675 * Note that in this function we must not read components of 'a' or
676 * 'b' once we have written the corresponding components of 'r'. ('r'
677 * might be one of 'a' or 'b'.)
678 */
679
680 /* n1, n2 */
681 if (b->Z_is_one) {
682 if (!BN_copy(n1, &a->X))
683 goto end;
684 if (!BN_copy(n2, &a->Y))
685 goto end;
686 /* n1 = X_a */
687 /* n2 = Y_a */
688 } else {
689 if (!field_sqr(group, n0, &b->Z, ctx))
690 goto end;
691 if (!field_mul(group, n1, &a->X, n0, ctx))
692 goto end;
693 /* n1 = X_a * Z_b^2 */
694
695 if (!field_mul(group, n0, n0, &b->Z, ctx))
696 goto end;
697 if (!field_mul(group, n2, &a->Y, n0, ctx))
698 goto end;
699 /* n2 = Y_a * Z_b^3 */
700 }
701
702 /* n3, n4 */
703 if (a->Z_is_one) {
704 if (!BN_copy(n3, &b->X))
705 goto end;
706 if (!BN_copy(n4, &b->Y))
707 goto end;
708 /* n3 = X_b */
709 /* n4 = Y_b */
710 } else {
711 if (!field_sqr(group, n0, &a->Z, ctx))
712 goto end;
713 if (!field_mul(group, n3, &b->X, n0, ctx))
714 goto end;
715 /* n3 = X_b * Z_a^2 */
716
717 if (!field_mul(group, n0, n0, &a->Z, ctx))
718 goto end;
719 if (!field_mul(group, n4, &b->Y, n0, ctx))
720 goto end;
721 /* n4 = Y_b * Z_a^3 */
722 }
723
724 /* n5, n6 */
725 if (!BN_mod_sub_quick(n5, n1, n3, p))
726 goto end;
727 if (!BN_mod_sub_quick(n6, n2, n4, p))
728 goto end;
729 /* n5 = n1 - n3 */
730 /* n6 = n2 - n4 */
731
732 if (BN_is_zero(n5)) {
733 if (BN_is_zero(n6)) {
734 /* a is the same point as b */
735 BN_CTX_end(ctx);
736 ret = EC_POINT_dbl(group, r, a, ctx);
737 ctx = NULL;
738 goto end;
739 } else {
740 /* a is the inverse of b */
741 BN_zero(&r->Z);
742 r->Z_is_one = 0;
743 ret = 1;
744 goto end;
745 }
746 }
747 /* 'n7', 'n8' */
748 if (!BN_mod_add_quick(n1, n1, n3, p))
749 goto end;
750 if (!BN_mod_add_quick(n2, n2, n4, p))
751 goto end;
752 /* 'n7' = n1 + n3 */
753 /* 'n8' = n2 + n4 */
754
755 /* Z_r */
756 if (a->Z_is_one && b->Z_is_one) {
757 if (!BN_copy(&r->Z, n5))
758 goto end;
759 } else {
760 if (a->Z_is_one) {
761 if (!BN_copy(n0, &b->Z))
762 goto end;
763 } else if (b->Z_is_one) {
764 if (!BN_copy(n0, &a->Z))
765 goto end;
766 } else {
767 if (!field_mul(group, n0, &a->Z, &b->Z, ctx))
768 goto end;
769 }
770 if (!field_mul(group, &r->Z, n0, n5, ctx))
771 goto end;
772 }
773 r->Z_is_one = 0;
774 /* Z_r = Z_a * Z_b * n5 */
775
776 /* X_r */
777 if (!field_sqr(group, n0, n6, ctx))
778 goto end;
779 if (!field_sqr(group, n4, n5, ctx))
780 goto end;
781 if (!field_mul(group, n3, n1, n4, ctx))
782 goto end;
783 if (!BN_mod_sub_quick(&r->X, n0, n3, p))
784 goto end;
785 /* X_r = n6^2 - n5^2 * 'n7' */
786
787 /* 'n9' */
788 if (!BN_mod_lshift1_quick(n0, &r->X, p))
789 goto end;
790 if (!BN_mod_sub_quick(n0, n3, n0, p))
791 goto end;
792 /* n9 = n5^2 * 'n7' - 2 * X_r */
793
794 /* Y_r */
795 if (!field_mul(group, n0, n0, n6, ctx))
796 goto end;
797 if (!field_mul(group, n5, n4, n5, ctx))
798 goto end; /* now n5 is n5^3 */
799 if (!field_mul(group, n1, n2, n5, ctx))
800 goto end;
801 if (!BN_mod_sub_quick(n0, n0, n1, p))
802 goto end;
803 if (BN_is_odd(n0))
804 if (!BN_add(n0, n0, p))
805 goto end;
806 /* now 0 <= n0 < 2*p, and n0 is even */
807 if (!BN_rshift1(&r->Y, n0))
808 goto end;
809 /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
810
811 ret = 1;
812
813end:
814 if (ctx) /* otherwise we already called BN_CTX_end */
815 BN_CTX_end(ctx);
816 BN_CTX_free(new_ctx);
817 return ret;
818}
819
820
821int
822ec_GFp_simple_dbl(const EC_GROUP * group, EC_POINT * r, const EC_POINT * a, BN_CTX * ctx)
823{
824 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
825 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
826 const BIGNUM *p;
827 BN_CTX *new_ctx = NULL;
828 BIGNUM *n0, *n1, *n2, *n3;
829 int ret = 0;
830
831 if (EC_POINT_is_at_infinity(group, a) > 0) {
832 BN_zero(&r->Z);
833 r->Z_is_one = 0;
834 return 1;
835 }
836 field_mul = group->meth->field_mul;
837 field_sqr = group->meth->field_sqr;
838 p = &group->field;
839
840 if (ctx == NULL) {
841 ctx = new_ctx = BN_CTX_new();
842 if (ctx == NULL)
843 return 0;
844 }
845 BN_CTX_start(ctx);
846 if ((n0 = BN_CTX_get(ctx)) == NULL)
847 goto err;
848 if ((n1 = BN_CTX_get(ctx)) == NULL)
849 goto err;
850 if ((n2 = BN_CTX_get(ctx)) == NULL)
851 goto err;
852 if ((n3 = BN_CTX_get(ctx)) == NULL)
853 goto err;
854
855 /*
856 * Note that in this function we must not read components of 'a' once
857 * we have written the corresponding components of 'r'. ('r' might
858 * the same as 'a'.)
859 */
860
861 /* n1 */
862 if (a->Z_is_one) {
863 if (!field_sqr(group, n0, &a->X, ctx))
864 goto err;
865 if (!BN_mod_lshift1_quick(n1, n0, p))
866 goto err;
867 if (!BN_mod_add_quick(n0, n0, n1, p))
868 goto err;
869 if (!BN_mod_add_quick(n1, n0, &group->a, p))
870 goto err;
871 /* n1 = 3 * X_a^2 + a_curve */
872 } else if (group->a_is_minus3) {
873 if (!field_sqr(group, n1, &a->Z, ctx))
874 goto err;
875 if (!BN_mod_add_quick(n0, &a->X, n1, p))
876 goto err;
877 if (!BN_mod_sub_quick(n2, &a->X, n1, p))
878 goto err;
879 if (!field_mul(group, n1, n0, n2, ctx))
880 goto err;
881 if (!BN_mod_lshift1_quick(n0, n1, p))
882 goto err;
883 if (!BN_mod_add_quick(n1, n0, n1, p))
884 goto err;
885 /*
886 * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) = 3 * X_a^2 - 3 *
887 * Z_a^4
888 */
889 } else {
890 if (!field_sqr(group, n0, &a->X, ctx))
891 goto err;
892 if (!BN_mod_lshift1_quick(n1, n0, p))
893 goto err;
894 if (!BN_mod_add_quick(n0, n0, n1, p))
895 goto err;
896 if (!field_sqr(group, n1, &a->Z, ctx))
897 goto err;
898 if (!field_sqr(group, n1, n1, ctx))
899 goto err;
900 if (!field_mul(group, n1, n1, &group->a, ctx))
901 goto err;
902 if (!BN_mod_add_quick(n1, n1, n0, p))
903 goto err;
904 /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
905 }
906
907 /* Z_r */
908 if (a->Z_is_one) {
909 if (!BN_copy(n0, &a->Y))
910 goto err;
911 } else {
912 if (!field_mul(group, n0, &a->Y, &a->Z, ctx))
913 goto err;
914 }
915 if (!BN_mod_lshift1_quick(&r->Z, n0, p))
916 goto err;
917 r->Z_is_one = 0;
918 /* Z_r = 2 * Y_a * Z_a */
919
920 /* n2 */
921 if (!field_sqr(group, n3, &a->Y, ctx))
922 goto err;
923 if (!field_mul(group, n2, &a->X, n3, ctx))
924 goto err;
925 if (!BN_mod_lshift_quick(n2, n2, 2, p))
926 goto err;
927 /* n2 = 4 * X_a * Y_a^2 */
928
929 /* X_r */
930 if (!BN_mod_lshift1_quick(n0, n2, p))
931 goto err;
932 if (!field_sqr(group, &r->X, n1, ctx))
933 goto err;
934 if (!BN_mod_sub_quick(&r->X, &r->X, n0, p))
935 goto err;
936 /* X_r = n1^2 - 2 * n2 */
937
938 /* n3 */
939 if (!field_sqr(group, n0, n3, ctx))
940 goto err;
941 if (!BN_mod_lshift_quick(n3, n0, 3, p))
942 goto err;
943 /* n3 = 8 * Y_a^4 */
944
945 /* Y_r */
946 if (!BN_mod_sub_quick(n0, n2, &r->X, p))
947 goto err;
948 if (!field_mul(group, n0, n1, n0, ctx))
949 goto err;
950 if (!BN_mod_sub_quick(&r->Y, n0, n3, p))
951 goto err;
952 /* Y_r = n1 * (n2 - X_r) - n3 */
953
954 ret = 1;
955
956err:
957 BN_CTX_end(ctx);
958 BN_CTX_free(new_ctx);
959 return ret;
960}
961
962
963int
964ec_GFp_simple_invert(const EC_GROUP * group, EC_POINT * point, BN_CTX * ctx)
965{
966 if (EC_POINT_is_at_infinity(group, point) > 0 || BN_is_zero(&point->Y))
967 /* point is its own inverse */
968 return 1;
969
970 return BN_usub(&point->Y, &group->field, &point->Y);
971}
972
973
974int
975ec_GFp_simple_is_at_infinity(const EC_GROUP * group, const EC_POINT * point)
976{
977 return BN_is_zero(&point->Z);
978}
979
980
981int
982ec_GFp_simple_is_on_curve(const EC_GROUP * group, const EC_POINT * point, BN_CTX * ctx)
983{
984 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
985 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
986 const BIGNUM *p;
987 BN_CTX *new_ctx = NULL;
988 BIGNUM *rh, *tmp, *Z4, *Z6;
989 int ret = -1;
990
991 if (EC_POINT_is_at_infinity(group, point) > 0)
992 return 1;
993
994 field_mul = group->meth->field_mul;
995 field_sqr = group->meth->field_sqr;
996 p = &group->field;
997
998 if (ctx == NULL) {
999 ctx = new_ctx = BN_CTX_new();
1000 if (ctx == NULL)
1001 return -1;
1002 }
1003 BN_CTX_start(ctx);
1004 if ((rh = BN_CTX_get(ctx)) == NULL)
1005 goto err;
1006 if ((tmp = BN_CTX_get(ctx)) == NULL)
1007 goto err;
1008 if ((Z4 = BN_CTX_get(ctx)) == NULL)
1009 goto err;
1010 if ((Z6 = BN_CTX_get(ctx)) == NULL)
1011 goto err;
1012
1013 /*
1014 * We have a curve defined by a Weierstrass equation y^2 = x^3 + a*x
1015 * + b. The point to consider is given in Jacobian projective
1016 * coordinates where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
1017 * Substituting this and multiplying by Z^6 transforms the above
1018 * equation into Y^2 = X^3 + a*X*Z^4 + b*Z^6. To test this, we add up
1019 * the right-hand side in 'rh'.
1020 */
1021
1022 /* rh := X^2 */
1023 if (!field_sqr(group, rh, &point->X, ctx))
1024 goto err;
1025
1026 if (!point->Z_is_one) {
1027 if (!field_sqr(group, tmp, &point->Z, ctx))
1028 goto err;
1029 if (!field_sqr(group, Z4, tmp, ctx))
1030 goto err;
1031 if (!field_mul(group, Z6, Z4, tmp, ctx))
1032 goto err;
1033
1034 /* rh := (rh + a*Z^4)*X */
1035 if (group->a_is_minus3) {
1036 if (!BN_mod_lshift1_quick(tmp, Z4, p))
1037 goto err;
1038 if (!BN_mod_add_quick(tmp, tmp, Z4, p))
1039 goto err;
1040 if (!BN_mod_sub_quick(rh, rh, tmp, p))
1041 goto err;
1042 if (!field_mul(group, rh, rh, &point->X, ctx))
1043 goto err;
1044 } else {
1045 if (!field_mul(group, tmp, Z4, &group->a, ctx))
1046 goto err;
1047 if (!BN_mod_add_quick(rh, rh, tmp, p))
1048 goto err;
1049 if (!field_mul(group, rh, rh, &point->X, ctx))
1050 goto err;
1051 }
1052
1053 /* rh := rh + b*Z^6 */
1054 if (!field_mul(group, tmp, &group->b, Z6, ctx))
1055 goto err;
1056 if (!BN_mod_add_quick(rh, rh, tmp, p))
1057 goto err;
1058 } else {
1059 /* point->Z_is_one */
1060
1061 /* rh := (rh + a)*X */
1062 if (!BN_mod_add_quick(rh, rh, &group->a, p))
1063 goto err;
1064 if (!field_mul(group, rh, rh, &point->X, ctx))
1065 goto err;
1066 /* rh := rh + b */
1067 if (!BN_mod_add_quick(rh, rh, &group->b, p))
1068 goto err;
1069 }
1070
1071 /* 'lh' := Y^2 */
1072 if (!field_sqr(group, tmp, &point->Y, ctx))
1073 goto err;
1074
1075 ret = (0 == BN_ucmp(tmp, rh));
1076
1077err:
1078 BN_CTX_end(ctx);
1079 BN_CTX_free(new_ctx);
1080 return ret;
1081}
1082
1083
1084int
1085ec_GFp_simple_cmp(const EC_GROUP * group, const EC_POINT * a, const EC_POINT * b, BN_CTX * ctx)
1086{
1087 /*
1088 * return values: -1 error 0 equal (in affine coordinates) 1
1089 * not equal
1090 */
1091
1092 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
1093 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1094 BN_CTX *new_ctx = NULL;
1095 BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
1096 const BIGNUM *tmp1_, *tmp2_;
1097 int ret = -1;
1098
1099 if (EC_POINT_is_at_infinity(group, a) > 0) {
1100 return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1;
1101 }
1102 if (EC_POINT_is_at_infinity(group, b) > 0)
1103 return 1;
1104
1105 if (a->Z_is_one && b->Z_is_one) {
1106 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
1107 }
1108 field_mul = group->meth->field_mul;
1109 field_sqr = group->meth->field_sqr;
1110
1111 if (ctx == NULL) {
1112 ctx = new_ctx = BN_CTX_new();
1113 if (ctx == NULL)
1114 return -1;
1115 }
1116 BN_CTX_start(ctx);
1117 if ((tmp1 = BN_CTX_get(ctx)) == NULL)
1118 goto end;
1119 if ((tmp2 = BN_CTX_get(ctx)) == NULL)
1120 goto end;
1121 if ((Za23 = BN_CTX_get(ctx)) == NULL)
1122 goto end;
1123 if ((Zb23 = BN_CTX_get(ctx)) == NULL)
1124 goto end;
1125
1126 /*
1127 * We have to decide whether (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2,
1128 * Y_b/Z_b^3), or equivalently, whether (X_a*Z_b^2, Y_a*Z_b^3) =
1129 * (X_b*Z_a^2, Y_b*Z_a^3).
1130 */
1131
1132 if (!b->Z_is_one) {
1133 if (!field_sqr(group, Zb23, &b->Z, ctx))
1134 goto end;
1135 if (!field_mul(group, tmp1, &a->X, Zb23, ctx))
1136 goto end;
1137 tmp1_ = tmp1;
1138 } else
1139 tmp1_ = &a->X;
1140 if (!a->Z_is_one) {
1141 if (!field_sqr(group, Za23, &a->Z, ctx))
1142 goto end;
1143 if (!field_mul(group, tmp2, &b->X, Za23, ctx))
1144 goto end;
1145 tmp2_ = tmp2;
1146 } else
1147 tmp2_ = &b->X;
1148
1149 /* compare X_a*Z_b^2 with X_b*Z_a^2 */
1150 if (BN_cmp(tmp1_, tmp2_) != 0) {
1151 ret = 1; /* points differ */
1152 goto end;
1153 }
1154 if (!b->Z_is_one) {
1155 if (!field_mul(group, Zb23, Zb23, &b->Z, ctx))
1156 goto end;
1157 if (!field_mul(group, tmp1, &a->Y, Zb23, ctx))
1158 goto end;
1159 /* tmp1_ = tmp1 */
1160 } else
1161 tmp1_ = &a->Y;
1162 if (!a->Z_is_one) {
1163 if (!field_mul(group, Za23, Za23, &a->Z, ctx))
1164 goto end;
1165 if (!field_mul(group, tmp2, &b->Y, Za23, ctx))
1166 goto end;
1167 /* tmp2_ = tmp2 */
1168 } else
1169 tmp2_ = &b->Y;
1170
1171 /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
1172 if (BN_cmp(tmp1_, tmp2_) != 0) {
1173 ret = 1; /* points differ */
1174 goto end;
1175 }
1176 /* points are equal */
1177 ret = 0;
1178
1179end:
1180 BN_CTX_end(ctx);
1181 BN_CTX_free(new_ctx);
1182 return ret;
1183}
1184
1185
1186int
1187ec_GFp_simple_make_affine(const EC_GROUP * group, EC_POINT * point, BN_CTX * ctx)
1188{
1189 BN_CTX *new_ctx = NULL;
1190 BIGNUM *x, *y;
1191 int ret = 0;
1192
1193 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0)
1194 return 1;
1195
1196 if (ctx == NULL) {
1197 ctx = new_ctx = BN_CTX_new();
1198 if (ctx == NULL)
1199 return 0;
1200 }
1201 BN_CTX_start(ctx);
1202 if ((x = BN_CTX_get(ctx)) == NULL)
1203 goto err;
1204 if ((y = BN_CTX_get(ctx)) == NULL)
1205 goto err;
1206
1207 if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
1208 goto err;
1209 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
1210 goto err;
1211 if (!point->Z_is_one) {
1212 ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
1213 goto err;
1214 }
1215 ret = 1;
1216
1217err:
1218 BN_CTX_end(ctx);
1219 BN_CTX_free(new_ctx);
1220 return ret;
1221}
1222
1223
1224int
1225ec_GFp_simple_points_make_affine(const EC_GROUP * group, size_t num, EC_POINT * points[], BN_CTX * ctx)
1226{
1227 BN_CTX *new_ctx = NULL;
1228 BIGNUM *tmp0, *tmp1;
1229 size_t pow2 = 0;
1230 BIGNUM **heap = NULL;
1231 size_t i;
1232 int ret = 0;
1233
1234 if (num == 0)
1235 return 1;
1236
1237 if (ctx == NULL) {
1238 ctx = new_ctx = BN_CTX_new();
1239 if (ctx == NULL)
1240 return 0;
1241 }
1242 BN_CTX_start(ctx);
1243 if ((tmp0 = BN_CTX_get(ctx)) == NULL)
1244 goto err;
1245 if ((tmp1 = BN_CTX_get(ctx)) == NULL)
1246 goto err;
1247
1248 /*
1249 * Before converting the individual points, compute inverses of all Z
1250 * values. Modular inversion is rather slow, but luckily we can do
1251 * with a single explicit inversion, plus about 3 multiplications per
1252 * input value.
1253 */
1254
1255 pow2 = 1;
1256 while (num > pow2)
1257 pow2 <<= 1;
1258 /*
1259 * Now pow2 is the smallest power of 2 satifsying pow2 >= num. We
1260 * need twice that.
1261 */
1262 pow2 <<= 1;
1263
1264 heap = reallocarray(NULL, pow2, sizeof heap[0]);
1265 if (heap == NULL)
1266 goto err;
1267
1268 /*
1269 * The array is used as a binary tree, exactly as in heapsort:
1270 *
1271 * heap[1] heap[2] heap[3] heap[4] heap[5]
1272 * heap[6] heap[7] heap[8]heap[9] heap[10]heap[11]
1273 * heap[12]heap[13] heap[14] heap[15]
1274 *
1275 * We put the Z's in the last line; then we set each other node to the
1276 * product of its two child-nodes (where empty or 0 entries are
1277 * treated as ones); then we invert heap[1]; then we invert each
1278 * other node by replacing it by the product of its parent (after
1279 * inversion) and its sibling (before inversion).
1280 */
1281 heap[0] = NULL;
1282 for (i = pow2 / 2 - 1; i > 0; i--)
1283 heap[i] = NULL;
1284 for (i = 0; i < num; i++)
1285 heap[pow2 / 2 + i] = &points[i]->Z;
1286 for (i = pow2 / 2 + num; i < pow2; i++)
1287 heap[i] = NULL;
1288
1289 /* set each node to the product of its children */
1290 for (i = pow2 / 2 - 1; i > 0; i--) {
1291 heap[i] = BN_new();
1292 if (heap[i] == NULL)
1293 goto err;
1294
1295 if (heap[2 * i] != NULL) {
1296 if ((heap[2 * i + 1] == NULL) || BN_is_zero(heap[2 * i + 1])) {
1297 if (!BN_copy(heap[i], heap[2 * i]))
1298 goto err;
1299 } else {
1300 if (BN_is_zero(heap[2 * i])) {
1301 if (!BN_copy(heap[i], heap[2 * i + 1]))
1302 goto err;
1303 } else {
1304 if (!group->meth->field_mul(group, heap[i],
1305 heap[2 * i], heap[2 * i + 1], ctx))
1306 goto err;
1307 }
1308 }
1309 }
1310 }
1311
1312 /* invert heap[1] */
1313 if (!BN_is_zero(heap[1])) {
1314 if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx)) {
1315 ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
1316 goto err;
1317 }
1318 }
1319 if (group->meth->field_encode != 0) {
1320 /*
1321 * in the Montgomery case, we just turned R*H (representing
1322 * H) into 1/(R*H), but we need R*(1/H) (representing
1323 * 1/H); i.e. we have need to multiply by the Montgomery
1324 * factor twice
1325 */
1326 if (!group->meth->field_encode(group, heap[1], heap[1], ctx))
1327 goto err;
1328 if (!group->meth->field_encode(group, heap[1], heap[1], ctx))
1329 goto err;
1330 }
1331 /* set other heap[i]'s to their inverses */
1332 for (i = 2; i < pow2 / 2 + num; i += 2) {
1333 /* i is even */
1334 if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1])) {
1335 if (!group->meth->field_mul(group, tmp0, heap[i / 2], heap[i + 1], ctx))
1336 goto err;
1337 if (!group->meth->field_mul(group, tmp1, heap[i / 2], heap[i], ctx))
1338 goto err;
1339 if (!BN_copy(heap[i], tmp0))
1340 goto err;
1341 if (!BN_copy(heap[i + 1], tmp1))
1342 goto err;
1343 } else {
1344 if (!BN_copy(heap[i], heap[i / 2]))
1345 goto err;
1346 }
1347 }
1348
1349 /*
1350 * we have replaced all non-zero Z's by their inverses, now fix up
1351 * all the points
1352 */
1353 for (i = 0; i < num; i++) {
1354 EC_POINT *p = points[i];
1355
1356 if (!BN_is_zero(&p->Z)) {
1357 /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
1358
1359 if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx))
1360 goto err;
1361 if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx))
1362 goto err;
1363
1364 if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx))
1365 goto err;
1366 if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx))
1367 goto err;
1368
1369 if (group->meth->field_set_to_one != 0) {
1370 if (!group->meth->field_set_to_one(group, &p->Z, ctx))
1371 goto err;
1372 } else {
1373 if (!BN_one(&p->Z))
1374 goto err;
1375 }
1376 p->Z_is_one = 1;
1377 }
1378 }
1379
1380 ret = 1;
1381
1382err:
1383 BN_CTX_end(ctx);
1384 BN_CTX_free(new_ctx);
1385 if (heap != NULL) {
1386 /*
1387 * heap[pow2/2] .. heap[pow2-1] have not been allocated
1388 * locally!
1389 */
1390 for (i = pow2 / 2 - 1; i > 0; i--) {
1391 BN_clear_free(heap[i]);
1392 }
1393 free(heap);
1394 }
1395 return ret;
1396}
1397
1398
1399int
1400ec_GFp_simple_field_mul(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
1401{
1402 return BN_mod_mul(r, a, b, &group->field, ctx);
1403}
1404
1405
1406int
1407ec_GFp_simple_field_sqr(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, BN_CTX * ctx)
1408{
1409 return BN_mod_sqr(r, a, &group->field, ctx);
1410}