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.h1162
-rw-r--r--src/lib/libcrypto/ec/ec2_mult.c446
-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.c1312
-rw-r--r--src/lib/libcrypto/ec/ec_check.c115
-rw-r--r--src/lib/libcrypto/ec/ec_curve.c3287
-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.c1109
-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.c321
-rw-r--r--src/lib/libcrypto/ec/ec_print.c178
-rw-r--r--src/lib/libcrypto/ec/eck_prn.c362
-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, 21172 deletions
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
deleted file mode 100644
index db0b99a8e9..0000000000
--- a/src/lib/libcrypto/ec/ec.h
+++ /dev/null
@@ -1,1162 +0,0 @@
1/* $OpenBSD: ec.h,v 1.9 2014/06/12 15:49:29 deraadt 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
398
399/********************************************************************/
400/* EC_POINT functions */
401/********************************************************************/
402
403/** Creates a new EC_POINT object for the specified EC_GROUP
404 * \param group EC_GROUP the underlying EC_GROUP object
405 * \return newly created EC_POINT object or NULL if an error occurred
406 */
407EC_POINT *EC_POINT_new(const EC_GROUP *group);
408
409/** Frees a EC_POINT object
410 * \param point EC_POINT object to be freed
411 */
412void EC_POINT_free(EC_POINT *point);
413
414/** Clears and frees a EC_POINT object
415 * \param point EC_POINT object to be cleared and freed
416 */
417void EC_POINT_clear_free(EC_POINT *point);
418
419/** Copies EC_POINT object
420 * \param dst destination EC_POINT object
421 * \param src source EC_POINT object
422 * \return 1 on success and 0 if an error occured
423 */
424int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
425
426/** Creates a new EC_POINT object and copies the content of the supplied
427 * EC_POINT
428 * \param src source EC_POINT object
429 * \param group underlying the EC_GROUP object
430 * \return newly created EC_POINT object or NULL if an error occurred
431 */
432EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
433
434/** Returns the EC_METHOD used in EC_POINT object
435 * \param point EC_POINT object
436 * \return the EC_METHOD used
437 */
438const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
439
440/** Sets a point to infinity (neutral element)
441 * \param group underlying EC_GROUP object
442 * \param point EC_POINT to set to infinity
443 * \return 1 on success and 0 if an error occured
444 */
445int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
446
447/** Sets the jacobian projective coordinates of a EC_POINT over GFp
448 * \param group underlying EC_GROUP object
449 * \param p EC_POINT object
450 * \param x BIGNUM with the x-coordinate
451 * \param y BIGNUM with the y-coordinate
452 * \param z BIGNUM with the z-coordinate
453 * \param ctx BN_CTX object (optional)
454 * \return 1 on success and 0 if an error occured
455 */
456int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
457 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
458
459/** Gets the jacobian projective coordinates of a EC_POINT over GFp
460 * \param group underlying EC_GROUP object
461 * \param p EC_POINT object
462 * \param x BIGNUM for the x-coordinate
463 * \param y BIGNUM for the y-coordinate
464 * \param z BIGNUM for the z-coordinate
465 * \param ctx BN_CTX object (optional)
466 * \return 1 on success and 0 if an error occured
467 */
468int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
469 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
470
471/** Sets the affine coordinates of a EC_POINT over GFp
472 * \param group underlying EC_GROUP object
473 * \param p EC_POINT object
474 * \param x BIGNUM with the x-coordinate
475 * \param y BIGNUM with the y-coordinate
476 * \param ctx BN_CTX object (optional)
477 * \return 1 on success and 0 if an error occured
478 */
479int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
480 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
481
482/** Gets the affine coordinates of a EC_POINT over GFp
483 * \param group underlying EC_GROUP object
484 * \param p EC_POINT object
485 * \param x BIGNUM for the x-coordinate
486 * \param y BIGNUM for the y-coordinate
487 * \param ctx BN_CTX object (optional)
488 * \return 1 on success and 0 if an error occured
489 */
490int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
491 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
492
493/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
494 * \param group underlying EC_GROUP object
495 * \param p EC_POINT object
496 * \param x BIGNUM with x-coordinate
497 * \param y_bit integer with the y-Bit (either 0 or 1)
498 * \param ctx BN_CTX object (optional)
499 * \return 1 on success and 0 if an error occured
500 */
501int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
502 const BIGNUM *x, int y_bit, BN_CTX *ctx);
503#ifndef OPENSSL_NO_EC2M
504/** Sets the affine coordinates of a EC_POINT over GF2m
505 * \param group underlying EC_GROUP object
506 * \param p EC_POINT object
507 * \param x BIGNUM with the x-coordinate
508 * \param y BIGNUM with the y-coordinate
509 * \param ctx BN_CTX object (optional)
510 * \return 1 on success and 0 if an error occured
511 */
512int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
513 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
514
515/** Gets the affine coordinates of a EC_POINT over GF2m
516 * \param group underlying EC_GROUP object
517 * \param p EC_POINT object
518 * \param x BIGNUM for the x-coordinate
519 * \param y BIGNUM for the y-coordinate
520 * \param ctx BN_CTX object (optional)
521 * \return 1 on success and 0 if an error occured
522 */
523int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
524 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
525
526/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
527 * \param group underlying EC_GROUP object
528 * \param p EC_POINT object
529 * \param x BIGNUM with x-coordinate
530 * \param y_bit integer with the y-Bit (either 0 or 1)
531 * \param ctx BN_CTX object (optional)
532 * \return 1 on success and 0 if an error occured
533 */
534int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
535 const BIGNUM *x, int y_bit, BN_CTX *ctx);
536#endif
537/** Encodes a EC_POINT object to a octet string
538 * \param group underlying EC_GROUP object
539 * \param p EC_POINT object
540 * \param form point conversion form
541 * \param buf memory buffer for the result. If NULL the function returns
542 * required buffer size.
543 * \param len length of the memory buffer
544 * \param ctx BN_CTX object (optional)
545 * \return the length of the encoded octet string or 0 if an error occurred
546 */
547size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
548 point_conversion_form_t form,
549 unsigned char *buf, size_t len, BN_CTX *ctx);
550
551/** Decodes a EC_POINT from a octet string
552 * \param group underlying EC_GROUP object
553 * \param p EC_POINT object
554 * \param buf memory buffer with the encoded ec point
555 * \param len length of the encoded ec point
556 * \param ctx BN_CTX object (optional)
557 * \return 1 on success and 0 if an error occured
558 */
559int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
560 const unsigned char *buf, size_t len, BN_CTX *ctx);
561
562/* other interfaces to point2oct/oct2point: */
563BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
564 point_conversion_form_t form, BIGNUM *, BN_CTX *);
565EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
566 EC_POINT *, BN_CTX *);
567char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
568 point_conversion_form_t form, BN_CTX *);
569EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
570 EC_POINT *, BN_CTX *);
571
572
573/********************************************************************/
574/* functions for doing EC_POINT arithmetic */
575/********************************************************************/
576
577/** Computes the sum of two EC_POINT
578 * \param group underlying EC_GROUP object
579 * \param r EC_POINT object for the result (r = a + b)
580 * \param a EC_POINT object with the first summand
581 * \param b EC_POINT object with the second summand
582 * \param ctx BN_CTX object (optional)
583 * \return 1 on success and 0 if an error occured
584 */
585int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
586
587/** Computes the double of a EC_POINT
588 * \param group underlying EC_GROUP object
589 * \param r EC_POINT object for the result (r = 2 * a)
590 * \param a EC_POINT object
591 * \param ctx BN_CTX object (optional)
592 * \return 1 on success and 0 if an error occured
593 */
594int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx);
595
596/** Computes the inverse of a EC_POINT
597 * \param group underlying EC_GROUP object
598 * \param a EC_POINT object to be inverted (it's used for the result as well)
599 * \param ctx BN_CTX object (optional)
600 * \return 1 on success and 0 if an error occured
601 */
602int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
603
604/** Checks whether the point is the neutral element of the group
605 * \param group the underlying EC_GROUP object
606 * \param p EC_POINT object
607 * \return 1 if the point is the neutral element and 0 otherwise
608 */
609int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
610
611/** Checks whether the point is on the curve
612 * \param group underlying EC_GROUP object
613 * \param point EC_POINT object to check
614 * \param ctx BN_CTX object (optional)
615 * \return 1 if point if on the curve and 0 otherwise
616 */
617int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx);
618
619/** Compares two EC_POINTs
620 * \param group underlying EC_GROUP object
621 * \param a first EC_POINT object
622 * \param b second EC_POINT object
623 * \param ctx BN_CTX object (optional)
624 * \return 0 if both points are equal and a value != 0 otherwise
625 */
626int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
627
628int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
629int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx);
630
631/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
632 * \param group underlying EC_GROUP object
633 * \param r EC_POINT object for the result
634 * \param n BIGNUM with the multiplier for the group generator (optional)
635 * \param num number futher summands
636 * \param p array of size num of EC_POINT objects
637 * \param m array of size num of BIGNUM objects
638 * \param ctx BN_CTX object (optional)
639 * \return 1 on success and 0 if an error occured
640 */
641int 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);
642
643/** Computes r = generator * n + q * m
644 * \param group underlying EC_GROUP object
645 * \param r EC_POINT object for the result
646 * \param n BIGNUM with the multiplier for the group generator (optional)
647 * \param q EC_POINT object with the first factor of the second summand
648 * \param m BIGNUM with the second factor of the second summand
649 * \param ctx BN_CTX object (optional)
650 * \return 1 on success and 0 if an error occured
651 */
652int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
653
654/** Stores multiples of generator for faster point multiplication
655 * \param group EC_GROUP object
656 * \param ctx BN_CTX object (optional)
657 * \return 1 on success and 0 if an error occured
658 */
659int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
660
661/** Reports whether a precomputation has been done
662 * \param group EC_GROUP object
663 * \return 1 if a pre-computation has been done and 0 otherwise
664 */
665int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
666
667
668/********************************************************************/
669/* ASN1 stuff */
670/********************************************************************/
671
672/* EC_GROUP_get_basis_type() returns the NID of the basis type
673 * used to represent the field elements */
674int EC_GROUP_get_basis_type(const EC_GROUP *);
675#ifndef OPENSSL_NO_EC2M
676int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
677int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
678 unsigned int *k2, unsigned int *k3);
679#endif
680
681#define OPENSSL_EC_NAMED_CURVE 0x001
682
683typedef struct ecpk_parameters_st ECPKPARAMETERS;
684
685EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
686int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
687
688#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
689#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
690#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
691 (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
692#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
693 (unsigned char *)(x))
694
695#ifndef OPENSSL_NO_BIO
696int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
697#endif
698int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
699
700
701/********************************************************************/
702/* EC_KEY functions */
703/********************************************************************/
704
705typedef struct ec_key_st EC_KEY;
706
707/* some values for the encoding_flag */
708#define EC_PKEY_NO_PARAMETERS 0x001
709#define EC_PKEY_NO_PUBKEY 0x002
710
711/* some values for the flags field */
712#define EC_FLAG_NON_FIPS_ALLOW 0x1
713#define EC_FLAG_FIPS_CHECKED 0x2
714
715/** Creates a new EC_KEY object.
716 * \return EC_KEY object or NULL if an error occurred.
717 */
718EC_KEY *EC_KEY_new(void);
719
720int EC_KEY_get_flags(const EC_KEY *key);
721
722void EC_KEY_set_flags(EC_KEY *key, int flags);
723
724void EC_KEY_clear_flags(EC_KEY *key, int flags);
725
726/** Creates a new EC_KEY object using a named curve as underlying
727 * EC_GROUP object.
728 * \param nid NID of the named curve.
729 * \return EC_KEY object or NULL if an error occurred.
730 */
731EC_KEY *EC_KEY_new_by_curve_name(int nid);
732
733/** Frees a EC_KEY object.
734 * \param key EC_KEY object to be freed.
735 */
736void EC_KEY_free(EC_KEY *key);
737
738/** Copies a EC_KEY object.
739 * \param dst destination EC_KEY object
740 * \param src src EC_KEY object
741 * \return dst or NULL if an error occurred.
742 */
743EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
744
745/** Creates a new EC_KEY object and copies the content from src to it.
746 * \param src the source EC_KEY object
747 * \return newly created EC_KEY object or NULL if an error occurred.
748 */
749EC_KEY *EC_KEY_dup(const EC_KEY *src);
750
751/** Increases the internal reference count of a EC_KEY object.
752 * \param key EC_KEY object
753 * \return 1 on success and 0 if an error occurred.
754 */
755int EC_KEY_up_ref(EC_KEY *key);
756
757/** Returns the EC_GROUP object of a EC_KEY object
758 * \param key EC_KEY object
759 * \return the EC_GROUP object (possibly NULL).
760 */
761const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
762
763/** Sets the EC_GROUP of a EC_KEY object.
764 * \param key EC_KEY object
765 * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY
766 * object will use an own copy of the EC_GROUP).
767 * \return 1 on success and 0 if an error occurred.
768 */
769int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
770
771/** Returns the private key of a EC_KEY object.
772 * \param key EC_KEY object
773 * \return a BIGNUM with the private key (possibly NULL).
774 */
775const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
776
777/** Sets the private key of a EC_KEY object.
778 * \param key EC_KEY object
779 * \param prv BIGNUM with the private key (note: the EC_KEY object
780 * will use an own copy of the BIGNUM).
781 * \return 1 on success and 0 if an error occurred.
782 */
783int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
784
785/** Returns the public key of a EC_KEY object.
786 * \param key the EC_KEY object
787 * \return a EC_POINT object with the public key (possibly NULL)
788 */
789const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
790
791/** Sets the public key of a EC_KEY object.
792 * \param key EC_KEY object
793 * \param pub EC_POINT object with the public key (note: the EC_KEY object
794 * will use an own copy of the EC_POINT object).
795 * \return 1 on success and 0 if an error occurred.
796 */
797int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
798
799unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
800void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
801point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
802void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
803/* functions to set/get method specific data */
804void *EC_KEY_get_key_method_data(EC_KEY *key,
805 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
806/** Sets the key method data of an EC_KEY object, if none has yet been set.
807 * \param key EC_KEY object
808 * \param data opaque data to install.
809 * \param dup_func a function that duplicates |data|.
810 * \param free_func a function that frees |data|.
811 * \param clear_free_func a function that wipes and frees |data|.
812 * \return the previously set data pointer, or NULL if |data| was inserted.
813 */
814void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
815 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
816/* wrapper functions for the underlying EC_GROUP object */
817void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
818
819/** Creates a table of pre-computed multiples of the generator to
820 * accelerate further EC_KEY operations.
821 * \param key EC_KEY object
822 * \param ctx BN_CTX object (optional)
823 * \return 1 on success and 0 if an error occurred.
824 */
825int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
826
827/** Creates a new ec private (and optional a new public) key.
828 * \param key EC_KEY object
829 * \return 1 on success and 0 if an error occurred.
830 */
831int EC_KEY_generate_key(EC_KEY *key);
832
833/** Verifies that a private and/or public key is valid.
834 * \param key the EC_KEY object
835 * \return 1 on success and 0 otherwise.
836 */
837int EC_KEY_check_key(const EC_KEY *key);
838
839/** Sets a public key from affine coordindates performing
840 * neccessary NIST PKV tests.
841 * \param key the EC_KEY object
842 * \param x public key x coordinate
843 * \param y public key y coordinate
844 * \return 1 on success and 0 otherwise.
845 */
846int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y);
847
848
849/********************************************************************/
850/* de- and encoding functions for SEC1 ECPrivateKey */
851/********************************************************************/
852
853/** Decodes a private key from a memory buffer.
854 * \param key a pointer to a EC_KEY object which should be used (or NULL)
855 * \param in pointer to memory with the DER encoded private key
856 * \param len length of the DER encoded private key
857 * \return the decoded private key or NULL if an error occurred.
858 */
859EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
860
861/** Encodes a private key object and stores the result in a buffer.
862 * \param key the EC_KEY object to encode
863 * \param out the buffer for the result (if NULL the function returns number
864 * of bytes needed).
865 * \return 1 on success and 0 if an error occurred.
866 */
867int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
868
869
870/********************************************************************/
871/* de- and encoding functions for EC parameters */
872/********************************************************************/
873
874/** Decodes ec parameter from a memory buffer.
875 * \param key a pointer to a EC_KEY object which should be used (or NULL)
876 * \param in pointer to memory with the DER encoded ec parameters
877 * \param len length of the DER encoded ec parameters
878 * \return a EC_KEY object with the decoded parameters or NULL if an error
879 * occurred.
880 */
881EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
882
883/** Encodes ec parameter and stores the result in a buffer.
884 * \param key the EC_KEY object with ec paramters to encode
885 * \param out the buffer for the result (if NULL the function returns number
886 * of bytes needed).
887 * \return 1 on success and 0 if an error occurred.
888 */
889int i2d_ECParameters(EC_KEY *key, unsigned char **out);
890
891
892/********************************************************************/
893/* de- and encoding functions for EC public key */
894/* (octet string, not DER -- hence 'o2i' and 'i2o') */
895/********************************************************************/
896
897/** Decodes a ec public key from a octet string.
898 * \param key a pointer to a EC_KEY object which should be used
899 * \param in memory buffer with the encoded public key
900 * \param len length of the encoded public key
901 * \return EC_KEY object with decoded public key or NULL if an error
902 * occurred.
903 */
904EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
905
906/** Encodes a ec public key in an octet string.
907 * \param key the EC_KEY object with the public key
908 * \param out the buffer for the result (if NULL the function returns number
909 * of bytes needed).
910 * \return 1 on success and 0 if an error occurred
911 */
912int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
913
914#ifndef OPENSSL_NO_BIO
915/** Prints out the ec parameters on human readable form.
916 * \param bp BIO object to which the information is printed
917 * \param key EC_KEY object
918 * \return 1 on success and 0 if an error occurred
919 */
920int ECParameters_print(BIO *bp, const EC_KEY *key);
921
922/** Prints out the contents of a EC_KEY object
923 * \param bp BIO object to which the information is printed
924 * \param key EC_KEY object
925 * \param off line offset
926 * \return 1 on success and 0 if an error occurred
927 */
928int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
929
930#endif
931/** Prints out the ec parameters on human readable form.
932 * \param fp file descriptor to which the information is printed
933 * \param key EC_KEY object
934 * \return 1 on success and 0 if an error occurred
935 */
936int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
937
938/** Prints out the contents of a EC_KEY object
939 * \param fp file descriptor to which the information is printed
940 * \param key EC_KEY object
941 * \param off line offset
942 * \return 1 on success and 0 if an error occurred
943 */
944int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
945
946
947#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
948
949#ifndef __cplusplus
950#if defined(__SUNPRO_C)
951# if __SUNPRO_C >= 0x520
952# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
953# endif
954# endif
955#endif
956
957#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
958 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
959 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
960
961
962#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
963
964/* BEGIN ERROR CODES */
965/* The following lines are auto generated by the script mkerr.pl. Any changes
966 * made after this point may be overwritten when the script is next run.
967 */
968void ERR_load_EC_strings(void);
969
970/* Error codes for the EC functions. */
971
972/* Function codes. */
973#define EC_F_BN_TO_FELEM 224
974#define EC_F_COMPUTE_WNAF 143
975#define EC_F_D2I_ECPARAMETERS 144
976#define EC_F_D2I_ECPKPARAMETERS 145
977#define EC_F_D2I_ECPRIVATEKEY 146
978#define EC_F_DO_EC_KEY_PRINT 221
979#define EC_F_ECKEY_PARAM2TYPE 223
980#define EC_F_ECKEY_PARAM_DECODE 212
981#define EC_F_ECKEY_PRIV_DECODE 213
982#define EC_F_ECKEY_PRIV_ENCODE 214
983#define EC_F_ECKEY_PUB_DECODE 215
984#define EC_F_ECKEY_PUB_ENCODE 216
985#define EC_F_ECKEY_TYPE2PARAM 220
986#define EC_F_ECPARAMETERS_PRINT 147
987#define EC_F_ECPARAMETERS_PRINT_FP 148
988#define EC_F_ECPKPARAMETERS_PRINT 149
989#define EC_F_ECPKPARAMETERS_PRINT_FP 150
990#define EC_F_ECP_NIST_MOD_192 203
991#define EC_F_ECP_NIST_MOD_224 204
992#define EC_F_ECP_NIST_MOD_256 205
993#define EC_F_ECP_NIST_MOD_521 206
994#define EC_F_EC_ASN1_GROUP2CURVE 153
995#define EC_F_EC_ASN1_GROUP2FIELDID 154
996#define EC_F_EC_ASN1_GROUP2PARAMETERS 155
997#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156
998#define EC_F_EC_ASN1_PARAMETERS2GROUP 157
999#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158
1000#define EC_F_EC_EX_DATA_SET_DATA 211
1001#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208
1002#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159
1003#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195
1004#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160
1005#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161
1006#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
1007#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
1008#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164
1009#define EC_F_EC_GFP_MONT_FIELD_DECODE 133
1010#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134
1011#define EC_F_EC_GFP_MONT_FIELD_MUL 131
1012#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209
1013#define EC_F_EC_GFP_MONT_FIELD_SQR 132
1014#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189
1015#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135
1016#define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225
1017#define EC_F_EC_GFP_NISTP224_POINTS_MUL 228
1018#define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
1019#define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230
1020#define EC_F_EC_GFP_NISTP256_POINTS_MUL 231
1021#define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
1022#define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233
1023#define EC_F_EC_GFP_NISTP521_POINTS_MUL 234
1024#define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
1025#define EC_F_EC_GFP_NIST_FIELD_MUL 200
1026#define EC_F_EC_GFP_NIST_FIELD_SQR 201
1027#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202
1028#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165
1029#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166
1030#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100
1031#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101
1032#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102
1033#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103
1034#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104
1035#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137
1036#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167
1037#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
1038#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168
1039#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
1040#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169
1041#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
1042#define EC_F_EC_GROUP_CHECK 170
1043#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171
1044#define EC_F_EC_GROUP_COPY 106
1045#define EC_F_EC_GROUP_GET0_GENERATOR 139
1046#define EC_F_EC_GROUP_GET_COFACTOR 140
1047#define EC_F_EC_GROUP_GET_CURVE_GF2M 172
1048#define EC_F_EC_GROUP_GET_CURVE_GFP 130
1049#define EC_F_EC_GROUP_GET_DEGREE 173
1050#define EC_F_EC_GROUP_GET_ORDER 141
1051#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193
1052#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194
1053#define EC_F_EC_GROUP_NEW 108
1054#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174
1055#define EC_F_EC_GROUP_NEW_FROM_DATA 175
1056#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142
1057#define EC_F_EC_GROUP_SET_CURVE_GF2M 176
1058#define EC_F_EC_GROUP_SET_CURVE_GFP 109
1059#define EC_F_EC_GROUP_SET_EXTRA_DATA 110
1060#define EC_F_EC_GROUP_SET_GENERATOR 111
1061#define EC_F_EC_KEY_CHECK_KEY 177
1062#define EC_F_EC_KEY_COPY 178
1063#define EC_F_EC_KEY_GENERATE_KEY 179
1064#define EC_F_EC_KEY_NEW 182
1065#define EC_F_EC_KEY_PRINT 180
1066#define EC_F_EC_KEY_PRINT_FP 181
1067#define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229
1068#define EC_F_EC_POINTS_MAKE_AFFINE 136
1069#define EC_F_EC_POINT_ADD 112
1070#define EC_F_EC_POINT_CMP 113
1071#define EC_F_EC_POINT_COPY 114
1072#define EC_F_EC_POINT_DBL 115
1073#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183
1074#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116
1075#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117
1076#define EC_F_EC_POINT_INVERT 210
1077#define EC_F_EC_POINT_IS_AT_INFINITY 118
1078#define EC_F_EC_POINT_IS_ON_CURVE 119
1079#define EC_F_EC_POINT_MAKE_AFFINE 120
1080#define EC_F_EC_POINT_MUL 184
1081#define EC_F_EC_POINT_NEW 121
1082#define EC_F_EC_POINT_OCT2POINT 122
1083#define EC_F_EC_POINT_POINT2OCT 123
1084#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185
1085#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124
1086#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186
1087#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125
1088#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126
1089#define EC_F_EC_POINT_SET_TO_INFINITY 127
1090#define EC_F_EC_PRE_COMP_DUP 207
1091#define EC_F_EC_PRE_COMP_NEW 196
1092#define EC_F_EC_WNAF_MUL 187
1093#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188
1094#define EC_F_I2D_ECPARAMETERS 190
1095#define EC_F_I2D_ECPKPARAMETERS 191
1096#define EC_F_I2D_ECPRIVATEKEY 192
1097#define EC_F_I2O_ECPUBLICKEY 151
1098#define EC_F_NISTP224_PRE_COMP_NEW 227
1099#define EC_F_NISTP256_PRE_COMP_NEW 236
1100#define EC_F_NISTP521_PRE_COMP_NEW 237
1101#define EC_F_O2I_ECPUBLICKEY 152
1102#define EC_F_OLD_EC_PRIV_DECODE 222
1103#define EC_F_PKEY_EC_CTRL 197
1104#define EC_F_PKEY_EC_CTRL_STR 198
1105#define EC_F_PKEY_EC_DERIVE 217
1106#define EC_F_PKEY_EC_KEYGEN 199
1107#define EC_F_PKEY_EC_PARAMGEN 219
1108#define EC_F_PKEY_EC_SIGN 218
1109
1110/* Reason codes. */
1111#define EC_R_ASN1_ERROR 115
1112#define EC_R_ASN1_UNKNOWN_FIELD 116
1113#define EC_R_BIGNUM_OUT_OF_RANGE 144
1114#define EC_R_BUFFER_TOO_SMALL 100
1115#define EC_R_COORDINATES_OUT_OF_RANGE 146
1116#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
1117#define EC_R_DECODE_ERROR 142
1118#define EC_R_DISCRIMINANT_IS_ZERO 118
1119#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
1120#define EC_R_FIELD_TOO_LARGE 143
1121#define EC_R_GF2M_NOT_SUPPORTED 147
1122#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
1123#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
1124#define EC_R_INCOMPATIBLE_OBJECTS 101
1125#define EC_R_INVALID_ARGUMENT 112
1126#define EC_R_INVALID_COMPRESSED_POINT 110
1127#define EC_R_INVALID_COMPRESSION_BIT 109
1128#define EC_R_INVALID_CURVE 141
1129#define EC_R_INVALID_DIGEST_TYPE 138
1130#define EC_R_INVALID_ENCODING 102
1131#define EC_R_INVALID_FIELD 103
1132#define EC_R_INVALID_FORM 104
1133#define EC_R_INVALID_GROUP_ORDER 122
1134#define EC_R_INVALID_PENTANOMIAL_BASIS 132
1135#define EC_R_INVALID_PRIVATE_KEY 123
1136#define EC_R_INVALID_TRINOMIAL_BASIS 137
1137#define EC_R_KEYS_NOT_SET 140
1138#define EC_R_MISSING_PARAMETERS 124
1139#define EC_R_MISSING_PRIVATE_KEY 125
1140#define EC_R_NOT_A_NIST_PRIME 135
1141#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136
1142#define EC_R_NOT_IMPLEMENTED 126
1143#define EC_R_NOT_INITIALIZED 111
1144#define EC_R_NO_FIELD_MOD 133
1145#define EC_R_NO_PARAMETERS_SET 139
1146#define EC_R_PASSED_NULL_PARAMETER 134
1147#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
1148#define EC_R_POINT_AT_INFINITY 106
1149#define EC_R_POINT_IS_NOT_ON_CURVE 107
1150#define EC_R_SLOT_FULL 108
1151#define EC_R_UNDEFINED_GENERATOR 113
1152#define EC_R_UNDEFINED_ORDER 128
1153#define EC_R_UNKNOWN_GROUP 129
1154#define EC_R_UNKNOWN_ORDER 114
1155#define EC_R_UNSUPPORTED_FIELD 131
1156#define EC_R_WRONG_CURVE_PARAMETERS 145
1157#define EC_R_WRONG_ORDER 130
1158
1159#ifdef __cplusplus
1160}
1161#endif
1162#endif
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c
deleted file mode 100644
index 8f0091efe1..0000000000
--- a/src/lib/libcrypto/ec/ec2_mult.c
+++ /dev/null
@@ -1,446 +0,0 @@
1/* $OpenBSD: ec2_mult.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-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 bn_wexpand(x1, group->field.top);
293 bn_wexpand(z1, group->field.top);
294 bn_wexpand(x2, group->field.top);
295 bn_wexpand(z2, group->field.top);
296
297 if (!BN_GF2m_mod_arr(x1, &point->X, group->poly))
298 goto err; /* x1 = x */
299 if (!BN_one(z1))
300 goto err; /* z1 = 1 */
301 if (!group->meth->field_sqr(group, z2, x1, ctx))
302 goto err; /* z2 = x1^2 = x^2 */
303 if (!group->meth->field_sqr(group, x2, z2, ctx))
304 goto err;
305 if (!BN_GF2m_add(x2, x2, &group->b))
306 goto err; /* x2 = x^4 + b */
307
308 /* find top most bit and go one past it */
309 i = scalar->top - 1;
310 mask = BN_TBIT;
311 word = scalar->d[i];
312 while (!(word & mask))
313 mask >>= 1;
314 mask >>= 1;
315 /* if top most bit was at word break, go to next word */
316 if (!mask) {
317 i--;
318 mask = BN_TBIT;
319 }
320 for (; i >= 0; i--) {
321 word = scalar->d[i];
322 while (mask) {
323 BN_consttime_swap(word & mask, x1, x2, group->field.top);
324 BN_consttime_swap(word & mask, z1, z2, group->field.top);
325 if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx))
326 goto err;
327 if (!gf2m_Mdouble(group, x1, z1, ctx))
328 goto err;
329 BN_consttime_swap(word & mask, x1, x2, group->field.top);
330 BN_consttime_swap(word & mask, z1, z2, group->field.top);
331 mask >>= 1;
332 }
333 mask = BN_TBIT;
334 }
335
336 /* convert out of "projective" coordinates */
337 i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
338 if (i == 0)
339 goto err;
340 else if (i == 1) {
341 if (!EC_POINT_set_to_infinity(group, r))
342 goto err;
343 } else {
344 if (!BN_one(&r->Z))
345 goto err;
346 r->Z_is_one = 1;
347 }
348
349 /* GF(2^m) field elements should always have BIGNUM::neg = 0 */
350 BN_set_negative(&r->X, 0);
351 BN_set_negative(&r->Y, 0);
352
353 ret = 1;
354
355err:
356 BN_CTX_end(ctx);
357 return ret;
358}
359
360
361/* Computes the sum
362 * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
363 * gracefully ignoring NULL scalar values.
364 */
365int
366ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
367 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
368{
369 BN_CTX *new_ctx = NULL;
370 int ret = 0;
371 size_t i;
372 EC_POINT *p = NULL;
373 EC_POINT *acc = NULL;
374
375 if (ctx == NULL) {
376 ctx = new_ctx = BN_CTX_new();
377 if (ctx == NULL)
378 return 0;
379 }
380 /*
381 * This implementation is more efficient than the wNAF implementation
382 * for 2 or fewer points. Use the ec_wNAF_mul implementation for 3
383 * or more points, or if we can perform a fast multiplication based
384 * on precomputation.
385 */
386 if ((scalar && (num > 1)) || (num > 2) ||
387 (num == 0 && EC_GROUP_have_precompute_mult(group))) {
388 ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
389 goto err;
390 }
391 if ((p = EC_POINT_new(group)) == NULL)
392 goto err;
393 if ((acc = EC_POINT_new(group)) == NULL)
394 goto err;
395
396 if (!EC_POINT_set_to_infinity(group, acc))
397 goto err;
398
399 if (scalar) {
400 if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx))
401 goto err;
402 if (BN_is_negative(scalar))
403 if (!group->meth->invert(group, p, ctx))
404 goto err;
405 if (!group->meth->add(group, acc, acc, p, ctx))
406 goto err;
407 }
408 for (i = 0; i < num; i++) {
409 if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx))
410 goto err;
411 if (BN_is_negative(scalars[i]))
412 if (!group->meth->invert(group, p, ctx))
413 goto err;
414 if (!group->meth->add(group, acc, acc, p, ctx))
415 goto err;
416 }
417
418 if (!EC_POINT_copy(r, acc))
419 goto err;
420
421 ret = 1;
422
423err:
424 EC_POINT_free(p);
425 EC_POINT_free(acc);
426 BN_CTX_free(new_ctx);
427 return ret;
428}
429
430
431/* Precomputation for point multiplication: fall back to wNAF methods
432 * because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */
433
434int
435ec_GF2m_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
436{
437 return ec_wNAF_precompute_mult(group, ctx);
438}
439
440int
441ec_GF2m_have_precompute_mult(const EC_GROUP * group)
442{
443 return ec_wNAF_have_precompute_mult(group);
444}
445
446#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 c0ef6f40e4..0000000000
--- a/src/lib/libcrypto/ec/ec_asn1.c
+++ /dev/null
@@ -1,1312 +0,0 @@
1/* $OpenBSD: ec_asn1.c,v 1.12 2015/02/10 05:43:09 jsing 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 */
201ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
202 ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
203 ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
204 ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
205} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
206
207DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
208
209X9_62_PENTANOMIAL *
210X9_62_PENTANOMIAL_new(void)
211{
212 return (X9_62_PENTANOMIAL*)ASN1_item_new(&X9_62_PENTANOMIAL_it);
213}
214
215void
216X9_62_PENTANOMIAL_free(X9_62_PENTANOMIAL *a)
217{
218 ASN1_item_free((ASN1_VALUE *)a, &X9_62_PENTANOMIAL_it);
219}
220
221ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
222
223ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
224 ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
225 ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
226 ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
227} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
228
229ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
230 ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
231 ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
232 ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
233} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
234DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
235
236X9_62_CHARACTERISTIC_TWO *
237X9_62_CHARACTERISTIC_TWO_new(void)
238{
239 return (X9_62_CHARACTERISTIC_TWO*)ASN1_item_new(&X9_62_CHARACTERISTIC_TWO_it);
240}
241
242void
243X9_62_CHARACTERISTIC_TWO_free(X9_62_CHARACTERISTIC_TWO *a)
244{
245 ASN1_item_free((ASN1_VALUE *)a, &X9_62_CHARACTERISTIC_TWO_it);
246}
247ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
248
249ASN1_ADB(X9_62_FIELDID) = {
250 ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
251 ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
252} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
253
254ASN1_SEQUENCE(X9_62_FIELDID) = {
255 ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
256 ASN1_ADB_OBJECT(X9_62_FIELDID)
257} ASN1_SEQUENCE_END(X9_62_FIELDID)
258
259ASN1_SEQUENCE(X9_62_CURVE) = {
260 ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
261 ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
262 ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
263} ASN1_SEQUENCE_END(X9_62_CURVE)
264
265ASN1_SEQUENCE(ECPARAMETERS) = {
266 ASN1_SIMPLE(ECPARAMETERS, version, LONG),
267 ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
268 ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
269 ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
270 ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
271 ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
272} ASN1_SEQUENCE_END(ECPARAMETERS)
273DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
274
275ECPARAMETERS *
276ECPARAMETERS_new(void)
277{
278 return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it);
279}
280
281void
282ECPARAMETERS_free(ECPARAMETERS *a)
283{
284 ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it);
285}
286
287ASN1_CHOICE(ECPKPARAMETERS) = {
288 ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
289 ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
290 ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
291} ASN1_CHOICE_END(ECPKPARAMETERS)
292DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
293DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
294
295ECPKPARAMETERS *
296d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len)
297{
298 return (ECPKPARAMETERS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
299 &ECPKPARAMETERS_it);
300}
301
302int
303i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out)
304{
305 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it);
306}
307
308ECPKPARAMETERS *
309ECPKPARAMETERS_new(void)
310{
311 return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it);
312}
313
314void
315ECPKPARAMETERS_free(ECPKPARAMETERS *a)
316{
317 ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it);
318}
319
320ASN1_SEQUENCE(EC_PRIVATEKEY) = {
321 ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
322 ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
323 ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
324 ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
325} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
326DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
327DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
328
329EC_PRIVATEKEY *
330d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len)
331{
332 return (EC_PRIVATEKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
333 &EC_PRIVATEKEY_it);
334}
335
336int
337i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out)
338{
339 return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it);
340}
341
342EC_PRIVATEKEY *
343EC_PRIVATEKEY_new(void)
344{
345 return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it);
346}
347
348void
349EC_PRIVATEKEY_free(EC_PRIVATEKEY *a)
350{
351 ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it);
352}
353/* some declarations of internal function */
354
355/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
356static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
357/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
358static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
359/* ec_asn1_parameters2group() creates a EC_GROUP object from a
360 * ECPARAMETERS object */
361static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
362/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a
363 * EC_GROUP object */
364static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, ECPARAMETERS *);
365/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
366 * ECPKPARAMETERS object */
367static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
368/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
369 * EC_GROUP object */
370static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
371 ECPKPARAMETERS *);
372
373
374/* the function definitions */
375
376static int
377ec_asn1_group2fieldid(const EC_GROUP * group, X9_62_FIELDID * field)
378{
379 int ok = 0, nid;
380 BIGNUM *tmp = NULL;
381
382 if (group == NULL || field == NULL)
383 return 0;
384
385 /* clear the old values (if necessary) */
386 if (field->fieldType != NULL)
387 ASN1_OBJECT_free(field->fieldType);
388 if (field->p.other != NULL)
389 ASN1_TYPE_free(field->p.other);
390
391 nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
392 /* set OID for the field */
393 if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
394 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
395 goto err;
396 }
397 if (nid == NID_X9_62_prime_field) {
398 if ((tmp = BN_new()) == NULL) {
399 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
400 goto err;
401 }
402 /* the parameters are specified by the prime number p */
403 if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) {
404 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
405 goto err;
406 }
407 /* set the prime number */
408 field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
409 if (field->p.prime == NULL) {
410 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
411 goto err;
412 }
413 } else /* nid == NID_X9_62_characteristic_two_field */
414#ifdef OPENSSL_NO_EC2M
415 {
416 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
417 goto err;
418 }
419#else
420 {
421 int field_type;
422 X9_62_CHARACTERISTIC_TWO *char_two;
423
424 field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
425 char_two = field->p.char_two;
426
427 if (char_two == NULL) {
428 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
429 goto err;
430 }
431 char_two->m = (long) EC_GROUP_get_degree(group);
432
433 field_type = EC_GROUP_get_basis_type(group);
434
435 if (field_type == 0) {
436 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
437 goto err;
438 }
439 /* set base type OID */
440 if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
441 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
442 goto err;
443 }
444 if (field_type == NID_X9_62_tpBasis) {
445 unsigned int k;
446
447 if (!EC_GROUP_get_trinomial_basis(group, &k))
448 goto err;
449
450 char_two->p.tpBasis = ASN1_INTEGER_new();
451 if (!char_two->p.tpBasis) {
452 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
453 goto err;
454 }
455 if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long) k)) {
456 ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
457 ERR_R_ASN1_LIB);
458 goto err;
459 }
460 } else if (field_type == NID_X9_62_ppBasis) {
461 unsigned int k1, k2, k3;
462
463 if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
464 goto err;
465
466 char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
467 if (!char_two->p.ppBasis) {
468 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
469 goto err;
470 }
471 /* set k? values */
472 char_two->p.ppBasis->k1 = (long) k1;
473 char_two->p.ppBasis->k2 = (long) k2;
474 char_two->p.ppBasis->k3 = (long) k3;
475 } else { /* field_type == NID_X9_62_onBasis */
476 /* for ONB the parameters are (asn1) NULL */
477 char_two->p.onBasis = ASN1_NULL_new();
478 if (!char_two->p.onBasis) {
479 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
480 goto err;
481 }
482 }
483 }
484#endif
485
486 ok = 1;
487
488err:
489 BN_free(tmp);
490 return (ok);
491}
492
493static int
494ec_asn1_group2curve(const EC_GROUP * group, X9_62_CURVE * curve)
495{
496 int ok = 0, nid;
497 BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
498 unsigned char *buffer_1 = NULL, *buffer_2 = NULL, *a_buf = NULL,
499 *b_buf = NULL;
500 size_t len_1, len_2;
501 unsigned char char_zero = 0;
502
503 if (!group || !curve || !curve->a || !curve->b)
504 return 0;
505
506 if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
507 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
508 goto err;
509 }
510 nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
511
512 /* get a and b */
513 if (nid == NID_X9_62_prime_field) {
514 if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) {
515 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
516 goto err;
517 }
518 }
519#ifndef OPENSSL_NO_EC2M
520 else { /* nid == NID_X9_62_characteristic_two_field */
521 if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) {
522 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
523 goto err;
524 }
525 }
526#endif
527 len_1 = (size_t) BN_num_bytes(tmp_1);
528 len_2 = (size_t) BN_num_bytes(tmp_2);
529
530 if (len_1 == 0) {
531 /* len_1 == 0 => a == 0 */
532 a_buf = &char_zero;
533 len_1 = 1;
534 } else {
535 if ((buffer_1 = malloc(len_1)) == NULL) {
536 ECerr(EC_F_EC_ASN1_GROUP2CURVE,
537 ERR_R_MALLOC_FAILURE);
538 goto err;
539 }
540 if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
541 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
542 goto err;
543 }
544 a_buf = buffer_1;
545 }
546
547 if (len_2 == 0) {
548 /* len_2 == 0 => b == 0 */
549 b_buf = &char_zero;
550 len_2 = 1;
551 } else {
552 if ((buffer_2 = malloc(len_2)) == NULL) {
553 ECerr(EC_F_EC_ASN1_GROUP2CURVE,
554 ERR_R_MALLOC_FAILURE);
555 goto err;
556 }
557 if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
558 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
559 goto err;
560 }
561 b_buf = buffer_2;
562 }
563
564 /* set a and b */
565 if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
566 !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) {
567 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
568 goto err;
569 }
570 /* set the seed (optional) */
571 if (group->seed) {
572 if (!curve->seed)
573 if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
574 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
575 goto err;
576 }
577 curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
578 curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
579 if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
580 (int) group->seed_len)) {
581 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
582 goto err;
583 }
584 } else {
585 if (curve->seed) {
586 ASN1_BIT_STRING_free(curve->seed);
587 curve->seed = NULL;
588 }
589 }
590
591 ok = 1;
592
593err:
594 free(buffer_1);
595 free(buffer_2);
596 BN_free(tmp_1);
597 BN_free(tmp_2);
598 return (ok);
599}
600
601static ECPARAMETERS *
602ec_asn1_group2parameters(const EC_GROUP * group, ECPARAMETERS * param)
603{
604 int ok = 0;
605 size_t len = 0;
606 ECPARAMETERS *ret = NULL;
607 BIGNUM *tmp = NULL;
608 unsigned char *buffer = NULL;
609 const EC_POINT *point = NULL;
610 point_conversion_form_t form;
611
612 if ((tmp = BN_new()) == NULL) {
613 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
614 goto err;
615 }
616 if (param == NULL) {
617 if ((ret = ECPARAMETERS_new()) == NULL) {
618 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS,
619 ERR_R_MALLOC_FAILURE);
620 goto err;
621 }
622 } else
623 ret = param;
624
625 /* set the version (always one) */
626 ret->version = (long) 0x1;
627
628 /* set the fieldID */
629 if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
630 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
631 goto err;
632 }
633 /* set the curve */
634 if (!ec_asn1_group2curve(group, ret->curve)) {
635 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
636 goto err;
637 }
638 /* set the base point */
639 if ((point = EC_GROUP_get0_generator(group)) == NULL) {
640 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
641 goto err;
642 }
643 form = EC_GROUP_get_point_conversion_form(group);
644
645 len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
646 if (len == 0) {
647 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
648 goto err;
649 }
650 if ((buffer = malloc(len)) == NULL) {
651 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
652 goto err;
653 }
654 if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) {
655 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
656 goto err;
657 }
658 if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
659 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
660 goto err;
661 }
662 if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) {
663 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
664 goto err;
665 }
666 /* set the order */
667 if (!EC_GROUP_get_order(group, tmp, NULL)) {
668 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
669 goto err;
670 }
671 ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
672 if (ret->order == NULL) {
673 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
674 goto err;
675 }
676 /* set the cofactor (optional) */
677 if (EC_GROUP_get_cofactor(group, tmp, NULL)) {
678 ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
679 if (ret->cofactor == NULL) {
680 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
681 goto err;
682 }
683 }
684 ok = 1;
685
686err: if (!ok) {
687 if (ret && !param)
688 ECPARAMETERS_free(ret);
689 ret = NULL;
690 }
691 BN_free(tmp);
692 free(buffer);
693 return (ret);
694}
695
696ECPKPARAMETERS *
697ec_asn1_group2pkparameters(const EC_GROUP * group, ECPKPARAMETERS * params)
698{
699 int ok = 1, tmp;
700 ECPKPARAMETERS *ret = params;
701
702 if (ret == NULL) {
703 if ((ret = ECPKPARAMETERS_new()) == NULL) {
704 ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS,
705 ERR_R_MALLOC_FAILURE);
706 return NULL;
707 }
708 } else {
709 if (ret->type == 0 && ret->value.named_curve)
710 ASN1_OBJECT_free(ret->value.named_curve);
711 else if (ret->type == 1 && ret->value.parameters)
712 ECPARAMETERS_free(ret->value.parameters);
713 }
714
715 if (EC_GROUP_get_asn1_flag(group)) {
716 /*
717 * use the asn1 OID to describe the the elliptic curve
718 * parameters
719 */
720 tmp = EC_GROUP_get_curve_name(group);
721 if (tmp) {
722 ret->type = 0;
723 if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
724 ok = 0;
725 } else
726 /* we don't kmow the nid => ERROR */
727 ok = 0;
728 } else {
729 /* use the ECPARAMETERS structure */
730 ret->type = 1;
731 if ((ret->value.parameters = ec_asn1_group2parameters(
732 group, NULL)) == NULL)
733 ok = 0;
734 }
735
736 if (!ok) {
737 ECPKPARAMETERS_free(ret);
738 return NULL;
739 }
740 return ret;
741}
742
743static EC_GROUP *
744ec_asn1_parameters2group(const ECPARAMETERS * params)
745{
746 int ok = 0, tmp;
747 EC_GROUP *ret = NULL;
748 BIGNUM *p = NULL, *a = NULL, *b = NULL;
749 EC_POINT *point = NULL;
750 long field_bits;
751
752 if (!params->fieldID || !params->fieldID->fieldType ||
753 !params->fieldID->p.ptr) {
754 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
755 goto err;
756 }
757 /* now extract the curve parameters a and b */
758 if (!params->curve || !params->curve->a ||
759 !params->curve->a->data || !params->curve->b ||
760 !params->curve->b->data) {
761 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
762 goto err;
763 }
764 a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
765 if (a == NULL) {
766 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
767 goto err;
768 }
769 b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
770 if (b == NULL) {
771 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
772 goto err;
773 }
774 /* get the field parameters */
775 tmp = OBJ_obj2nid(params->fieldID->fieldType);
776 if (tmp == NID_X9_62_characteristic_two_field)
777#ifdef OPENSSL_NO_EC2M
778 {
779 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
780 goto err;
781 }
782#else
783 {
784 X9_62_CHARACTERISTIC_TWO *char_two;
785
786 char_two = params->fieldID->p.char_two;
787
788 field_bits = char_two->m;
789 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
790 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
791 goto err;
792 }
793 if ((p = BN_new()) == NULL) {
794 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
795 goto err;
796 }
797 /* get the base type */
798 tmp = OBJ_obj2nid(char_two->type);
799
800 if (tmp == NID_X9_62_tpBasis) {
801 long tmp_long;
802
803 if (!char_two->p.tpBasis) {
804 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
805 goto err;
806 }
807 tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
808
809 if (!(char_two->m > tmp_long && tmp_long > 0)) {
810 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
811 goto err;
812 }
813 /* create the polynomial */
814 if (!BN_set_bit(p, (int) char_two->m))
815 goto err;
816 if (!BN_set_bit(p, (int) tmp_long))
817 goto err;
818 if (!BN_set_bit(p, 0))
819 goto err;
820 } else if (tmp == NID_X9_62_ppBasis) {
821 X9_62_PENTANOMIAL *penta;
822
823 penta = char_two->p.ppBasis;
824 if (!penta) {
825 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
826 goto err;
827 }
828 if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0)) {
829 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
830 goto err;
831 }
832 /* create the polynomial */
833 if (!BN_set_bit(p, (int) char_two->m))
834 goto err;
835 if (!BN_set_bit(p, (int) penta->k1))
836 goto err;
837 if (!BN_set_bit(p, (int) penta->k2))
838 goto err;
839 if (!BN_set_bit(p, (int) penta->k3))
840 goto err;
841 if (!BN_set_bit(p, 0))
842 goto err;
843 } else if (tmp == NID_X9_62_onBasis) {
844 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
845 goto err;
846 } else { /* error */
847 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
848 goto err;
849 }
850
851 /* create the EC_GROUP structure */
852 ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
853 }
854#endif
855 else if (tmp == NID_X9_62_prime_field) {
856 /* we have a curve over a prime field */
857 /* extract the prime number */
858 if (!params->fieldID->p.prime) {
859 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
860 goto err;
861 }
862 p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
863 if (p == NULL) {
864 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
865 goto err;
866 }
867 if (BN_is_negative(p) || BN_is_zero(p)) {
868 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
869 goto err;
870 }
871 field_bits = BN_num_bits(p);
872 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
873 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
874 goto err;
875 }
876 /* create the EC_GROUP structure */
877 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
878 } else {
879 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
880 goto err;
881 }
882
883 if (ret == NULL) {
884 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
885 goto err;
886 }
887 /* extract seed (optional) */
888 if (params->curve->seed != NULL) {
889 free(ret->seed);
890 if (!(ret->seed = malloc(params->curve->seed->length))) {
891 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
892 ERR_R_MALLOC_FAILURE);
893 goto err;
894 }
895 memcpy(ret->seed, params->curve->seed->data,
896 params->curve->seed->length);
897 ret->seed_len = params->curve->seed->length;
898 }
899 if (!params->order || !params->base || !params->base->data) {
900 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
901 goto err;
902 }
903 if ((point = EC_POINT_new(ret)) == NULL)
904 goto err;
905
906 /* set the point conversion form */
907 EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
908 (params->base->data[0] & ~0x01));
909
910 /* extract the ec point */
911 if (!EC_POINT_oct2point(ret, point, params->base->data,
912 params->base->length, NULL)) {
913 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
914 goto err;
915 }
916 /* extract the order */
917 if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
918 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
919 goto err;
920 }
921 if (BN_is_negative(a) || BN_is_zero(a)) {
922 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
923 goto err;
924 }
925 if (BN_num_bits(a) > (int) field_bits + 1) { /* Hasse bound */
926 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
927 goto err;
928 }
929 /* extract the cofactor (optional) */
930 if (params->cofactor == NULL) {
931 BN_free(b);
932 b = NULL;
933 } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
934 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
935 goto err;
936 }
937 /* set the generator, order and cofactor (if present) */
938 if (!EC_GROUP_set_generator(ret, point, a, b)) {
939 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
940 goto err;
941 }
942 ok = 1;
943
944err: if (!ok) {
945 EC_GROUP_clear_free(ret);
946 ret = NULL;
947 }
948 BN_free(p);
949 BN_free(a);
950 BN_free(b);
951 EC_POINT_free(point);
952 return (ret);
953}
954
955EC_GROUP *
956ec_asn1_pkparameters2group(const ECPKPARAMETERS * params)
957{
958 EC_GROUP *ret = NULL;
959 int tmp = 0;
960
961 if (params == NULL) {
962 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
963 EC_R_MISSING_PARAMETERS);
964 return NULL;
965 }
966 if (params->type == 0) {/* the curve is given by an OID */
967 tmp = OBJ_obj2nid(params->value.named_curve);
968 if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
969 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
970 EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
971 return NULL;
972 }
973 EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
974 } else if (params->type == 1) { /* the parameters are given by a
975 * ECPARAMETERS structure */
976 ret = ec_asn1_parameters2group(params->value.parameters);
977 if (!ret) {
978 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
979 return NULL;
980 }
981 EC_GROUP_set_asn1_flag(ret, 0x0);
982 } else if (params->type == 2) { /* implicitlyCA */
983 return NULL;
984 } else {
985 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
986 return NULL;
987 }
988
989 return ret;
990}
991
992/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
993
994EC_GROUP *
995d2i_ECPKParameters(EC_GROUP ** a, const unsigned char **in, long len)
996{
997 EC_GROUP *group = NULL;
998 ECPKPARAMETERS *params = NULL;
999
1000 if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
1001 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1002 ECPKPARAMETERS_free(params);
1003 return NULL;
1004 }
1005 if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
1006 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1007 ECPKPARAMETERS_free(params);
1008 return NULL;
1009 }
1010 if (a && *a)
1011 EC_GROUP_clear_free(*a);
1012 if (a)
1013 *a = group;
1014
1015 ECPKPARAMETERS_free(params);
1016 return (group);
1017}
1018
1019int
1020i2d_ECPKParameters(const EC_GROUP * a, unsigned char **out)
1021{
1022 int ret = 0;
1023 ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
1024 if (tmp == NULL) {
1025 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1026 return 0;
1027 }
1028 if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
1029 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1030 ECPKPARAMETERS_free(tmp);
1031 return 0;
1032 }
1033 ECPKPARAMETERS_free(tmp);
1034 return (ret);
1035}
1036
1037/* some EC_KEY functions */
1038
1039EC_KEY *
1040d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len)
1041{
1042 int ok = 0;
1043 EC_KEY *ret = NULL;
1044 EC_PRIVATEKEY *priv_key = NULL;
1045
1046 if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1047 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1048 return NULL;
1049 }
1050 if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL) {
1051 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1052 EC_PRIVATEKEY_free(priv_key);
1053 return NULL;
1054 }
1055 if (a == NULL || *a == NULL) {
1056 if ((ret = EC_KEY_new()) == NULL) {
1057 ECerr(EC_F_D2I_ECPRIVATEKEY,
1058 ERR_R_MALLOC_FAILURE);
1059 goto err;
1060 }
1061 if (a)
1062 *a = ret;
1063 } else
1064 ret = *a;
1065
1066 if (priv_key->parameters) {
1067 EC_GROUP_clear_free(ret->group);
1068 ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1069 }
1070 if (ret->group == NULL) {
1071 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1072 goto err;
1073 }
1074 ret->version = priv_key->version;
1075
1076 if (priv_key->privateKey) {
1077 ret->priv_key = BN_bin2bn(
1078 M_ASN1_STRING_data(priv_key->privateKey),
1079 M_ASN1_STRING_length(priv_key->privateKey),
1080 ret->priv_key);
1081 if (ret->priv_key == NULL) {
1082 ECerr(EC_F_D2I_ECPRIVATEKEY,
1083 ERR_R_BN_LIB);
1084 goto err;
1085 }
1086 } else {
1087 ECerr(EC_F_D2I_ECPRIVATEKEY,
1088 EC_R_MISSING_PRIVATE_KEY);
1089 goto err;
1090 }
1091
1092 if (priv_key->publicKey) {
1093 const unsigned char *pub_oct;
1094 size_t pub_oct_len;
1095
1096 EC_POINT_clear_free(ret->pub_key);
1097 ret->pub_key = EC_POINT_new(ret->group);
1098 if (ret->pub_key == NULL) {
1099 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1100 goto err;
1101 }
1102 pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
1103 pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1104 /* save the point conversion form */
1105 ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01);
1106 if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1107 pub_oct, pub_oct_len, NULL)) {
1108 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1109 goto err;
1110 }
1111 }
1112 ok = 1;
1113err:
1114 if (!ok) {
1115 if (ret)
1116 EC_KEY_free(ret);
1117 ret = NULL;
1118 }
1119 if (priv_key)
1120 EC_PRIVATEKEY_free(priv_key);
1121
1122 return (ret);
1123}
1124
1125int
1126i2d_ECPrivateKey(EC_KEY * a, unsigned char **out)
1127{
1128 int ret = 0, ok = 0;
1129 unsigned char *buffer = NULL;
1130 size_t buf_len = 0, tmp_len;
1131 EC_PRIVATEKEY *priv_key = NULL;
1132
1133 if (a == NULL || a->group == NULL || a->priv_key == NULL) {
1134 ECerr(EC_F_I2D_ECPRIVATEKEY,
1135 ERR_R_PASSED_NULL_PARAMETER);
1136 goto err;
1137 }
1138 if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1139 ECerr(EC_F_I2D_ECPRIVATEKEY,
1140 ERR_R_MALLOC_FAILURE);
1141 goto err;
1142 }
1143 priv_key->version = a->version;
1144
1145 buf_len = (size_t) BN_num_bytes(a->priv_key);
1146 buffer = malloc(buf_len);
1147 if (buffer == NULL) {
1148 ECerr(EC_F_I2D_ECPRIVATEKEY,
1149 ERR_R_MALLOC_FAILURE);
1150 goto err;
1151 }
1152 if (!BN_bn2bin(a->priv_key, buffer)) {
1153 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1154 goto err;
1155 }
1156 if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
1157 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1158 goto err;
1159 }
1160 if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
1161 if ((priv_key->parameters = ec_asn1_group2pkparameters(
1162 a->group, priv_key->parameters)) == NULL) {
1163 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1164 goto err;
1165 }
1166 }
1167 if (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key != NULL) {
1168 priv_key->publicKey = M_ASN1_BIT_STRING_new();
1169 if (priv_key->publicKey == NULL) {
1170 ECerr(EC_F_I2D_ECPRIVATEKEY,
1171 ERR_R_MALLOC_FAILURE);
1172 goto err;
1173 }
1174 tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1175 a->conv_form, NULL, 0, NULL);
1176
1177 if (tmp_len > buf_len) {
1178 unsigned char *tmp_buffer = realloc(buffer, tmp_len);
1179 if (!tmp_buffer) {
1180 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1181 goto err;
1182 }
1183 buffer = tmp_buffer;
1184 buf_len = tmp_len;
1185 }
1186 if (!EC_POINT_point2oct(a->group, a->pub_key,
1187 a->conv_form, buffer, buf_len, NULL)) {
1188 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1189 goto err;
1190 }
1191 priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
1192 priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1193 if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer,
1194 buf_len)) {
1195 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1196 goto err;
1197 }
1198 }
1199 if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
1200 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1201 goto err;
1202 }
1203 ok = 1;
1204err:
1205 free(buffer);
1206 if (priv_key)
1207 EC_PRIVATEKEY_free(priv_key);
1208 return (ok ? ret : 0);
1209}
1210
1211int
1212i2d_ECParameters(EC_KEY * a, unsigned char **out)
1213{
1214 if (a == NULL) {
1215 ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1216 return 0;
1217 }
1218 return i2d_ECPKParameters(a->group, out);
1219}
1220
1221EC_KEY *
1222d2i_ECParameters(EC_KEY ** a, const unsigned char **in, long len)
1223{
1224 EC_KEY *ret;
1225
1226 if (in == NULL || *in == NULL) {
1227 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1228 return NULL;
1229 }
1230 if (a == NULL || *a == NULL) {
1231 if ((ret = EC_KEY_new()) == NULL) {
1232 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1233 return NULL;
1234 }
1235 if (a)
1236 *a = ret;
1237 } else
1238 ret = *a;
1239
1240 if (!d2i_ECPKParameters(&ret->group, in, len)) {
1241 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1242 return NULL;
1243 }
1244 return ret;
1245}
1246
1247EC_KEY *
1248o2i_ECPublicKey(EC_KEY ** a, const unsigned char **in, long len)
1249{
1250 EC_KEY *ret = NULL;
1251
1252 if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
1253 /*
1254 * sorry, but a EC_GROUP-structur is necessary to set the
1255 * public key
1256 */
1257 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1258 return 0;
1259 }
1260 ret = *a;
1261 if (ret->pub_key == NULL &&
1262 (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
1263 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1264 return 0;
1265 }
1266 if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) {
1267 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1268 return 0;
1269 }
1270 /* save the point conversion form */
1271 ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01);
1272 *in += len;
1273 return ret;
1274}
1275
1276int
1277i2o_ECPublicKey(EC_KEY * a, unsigned char **out)
1278{
1279 size_t buf_len = 0;
1280 int new_buffer = 0;
1281
1282 if (a == NULL) {
1283 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1284 return 0;
1285 }
1286 buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1287 a->conv_form, NULL, 0, NULL);
1288
1289 if (out == NULL || buf_len == 0)
1290 /* out == NULL => just return the length of the octet string */
1291 return buf_len;
1292
1293 if (*out == NULL) {
1294 if ((*out = malloc(buf_len)) == NULL) {
1295 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1296 return 0;
1297 }
1298 new_buffer = 1;
1299 }
1300 if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1301 *out, buf_len, NULL)) {
1302 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1303 if (new_buffer) {
1304 free(*out);
1305 *out = NULL;
1306 }
1307 return 0;
1308 }
1309 if (!new_buffer)
1310 *out += buf_len;
1311 return buf_len;
1312}
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 d913867b76..0000000000
--- a/src/lib/libcrypto/ec/ec_curve.c
+++ /dev/null
@@ -1,3287 +0,0 @@
1/* $OpenBSD: ec_curve.c,v 1.11 2015/02/09 01:12:03 doug 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 <openssl/opensslconf.h>
73
74#include "ec_lcl.h"
75#include <openssl/err.h>
76#include <openssl/obj_mac.h>
77
78typedef struct {
79 int field_type, /* either NID_X9_62_prime_field or
80 * NID_X9_62_characteristic_two_field */
81 seed_len, param_len;
82 unsigned int cofactor; /* promoted to BN_ULONG */
83} EC_CURVE_DATA;
84
85/* the nist prime curves */
86static const struct {
87 EC_CURVE_DATA h;
88 unsigned char data[20 + 24 * 6];
89}
90 _EC_NIST_PRIME_192 = {
91 {
92 NID_X9_62_prime_field, 20, 24, 1
93 },
94 {
95 0x30, 0x45, 0xAE, 0x6F, 0xC8, 0x42, 0x2F, 0x64, 0xED, 0x57, /* seed */
96 0x95, 0x28, 0xD3, 0x81, 0x20, 0xEA, 0xE1, 0x21, 0x96, 0xD5,
97
98 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
99 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
100 0xFF, 0xFF, 0xFF, 0xFF,
101 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
102 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
103 0xFF, 0xFF, 0xFF, 0xFC,
104 0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, /* b */
105 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC,
106 0xC1, 0x46, 0xB9, 0xB1,
107 0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, /* x */
108 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD,
109 0x82, 0xFF, 0x10, 0x12,
110 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, /* y */
111 0x11, 0xed, 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1,
112 0x1e, 0x79, 0x48, 0x11,
113 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
114 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1,
115 0xB4, 0xD2, 0x28, 0x31
116 }
117};
118
119static const struct {
120 EC_CURVE_DATA h;
121 unsigned char data[20 + 28 * 6];
122}
123 _EC_NIST_PRIME_224 = {
124 {
125 NID_X9_62_prime_field, 20, 28, 1
126 },
127 {
128 0xBD, 0x71, 0x34, 0x47, 0x99, 0xD5, 0xC7, 0xFC, 0xDC, 0x45, /* seed */
129 0xB5, 0x9F, 0xA3, 0xB9, 0xAB, 0x8F, 0x6A, 0x94, 0x8B, 0xC5,
130
131 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
132 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
134 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
135 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
136 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
137 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
138 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA,
139 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4,
140 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
141 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22,
142 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21,
143 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
144 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
145 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
146 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
147 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E,
148 0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D
149 }
150};
151
152static const struct {
153 EC_CURVE_DATA h;
154 unsigned char data[20 + 48 * 6];
155}
156 _EC_NIST_PRIME_384 = {
157 {
158 NID_X9_62_prime_field, 20, 48, 1
159 },
160 {
161 0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, /* seed */
162 0x89, 0x6A, 0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73,
163
164 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
165 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
166 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
167 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
169 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
170 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
171 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
172 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
174 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, /* b */
175 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E,
176 0xFE, 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13,
177 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D,
178 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
179 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, /* x */
180 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62,
181 0x8B, 0xA7, 0x9B, 0x98, 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54,
182 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C,
183 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
184 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, /* y */
185 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd,
186 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0,
187 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
188 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
189 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
190 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
191 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37,
192 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A,
193 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
194 }
195};
196
197static const struct {
198 EC_CURVE_DATA h;
199 unsigned char data[20 + 66 * 6];
200}
201 _EC_NIST_PRIME_521 = {
202 {
203 NID_X9_62_prime_field, 20, 66, 1
204 },
205 {
206 0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, /* seed */
207 0x67, 0x17, 0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA,
208
209 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
210 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
211 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
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,
216 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
217 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
218 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
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, 0xFC,
223 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, /* b */
224 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA,
225 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91,
226 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E,
227 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 0xBF, 0x07,
228 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
229 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
230 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, /* x */
231 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64,
232 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60,
233 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7,
234 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 0xA8, 0xDE,
235 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
236 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
237 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, /* y */
238 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5,
239 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
240 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
241 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
242 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
243 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
244 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
245 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
246 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
247 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
248 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 0xA5, 0xD0,
249 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
250 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09
251 }
252};
253
254/* the x9.62 prime curves (minus the nist prime curves) */
255static const struct {
256 EC_CURVE_DATA h;
257 unsigned char data[20 + 24 * 6];
258}
259 _EC_X9_62_PRIME_192V2 = {
260 {
261 NID_X9_62_prime_field, 20, 24, 1
262 },
263 {
264 0x31, 0xA9, 0x2E, 0xE2, 0x02, 0x9F, 0xD1, 0x0D, 0x90, 0x1B, /* seed */
265 0x11, 0x3E, 0x99, 0x07, 0x10, 0xF0, 0xD2, 0x1A, 0xC6, 0xB6,
266
267 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
268 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
269 0xFF, 0xFF, 0xFF, 0xFF,
270 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
271 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
272 0xFF, 0xFF, 0xFF, 0xFC,
273 0xCC, 0x22, 0xD6, 0xDF, 0xB9, 0x5C, 0x6B, 0x25, 0xE4, 0x9C, /* b */
274 0x0D, 0x63, 0x64, 0xA4, 0xE5, 0x98, 0x0C, 0x39, 0x3A, 0xA2,
275 0x16, 0x68, 0xD9, 0x53,
276 0xEE, 0xA2, 0xBA, 0xE7, 0xE1, 0x49, 0x78, 0x42, 0xF2, 0xDE, /* x */
277 0x77, 0x69, 0xCF, 0xE9, 0xC9, 0x89, 0xC0, 0x72, 0xAD, 0x69,
278 0x6F, 0x48, 0x03, 0x4A,
279 0x65, 0x74, 0xd1, 0x1d, 0x69, 0xb6, 0xec, 0x7a, 0x67, 0x2b, /* y */
280 0xb8, 0x2a, 0x08, 0x3d, 0xf2, 0xf2, 0xb0, 0x84, 0x7d, 0xe9,
281 0x70, 0xb2, 0xde, 0x15,
282 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
283 0xFF, 0xFE, 0x5F, 0xB1, 0xA7, 0x24, 0xDC, 0x80, 0x41, 0x86,
284 0x48, 0xD8, 0xDD, 0x31
285 }
286};
287
288static const struct {
289 EC_CURVE_DATA h;
290 unsigned char data[20 + 24 * 6];
291}
292 _EC_X9_62_PRIME_192V3 = {
293 {
294 NID_X9_62_prime_field, 20, 24, 1
295 },
296 {
297 0xC4, 0x69, 0x68, 0x44, 0x35, 0xDE, 0xB3, 0x78, 0xC4, 0xB6, /* seed */
298 0x5C, 0xA9, 0x59, 0x1E, 0x2A, 0x57, 0x63, 0x05, 0x9A, 0x2E,
299
300 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
301 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
302 0xFF, 0xFF, 0xFF, 0xFF,
303 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
304 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
305 0xFF, 0xFF, 0xFF, 0xFC,
306 0x22, 0x12, 0x3D, 0xC2, 0x39, 0x5A, 0x05, 0xCA, 0xA7, 0x42, /* b */
307 0x3D, 0xAE, 0xCC, 0xC9, 0x47, 0x60, 0xA7, 0xD4, 0x62, 0x25,
308 0x6B, 0xD5, 0x69, 0x16,
309 0x7D, 0x29, 0x77, 0x81, 0x00, 0xC6, 0x5A, 0x1D, 0xA1, 0x78, /* x */
310 0x37, 0x16, 0x58, 0x8D, 0xCE, 0x2B, 0x8B, 0x4A, 0xEE, 0x8E,
311 0x22, 0x8F, 0x18, 0x96,
312 0x38, 0xa9, 0x0f, 0x22, 0x63, 0x73, 0x37, 0x33, 0x4b, 0x49, /* y */
313 0xdc, 0xb6, 0x6a, 0x6d, 0xc8, 0xf9, 0x97, 0x8a, 0xca, 0x76,
314 0x48, 0xa9, 0x43, 0xb0,
315 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
316 0xFF, 0xFF, 0x7A, 0x62, 0xD0, 0x31, 0xC8, 0x3F, 0x42, 0x94,
317 0xF6, 0x40, 0xEC, 0x13
318 }
319};
320
321static const struct {
322 EC_CURVE_DATA h;
323 unsigned char data[20 + 30 * 6];
324}
325 _EC_X9_62_PRIME_239V1 = {
326 {
327 NID_X9_62_prime_field, 20, 30, 1
328 },
329 {
330 0xE4, 0x3B, 0xB4, 0x60, 0xF0, 0xB8, 0x0C, 0xC0, 0xC0, 0xB0, /* seed */
331 0x75, 0x79, 0x8E, 0x94, 0x80, 0x60, 0xF8, 0x32, 0x1B, 0x7D,
332
333 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
334 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
336
337 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
338 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
340
341 0x6B, 0x01, 0x6C, 0x3B, 0xDC, 0xF1, 0x89, 0x41, 0xD0, 0xD6, /* b */
342 0x54, 0x92, 0x14, 0x75, 0xCA, 0x71, 0xA9, 0xDB, 0x2F, 0xB2,
343 0x7D, 0x1D, 0x37, 0x79, 0x61, 0x85, 0xC2, 0x94, 0x2C, 0x0A,
344
345 0x0F, 0xFA, 0x96, 0x3C, 0xDC, 0xA8, 0x81, 0x6C, 0xCC, 0x33, /* x */
346 0xB8, 0x64, 0x2B, 0xED, 0xF9, 0x05, 0xC3, 0xD3, 0x58, 0x57,
347 0x3D, 0x3F, 0x27, 0xFB, 0xBD, 0x3B, 0x3C, 0xB9, 0xAA, 0xAF,
348
349 0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40, /* y */
350 0x54, 0xca, 0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18,
351 0xce, 0x22, 0x6b, 0x39, 0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae,
352
353 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
354 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x9E, 0x5E, 0x9A, 0x9F, 0x5D,
355 0x90, 0x71, 0xFB, 0xD1, 0x52, 0x26, 0x88, 0x90, 0x9D, 0x0B
356 }
357};
358
359static const struct {
360 EC_CURVE_DATA h;
361 unsigned char data[20 + 30 * 6];
362}
363 _EC_X9_62_PRIME_239V2 = {
364 {
365 NID_X9_62_prime_field, 20, 30, 1
366 },
367 {
368 0xE8, 0xB4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xCA, 0x3B, /* seed */
369 0x80, 0x99, 0x98, 0x2B, 0xE0, 0x9F, 0xCB, 0x9A, 0xE6, 0x16,
370
371 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
372 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
374
375 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
376 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
378
379 0x61, 0x7F, 0xAB, 0x68, 0x32, 0x57, 0x6C, 0xBB, 0xFE, 0xD5, /* b */
380 0x0D, 0x99, 0xF0, 0x24, 0x9C, 0x3F, 0xEE, 0x58, 0xB9, 0x4B,
381 0xA0, 0x03, 0x8C, 0x7A, 0xE8, 0x4C, 0x8C, 0x83, 0x2F, 0x2C,
382
383 0x38, 0xAF, 0x09, 0xD9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xC9, /* x */
384 0x21, 0xBB, 0x5E, 0x9E, 0x26, 0x29, 0x6A, 0x3C, 0xDC, 0xF2,
385 0xF3, 0x57, 0x57, 0xA0, 0xEA, 0xFD, 0x87, 0xB8, 0x30, 0xE7,
386
387 0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d, /* y */
388 0xa0, 0xfc, 0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55,
389 0xde, 0x6e, 0xf4, 0x60, 0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba,
390
391 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
392 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xCF, 0xA7, 0xE8, 0x59, 0x43,
393 0x77, 0xD4, 0x14, 0xC0, 0x38, 0x21, 0xBC, 0x58, 0x20, 0x63
394 }
395};
396
397static const struct {
398 EC_CURVE_DATA h;
399 unsigned char data[20 + 30 * 6];
400}
401 _EC_X9_62_PRIME_239V3 = {
402 {
403 NID_X9_62_prime_field, 20, 30, 1
404 },
405 {
406 0x7D, 0x73, 0x74, 0x16, 0x8F, 0xFE, 0x34, 0x71, 0xB6, 0x0A, /* seed */
407 0x85, 0x76, 0x86, 0xA1, 0x94, 0x75, 0xD3, 0xBF, 0xA2, 0xFF,
408
409 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
410 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
412
413 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
414 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
416
417 0x25, 0x57, 0x05, 0xFA, 0x2A, 0x30, 0x66, 0x54, 0xB1, 0xF4, /* b */
418 0xCB, 0x03, 0xD6, 0xA7, 0x50, 0xA3, 0x0C, 0x25, 0x01, 0x02,
419 0xD4, 0x98, 0x87, 0x17, 0xD9, 0xBA, 0x15, 0xAB, 0x6D, 0x3E,
420
421 0x67, 0x68, 0xAE, 0x8E, 0x18, 0xBB, 0x92, 0xCF, 0xCF, 0x00, /* x */
422 0x5C, 0x94, 0x9A, 0xA2, 0xC6, 0xD9, 0x48, 0x53, 0xD0, 0xE6,
423 0x60, 0xBB, 0xF8, 0x54, 0xB1, 0xC9, 0x50, 0x5F, 0xE9, 0x5A,
424
425 0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d, /* y */
426 0x55, 0x2b, 0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b,
427 0x6e, 0x81, 0x84, 0x99, 0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3,
428
429 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
430 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x97, 0x5D, 0xEB, 0x41, 0xB3,
431 0xA6, 0x05, 0x7C, 0x3C, 0x43, 0x21, 0x46, 0x52, 0x65, 0x51
432 }
433};
434
435
436static const struct {
437 EC_CURVE_DATA h;
438 unsigned char data[20 + 32 * 6];
439}
440 _EC_X9_62_PRIME_256V1 = {
441 {
442 NID_X9_62_prime_field, 20, 32, 1
443 },
444 {
445 0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, /* seed */
446 0x78, 0xE1, 0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90,
447
448 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* p */
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
451 0xFF, 0xFF,
452 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* a */
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
455 0xFF, 0xFC,
456 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, /* b */
457 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0,
458 0xCC, 0x53, 0xB0, 0xF6, 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2,
459 0x60, 0x4B,
460 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, /* x */
461 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81,
462 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98,
463 0xC2, 0x96,
464 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, /* y */
465 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
466 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf,
467 0x51, 0xf5,
468 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, /* order */
469 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD,
470 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63,
471 0x25, 0x51
472 }
473};
474
475/* the secg prime curves (minus the nist and x9.62 prime curves) */
476static const struct {
477 EC_CURVE_DATA h;
478 unsigned char data[20 + 14 * 6];
479}
480 _EC_SECG_PRIME_112R1 = {
481 {
482 NID_X9_62_prime_field, 20, 14, 1
483 },
484 {
485 0x00, 0xF5, 0x0B, 0x02, 0x8E, 0x4D, 0x69, 0x6E, 0x67, 0x68, /* seed */
486 0x75, 0x61, 0x51, 0x75, 0x29, 0x04, 0x72, 0x78, 0x3F, 0xB1,
487
488 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, /* p */
489 0xBE, 0xAD, 0x20, 0x8B,
490 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, /* a */
491 0xBE, 0xAD, 0x20, 0x88,
492 0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, /* b */
493 0x11, 0x70, 0x2B, 0x22,
494 0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, /* x */
495 0xF9, 0xC2, 0xF0, 0x98,
496 0xa8, 0x9c, 0xe5, 0xaf, 0x87, 0x24, 0xc0, 0xa2, 0x3e, 0x0e, /* y */
497 0x0f, 0xf7, 0x75, 0x00,
498 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, /* order */
499 0xAC, 0x65, 0x61, 0xC5
500 }
501};
502
503static const struct {
504 EC_CURVE_DATA h;
505 unsigned char data[20 + 14 * 6];
506}
507 _EC_SECG_PRIME_112R2 = {
508 {
509 NID_X9_62_prime_field, 20, 14, 4
510 },
511 {
512 0x00, 0x27, 0x57, 0xA1, 0x11, 0x4D, 0x69, 0x6E, 0x67, 0x68, /* seed */
513 0x75, 0x61, 0x51, 0x75, 0x53, 0x16, 0xC0, 0x5E, 0x0B, 0xD4,
514
515 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, /* p */
516 0xBE, 0xAD, 0x20, 0x8B,
517 0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, /* a */
518 0x5C, 0x0E, 0xF0, 0x2C,
519 0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, /* b */
520 0x4C, 0x85, 0xD7, 0x09,
521 0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, /* x */
522 0xD0, 0x92, 0x86, 0x43,
523 0xad, 0xcd, 0x46, 0xf5, 0x88, 0x2e, 0x37, 0x47, 0xde, 0xf3, /* y */
524 0x6e, 0x95, 0x6e, 0x97,
525 0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, /* order */
526 0x05, 0x20, 0xD0, 0x4B
527 }
528};
529
530static const struct {
531 EC_CURVE_DATA h;
532 unsigned char data[20 + 16 * 6];
533}
534 _EC_SECG_PRIME_128R1 = {
535 {
536 NID_X9_62_prime_field, 20, 16, 1
537 },
538 {
539 0x00, 0x0E, 0x0D, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, /* seed */
540 0x51, 0x75, 0x0C, 0xC0, 0x3A, 0x44, 0x73, 0xD0, 0x36, 0x79,
541
542 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
543 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
544 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
545 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
546 0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, /* b */
547 0x99, 0x3C, 0x2C, 0xEE, 0x5E, 0xD3,
548 0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, /* x */
549 0x60, 0x7C, 0xA5, 0x2C, 0x5B, 0x86,
550 0xcf, 0x5a, 0xc8, 0x39, 0x5b, 0xaf, 0xeb, 0x13, 0xc0, 0x2d, /* y */
551 0xa2, 0x92, 0xdd, 0xed, 0x7a, 0x83,
552 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, /* order */
553 0x0D, 0x1B, 0x90, 0x38, 0xA1, 0x15
554 }
555};
556
557static const struct {
558 EC_CURVE_DATA h;
559 unsigned char data[20 + 16 * 6];
560}
561 _EC_SECG_PRIME_128R2 = {
562 {
563 NID_X9_62_prime_field, 20, 16, 4
564 },
565 {
566 0x00, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, /* seed */
567 0x12, 0xD8, 0xF0, 0x34, 0x31, 0xFC, 0xE6, 0x3B, 0x88, 0xF4,
568
569 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
570 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
571 0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, /* a */
572 0xCC, 0x9B, 0xBF, 0xF9, 0xAE, 0xE1,
573 0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, /* b */
574 0x65, 0x58, 0xBB, 0x6D, 0x8A, 0x5D,
575 0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, /* x */
576 0x32, 0xA7, 0xCD, 0xEB, 0xC1, 0x40,
577 0x27, 0xb6, 0x91, 0x6a, 0x89, 0x4d, 0x3a, 0xee, 0x71, 0x06, /* y */
578 0xfe, 0x80, 0x5f, 0xc3, 0x4b, 0x44,
579 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, /* order */
580 0x24, 0x72, 0x06, 0x13, 0xB5, 0xA3
581 }
582};
583
584static const struct {
585 EC_CURVE_DATA h;
586 unsigned char data[0 + 21 * 6];
587}
588 _EC_SECG_PRIME_160K1 = {
589 {
590 NID_X9_62_prime_field, 0, 21, 1
591 },
592 { /* no seed */
593 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
594 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC,
595 0x73,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x07,
602 0x00, 0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, /* x */
603 0x01, 0x9E, 0x76, 0x30, 0x36, 0xF4, 0xF5, 0xDD, 0x4D, 0x7E,
604 0xBB,
605 0x00, 0x93, 0x8c, 0xf9, 0x35, 0x31, 0x8f, 0xdc, 0xed, 0x6b, /* y */
606 0xc2, 0x82, 0x86, 0x53, 0x17, 0x33, 0xc3, 0xf0, 0x3c, 0x4f,
607 0xee,
608 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
609 0x01, 0xB8, 0xFA, 0x16, 0xDF, 0xAB, 0x9A, 0xCA, 0x16, 0xB6,
610 0xB3
611 }
612};
613
614static const struct {
615 EC_CURVE_DATA h;
616 unsigned char data[20 + 21 * 6];
617}
618 _EC_SECG_PRIME_160R1 = {
619 {
620 NID_X9_62_prime_field, 20, 21, 1
621 },
622 {
623 0x10, 0x53, 0xCD, 0xE4, 0x2C, 0x14, 0xD6, 0x96, 0xE6, 0x76, /* seed */
624 0x87, 0x56, 0x15, 0x17, 0x53, 0x3B, 0xF3, 0xF8, 0x33, 0x45,
625
626 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
627 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
628 0xFF,
629 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
630 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
631 0xFC,
632 0x00, 0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, /* b */
633 0xAC, 0xF8, 0x9F, 0x81, 0xD4, 0xD4, 0xAD, 0xC5, 0x65, 0xFA,
634 0x45,
635 0x00, 0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, /* x */
636 0x64, 0x69, 0x89, 0x68, 0xC3, 0x8B, 0xB9, 0x13, 0xCB, 0xFC,
637 0x82,
638 0x00, 0x23, 0xa6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7d, 0x59, /* y */
639 0xdc, 0xc9, 0x12, 0x04, 0x23, 0x51, 0x37, 0x7a, 0xc5, 0xfb,
640 0x32,
641 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
642 0x01, 0xF4, 0xC8, 0xF9, 0x27, 0xAE, 0xD3, 0xCA, 0x75, 0x22,
643 0x57
644 }
645};
646
647static const struct {
648 EC_CURVE_DATA h;
649 unsigned char data[20 + 21 * 6];
650}
651 _EC_SECG_PRIME_160R2 = {
652 {
653 NID_X9_62_prime_field, 20, 21, 1
654 },
655 {
656 0xB9, 0x9B, 0x99, 0xB0, 0x99, 0xB3, 0x23, 0xE0, 0x27, 0x09, /* seed */
657 0xA4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51,
658
659 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
660 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC,
661 0x73,
662 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
663 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC,
664 0x70,
665 0x00, 0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, /* b */
666 0x57, 0x27, 0x49, 0x04, 0x66, 0x4D, 0x5A, 0xF5, 0x03, 0x88,
667 0xBA,
668 0x00, 0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, /* x */
669 0x4F, 0xF1, 0x1B, 0x30, 0xF7, 0x19, 0x9D, 0x31, 0x44, 0xCE,
670 0x6D,
671 0x00, 0xfe, 0xaf, 0xfe, 0xf2, 0xe3, 0x31, 0xf2, 0x96, 0xe0, /* y */
672 0x71, 0xfa, 0x0d, 0xf9, 0x98, 0x2c, 0xfe, 0xa7, 0xd4, 0x3f,
673 0x2e,
674 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
675 0x00, 0x35, 0x1E, 0xE7, 0x86, 0xA8, 0x18, 0xF3, 0xA1, 0xA1,
676 0x6B
677 }
678};
679
680static const struct {
681 EC_CURVE_DATA h;
682 unsigned char data[0 + 24 * 6];
683}
684 _EC_SECG_PRIME_192K1 = {
685 {
686 NID_X9_62_prime_field, 0, 24, 1
687 },
688 { /* no seed */
689 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
690 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
691 0xFF, 0xFF, 0xEE, 0x37,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x03,
698 0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, /* x */
699 0x7D, 0x02, 0x80, 0xB7, 0xF4, 0x34, 0x1D, 0xA5, 0xD1, 0xB1,
700 0xEA, 0xE0, 0x6C, 0x7D,
701 0x9b, 0x2f, 0x2f, 0x6d, 0x9c, 0x56, 0x28, 0xa7, 0x84, 0x41, /* y */
702 0x63, 0xd0, 0x15, 0xbe, 0x86, 0x34, 0x40, 0x82, 0xaa, 0x88,
703 0xd9, 0x5e, 0x2f, 0x9d,
704 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
705 0xFF, 0xFE, 0x26, 0xF2, 0xFC, 0x17, 0x0F, 0x69, 0x46, 0x6A,
706 0x74, 0xDE, 0xFD, 0x8D
707 }
708};
709
710static const struct {
711 EC_CURVE_DATA h;
712 unsigned char data[0 + 29 * 6];
713}
714 _EC_SECG_PRIME_224K1 = {
715 {
716 NID_X9_62_prime_field, 0, 29, 1
717 },
718 { /* no seed */
719 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
720 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
721 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE5, 0x6D,
722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
728 0x00, 0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, /* x */
729 0xFC, 0x28, 0xA1, 0x69, 0xA4, 0x67, 0xE9, 0xE4, 0x70, 0x75,
730 0xA9, 0x0F, 0x7E, 0x65, 0x0E, 0xB6, 0xB7, 0xA4, 0x5C,
731 0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82, /* y */
732 0xca, 0xfb, 0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd,
733 0x59, 0xe2, 0xca, 0x4b, 0xdb, 0x55, 0x6d, 0x61, 0xa5,
734 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
735 0x00, 0x00, 0x00, 0x00, 0x01, 0xDC, 0xE8, 0xD2, 0xEC, 0x61,
736 0x84, 0xCA, 0xF0, 0xA9, 0x71, 0x76, 0x9F, 0xB1, 0xF7
737 }
738};
739
740static const struct {
741 EC_CURVE_DATA h;
742 unsigned char data[0 + 32 * 6];
743}
744 _EC_SECG_PRIME_256K1 = {
745 {
746 NID_X9_62_prime_field, 0, 32, 1
747 },
748 { /* no seed */
749 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
750 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
751 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
752 0xFC, 0x2F,
753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756 0x00, 0x00,
757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760 0x00, 0x07,
761 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, /* x */
762 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB,
763 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8,
764 0x17, 0x98,
765 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, /* y */
766 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48,
767 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10,
768 0xd4, 0xb8,
769 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
770 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6,
771 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36,
772 0x41, 0x41
773 }
774};
775
776/* some wap/wtls curves */
777static const struct {
778 EC_CURVE_DATA h;
779 unsigned char data[0 + 15 * 6];
780}
781 _EC_WTLS_8 = {
782 {
783 NID_X9_62_prime_field, 0, 15, 1
784 },
785 { /* no seed */
786 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
787 0xFF, 0xFF, 0xFF, 0xFD, 0xE7,
788 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
789 0x00, 0x00, 0x00, 0x00, 0x00,
790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
791 0x00, 0x00, 0x00, 0x00, 0x03,
792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
793 0x00, 0x00, 0x00, 0x00, 0x01,
794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* y */
795 0x00, 0x00, 0x00, 0x00, 0x02,
796 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEC, 0xEA, /* order */
797 0x55, 0x1A, 0xD8, 0x37, 0xE9
798 }
799};
800
801static const struct {
802 EC_CURVE_DATA h;
803 unsigned char data[0 + 21 * 6];
804}
805 _EC_WTLS_9 = {
806 {
807 NID_X9_62_prime_field, 0, 21, 1
808 },
809 { /* no seed */
810 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
811 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80,
812 0x8F,
813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
815 0x00,
816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
818 0x03,
819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
821 0x01,
822 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* y */
823 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
824 0x02,
825 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
826 0x01, 0xCD, 0xC9, 0x8A, 0xE0, 0xE2, 0xDE, 0x57, 0x4A, 0xBF,
827 0x33
828 }
829};
830
831static const struct {
832 EC_CURVE_DATA h;
833 unsigned char data[0 + 28 * 6];
834}
835 _EC_WTLS_12 = {
836 {
837 NID_X9_62_prime_field, 0, 28, 1
838 },
839 { /* no seed */
840 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
841 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
843 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
844 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
845 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
846 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
847 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA,
848 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4,
849 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
850 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22,
851 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21,
852 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
853 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
854 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
855 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
856 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E,
857 0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D
858 }
859};
860
861#ifndef OPENSSL_NO_EC2M
862
863/* characteristic two curves */
864static const struct {
865 EC_CURVE_DATA h;
866 unsigned char data[20 + 15 * 6];
867}
868 _EC_SECG_CHAR2_113R1 = {
869 {
870 NID_X9_62_characteristic_two_field, 20, 15, 2
871 },
872 {
873 0x10, 0xE7, 0x23, 0xAB, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, /* seed */
874 0x56, 0x15, 0x17, 0x56, 0xFE, 0xBF, 0x8F, 0xCB, 0x49, 0xA9,
875
876 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
877 0x00, 0x00, 0x00, 0x02, 0x01,
878 0x00, 0x30, 0x88, 0x25, 0x0C, 0xA6, 0xE7, 0xC7, 0xFE, 0x64, /* a */
879 0x9C, 0xE8, 0x58, 0x20, 0xF7,
880 0x00, 0xE8, 0xBE, 0xE4, 0xD3, 0xE2, 0x26, 0x07, 0x44, 0x18, /* b */
881 0x8B, 0xE0, 0xE9, 0xC7, 0x23,
882 0x00, 0x9D, 0x73, 0x61, 0x6F, 0x35, 0xF4, 0xAB, 0x14, 0x07, /* x */
883 0xD7, 0x35, 0x62, 0xC1, 0x0F,
884 0x00, 0xA5, 0x28, 0x30, 0x27, 0x79, 0x58, 0xEE, 0x84, 0xD1, /* y */
885 0x31, 0x5E, 0xD3, 0x18, 0x86,
886 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xCC, /* order */
887 0xEC, 0x8A, 0x39, 0xE5, 0x6F
888 }
889};
890
891static const struct {
892 EC_CURVE_DATA h;
893 unsigned char data[20 + 15 * 6];
894}
895 _EC_SECG_CHAR2_113R2 = {
896 {
897 NID_X9_62_characteristic_two_field, 20, 15, 2
898 },
899 {
900 0x10, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, /* seed */
901 0xF4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x5D,
902
903 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
904 0x00, 0x00, 0x00, 0x02, 0x01,
905 0x00, 0x68, 0x99, 0x18, 0xDB, 0xEC, 0x7E, 0x5A, 0x0D, 0xD6, /* a */
906 0xDF, 0xC0, 0xAA, 0x55, 0xC7,
907 0x00, 0x95, 0xE9, 0xA9, 0xEC, 0x9B, 0x29, 0x7B, 0xD4, 0xBF, /* b */
908 0x36, 0xE0, 0x59, 0x18, 0x4F,
909 0x01, 0xA5, 0x7A, 0x6A, 0x7B, 0x26, 0xCA, 0x5E, 0xF5, 0x2F, /* x */
910 0xCD, 0xB8, 0x16, 0x47, 0x97,
911 0x00, 0xB3, 0xAD, 0xC9, 0x4E, 0xD1, 0xFE, 0x67, 0x4C, 0x06, /* y */
912 0xE6, 0x95, 0xBA, 0xBA, 0x1D,
913 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x78, /* order */
914 0x9B, 0x24, 0x96, 0xAF, 0x93
915 }
916};
917
918static const struct {
919 EC_CURVE_DATA h;
920 unsigned char data[20 + 17 * 6];
921}
922 _EC_SECG_CHAR2_131R1 = {
923 {
924 NID_X9_62_characteristic_two_field, 20, 17, 2
925 },
926 {
927 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x98, /* seed */
928 0x5B, 0xD3, 0xAD, 0xBA, 0xDA, 0x21, 0xB4, 0x3A, 0x97, 0xE2,
929
930 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
931 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0D,
932 0x07, 0xA1, 0x1B, 0x09, 0xA7, 0x6B, 0x56, 0x21, 0x44, 0x41, /* a */
933 0x8F, 0xF3, 0xFF, 0x8C, 0x25, 0x70, 0xB8,
934 0x02, 0x17, 0xC0, 0x56, 0x10, 0x88, 0x4B, 0x63, 0xB9, 0xC6, /* b */
935 0xC7, 0x29, 0x16, 0x78, 0xF9, 0xD3, 0x41,
936 0x00, 0x81, 0xBA, 0xF9, 0x1F, 0xDF, 0x98, 0x33, 0xC4, 0x0F, /* x */
937 0x9C, 0x18, 0x13, 0x43, 0x63, 0x83, 0x99,
938 0x07, 0x8C, 0x6E, 0x7E, 0xA3, 0x8C, 0x00, 0x1F, 0x73, 0xC8, /* y */
939 0x13, 0x4B, 0x1B, 0x4E, 0xF9, 0xE1, 0x50,
940 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, /* order */
941 0x23, 0x95, 0x3A, 0x94, 0x64, 0xB5, 0x4D
942 }
943};
944
945static const struct {
946 EC_CURVE_DATA h;
947 unsigned char data[20 + 17 * 6];
948}
949 _EC_SECG_CHAR2_131R2 = {
950 {
951 NID_X9_62_characteristic_two_field, 20, 17, 2
952 },
953 {
954 0x98, 0x5B, 0xD3, 0xAD, 0xBA, 0xD4, 0xD6, 0x96, 0xE6, 0x76, /* seed */
955 0x87, 0x56, 0x15, 0x17, 0x5A, 0x21, 0xB4, 0x3A, 0x97, 0xE3,
956
957 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
958 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0D,
959 0x03, 0xE5, 0xA8, 0x89, 0x19, 0xD7, 0xCA, 0xFC, 0xBF, 0x41, /* a */
960 0x5F, 0x07, 0xC2, 0x17, 0x65, 0x73, 0xB2,
961 0x04, 0xB8, 0x26, 0x6A, 0x46, 0xC5, 0x56, 0x57, 0xAC, 0x73, /* b */
962 0x4C, 0xE3, 0x8F, 0x01, 0x8F, 0x21, 0x92,
963 0x03, 0x56, 0xDC, 0xD8, 0xF2, 0xF9, 0x50, 0x31, 0xAD, 0x65, /* x */
964 0x2D, 0x23, 0x95, 0x1B, 0xB3, 0x66, 0xA8,
965 0x06, 0x48, 0xF0, 0x6D, 0x86, 0x79, 0x40, 0xA5, 0x36, 0x6D, /* y */
966 0x9E, 0x26, 0x5D, 0xE9, 0xEB, 0x24, 0x0F,
967 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, /* order */
968 0x54, 0xA2, 0x33, 0x04, 0x9B, 0xA9, 0x8F
969 }
970};
971
972static const struct {
973 EC_CURVE_DATA h;
974 unsigned char data[0 + 21 * 6];
975}
976 _EC_NIST_CHAR2_163K = {
977 {
978 NID_X9_62_characteristic_two_field, 0, 21, 2
979 },
980 { /* no seed */
981 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
982 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
983 0xC9,
984 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
985 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
986 0x01,
987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
988 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
989 0x01,
990 0x02, 0xFE, 0x13, 0xC0, 0x53, 0x7B, 0xBC, 0x11, 0xAC, 0xAA, /* x */
991 0x07, 0xD7, 0x93, 0xDE, 0x4E, 0x6D, 0x5E, 0x5C, 0x94, 0xEE,
992 0xE8,
993 0x02, 0x89, 0x07, 0x0F, 0xB0, 0x5D, 0x38, 0xFF, 0x58, 0x32, /* y */
994 0x1F, 0x2E, 0x80, 0x05, 0x36, 0xD5, 0x38, 0xCC, 0xDA, 0xA3,
995 0xD9,
996 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
997 0x02, 0x01, 0x08, 0xA2, 0xE0, 0xCC, 0x0D, 0x99, 0xF8, 0xA5,
998 0xEF
999 }
1000};
1001
1002static const struct {
1003 EC_CURVE_DATA h;
1004 unsigned char data[0 + 21 * 6];
1005}
1006 _EC_SECG_CHAR2_163R1 = {
1007 {
1008 NID_X9_62_characteristic_two_field, 0, 21, 2
1009 },
1010 { /* no seed */
1011 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1012 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1013 0xC9,
1014 0x07, 0xB6, 0x88, 0x2C, 0xAA, 0xEF, 0xA8, 0x4F, 0x95, 0x54, /* a */
1015 0xFF, 0x84, 0x28, 0xBD, 0x88, 0xE2, 0x46, 0xD2, 0x78, 0x2A,
1016 0xE2,
1017 0x07, 0x13, 0x61, 0x2D, 0xCD, 0xDC, 0xB4, 0x0A, 0xAB, 0x94, /* b */
1018 0x6B, 0xDA, 0x29, 0xCA, 0x91, 0xF7, 0x3A, 0xF9, 0x58, 0xAF,
1019 0xD9,
1020 0x03, 0x69, 0x97, 0x96, 0x97, 0xAB, 0x43, 0x89, 0x77, 0x89, /* x */
1021 0x56, 0x67, 0x89, 0x56, 0x7F, 0x78, 0x7A, 0x78, 0x76, 0xA6,
1022 0x54,
1023 0x00, 0x43, 0x5E, 0xDB, 0x42, 0xEF, 0xAF, 0xB2, 0x98, 0x9D, /* y */
1024 0x51, 0xFE, 0xFC, 0xE3, 0xC8, 0x09, 0x88, 0xF4, 0x1F, 0xF8,
1025 0x83,
1026 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1027 0xFF, 0x48, 0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27,
1028 0x9B
1029 }
1030};
1031
1032static const struct {
1033 EC_CURVE_DATA h;
1034 unsigned char data[0 + 21 * 6];
1035}
1036 _EC_NIST_CHAR2_163B = {
1037 {
1038 NID_X9_62_characteristic_two_field, 0, 21, 2
1039 },
1040 { /* no seed */
1041 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1042 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1043 0xC9,
1044 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1045 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1046 0x01,
1047 0x02, 0x0A, 0x60, 0x19, 0x07, 0xB8, 0xC9, 0x53, 0xCA, 0x14, /* b */
1048 0x81, 0xEB, 0x10, 0x51, 0x2F, 0x78, 0x74, 0x4A, 0x32, 0x05,
1049 0xFD,
1050 0x03, 0xF0, 0xEB, 0xA1, 0x62, 0x86, 0xA2, 0xD5, 0x7E, 0xA0, /* x */
1051 0x99, 0x11, 0x68, 0xD4, 0x99, 0x46, 0x37, 0xE8, 0x34, 0x3E,
1052 0x36,
1053 0x00, 0xD5, 0x1F, 0xBC, 0x6C, 0x71, 0xA0, 0x09, 0x4F, 0xA2, /* y */
1054 0xCD, 0xD5, 0x45, 0xB1, 0x1C, 0x5C, 0x0C, 0x79, 0x73, 0x24,
1055 0xF1,
1056 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1057 0x02, 0x92, 0xFE, 0x77, 0xE7, 0x0C, 0x12, 0xA4, 0x23, 0x4C,
1058 0x33
1059 }
1060};
1061
1062static const struct {
1063 EC_CURVE_DATA h;
1064 unsigned char data[20 + 25 * 6];
1065}
1066 _EC_SECG_CHAR2_193R1 = {
1067 {
1068 NID_X9_62_characteristic_two_field, 20, 25, 2
1069 },
1070 {
1071 0x10, 0x3F, 0xAE, 0xC7, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, /* seed */
1072 0x61, 0x51, 0x75, 0x77, 0x7F, 0xC5, 0xB1, 0x91, 0xEF, 0x30,
1073
1074 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1075 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1076 0x00, 0x00, 0x00, 0x80, 0x01,
1077 0x00, 0x17, 0x85, 0x8F, 0xEB, 0x7A, 0x98, 0x97, 0x51, 0x69, /* a */
1078 0xE1, 0x71, 0xF7, 0x7B, 0x40, 0x87, 0xDE, 0x09, 0x8A, 0xC8,
1079 0xA9, 0x11, 0xDF, 0x7B, 0x01,
1080 0x00, 0xFD, 0xFB, 0x49, 0xBF, 0xE6, 0xC3, 0xA8, 0x9F, 0xAC, /* b */
1081 0xAD, 0xAA, 0x7A, 0x1E, 0x5B, 0xBC, 0x7C, 0xC1, 0xC2, 0xE5,
1082 0xD8, 0x31, 0x47, 0x88, 0x14,
1083 0x01, 0xF4, 0x81, 0xBC, 0x5F, 0x0F, 0xF8, 0x4A, 0x74, 0xAD, /* x */
1084 0x6C, 0xDF, 0x6F, 0xDE, 0xF4, 0xBF, 0x61, 0x79, 0x62, 0x53,
1085 0x72, 0xD8, 0xC0, 0xC5, 0xE1,
1086 0x00, 0x25, 0xE3, 0x99, 0xF2, 0x90, 0x37, 0x12, 0xCC, 0xF3, /* y */
1087 0xEA, 0x9E, 0x3A, 0x1A, 0xD1, 0x7F, 0xB0, 0xB3, 0x20, 0x1B,
1088 0x6A, 0xF7, 0xCE, 0x1B, 0x05,
1089 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1090 0x00, 0x00, 0x00, 0xC7, 0xF3, 0x4A, 0x77, 0x8F, 0x44, 0x3A,
1091 0xCC, 0x92, 0x0E, 0xBA, 0x49
1092 }
1093};
1094
1095static const struct {
1096 EC_CURVE_DATA h;
1097 unsigned char data[20 + 25 * 6];
1098}
1099 _EC_SECG_CHAR2_193R2 = {
1100 {
1101 NID_X9_62_characteristic_two_field, 20, 25, 2
1102 },
1103 {
1104 0x10, 0xB7, 0xB4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, /* seed */
1105 0x17, 0x51, 0x37, 0xC8, 0xA1, 0x6F, 0xD0, 0xDA, 0x22, 0x11,
1106
1107 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109 0x00, 0x00, 0x00, 0x80, 0x01,
1110 0x01, 0x63, 0xF3, 0x5A, 0x51, 0x37, 0xC2, 0xCE, 0x3E, 0xA6, /* a */
1111 0xED, 0x86, 0x67, 0x19, 0x0B, 0x0B, 0xC4, 0x3E, 0xCD, 0x69,
1112 0x97, 0x77, 0x02, 0x70, 0x9B,
1113 0x00, 0xC9, 0xBB, 0x9E, 0x89, 0x27, 0xD4, 0xD6, 0x4C, 0x37, /* b */
1114 0x7E, 0x2A, 0xB2, 0x85, 0x6A, 0x5B, 0x16, 0xE3, 0xEF, 0xB7,
1115 0xF6, 0x1D, 0x43, 0x16, 0xAE,
1116 0x00, 0xD9, 0xB6, 0x7D, 0x19, 0x2E, 0x03, 0x67, 0xC8, 0x03, /* x */
1117 0xF3, 0x9E, 0x1A, 0x7E, 0x82, 0xCA, 0x14, 0xA6, 0x51, 0x35,
1118 0x0A, 0xAE, 0x61, 0x7E, 0x8F,
1119 0x01, 0xCE, 0x94, 0x33, 0x56, 0x07, 0xC3, 0x04, 0xAC, 0x29, /* y */
1120 0xE7, 0xDE, 0xFB, 0xD9, 0xCA, 0x01, 0xF5, 0x96, 0xF9, 0x27,
1121 0x22, 0x4C, 0xDE, 0xCF, 0x6C,
1122 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1123 0x00, 0x00, 0x01, 0x5A, 0xAB, 0x56, 0x1B, 0x00, 0x54, 0x13,
1124 0xCC, 0xD4, 0xEE, 0x99, 0xD5
1125 }
1126};
1127
1128static const struct {
1129 EC_CURVE_DATA h;
1130 unsigned char data[0 + 30 * 6];
1131}
1132 _EC_NIST_CHAR2_233K = {
1133 {
1134 NID_X9_62_characteristic_two_field, 0, 30, 4
1135 },
1136 { /* no seed */
1137 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1139 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1140
1141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1144
1145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1148
1149 0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, /* x */
1150 0x29, 0xF2, 0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2,
1151 0x6B, 0xF5, 0x0A, 0x4C, 0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
1152
1153 0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, /* y */
1154 0x55, 0x5A, 0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A,
1155 0xEB, 0x9B, 0x56, 0xE0, 0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3,
1156
1157 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1158 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15,
1159 0xBC, 0xD4, 0x6E, 0xFB, 0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
1160 }
1161};
1162
1163static const struct {
1164 EC_CURVE_DATA h;
1165 unsigned char data[20 + 30 * 6];
1166}
1167 _EC_NIST_CHAR2_233B = {
1168 {
1169 NID_X9_62_characteristic_two_field, 20, 30, 2
1170 },
1171 {
1172 0x74, 0xD5, 0x9F, 0xF0, 0x7F, 0x6B, 0x41, 0x3D, 0x0E, 0xA1, /* seed */
1173 0x4B, 0x34, 0x4B, 0x20, 0xA2, 0xDB, 0x04, 0x9B, 0x50, 0xC3,
1174
1175 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1177 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1178
1179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1182
1183 0x00, 0x66, 0x64, 0x7E, 0xDE, 0x6C, 0x33, 0x2C, 0x7F, 0x8C, /* b */
1184 0x09, 0x23, 0xBB, 0x58, 0x21, 0x3B, 0x33, 0x3B, 0x20, 0xE9,
1185 0xCE, 0x42, 0x81, 0xFE, 0x11, 0x5F, 0x7D, 0x8F, 0x90, 0xAD,
1186
1187 0x00, 0xFA, 0xC9, 0xDF, 0xCB, 0xAC, 0x83, 0x13, 0xBB, 0x21, /* x */
1188 0x39, 0xF1, 0xBB, 0x75, 0x5F, 0xEF, 0x65, 0xBC, 0x39, 0x1F,
1189 0x8B, 0x36, 0xF8, 0xF8, 0xEB, 0x73, 0x71, 0xFD, 0x55, 0x8B,
1190
1191 0x01, 0x00, 0x6A, 0x08, 0xA4, 0x19, 0x03, 0x35, 0x06, 0x78, /* y */
1192 0xE5, 0x85, 0x28, 0xBE, 0xBF, 0x8A, 0x0B, 0xEF, 0xF8, 0x67,
1193 0xA7, 0xCA, 0x36, 0x71, 0x6F, 0x7E, 0x01, 0xF8, 0x10, 0x52,
1194
1195 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1196 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F,
1197 0x8A, 0x69, 0x22, 0x03, 0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7
1198 }
1199};
1200
1201static const struct {
1202 EC_CURVE_DATA h;
1203 unsigned char data[0 + 30 * 6];
1204}
1205 _EC_SECG_CHAR2_239K1 = {
1206 {
1207 NID_X9_62_characteristic_two_field, 0, 30, 4
1208 },
1209 { /* no seed */
1210 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1211 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1213
1214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1217
1218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1221
1222 0x29, 0xA0, 0xB6, 0xA8, 0x87, 0xA9, 0x83, 0xE9, 0x73, 0x09, /* x */
1223 0x88, 0xA6, 0x87, 0x27, 0xA8, 0xB2, 0xD1, 0x26, 0xC4, 0x4C,
1224 0xC2, 0xCC, 0x7B, 0x2A, 0x65, 0x55, 0x19, 0x30, 0x35, 0xDC,
1225
1226 0x76, 0x31, 0x08, 0x04, 0xF1, 0x2E, 0x54, 0x9B, 0xDB, 0x01, /* y */
1227 0x1C, 0x10, 0x30, 0x89, 0xE7, 0x35, 0x10, 0xAC, 0xB2, 0x75,
1228 0xFC, 0x31, 0x2A, 0x5D, 0xC6, 0xB7, 0x65, 0x53, 0xF0, 0xCA,
1229
1230 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1231 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0x79, 0xFE, 0xC6, 0x7C,
1232 0xB6, 0xE9, 0x1F, 0x1C, 0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5
1233 }
1234};
1235
1236static const struct {
1237 EC_CURVE_DATA h;
1238 unsigned char data[0 + 36 * 6];
1239}
1240 _EC_NIST_CHAR2_283K = {
1241 {
1242 NID_X9_62_characteristic_two_field, 0, 36, 4
1243 },
1244 { /* no seed */
1245 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1248 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
1249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1256 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1257 0x05, 0x03, 0x21, 0x3F, 0x78, 0xCA, 0x44, 0x88, 0x3F, 0x1A, /* x */
1258 0x3B, 0x81, 0x62, 0xF1, 0x88, 0xE5, 0x53, 0xCD, 0x26, 0x5F,
1259 0x23, 0xC1, 0x56, 0x7A, 0x16, 0x87, 0x69, 0x13, 0xB0, 0xC2,
1260 0xAC, 0x24, 0x58, 0x49, 0x28, 0x36,
1261 0x01, 0xCC, 0xDA, 0x38, 0x0F, 0x1C, 0x9E, 0x31, 0x8D, 0x90, /* y */
1262 0xF9, 0x5D, 0x07, 0xE5, 0x42, 0x6F, 0xE8, 0x7E, 0x45, 0xC0,
1263 0xE8, 0x18, 0x46, 0x98, 0xE4, 0x59, 0x62, 0x36, 0x4E, 0x34,
1264 0x11, 0x61, 0x77, 0xDD, 0x22, 0x59,
1265 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1266 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xAE,
1267 0x2E, 0xD0, 0x75, 0x77, 0x26, 0x5D, 0xFF, 0x7F, 0x94, 0x45,
1268 0x1E, 0x06, 0x1E, 0x16, 0x3C, 0x61
1269 }
1270};
1271
1272static const struct {
1273 EC_CURVE_DATA h;
1274 unsigned char data[20 + 36 * 6];
1275}
1276 _EC_NIST_CHAR2_283B = {
1277 {
1278 NID_X9_62_characteristic_two_field, 20, 36, 2
1279 },
1280 {
1281 0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D, /* no seed */
1282 0xD5, 0xB6, 0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE,
1283
1284 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1287 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
1288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1291 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1292 0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, /* b */
1293 0xAF, 0x8A, 0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76,
1294 0x45, 0x30, 0x9F, 0xA2, 0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26,
1295 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5,
1296 0x05, 0xF9, 0x39, 0x25, 0x8D, 0xB7, 0xDD, 0x90, 0xE1, 0x93, /* x */
1297 0x4F, 0x8C, 0x70, 0xB0, 0xDF, 0xEC, 0x2E, 0xED, 0x25, 0xB8,
1298 0x55, 0x7E, 0xAC, 0x9C, 0x80, 0xE2, 0xE1, 0x98, 0xF8, 0xCD,
1299 0xBE, 0xCD, 0x86, 0xB1, 0x20, 0x53,
1300 0x03, 0x67, 0x68, 0x54, 0xFE, 0x24, 0x14, 0x1C, 0xB9, 0x8F, /* y */
1301 0xE6, 0xD4, 0xB2, 0x0D, 0x02, 0xB4, 0x51, 0x6F, 0xF7, 0x02,
1302 0x35, 0x0E, 0xDD, 0xB0, 0x82, 0x67, 0x79, 0xC8, 0x13, 0xF0,
1303 0xDF, 0x45, 0xBE, 0x81, 0x12, 0xF4,
1304 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1305 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x90,
1306 0x39, 0x96, 0x60, 0xFC, 0x93, 0x8A, 0x90, 0x16, 0x5B, 0x04,
1307 0x2A, 0x7C, 0xEF, 0xAD, 0xB3, 0x07
1308 }
1309};
1310
1311static const struct {
1312 EC_CURVE_DATA h;
1313 unsigned char data[0 + 52 * 6];
1314}
1315 _EC_NIST_CHAR2_409K = {
1316 {
1317 NID_X9_62_characteristic_two_field, 0, 52, 4
1318 },
1319 { /* no seed */
1320 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1324 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x01,
1326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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,
1332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1337 0x00, 0x01,
1338 0x00, 0x60, 0xF0, 0x5F, 0x65, 0x8F, 0x49, 0xC1, 0xAD, 0x3A, /* x */
1339 0xB1, 0x89, 0x0F, 0x71, 0x84, 0x21, 0x0E, 0xFD, 0x09, 0x87,
1340 0xE3, 0x07, 0xC8, 0x4C, 0x27, 0xAC, 0xCF, 0xB8, 0xF9, 0xF6,
1341 0x7C, 0xC2, 0xC4, 0x60, 0x18, 0x9E, 0xB5, 0xAA, 0xAA, 0x62,
1342 0xEE, 0x22, 0x2E, 0xB1, 0xB3, 0x55, 0x40, 0xCF, 0xE9, 0x02,
1343 0x37, 0x46,
1344 0x01, 0xE3, 0x69, 0x05, 0x0B, 0x7C, 0x4E, 0x42, 0xAC, 0xBA, /* y */
1345 0x1D, 0xAC, 0xBF, 0x04, 0x29, 0x9C, 0x34, 0x60, 0x78, 0x2F,
1346 0x91, 0x8E, 0xA4, 0x27, 0xE6, 0x32, 0x51, 0x65, 0xE9, 0xEA,
1347 0x10, 0xE3, 0xDA, 0x5F, 0x6C, 0x42, 0xE9, 0xC5, 0x52, 0x15,
1348 0xAA, 0x9C, 0xA2, 0x7A, 0x58, 0x63, 0xEC, 0x48, 0xD8, 0xE0,
1349 0x28, 0x6B,
1350 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1351 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1352 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x5F, 0x83, 0xB2,
1353 0xD4, 0xEA, 0x20, 0x40, 0x0E, 0xC4, 0x55, 0x7D, 0x5E, 0xD3,
1354 0xE3, 0xE7, 0xCA, 0x5B, 0x4B, 0x5C, 0x83, 0xB8, 0xE0, 0x1E,
1355 0x5F, 0xCF
1356 }
1357};
1358
1359static const struct {
1360 EC_CURVE_DATA h;
1361 unsigned char data[20 + 52 * 6];
1362}
1363 _EC_NIST_CHAR2_409B = {
1364 {
1365 NID_X9_62_characteristic_two_field, 20, 52, 2
1366 },
1367 {
1368 0x40, 0x99, 0xB5, 0xA4, 0x57, 0xF9, 0xD6, 0x9F, 0x79, 0x21, /* seed */
1369 0x3D, 0x09, 0x4C, 0x4B, 0xCD, 0x4D, 0x42, 0x62, 0x21, 0x0B,
1370
1371 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1375 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1376 0x00, 0x01,
1377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382 0x00, 0x01,
1383 0x00, 0x21, 0xA5, 0xC2, 0xC8, 0xEE, 0x9F, 0xEB, 0x5C, 0x4B, /* b */
1384 0x9A, 0x75, 0x3B, 0x7B, 0x47, 0x6B, 0x7F, 0xD6, 0x42, 0x2E,
1385 0xF1, 0xF3, 0xDD, 0x67, 0x47, 0x61, 0xFA, 0x99, 0xD6, 0xAC,
1386 0x27, 0xC8, 0xA9, 0xA1, 0x97, 0xB2, 0x72, 0x82, 0x2F, 0x6C,
1387 0xD5, 0x7A, 0x55, 0xAA, 0x4F, 0x50, 0xAE, 0x31, 0x7B, 0x13,
1388 0x54, 0x5F,
1389 0x01, 0x5D, 0x48, 0x60, 0xD0, 0x88, 0xDD, 0xB3, 0x49, 0x6B, /* x */
1390 0x0C, 0x60, 0x64, 0x75, 0x62, 0x60, 0x44, 0x1C, 0xDE, 0x4A,
1391 0xF1, 0x77, 0x1D, 0x4D, 0xB0, 0x1F, 0xFE, 0x5B, 0x34, 0xE5,
1392 0x97, 0x03, 0xDC, 0x25, 0x5A, 0x86, 0x8A, 0x11, 0x80, 0x51,
1393 0x56, 0x03, 0xAE, 0xAB, 0x60, 0x79, 0x4E, 0x54, 0xBB, 0x79,
1394 0x96, 0xA7,
1395 0x00, 0x61, 0xB1, 0xCF, 0xAB, 0x6B, 0xE5, 0xF3, 0x2B, 0xBF, /* y */
1396 0xA7, 0x83, 0x24, 0xED, 0x10, 0x6A, 0x76, 0x36, 0xB9, 0xC5,
1397 0xA7, 0xBD, 0x19, 0x8D, 0x01, 0x58, 0xAA, 0x4F, 0x54, 0x88,
1398 0xD0, 0x8F, 0x38, 0x51, 0x4F, 0x1F, 0xDF, 0x4B, 0x4F, 0x40,
1399 0xD2, 0x18, 0x1B, 0x36, 0x81, 0xC3, 0x64, 0xBA, 0x02, 0x73,
1400 0xC7, 0x06,
1401 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE2, 0xAA, 0xD6,
1404 0xA6, 0x12, 0xF3, 0x33, 0x07, 0xBE, 0x5F, 0xA4, 0x7C, 0x3C,
1405 0x9E, 0x05, 0x2F, 0x83, 0x81, 0x64, 0xCD, 0x37, 0xD9, 0xA2,
1406 0x11, 0x73
1407 }
1408};
1409
1410static const struct {
1411 EC_CURVE_DATA h;
1412 unsigned char data[0 + 72 * 6];
1413}
1414 _EC_NIST_CHAR2_571K = {
1415 {
1416 NID_X9_62_characteristic_two_field, 0, 72, 4
1417 },
1418 { /* no seed */
1419 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 0x04, 0x25,
1427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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,
1435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
1436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x01,
1443 0x02, 0x6E, 0xB7, 0xA8, 0x59, 0x92, 0x3F, 0xBC, 0x82, 0x18, /* x */
1444 0x96, 0x31, 0xF8, 0x10, 0x3F, 0xE4, 0xAC, 0x9C, 0xA2, 0x97,
1445 0x00, 0x12, 0xD5, 0xD4, 0x60, 0x24, 0x80, 0x48, 0x01, 0x84,
1446 0x1C, 0xA4, 0x43, 0x70, 0x95, 0x84, 0x93, 0xB2, 0x05, 0xE6,
1447 0x47, 0xDA, 0x30, 0x4D, 0xB4, 0xCE, 0xB0, 0x8C, 0xBB, 0xD1,
1448 0xBA, 0x39, 0x49, 0x47, 0x76, 0xFB, 0x98, 0x8B, 0x47, 0x17,
1449 0x4D, 0xCA, 0x88, 0xC7, 0xE2, 0x94, 0x52, 0x83, 0xA0, 0x1C,
1450 0x89, 0x72,
1451 0x03, 0x49, 0xDC, 0x80, 0x7F, 0x4F, 0xBF, 0x37, 0x4F, 0x4A, /* y */
1452 0xEA, 0xDE, 0x3B, 0xCA, 0x95, 0x31, 0x4D, 0xD5, 0x8C, 0xEC,
1453 0x9F, 0x30, 0x7A, 0x54, 0xFF, 0xC6, 0x1E, 0xFC, 0x00, 0x6D,
1454 0x8A, 0x2C, 0x9D, 0x49, 0x79, 0xC0, 0xAC, 0x44, 0xAE, 0xA7,
1455 0x4F, 0xBE, 0xBB, 0xB9, 0xF7, 0x72, 0xAE, 0xDC, 0xB6, 0x20,
1456 0xB0, 0x1A, 0x7B, 0xA7, 0xAF, 0x1B, 0x32, 0x04, 0x30, 0xC8,
1457 0x59, 0x19, 0x84, 0xF6, 0x01, 0xCD, 0x4C, 0x14, 0x3E, 0xF1,
1458 0xC7, 0xA3,
1459 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x18, 0x50, 0xE1,
1463 0xF1, 0x9A, 0x63, 0xE4, 0xB3, 0x91, 0xA8, 0xDB, 0x91, 0x7F,
1464 0x41, 0x38, 0xB6, 0x30, 0xD8, 0x4B, 0xE5, 0xD6, 0x39, 0x38,
1465 0x1E, 0x91, 0xDE, 0xB4, 0x5C, 0xFE, 0x77, 0x8F, 0x63, 0x7C,
1466 0x10, 0x01
1467 }
1468};
1469
1470static const struct {
1471 EC_CURVE_DATA h;
1472 unsigned char data[20 + 72 * 6];
1473}
1474 _EC_NIST_CHAR2_571B = {
1475 {
1476 NID_X9_62_characteristic_two_field, 20, 72, 2
1477 },
1478 {
1479 0x2A, 0xA0, 0x58, 0xF7, 0x3A, 0x0E, 0x33, 0xAB, 0x48, 0x6B, /* seed */
1480 0x0F, 0x61, 0x04, 0x10, 0xC5, 0x3A, 0x7F, 0x13, 0x23, 0x10,
1481
1482 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 0x04, 0x25,
1490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x01,
1498 0x02, 0xF4, 0x0E, 0x7E, 0x22, 0x21, 0xF2, 0x95, 0xDE, 0x29, /* b */
1499 0x71, 0x17, 0xB7, 0xF3, 0xD6, 0x2F, 0x5C, 0x6A, 0x97, 0xFF,
1500 0xCB, 0x8C, 0xEF, 0xF1, 0xCD, 0x6B, 0xA8, 0xCE, 0x4A, 0x9A,
1501 0x18, 0xAD, 0x84, 0xFF, 0xAB, 0xBD, 0x8E, 0xFA, 0x59, 0x33,
1502 0x2B, 0xE7, 0xAD, 0x67, 0x56, 0xA6, 0x6E, 0x29, 0x4A, 0xFD,
1503 0x18, 0x5A, 0x78, 0xFF, 0x12, 0xAA, 0x52, 0x0E, 0x4D, 0xE7,
1504 0x39, 0xBA, 0xCA, 0x0C, 0x7F, 0xFE, 0xFF, 0x7F, 0x29, 0x55,
1505 0x72, 0x7A,
1506 0x03, 0x03, 0x00, 0x1D, 0x34, 0xB8, 0x56, 0x29, 0x6C, 0x16, /* x */
1507 0xC0, 0xD4, 0x0D, 0x3C, 0xD7, 0x75, 0x0A, 0x93, 0xD1, 0xD2,
1508 0x95, 0x5F, 0xA8, 0x0A, 0xA5, 0xF4, 0x0F, 0xC8, 0xDB, 0x7B,
1509 0x2A, 0xBD, 0xBD, 0xE5, 0x39, 0x50, 0xF4, 0xC0, 0xD2, 0x93,
1510 0xCD, 0xD7, 0x11, 0xA3, 0x5B, 0x67, 0xFB, 0x14, 0x99, 0xAE,
1511 0x60, 0x03, 0x86, 0x14, 0xF1, 0x39, 0x4A, 0xBF, 0xA3, 0xB4,
1512 0xC8, 0x50, 0xD9, 0x27, 0xE1, 0xE7, 0x76, 0x9C, 0x8E, 0xEC,
1513 0x2D, 0x19,
1514 0x03, 0x7B, 0xF2, 0x73, 0x42, 0xDA, 0x63, 0x9B, 0x6D, 0xCC, /* y */
1515 0xFF, 0xFE, 0xB7, 0x3D, 0x69, 0xD7, 0x8C, 0x6C, 0x27, 0xA6,
1516 0x00, 0x9C, 0xBB, 0xCA, 0x19, 0x80, 0xF8, 0x53, 0x39, 0x21,
1517 0xE8, 0xA6, 0x84, 0x42, 0x3E, 0x43, 0xBA, 0xB0, 0x8A, 0x57,
1518 0x62, 0x91, 0xAF, 0x8F, 0x46, 0x1B, 0xB2, 0xA8, 0xB3, 0x53,
1519 0x1D, 0x2F, 0x04, 0x85, 0xC1, 0x9B, 0x16, 0xE2, 0xF1, 0x51,
1520 0x6E, 0x23, 0xDD, 0x3C, 0x1A, 0x48, 0x27, 0xAF, 0x1B, 0x8A,
1521 0xC1, 0x5B,
1522 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1523 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1524 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1525 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x61, 0xCE, 0x18,
1526 0xFF, 0x55, 0x98, 0x73, 0x08, 0x05, 0x9B, 0x18, 0x68, 0x23,
1527 0x85, 0x1E, 0xC7, 0xDD, 0x9C, 0xA1, 0x16, 0x1D, 0xE9, 0x3D,
1528 0x51, 0x74, 0xD6, 0x6E, 0x83, 0x82, 0xE9, 0xBB, 0x2F, 0xE8,
1529 0x4E, 0x47
1530 }
1531};
1532
1533static const struct {
1534 EC_CURVE_DATA h;
1535 unsigned char data[20 + 21 * 6];
1536}
1537 _EC_X9_62_CHAR2_163V1 = {
1538 {
1539 NID_X9_62_characteristic_two_field, 20, 21, 2
1540 },
1541 {
1542 0xD2, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE,
1543 0xF4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x54, /* seed */
1544
1545 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1547 0x07,
1548 0x07, 0x25, 0x46, 0xB5, 0x43, 0x52, 0x34, 0xA4, 0x22, 0xE0, /* a */
1549 0x78, 0x96, 0x75, 0xF4, 0x32, 0xC8, 0x94, 0x35, 0xDE, 0x52,
1550 0x42,
1551 0x00, 0xC9, 0x51, 0x7D, 0x06, 0xD5, 0x24, 0x0D, 0x3C, 0xFF, /* b */
1552 0x38, 0xC7, 0x4B, 0x20, 0xB6, 0xCD, 0x4D, 0x6F, 0x9D, 0xD4,
1553 0xD9,
1554 0x07, 0xAF, 0x69, 0x98, 0x95, 0x46, 0x10, 0x3D, 0x79, 0x32, /* x */
1555 0x9F, 0xCC, 0x3D, 0x74, 0x88, 0x0F, 0x33, 0xBB, 0xE8, 0x03,
1556 0xCB,
1557 0x01, 0xEC, 0x23, 0x21, 0x1B, 0x59, 0x66, 0xAD, 0xEA, 0x1D, /* y */
1558 0x3F, 0x87, 0xF7, 0xEA, 0x58, 0x48, 0xAE, 0xF0, 0xB7, 0xCA,
1559 0x9F,
1560 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1561 0x01, 0xE6, 0x0F, 0xC8, 0x82, 0x1C, 0xC7, 0x4D, 0xAE, 0xAF,
1562 0xC1
1563 }
1564};
1565
1566static const struct {
1567 EC_CURVE_DATA h;
1568 unsigned char data[20 + 21 * 6];
1569}
1570 _EC_X9_62_CHAR2_163V2 = {
1571 {
1572 NID_X9_62_characteristic_two_field, 20, 21, 2
1573 },
1574 {
1575 0x53, 0x81, 0x4C, 0x05, 0x0D, 0x44, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1576 0x87, 0x56, 0x15, 0x17, 0x58, 0x0C, 0xA4, 0xE2, 0x9F, 0xFD,
1577
1578 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1580 0x07,
1581 0x01, 0x08, 0xB3, 0x9E, 0x77, 0xC4, 0xB1, 0x08, 0xBE, 0xD9, /* a */
1582 0x81, 0xED, 0x0E, 0x89, 0x0E, 0x11, 0x7C, 0x51, 0x1C, 0xF0,
1583 0x72,
1584 0x06, 0x67, 0xAC, 0xEB, 0x38, 0xAF, 0x4E, 0x48, 0x8C, 0x40, /* b */
1585 0x74, 0x33, 0xFF, 0xAE, 0x4F, 0x1C, 0x81, 0x16, 0x38, 0xDF,
1586 0x20,
1587 0x00, 0x24, 0x26, 0x6E, 0x4E, 0xB5, 0x10, 0x6D, 0x0A, 0x96, /* x */
1588 0x4D, 0x92, 0xC4, 0x86, 0x0E, 0x26, 0x71, 0xDB, 0x9B, 0x6C,
1589 0xC5,
1590 0x07, 0x9F, 0x68, 0x4D, 0xDF, 0x66, 0x84, 0xC5, 0xCD, 0x25, /* y */
1591 0x8B, 0x38, 0x90, 0x02, 0x1B, 0x23, 0x86, 0xDF, 0xD1, 0x9F,
1592 0xC5,
1593 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1594 0xFD, 0xF6, 0x4D, 0xE1, 0x15, 0x1A, 0xDB, 0xB7, 0x8F, 0x10,
1595 0xA7
1596 }
1597};
1598
1599static const struct {
1600 EC_CURVE_DATA h;
1601 unsigned char data[20 + 21 * 6];
1602}
1603 _EC_X9_62_CHAR2_163V3 = {
1604 {
1605 NID_X9_62_characteristic_two_field, 20, 21, 2
1606 },
1607 {
1608 0x50, 0xCB, 0xF1, 0xD9, 0x5C, 0xA9, 0x4D, 0x69, 0x6E, 0x67, /* seed */
1609 0x68, 0x75, 0x61, 0x51, 0x75, 0xF1, 0x6A, 0x36, 0xA3, 0xB8,
1610
1611 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1613 0x07,
1614 0x07, 0xA5, 0x26, 0xC6, 0x3D, 0x3E, 0x25, 0xA2, 0x56, 0xA0, /* a */
1615 0x07, 0x69, 0x9F, 0x54, 0x47, 0xE3, 0x2A, 0xE4, 0x56, 0xB5,
1616 0x0E,
1617 0x03, 0xF7, 0x06, 0x17, 0x98, 0xEB, 0x99, 0xE2, 0x38, 0xFD, /* b */
1618 0x6F, 0x1B, 0xF9, 0x5B, 0x48, 0xFE, 0xEB, 0x48, 0x54, 0x25,
1619 0x2B,
1620 0x02, 0xF9, 0xF8, 0x7B, 0x7C, 0x57, 0x4D, 0x0B, 0xDE, 0xCF, /* x */
1621 0x8A, 0x22, 0xE6, 0x52, 0x47, 0x75, 0xF9, 0x8C, 0xDE, 0xBD,
1622 0xCB,
1623 0x05, 0xB9, 0x35, 0x59, 0x0C, 0x15, 0x5E, 0x17, 0xEA, 0x48, /* y */
1624 0xEB, 0x3F, 0xF3, 0x71, 0x8B, 0x89, 0x3D, 0xF5, 0x9A, 0x05,
1625 0xD0,
1626 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
1627 0xFE, 0x1A, 0xEE, 0x14, 0x0F, 0x11, 0x0A, 0xFF, 0x96, 0x13,
1628 0x09
1629 }
1630};
1631
1632static const struct {
1633 EC_CURVE_DATA h;
1634 unsigned char data[0 + 23 * 6];
1635}
1636 _EC_X9_62_CHAR2_176V1 = {
1637 {
1638 NID_X9_62_characteristic_two_field, 0, 23, 0xFF6E
1639 },
1640 { /* no seed */
1641 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
1643 0x00, 0x00, 0x07,
1644 0x00, 0xE4, 0xE6, 0xDB, 0x29, 0x95, 0x06, 0x5C, 0x40, 0x7D, /* a */
1645 0x9D, 0x39, 0xB8, 0xD0, 0x96, 0x7B, 0x96, 0x70, 0x4B, 0xA8,
1646 0xE9, 0xC9, 0x0B,
1647 0x00, 0x5D, 0xDA, 0x47, 0x0A, 0xBE, 0x64, 0x14, 0xDE, 0x8E, /* b */
1648 0xC1, 0x33, 0xAE, 0x28, 0xE9, 0xBB, 0xD7, 0xFC, 0xEC, 0x0A,
1649 0xE0, 0xFF, 0xF2,
1650 0x00, 0x8D, 0x16, 0xC2, 0x86, 0x67, 0x98, 0xB6, 0x00, 0xF9, /* x */
1651 0xF0, 0x8B, 0xB4, 0xA8, 0xE8, 0x60, 0xF3, 0x29, 0x8C, 0xE0,
1652 0x4A, 0x57, 0x98,
1653 0x00, 0x6F, 0xA4, 0x53, 0x9C, 0x2D, 0xAD, 0xDD, 0xD6, 0xBA, /* y */
1654 0xB5, 0x16, 0x7D, 0x61, 0xB4, 0x36, 0xE1, 0xD9, 0x2B, 0xB1,
1655 0x6A, 0x56, 0x2C,
1656 0x00, 0x00, 0x01, 0x00, 0x92, 0x53, 0x73, 0x97, 0xEC, 0xA4, /* order */
1657 0xF6, 0x14, 0x57, 0x99, 0xD6, 0x2B, 0x0A, 0x19, 0xCE, 0x06,
1658 0xFE, 0x26, 0xAD
1659 }
1660};
1661
1662static const struct {
1663 EC_CURVE_DATA h;
1664 unsigned char data[20 + 24 * 6];
1665}
1666 _EC_X9_62_CHAR2_191V1 = {
1667 {
1668 NID_X9_62_characteristic_two_field, 20, 24, 2
1669 },
1670 {
1671 0x4E, 0x13, 0xCA, 0x54, 0x27, 0x44, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1672 0x87, 0x56, 0x15, 0x17, 0x55, 0x2F, 0x27, 0x9A, 0x8C, 0x84,
1673
1674 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1676 0x00, 0x00, 0x02, 0x01,
1677 0x28, 0x66, 0x53, 0x7B, 0x67, 0x67, 0x52, 0x63, 0x6A, 0x68, /* a */
1678 0xF5, 0x65, 0x54, 0xE1, 0x26, 0x40, 0x27, 0x6B, 0x64, 0x9E,
1679 0xF7, 0x52, 0x62, 0x67,
1680 0x2E, 0x45, 0xEF, 0x57, 0x1F, 0x00, 0x78, 0x6F, 0x67, 0xB0, /* b */
1681 0x08, 0x1B, 0x94, 0x95, 0xA3, 0xD9, 0x54, 0x62, 0xF5, 0xDE,
1682 0x0A, 0xA1, 0x85, 0xEC,
1683 0x36, 0xB3, 0xDA, 0xF8, 0xA2, 0x32, 0x06, 0xF9, 0xC4, 0xF2, /* x */
1684 0x99, 0xD7, 0xB2, 0x1A, 0x9C, 0x36, 0x91, 0x37, 0xF2, 0xC8,
1685 0x4A, 0xE1, 0xAA, 0x0D,
1686 0x76, 0x5B, 0xE7, 0x34, 0x33, 0xB3, 0xF9, 0x5E, 0x33, 0x29, /* y */
1687 0x32, 0xE7, 0x0E, 0xA2, 0x45, 0xCA, 0x24, 0x18, 0xEA, 0x0E,
1688 0xF9, 0x80, 0x18, 0xFB,
1689 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1690 0x00, 0x00, 0x04, 0xA2, 0x0E, 0x90, 0xC3, 0x90, 0x67, 0xC8,
1691 0x93, 0xBB, 0xB9, 0xA5
1692 }
1693};
1694
1695static const struct {
1696 EC_CURVE_DATA h;
1697 unsigned char data[20 + 24 * 6];
1698}
1699 _EC_X9_62_CHAR2_191V2 = {
1700 {
1701 NID_X9_62_characteristic_two_field, 20, 24, 4
1702 },
1703 {
1704 0x08, 0x71, 0xEF, 0x2F, 0xEF, 0x24, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1705 0x87, 0x56, 0x15, 0x17, 0x58, 0xBE, 0xE0, 0xD9, 0x5C, 0x15,
1706
1707 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1709 0x00, 0x00, 0x02, 0x01,
1710 0x40, 0x10, 0x28, 0x77, 0x4D, 0x77, 0x77, 0xC7, 0xB7, 0x66, /* a */
1711 0x6D, 0x13, 0x66, 0xEA, 0x43, 0x20, 0x71, 0x27, 0x4F, 0x89,
1712 0xFF, 0x01, 0xE7, 0x18,
1713 0x06, 0x20, 0x04, 0x8D, 0x28, 0xBC, 0xBD, 0x03, 0xB6, 0x24, /* b */
1714 0x9C, 0x99, 0x18, 0x2B, 0x7C, 0x8C, 0xD1, 0x97, 0x00, 0xC3,
1715 0x62, 0xC4, 0x6A, 0x01,
1716 0x38, 0x09, 0xB2, 0xB7, 0xCC, 0x1B, 0x28, 0xCC, 0x5A, 0x87, /* x */
1717 0x92, 0x6A, 0xAD, 0x83, 0xFD, 0x28, 0x78, 0x9E, 0x81, 0xE2,
1718 0xC9, 0xE3, 0xBF, 0x10,
1719 0x17, 0x43, 0x43, 0x86, 0x62, 0x6D, 0x14, 0xF3, 0xDB, 0xF0, /* y */
1720 0x17, 0x60, 0xD9, 0x21, 0x3A, 0x3E, 0x1C, 0xF3, 0x7A, 0xEC,
1721 0x43, 0x7D, 0x66, 0x8A,
1722 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1723 0x00, 0x00, 0x50, 0x50, 0x8C, 0xB8, 0x9F, 0x65, 0x28, 0x24,
1724 0xE0, 0x6B, 0x81, 0x73
1725 }
1726};
1727
1728static const struct {
1729 EC_CURVE_DATA h;
1730 unsigned char data[20 + 24 * 6];
1731}
1732 _EC_X9_62_CHAR2_191V3 = {
1733 {
1734 NID_X9_62_characteristic_two_field, 20, 24, 6
1735 },
1736 {
1737 0xE0, 0x53, 0x51, 0x2D, 0xC6, 0x84, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1738 0x87, 0x56, 0x15, 0x17, 0x50, 0x67, 0xAE, 0x78, 0x6D, 0x1F,
1739
1740 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1742 0x00, 0x00, 0x02, 0x01,
1743 0x6C, 0x01, 0x07, 0x47, 0x56, 0x09, 0x91, 0x22, 0x22, 0x10, /* a */
1744 0x56, 0x91, 0x1C, 0x77, 0xD7, 0x7E, 0x77, 0xA7, 0x77, 0xE7,
1745 0xE7, 0xE7, 0x7F, 0xCB,
1746 0x71, 0xFE, 0x1A, 0xF9, 0x26, 0xCF, 0x84, 0x79, 0x89, 0xEF, /* b */
1747 0xEF, 0x8D, 0xB4, 0x59, 0xF6, 0x63, 0x94, 0xD9, 0x0F, 0x32,
1748 0xAD, 0x3F, 0x15, 0xE8,
1749 0x37, 0x5D, 0x4C, 0xE2, 0x4F, 0xDE, 0x43, 0x44, 0x89, 0xDE, /* x */
1750 0x87, 0x46, 0xE7, 0x17, 0x86, 0x01, 0x50, 0x09, 0xE6, 0x6E,
1751 0x38, 0xA9, 0x26, 0xDD,
1752 0x54, 0x5A, 0x39, 0x17, 0x61, 0x96, 0x57, 0x5D, 0x98, 0x59, /* y */
1753 0x99, 0x36, 0x6E, 0x6A, 0xD3, 0x4C, 0xE0, 0xA7, 0x7C, 0xD7,
1754 0x12, 0x7B, 0x06, 0xBE,
1755 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, /* order */
1756 0x55, 0x55, 0x61, 0x0C, 0x0B, 0x19, 0x68, 0x12, 0xBF, 0xB6,
1757 0x28, 0x8A, 0x3E, 0xA3
1758 }
1759};
1760
1761static const struct {
1762 EC_CURVE_DATA h;
1763 unsigned char data[0 + 27 * 6];
1764}
1765 _EC_X9_62_CHAR2_208W1 = {
1766 {
1767 NID_X9_62_characteristic_two_field, 0, 27, 0xFE48
1768 },
1769 { /* no seed */
1770 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
1773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
1774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1776 0x00, 0xC8, 0x61, 0x9E, 0xD4, 0x5A, 0x62, 0xE6, 0x21, 0x2E, /* b */
1777 0x11, 0x60, 0x34, 0x9E, 0x2B, 0xFA, 0x84, 0x44, 0x39, 0xFA,
1778 0xFC, 0x2A, 0x3F, 0xD1, 0x63, 0x8F, 0x9E,
1779 0x00, 0x89, 0xFD, 0xFB, 0xE4, 0xAB, 0xE1, 0x93, 0xDF, 0x95, /* x */
1780 0x59, 0xEC, 0xF0, 0x7A, 0xC0, 0xCE, 0x78, 0x55, 0x4E, 0x27,
1781 0x84, 0xEB, 0x8C, 0x1E, 0xD1, 0xA5, 0x7A,
1782 0x00, 0x0F, 0x55, 0xB5, 0x1A, 0x06, 0xE7, 0x8E, 0x9A, 0xC3, /* y */
1783 0x8A, 0x03, 0x5F, 0xF5, 0x20, 0xD8, 0xB0, 0x17, 0x81, 0xBE,
1784 0xB1, 0xA6, 0xBB, 0x08, 0x61, 0x7D, 0xE3,
1785 0x00, 0x00, 0x01, 0x01, 0xBA, 0xF9, 0x5C, 0x97, 0x23, 0xC5, /* order */
1786 0x7B, 0x6C, 0x21, 0xDA, 0x2E, 0xFF, 0x2D, 0x5E, 0xD5, 0x88,
1787 0xBD, 0xD5, 0x71, 0x7E, 0x21, 0x2F, 0x9D
1788 }
1789};
1790
1791static const struct {
1792 EC_CURVE_DATA h;
1793 unsigned char data[20 + 30 * 6];
1794}
1795 _EC_X9_62_CHAR2_239V1 = {
1796 {
1797 NID_X9_62_characteristic_two_field, 20, 30, 4
1798 },
1799 {
1800 0xD3, 0x4B, 0x9A, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, /* seed */
1801 0x51, 0x75, 0xCA, 0x71, 0xB9, 0x20, 0xBF, 0xEF, 0xB0, 0x5D,
1802
1803 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1804 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1805 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
1806
1807 0x32, 0x01, 0x08, 0x57, 0x07, 0x7C, 0x54, 0x31, 0x12, 0x3A, /* a */
1808 0x46, 0xB8, 0x08, 0x90, 0x67, 0x56, 0xF5, 0x43, 0x42, 0x3E,
1809 0x8D, 0x27, 0x87, 0x75, 0x78, 0x12, 0x57, 0x78, 0xAC, 0x76,
1810
1811 0x79, 0x04, 0x08, 0xF2, 0xEE, 0xDA, 0xF3, 0x92, 0xB0, 0x12, /* b */
1812 0xED, 0xEF, 0xB3, 0x39, 0x2F, 0x30, 0xF4, 0x32, 0x7C, 0x0C,
1813 0xA3, 0xF3, 0x1F, 0xC3, 0x83, 0xC4, 0x22, 0xAA, 0x8C, 0x16,
1814
1815 0x57, 0x92, 0x70, 0x98, 0xFA, 0x93, 0x2E, 0x7C, 0x0A, 0x96, /* x */
1816 0xD3, 0xFD, 0x5B, 0x70, 0x6E, 0xF7, 0xE5, 0xF5, 0xC1, 0x56,
1817 0xE1, 0x6B, 0x7E, 0x7C, 0x86, 0x03, 0x85, 0x52, 0xE9, 0x1D,
1818
1819 0x61, 0xD8, 0xEE, 0x50, 0x77, 0xC3, 0x3F, 0xEC, 0xF6, 0xF1, /* y */
1820 0xA1, 0x6B, 0x26, 0x8D, 0xE4, 0x69, 0xC3, 0xC7, 0x74, 0x4E,
1821 0xA9, 0xA9, 0x71, 0x64, 0x9F, 0xC7, 0xA9, 0x61, 0x63, 0x05,
1822
1823 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
1824 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x4D, 0x42, 0xFF, 0xE1,
1825 0x49, 0x2A, 0x49, 0x93, 0xF1, 0xCA, 0xD6, 0x66, 0xE4, 0x47
1826 }
1827};
1828
1829static const struct {
1830 EC_CURVE_DATA h;
1831 unsigned char data[20 + 30 * 6];
1832}
1833 _EC_X9_62_CHAR2_239V2 = {
1834 {
1835 NID_X9_62_characteristic_two_field, 20, 30, 6
1836 },
1837 {
1838 0x2A, 0xA6, 0x98, 0x2F, 0xDF, 0xA4, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1839 0x87, 0x56, 0x15, 0x17, 0x5D, 0x26, 0x67, 0x27, 0x27, 0x7D,
1840
1841 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1843 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
1844
1845 0x42, 0x30, 0x01, 0x77, 0x57, 0xA7, 0x67, 0xFA, 0xE4, 0x23, /* a */
1846 0x98, 0x56, 0x9B, 0x74, 0x63, 0x25, 0xD4, 0x53, 0x13, 0xAF,
1847 0x07, 0x66, 0x26, 0x64, 0x79, 0xB7, 0x56, 0x54, 0xE6, 0x5F,
1848
1849 0x50, 0x37, 0xEA, 0x65, 0x41, 0x96, 0xCF, 0xF0, 0xCD, 0x82, /* b */
1850 0xB2, 0xC1, 0x4A, 0x2F, 0xCF, 0x2E, 0x3F, 0xF8, 0x77, 0x52,
1851 0x85, 0xB5, 0x45, 0x72, 0x2F, 0x03, 0xEA, 0xCD, 0xB7, 0x4B,
1852
1853 0x28, 0xF9, 0xD0, 0x4E, 0x90, 0x00, 0x69, 0xC8, 0xDC, 0x47, /* x */
1854 0xA0, 0x85, 0x34, 0xFE, 0x76, 0xD2, 0xB9, 0x00, 0xB7, 0xD7,
1855 0xEF, 0x31, 0xF5, 0x70, 0x9F, 0x20, 0x0C, 0x4C, 0xA2, 0x05,
1856
1857 0x56, 0x67, 0x33, 0x4C, 0x45, 0xAF, 0xF3, 0xB5, 0xA0, 0x3B, /* y */
1858 0xAD, 0x9D, 0xD7, 0x5E, 0x2C, 0x71, 0xA9, 0x93, 0x62, 0x56,
1859 0x7D, 0x54, 0x53, 0xF7, 0xFA, 0x6E, 0x22, 0x7E, 0xC8, 0x33,
1860
1861 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, /* order */
1862 0x55, 0x55, 0x55, 0x55, 0x55, 0x3C, 0x6F, 0x28, 0x85, 0x25,
1863 0x9C, 0x31, 0xE3, 0xFC, 0xDF, 0x15, 0x46, 0x24, 0x52, 0x2D
1864 }
1865};
1866
1867static const struct {
1868 EC_CURVE_DATA h;
1869 unsigned char data[20 + 30 * 6];
1870}
1871 _EC_X9_62_CHAR2_239V3 = {
1872 {
1873 NID_X9_62_characteristic_two_field, 20, 30, 0xA
1874 },
1875 {
1876 0x9E, 0x07, 0x6F, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, /* seed */
1877 0x51, 0x75, 0xE1, 0x1E, 0x9F, 0xDD, 0x77, 0xF9, 0x20, 0x41,
1878
1879 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1880 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1881 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
1882
1883 0x01, 0x23, 0x87, 0x74, 0x66, 0x6A, 0x67, 0x76, 0x6D, 0x66, /* a */
1884 0x76, 0xF7, 0x78, 0xE6, 0x76, 0xB6, 0x69, 0x99, 0x17, 0x66,
1885 0x66, 0xE6, 0x87, 0x66, 0x6D, 0x87, 0x66, 0xC6, 0x6A, 0x9F,
1886
1887 0x6A, 0x94, 0x19, 0x77, 0xBA, 0x9F, 0x6A, 0x43, 0x51, 0x99, /* b */
1888 0xAC, 0xFC, 0x51, 0x06, 0x7E, 0xD5, 0x87, 0xF5, 0x19, 0xC5,
1889 0xEC, 0xB5, 0x41, 0xB8, 0xE4, 0x41, 0x11, 0xDE, 0x1D, 0x40,
1890
1891 0x70, 0xF6, 0xE9, 0xD0, 0x4D, 0x28, 0x9C, 0x4E, 0x89, 0x91, /* x */
1892 0x3C, 0xE3, 0x53, 0x0B, 0xFD, 0xE9, 0x03, 0x97, 0x7D, 0x42,
1893 0xB1, 0x46, 0xD5, 0x39, 0xBF, 0x1B, 0xDE, 0x4E, 0x9C, 0x92,
1894
1895 0x2E, 0x5A, 0x0E, 0xAF, 0x6E, 0x5E, 0x13, 0x05, 0xB9, 0x00, /* y */
1896 0x4D, 0xCE, 0x5C, 0x0E, 0xD7, 0xFE, 0x59, 0xA3, 0x56, 0x08,
1897 0xF3, 0x38, 0x37, 0xC8, 0x16, 0xD8, 0x0B, 0x79, 0xF4, 0x61,
1898
1899 0x0C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, /* order */
1900 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xAC, 0x49, 0x12, 0xD2, 0xD9,
1901 0xDF, 0x90, 0x3E, 0xF9, 0x88, 0x8B, 0x8A, 0x0E, 0x4C, 0xFF
1902 }
1903};
1904
1905static const struct {
1906 EC_CURVE_DATA h;
1907 unsigned char data[0 + 35 * 6];
1908}
1909 _EC_X9_62_CHAR2_272W1 = {
1910 {
1911 NID_X9_62_characteristic_two_field, 0, 35, 0xFF06
1912 },
1913 { /* no seed */
1914 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1915 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1916 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
1917 0x00, 0x00, 0x00, 0x00, 0x0B,
1918 0x00, 0x91, 0xA0, 0x91, 0xF0, 0x3B, 0x5F, 0xBA, 0x4A, 0xB2, /* a */
1919 0xCC, 0xF4, 0x9C, 0x4E, 0xDD, 0x22, 0x0F, 0xB0, 0x28, 0x71,
1920 0x2D, 0x42, 0xBE, 0x75, 0x2B, 0x2C, 0x40, 0x09, 0x4D, 0xBA,
1921 0xCD, 0xB5, 0x86, 0xFB, 0x20,
1922 0x00, 0x71, 0x67, 0xEF, 0xC9, 0x2B, 0xB2, 0xE3, 0xCE, 0x7C, /* b */
1923 0x8A, 0xAA, 0xFF, 0x34, 0xE1, 0x2A, 0x9C, 0x55, 0x70, 0x03,
1924 0xD7, 0xC7, 0x3A, 0x6F, 0xAF, 0x00, 0x3F, 0x99, 0xF6, 0xCC,
1925 0x84, 0x82, 0xE5, 0x40, 0xF7,
1926 0x00, 0x61, 0x08, 0xBA, 0xBB, 0x2C, 0xEE, 0xBC, 0xF7, 0x87, /* x */
1927 0x05, 0x8A, 0x05, 0x6C, 0xBE, 0x0C, 0xFE, 0x62, 0x2D, 0x77,
1928 0x23, 0xA2, 0x89, 0xE0, 0x8A, 0x07, 0xAE, 0x13, 0xEF, 0x0D,
1929 0x10, 0xD1, 0x71, 0xDD, 0x8D,
1930 0x00, 0x10, 0xC7, 0x69, 0x57, 0x16, 0x85, 0x1E, 0xEF, 0x6B, /* y */
1931 0xA7, 0xF6, 0x87, 0x2E, 0x61, 0x42, 0xFB, 0xD2, 0x41, 0xB8,
1932 0x30, 0xFF, 0x5E, 0xFC, 0xAC, 0xEC, 0xCA, 0xB0, 0x5E, 0x02,
1933 0x00, 0x5D, 0xDE, 0x9D, 0x23,
1934 0x00, 0x00, 0x01, 0x00, 0xFA, 0xF5, 0x13, 0x54, 0xE0, 0xE3, /* order */
1935 0x9E, 0x48, 0x92, 0xDF, 0x6E, 0x31, 0x9C, 0x72, 0xC8, 0x16,
1936 0x16, 0x03, 0xFA, 0x45, 0xAA, 0x7B, 0x99, 0x8A, 0x16, 0x7B,
1937 0x8F, 0x1E, 0x62, 0x95, 0x21
1938 }
1939};
1940
1941static const struct {
1942 EC_CURVE_DATA h;
1943 unsigned char data[0 + 39 * 6];
1944}
1945 _EC_X9_62_CHAR2_304W1 = {
1946 {
1947 NID_X9_62_characteristic_two_field, 0, 39, 0xFE2E
1948 },
1949 { /* no seed */
1950 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1951 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1952 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1953 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07,
1954 0x00, 0xFD, 0x0D, 0x69, 0x31, 0x49, 0xA1, 0x18, 0xF6, 0x51, /* a */
1955 0xE6, 0xDC, 0xE6, 0x80, 0x20, 0x85, 0x37, 0x7E, 0x5F, 0x88,
1956 0x2D, 0x1B, 0x51, 0x0B, 0x44, 0x16, 0x00, 0x74, 0xC1, 0x28,
1957 0x80, 0x78, 0x36, 0x5A, 0x03, 0x96, 0xC8, 0xE6, 0x81,
1958 0x00, 0xBD, 0xDB, 0x97, 0xE5, 0x55, 0xA5, 0x0A, 0x90, 0x8E, /* b */
1959 0x43, 0xB0, 0x1C, 0x79, 0x8E, 0xA5, 0xDA, 0xA6, 0x78, 0x8F,
1960 0x1E, 0xA2, 0x79, 0x4E, 0xFC, 0xF5, 0x71, 0x66, 0xB8, 0xC1,
1961 0x40, 0x39, 0x60, 0x1E, 0x55, 0x82, 0x73, 0x40, 0xBE,
1962 0x00, 0x19, 0x7B, 0x07, 0x84, 0x5E, 0x9B, 0xE2, 0xD9, 0x6A, /* x */
1963 0xDB, 0x0F, 0x5F, 0x3C, 0x7F, 0x2C, 0xFF, 0xBD, 0x7A, 0x3E,
1964 0xB8, 0xB6, 0xFE, 0xC3, 0x5C, 0x7F, 0xD6, 0x7F, 0x26, 0xDD,
1965 0xF6, 0x28, 0x5A, 0x64, 0x4F, 0x74, 0x0A, 0x26, 0x14,
1966 0x00, 0xE1, 0x9F, 0xBE, 0xB7, 0x6E, 0x0D, 0xA1, 0x71, 0x51, /* y */
1967 0x7E, 0xCF, 0x40, 0x1B, 0x50, 0x28, 0x9B, 0xF0, 0x14, 0x10,
1968 0x32, 0x88, 0x52, 0x7A, 0x9B, 0x41, 0x6A, 0x10, 0x5E, 0x80,
1969 0x26, 0x0B, 0x54, 0x9F, 0xDC, 0x1B, 0x92, 0xC0, 0x3B,
1970 0x00, 0x00, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, /* order */
1971 0x80, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80,
1972 0x01, 0x02, 0x2D, 0x5C, 0x91, 0xDD, 0x17, 0x3F, 0x8F, 0xB5,
1973 0x61, 0xDA, 0x68, 0x99, 0x16, 0x44, 0x43, 0x05, 0x1D
1974 }
1975};
1976
1977static const struct {
1978 EC_CURVE_DATA h;
1979 unsigned char data[20 + 45 * 6];
1980}
1981 _EC_X9_62_CHAR2_359V1 = {
1982 {
1983 NID_X9_62_characteristic_two_field, 20, 45, 0x4C
1984 },
1985 {
1986 0x2B, 0x35, 0x49, 0x20, 0xB7, 0x24, 0xD6, 0x96, 0xE6, 0x76, /* seed */
1987 0x87, 0x56, 0x15, 0x17, 0x58, 0x5B, 0xA1, 0x33, 0x2D, 0xC6,
1988
1989 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
1990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1993 0x00, 0x00, 0x00, 0x00, 0x01,
1994 0x56, 0x67, 0x67, 0x6A, 0x65, 0x4B, 0x20, 0x75, 0x4F, 0x35, /* a */
1995 0x6E, 0xA9, 0x20, 0x17, 0xD9, 0x46, 0x56, 0x7C, 0x46, 0x67,
1996 0x55, 0x56, 0xF1, 0x95, 0x56, 0xA0, 0x46, 0x16, 0xB5, 0x67,
1997 0xD2, 0x23, 0xA5, 0xE0, 0x56, 0x56, 0xFB, 0x54, 0x90, 0x16,
1998 0xA9, 0x66, 0x56, 0xA5, 0x57,
1999 0x24, 0x72, 0xE2, 0xD0, 0x19, 0x7C, 0x49, 0x36, 0x3F, 0x1F, /* b */
2000 0xE7, 0xF5, 0xB6, 0xDB, 0x07, 0x5D, 0x52, 0xB6, 0x94, 0x7D,
2001 0x13, 0x5D, 0x8C, 0xA4, 0x45, 0x80, 0x5D, 0x39, 0xBC, 0x34,
2002 0x56, 0x26, 0x08, 0x96, 0x87, 0x74, 0x2B, 0x63, 0x29, 0xE7,
2003 0x06, 0x80, 0x23, 0x19, 0x88,
2004 0x3C, 0x25, 0x8E, 0xF3, 0x04, 0x77, 0x67, 0xE7, 0xED, 0xE0, /* x */
2005 0xF1, 0xFD, 0xAA, 0x79, 0xDA, 0xEE, 0x38, 0x41, 0x36, 0x6A,
2006 0x13, 0x2E, 0x16, 0x3A, 0xCE, 0xD4, 0xED, 0x24, 0x01, 0xDF,
2007 0x9C, 0x6B, 0xDC, 0xDE, 0x98, 0xE8, 0xE7, 0x07, 0xC0, 0x7A,
2008 0x22, 0x39, 0xB1, 0xB0, 0x97,
2009 0x53, 0xD7, 0xE0, 0x85, 0x29, 0x54, 0x70, 0x48, 0x12, 0x1E, /* y */
2010 0x9C, 0x95, 0xF3, 0x79, 0x1D, 0xD8, 0x04, 0x96, 0x39, 0x48,
2011 0xF3, 0x4F, 0xAE, 0x7B, 0xF4, 0x4E, 0xA8, 0x23, 0x65, 0xDC,
2012 0x78, 0x68, 0xFE, 0x57, 0xE4, 0xAE, 0x2D, 0xE2, 0x11, 0x30,
2013 0x5A, 0x40, 0x71, 0x04, 0xBD,
2014 0x01, 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, /* order */
2015 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF,
2016 0x28, 0x6B, 0xC9, 0xFB, 0x8F, 0x6B, 0x85, 0xC5, 0x56, 0x89,
2017 0x2C, 0x20, 0xA7, 0xEB, 0x96, 0x4F, 0xE7, 0x71, 0x9E, 0x74,
2018 0xF4, 0x90, 0x75, 0x8D, 0x3B
2019 }
2020};
2021
2022static const struct {
2023 EC_CURVE_DATA h;
2024 unsigned char data[0 + 47 * 6];
2025}
2026 _EC_X9_62_CHAR2_368W1 = {
2027 {
2028 NID_X9_62_characteristic_two_field, 0, 47, 0xFF70
2029 },
2030 { /* no seed */
2031 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2032 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2033 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2034 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
2035 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
2036 0x00, 0xE0, 0xD2, 0xEE, 0x25, 0x09, 0x52, 0x06, 0xF5, 0xE2, /* a */
2037 0xA4, 0xF9, 0xED, 0x22, 0x9F, 0x1F, 0x25, 0x6E, 0x79, 0xA0,
2038 0xE2, 0xB4, 0x55, 0x97, 0x0D, 0x8D, 0x0D, 0x86, 0x5B, 0xD9,
2039 0x47, 0x78, 0xC5, 0x76, 0xD6, 0x2F, 0x0A, 0xB7, 0x51, 0x9C,
2040 0xCD, 0x2A, 0x1A, 0x90, 0x6A, 0xE3, 0x0D,
2041 0x00, 0xFC, 0x12, 0x17, 0xD4, 0x32, 0x0A, 0x90, 0x45, 0x2C, /* b */
2042 0x76, 0x0A, 0x58, 0xED, 0xCD, 0x30, 0xC8, 0xDD, 0x06, 0x9B,
2043 0x3C, 0x34, 0x45, 0x38, 0x37, 0xA3, 0x4E, 0xD5, 0x0C, 0xB5,
2044 0x49, 0x17, 0xE1, 0xC2, 0x11, 0x2D, 0x84, 0xD1, 0x64, 0xF4,
2045 0x44, 0xF8, 0xF7, 0x47, 0x86, 0x04, 0x6A,
2046 0x00, 0x10, 0x85, 0xE2, 0x75, 0x53, 0x81, 0xDC, 0xCC, 0xE3, /* x */
2047 0xC1, 0x55, 0x7A, 0xFA, 0x10, 0xC2, 0xF0, 0xC0, 0xC2, 0x82,
2048 0x56, 0x46, 0xC5, 0xB3, 0x4A, 0x39, 0x4C, 0xBC, 0xFA, 0x8B,
2049 0xC1, 0x6B, 0x22, 0xE7, 0xE7, 0x89, 0xE9, 0x27, 0xBE, 0x21,
2050 0x6F, 0x02, 0xE1, 0xFB, 0x13, 0x6A, 0x5F,
2051 0x00, 0x7B, 0x3E, 0xB1, 0xBD, 0xDC, 0xBA, 0x62, 0xD5, 0xD8, /* y */
2052 0xB2, 0x05, 0x9B, 0x52, 0x57, 0x97, 0xFC, 0x73, 0x82, 0x2C,
2053 0x59, 0x05, 0x9C, 0x62, 0x3A, 0x45, 0xFF, 0x38, 0x43, 0xCE,
2054 0xE8, 0xF8, 0x7C, 0xD1, 0x85, 0x5A, 0xDA, 0xA8, 0x1E, 0x2A,
2055 0x07, 0x50, 0xB8, 0x0F, 0xDA, 0x23, 0x10,
2056 0x00, 0x00, 0x01, 0x00, 0x90, 0x51, 0x2D, 0xA9, 0xAF, 0x72, /* order */
2057 0xB0, 0x83, 0x49, 0xD9, 0x8A, 0x5D, 0xD4, 0xC7, 0xB0, 0x53,
2058 0x2E, 0xCA, 0x51, 0xCE, 0x03, 0xE2, 0xD1, 0x0F, 0x3B, 0x7A,
2059 0xC5, 0x79, 0xBD, 0x87, 0xE9, 0x09, 0xAE, 0x40, 0xA6, 0xF1,
2060 0x31, 0xE9, 0xCF, 0xCE, 0x5B, 0xD9, 0x67
2061 }
2062};
2063
2064static const struct {
2065 EC_CURVE_DATA h;
2066 unsigned char data[0 + 54 * 6];
2067}
2068 _EC_X9_62_CHAR2_431R1 = {
2069 {
2070 NID_X9_62_characteristic_two_field, 0, 54, 0x2760
2071 },
2072 { /* no seed */
2073 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2074 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2075 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
2077 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2078 0x00, 0x00, 0x00, 0x01,
2079 0x1A, 0x82, 0x7E, 0xF0, 0x0D, 0xD6, 0xFC, 0x0E, 0x23, 0x4C, /* a */
2080 0xAF, 0x04, 0x6C, 0x6A, 0x5D, 0x8A, 0x85, 0x39, 0x5B, 0x23,
2081 0x6C, 0xC4, 0xAD, 0x2C, 0xF3, 0x2A, 0x0C, 0xAD, 0xBD, 0xC9,
2082 0xDD, 0xF6, 0x20, 0xB0, 0xEB, 0x99, 0x06, 0xD0, 0x95, 0x7F,
2083 0x6C, 0x6F, 0xEA, 0xCD, 0x61, 0x54, 0x68, 0xDF, 0x10, 0x4D,
2084 0xE2, 0x96, 0xCD, 0x8F,
2085 0x10, 0xD9, 0xB4, 0xA3, 0xD9, 0x04, 0x7D, 0x8B, 0x15, 0x43, /* b */
2086 0x59, 0xAB, 0xFB, 0x1B, 0x7F, 0x54, 0x85, 0xB0, 0x4C, 0xEB,
2087 0x86, 0x82, 0x37, 0xDD, 0xC9, 0xDE, 0xDA, 0x98, 0x2A, 0x67,
2088 0x9A, 0x5A, 0x91, 0x9B, 0x62, 0x6D, 0x4E, 0x50, 0xA8, 0xDD,
2089 0x73, 0x1B, 0x10, 0x7A, 0x99, 0x62, 0x38, 0x1F, 0xB5, 0xD8,
2090 0x07, 0xBF, 0x26, 0x18,
2091 0x12, 0x0F, 0xC0, 0x5D, 0x3C, 0x67, 0xA9, 0x9D, 0xE1, 0x61, /* x */
2092 0xD2, 0xF4, 0x09, 0x26, 0x22, 0xFE, 0xCA, 0x70, 0x1B, 0xE4,
2093 0xF5, 0x0F, 0x47, 0x58, 0x71, 0x4E, 0x8A, 0x87, 0xBB, 0xF2,
2094 0xA6, 0x58, 0xEF, 0x8C, 0x21, 0xE7, 0xC5, 0xEF, 0xE9, 0x65,
2095 0x36, 0x1F, 0x6C, 0x29, 0x99, 0xC0, 0xC2, 0x47, 0xB0, 0xDB,
2096 0xD7, 0x0C, 0xE6, 0xB7,
2097 0x20, 0xD0, 0xAF, 0x89, 0x03, 0xA9, 0x6F, 0x8D, 0x5F, 0xA2, /* y */
2098 0xC2, 0x55, 0x74, 0x5D, 0x3C, 0x45, 0x1B, 0x30, 0x2C, 0x93,
2099 0x46, 0xD9, 0xB7, 0xE4, 0x85, 0xE7, 0xBC, 0xE4, 0x1F, 0x6B,
2100 0x59, 0x1F, 0x3E, 0x8F, 0x6A, 0xDD, 0xCB, 0xB0, 0xBC, 0x4C,
2101 0x2F, 0x94, 0x7A, 0x7D, 0xE1, 0xA8, 0x9B, 0x62, 0x5D, 0x6A,
2102 0x59, 0x8B, 0x37, 0x60,
2103 0x00, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, /* order */
2104 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03,
2105 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x23,
2106 0xC3, 0x13, 0xFA, 0xB5, 0x05, 0x89, 0x70, 0x3B, 0x5E, 0xC6,
2107 0x8D, 0x35, 0x87, 0xFE, 0xC6, 0x0D, 0x16, 0x1C, 0xC1, 0x49,
2108 0xC1, 0xAD, 0x4A, 0x91
2109 }
2110};
2111
2112static const struct {
2113 EC_CURVE_DATA h;
2114 unsigned char data[0 + 15 * 6];
2115}
2116 _EC_WTLS_1 = {
2117 {
2118 NID_X9_62_characteristic_two_field, 0, 15, 2
2119 },
2120 { /* no seed */
2121 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2122 0x00, 0x00, 0x00, 0x02, 0x01,
2123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2124 0x00, 0x00, 0x00, 0x00, 0x01,
2125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2126 0x00, 0x00, 0x00, 0x00, 0x01,
2127 0x01, 0x66, 0x79, 0x79, 0xA4, 0x0B, 0xA4, 0x97, 0xE5, 0xD5, /* x */
2128 0xC2, 0x70, 0x78, 0x06, 0x17,
2129 0x00, 0xF4, 0x4B, 0x4A, 0xF1, 0xEC, 0xC2, 0x63, 0x0E, 0x08, /* y */
2130 0x78, 0x5C, 0xEB, 0xCC, 0x15,
2131 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBF, /* order */
2132 0x91, 0xAF, 0x6D, 0xEA, 0x73
2133 }
2134};
2135
2136/* IPSec curves */
2137/* NOTE: The of curves over a extension field of non prime degree
2138 * is not recommended (Weil-descent).
2139 * As the group order is not a prime this curve is not suitable
2140 * for ECDSA.
2141 */
2142static const struct {
2143 EC_CURVE_DATA h;
2144 unsigned char data[0 + 20 * 6];
2145}
2146 _EC_IPSEC_155_ID3 = {
2147 {
2148 NID_X9_62_characteristic_two_field, 0, 20, 3
2149 },
2150 { /* no seed */
2151 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2152 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
2153
2154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2156
2157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x33, 0x8f,
2159
2160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
2162
2163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* y */
2164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8,
2165
2166 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, /* order */
2167 0xC7, 0xF3, 0xC7, 0x88, 0x1B, 0xD0, 0x86, 0x8F, 0xA8, 0x6C
2168 }
2169};
2170
2171/* NOTE: The of curves over a extension field of non prime degree
2172 * is not recommended (Weil-descent).
2173 * As the group order is not a prime this curve is not suitable
2174 * for ECDSA.
2175 */
2176static const struct {
2177 EC_CURVE_DATA h;
2178 unsigned char data[0 + 24 * 6];
2179}
2180 _EC_IPSEC_185_ID4 = {
2181 {
2182 NID_X9_62_characteristic_two_field, 0, 24, 2
2183 },
2184 { /* no seed */
2185 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2186 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
2187 0x00, 0x00, 0x00, 0x01,
2188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2190 0x00, 0x00, 0x00, 0x00,
2191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2193 0x00, 0x00, 0x1e, 0xe9,
2194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2196 0x00, 0x00, 0x00, 0x18,
2197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* y */
2198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2199 0x00, 0x00, 0x00, 0x0d,
2200 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
2201 0xFF, 0xFF, 0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20,
2202 0xBA, 0xFC, 0xA7, 0x5E
2203 }
2204};
2205
2206#endif
2207
2208/* These curves were added by Annie Yousar <a.yousar@informatik.hu-berlin.de>
2209 * For the definition of RFC 5639 curves see
2210 * http://www.ietf.org/rfc/rfc5639.txt
2211 * These curves are generated verifiable at random, nevertheless the seed is
2212 * omitted as parameter because the generation mechanism is different from
2213 * those defined in ANSI X9.62.
2214 */
2215
2216static const struct {
2217 EC_CURVE_DATA h;
2218 unsigned char data[0 + 20 * 6];
2219}
2220 _EC_brainpoolP160r1 = {
2221 {
2222 NID_X9_62_prime_field, 0, 20, 1
2223 },
2224 { /* no seed */
2225 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* p */
2226 0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F,
2227 0x34, 0x0E, 0x7B, 0xE2, 0xA2, 0x80, 0xEB, 0x74, 0xE2, 0xBE, /* a */
2228 0x61, 0xBA, 0xDA, 0x74, 0x5D, 0x97, 0xE8, 0xF7, 0xC3, 0x00,
2229 0x1E, 0x58, 0x9A, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4F, /* b */
2230 0xAA, 0x2D, 0xBD, 0xEC, 0x95, 0xC8, 0xD8, 0x67, 0x5E, 0x58,
2231 0xBE, 0xD5, 0xAF, 0x16, 0xEA, 0x3F, 0x6A, 0x4F, 0x62, 0x93, /* x */
2232 0x8C, 0x46, 0x31, 0xEB, 0x5A, 0xF7, 0xBD, 0xBC, 0xDB, 0xC3,
2233 0x16, 0x67, 0xCB, 0x47, 0x7A, 0x1A, 0x8E, 0xC3, 0x38, 0xF9, /* y */
2234 0x47, 0x41, 0x66, 0x9C, 0x97, 0x63, 0x16, 0xDA, 0x63, 0x21,
2235 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* order */
2236 0x59, 0x91, 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09
2237 }
2238};
2239
2240static const struct {
2241 EC_CURVE_DATA h;
2242 unsigned char data[0 + 20 * 6];
2243}
2244 _EC_brainpoolP160t1 = {
2245 {
2246 NID_X9_62_prime_field, 0, 20, 1
2247 },
2248 { /* no seed */
2249 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* p */
2250 0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F,
2251 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* a */
2252 0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0C,
2253 0x7A, 0x55, 0x6B, 0x6D, 0xAE, 0x53, 0x5B, 0x7B, 0x51, 0xED, /* b */
2254 0x2C, 0x4D, 0x7D, 0xAA, 0x7A, 0x0B, 0x5C, 0x55, 0xF3, 0x80,
2255 0xB1, 0x99, 0xB1, 0x3B, 0x9B, 0x34, 0xEF, 0xC1, 0x39, 0x7E, /* x */
2256 0x64, 0xBA, 0xEB, 0x05, 0xAC, 0xC2, 0x65, 0xFF, 0x23, 0x78,
2257 0xAD, 0xD6, 0x71, 0x8B, 0x7C, 0x7C, 0x19, 0x61, 0xF0, 0x99, /* y */
2258 0x1B, 0x84, 0x24, 0x43, 0x77, 0x21, 0x52, 0xC9, 0xE0, 0xAD,
2259 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, /* order */
2260 0x59, 0x91, 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09
2261 }
2262};
2263
2264static const struct {
2265 EC_CURVE_DATA h;
2266 unsigned char data[0 + 24 * 6];
2267}
2268 _EC_brainpoolP192r1 = {
2269 {
2270 NID_X9_62_prime_field, 0, 24, 1
2271 },
2272 { /* no seed */
2273 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* p */
2274 0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D,
2275 0xE1, 0xA8, 0x62, 0x97,
2276 0x6A, 0x91, 0x17, 0x40, 0x76, 0xB1, 0xE0, 0xE1, 0x9C, 0x39, /* a */
2277 0xC0, 0x31, 0xFE, 0x86, 0x85, 0xC1, 0xCA, 0xE0, 0x40, 0xE5,
2278 0xC6, 0x9A, 0x28, 0xEF,
2279 0x46, 0x9A, 0x28, 0xEF, 0x7C, 0x28, 0xCC, 0xA3, 0xDC, 0x72, /* b */
2280 0x1D, 0x04, 0x4F, 0x44, 0x96, 0xBC, 0xCA, 0x7E, 0xF4, 0x14,
2281 0x6F, 0xBF, 0x25, 0xC9,
2282 0xC0, 0xA0, 0x64, 0x7E, 0xAA, 0xB6, 0xA4, 0x87, 0x53, 0xB0, /* x */
2283 0x33, 0xC5, 0x6C, 0xB0, 0xF0, 0x90, 0x0A, 0x2F, 0x5C, 0x48,
2284 0x53, 0x37, 0x5F, 0xD6,
2285 0x14, 0xB6, 0x90, 0x86, 0x6A, 0xBD, 0x5B, 0xB8, 0x8B, 0x5F, /* y */
2286 0x48, 0x28, 0xC1, 0x49, 0x00, 0x02, 0xE6, 0x77, 0x3F, 0xA2,
2287 0xFA, 0x29, 0x9B, 0x8F,
2288 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* order */
2289 0x46, 0x2F, 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02,
2290 0x9A, 0xC4, 0xAC, 0xC1
2291 }
2292};
2293
2294static const struct {
2295 EC_CURVE_DATA h;
2296 unsigned char data[0 + 24 * 6];
2297}
2298 _EC_brainpoolP192t1 = {
2299 {
2300 NID_X9_62_prime_field, 0, 24, 1
2301 },
2302 { /* no seed */
2303 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* p */
2304 0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D,
2305 0xE1, 0xA8, 0x62, 0x97,
2306 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* a */
2307 0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D,
2308 0xE1, 0xA8, 0x62, 0x94,
2309 0x13, 0xD5, 0x6F, 0xFA, 0xEC, 0x78, 0x68, 0x1E, 0x68, 0xF9, /* b */
2310 0xDE, 0xB4, 0x3B, 0x35, 0xBE, 0xC2, 0xFB, 0x68, 0x54, 0x2E,
2311 0x27, 0x89, 0x7B, 0x79,
2312 0x3A, 0xE9, 0xE5, 0x8C, 0x82, 0xF6, 0x3C, 0x30, 0x28, 0x2E, /* x */
2313 0x1F, 0xE7, 0xBB, 0xF4, 0x3F, 0xA7, 0x2C, 0x44, 0x6A, 0xF6,
2314 0xF4, 0x61, 0x81, 0x29,
2315 0x09, 0x7E, 0x2C, 0x56, 0x67, 0xC2, 0x22, 0x3A, 0x90, 0x2A, /* y */
2316 0xB5, 0xCA, 0x44, 0x9D, 0x00, 0x84, 0xB7, 0xE5, 0xB3, 0xDE,
2317 0x7C, 0xCC, 0x01, 0xC9,
2318 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, /* order */
2319 0x46, 0x2F, 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02,
2320 0x9A, 0xC4, 0xAC, 0xC1
2321 }
2322};
2323
2324static const struct {
2325 EC_CURVE_DATA h;
2326 unsigned char data[0 + 28 * 6];
2327}
2328 _EC_brainpoolP224r1 = {
2329 {
2330 NID_X9_62_prime_field, 0, 28, 1
2331 },
2332 { /* no seed */
2333 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* p */
2334 0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57,
2335 0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFF,
2336 0x68, 0xA5, 0xE6, 0x2C, 0xA9, 0xCE, 0x6C, 0x1C, 0x29, 0x98, /* a */
2337 0x03, 0xA6, 0xC1, 0x53, 0x0B, 0x51, 0x4E, 0x18, 0x2A, 0xD8,
2338 0xB0, 0x04, 0x2A, 0x59, 0xCA, 0xD2, 0x9F, 0x43,
2339 0x25, 0x80, 0xF6, 0x3C, 0xCF, 0xE4, 0x41, 0x38, 0x87, 0x07, /* b */
2340 0x13, 0xB1, 0xA9, 0x23, 0x69, 0xE3, 0x3E, 0x21, 0x35, 0xD2,
2341 0x66, 0xDB, 0xB3, 0x72, 0x38, 0x6C, 0x40, 0x0B,
2342 0x0D, 0x90, 0x29, 0xAD, 0x2C, 0x7E, 0x5C, 0xF4, 0x34, 0x08, /* x */
2343 0x23, 0xB2, 0xA8, 0x7D, 0xC6, 0x8C, 0x9E, 0x4C, 0xE3, 0x17,
2344 0x4C, 0x1E, 0x6E, 0xFD, 0xEE, 0x12, 0xC0, 0x7D,
2345 0x58, 0xAA, 0x56, 0xF7, 0x72, 0xC0, 0x72, 0x6F, 0x24, 0xC6, /* y */
2346 0xB8, 0x9E, 0x4E, 0xCD, 0xAC, 0x24, 0x35, 0x4B, 0x9E, 0x99,
2347 0xCA, 0xA3, 0xF6, 0xD3, 0x76, 0x14, 0x02, 0xCD,
2348 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* order */
2349 0x30, 0x25, 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B,
2350 0x6D, 0xDE, 0xBC, 0xA3, 0xA5, 0xA7, 0x93, 0x9F
2351 }
2352};
2353
2354static const struct {
2355 EC_CURVE_DATA h;
2356 unsigned char data[0 + 28 * 6];
2357}
2358 _EC_brainpoolP224t1 = {
2359 {
2360 NID_X9_62_prime_field, 0, 28, 1
2361 },
2362 { /* no seed */
2363 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* p */
2364 0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57,
2365 0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFF,
2366 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* a */
2367 0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57,
2368 0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFC,
2369 0x4B, 0x33, 0x7D, 0x93, 0x41, 0x04, 0xCD, 0x7B, 0xEF, 0x27, /* b */
2370 0x1B, 0xF6, 0x0C, 0xED, 0x1E, 0xD2, 0x0D, 0xA1, 0x4C, 0x08,
2371 0xB3, 0xBB, 0x64, 0xF1, 0x8A, 0x60, 0x88, 0x8D,
2372 0x6A, 0xB1, 0xE3, 0x44, 0xCE, 0x25, 0xFF, 0x38, 0x96, 0x42, /* x */
2373 0x4E, 0x7F, 0xFE, 0x14, 0x76, 0x2E, 0xCB, 0x49, 0xF8, 0x92,
2374 0x8A, 0xC0, 0xC7, 0x60, 0x29, 0xB4, 0xD5, 0x80,
2375 0x03, 0x74, 0xE9, 0xF5, 0x14, 0x3E, 0x56, 0x8C, 0xD2, 0x3F, /* y */
2376 0x3F, 0x4D, 0x7C, 0x0D, 0x4B, 0x1E, 0x41, 0xC8, 0xCC, 0x0D,
2377 0x1C, 0x6A, 0xBD, 0x5F, 0x1A, 0x46, 0xDB, 0x4C,
2378 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, /* order */
2379 0x30, 0x25, 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B,
2380 0x6D, 0xDE, 0xBC, 0xA3, 0xA5, 0xA7, 0x93, 0x9F
2381 }
2382};
2383
2384static const struct {
2385 EC_CURVE_DATA h;
2386 unsigned char data[0 + 32 * 6];
2387}
2388 _EC_brainpoolP256r1 = {
2389 {
2390 NID_X9_62_prime_field, 0, 32, 1
2391 },
2392 { /* no seed */
2393 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* p */
2394 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23,
2395 0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E,
2396 0x53, 0x77,
2397 0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, /* a */
2398 0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7, 0xFB, 0x80, 0x55, 0xC1,
2399 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30,
2400 0xB5, 0xD9,
2401 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, /* b */
2402 0xB5, 0xD9, 0xBB, 0xD7, 0x7C, 0xBF, 0x95, 0x84, 0x16, 0x29,
2403 0x5C, 0xF7, 0xE1, 0xCE, 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C,
2404 0x07, 0xB6,
2405 0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, /* x */
2406 0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF, 0xB9, 0xDE, 0x27, 0xE1,
2407 0xE3, 0xBD, 0x23, 0xC2, 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE,
2408 0x32, 0x62,
2409 0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, /* y */
2410 0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9, 0xC2, 0x77, 0x45, 0x13,
2411 0x2D, 0xED, 0x8E, 0x54, 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04,
2412 0x69, 0x97,
2413 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* order */
2414 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3,
2415 0xB5, 0x61, 0xA6, 0xF7, 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48,
2416 0x56, 0xA7
2417 }
2418};
2419
2420static const struct {
2421 EC_CURVE_DATA h;
2422 unsigned char data[0 + 32 * 6];
2423}
2424 _EC_brainpoolP256t1 = {
2425 {
2426 NID_X9_62_prime_field, 0, 32, 1
2427 },
2428 { /* no seed */
2429 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* p */
2430 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23,
2431 0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E,
2432 0x53, 0x77,
2433 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* a */
2434 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23,
2435 0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E,
2436 0x53, 0x74,
2437 0x66, 0x2C, 0x61, 0xC4, 0x30, 0xD8, 0x4E, 0xA4, 0xFE, 0x66, /* b */
2438 0xA7, 0x73, 0x3D, 0x0B, 0x76, 0xB7, 0xBF, 0x93, 0xEB, 0xC4,
2439 0xAF, 0x2F, 0x49, 0x25, 0x6A, 0xE5, 0x81, 0x01, 0xFE, 0xE9,
2440 0x2B, 0x04,
2441 0xA3, 0xE8, 0xEB, 0x3C, 0xC1, 0xCF, 0xE7, 0xB7, 0x73, 0x22, /* x */
2442 0x13, 0xB2, 0x3A, 0x65, 0x61, 0x49, 0xAF, 0xA1, 0x42, 0xC4,
2443 0x7A, 0xAF, 0xBC, 0x2B, 0x79, 0xA1, 0x91, 0x56, 0x2E, 0x13,
2444 0x05, 0xF4,
2445 0x2D, 0x99, 0x6C, 0x82, 0x34, 0x39, 0xC5, 0x6D, 0x7F, 0x7B, /* y */
2446 0x22, 0xE1, 0x46, 0x44, 0x41, 0x7E, 0x69, 0xBC, 0xB6, 0xDE,
2447 0x39, 0xD0, 0x27, 0x00, 0x1D, 0xAB, 0xE8, 0xF3, 0x5B, 0x25,
2448 0xC9, 0xBE,
2449 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, /* order */
2450 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3,
2451 0xB5, 0x61, 0xA6, 0xF7, 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48,
2452 0x56, 0xA7
2453 }
2454};
2455
2456static const struct {
2457 EC_CURVE_DATA h;
2458 unsigned char data[0 + 40 * 6];
2459}
2460 _EC_brainpoolP320r1 = {
2461 {
2462 NID_X9_62_prime_field, 0, 40, 1
2463 },
2464 { /* no seed */
2465 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* p */
2466 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6,
2467 0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93,
2468 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x27,
2469 0x3E, 0xE3, 0x0B, 0x56, 0x8F, 0xBA, 0xB0, 0xF8, 0x83, 0xCC, /* a */
2470 0xEB, 0xD4, 0x6D, 0x3F, 0x3B, 0xB8, 0xA2, 0xA7, 0x35, 0x13,
2471 0xF5, 0xEB, 0x79, 0xDA, 0x66, 0x19, 0x0E, 0xB0, 0x85, 0xFF,
2472 0xA9, 0xF4, 0x92, 0xF3, 0x75, 0xA9, 0x7D, 0x86, 0x0E, 0xB4,
2473 0x52, 0x08, 0x83, 0x94, 0x9D, 0xFD, 0xBC, 0x42, 0xD3, 0xAD, /* b */
2474 0x19, 0x86, 0x40, 0x68, 0x8A, 0x6F, 0xE1, 0x3F, 0x41, 0x34,
2475 0x95, 0x54, 0xB4, 0x9A, 0xCC, 0x31, 0xDC, 0xCD, 0x88, 0x45,
2476 0x39, 0x81, 0x6F, 0x5E, 0xB4, 0xAC, 0x8F, 0xB1, 0xF1, 0xA6,
2477 0x43, 0xBD, 0x7E, 0x9A, 0xFB, 0x53, 0xD8, 0xB8, 0x52, 0x89, /* x */
2478 0xBC, 0xC4, 0x8E, 0xE5, 0xBF, 0xE6, 0xF2, 0x01, 0x37, 0xD1,
2479 0x0A, 0x08, 0x7E, 0xB6, 0xE7, 0x87, 0x1E, 0x2A, 0x10, 0xA5,
2480 0x99, 0xC7, 0x10, 0xAF, 0x8D, 0x0D, 0x39, 0xE2, 0x06, 0x11,
2481 0x14, 0xFD, 0xD0, 0x55, 0x45, 0xEC, 0x1C, 0xC8, 0xAB, 0x40, /* y */
2482 0x93, 0x24, 0x7F, 0x77, 0x27, 0x5E, 0x07, 0x43, 0xFF, 0xED,
2483 0x11, 0x71, 0x82, 0xEA, 0xA9, 0xC7, 0x78, 0x77, 0xAA, 0xAC,
2484 0x6A, 0xC7, 0xD3, 0x52, 0x45, 0xD1, 0x69, 0x2E, 0x8E, 0xE1,
2485 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* order */
2486 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5,
2487 0xB6, 0x8F, 0x12, 0xA3, 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86,
2488 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, 0x44, 0xC5, 0x93, 0x11
2489 }
2490};
2491
2492static const struct {
2493 EC_CURVE_DATA h;
2494 unsigned char data[0 + 40 * 6];
2495}
2496 _EC_brainpoolP320t1 = {
2497 {
2498 NID_X9_62_prime_field, 0, 40, 1
2499 },
2500 { /* no seed */
2501 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* p */
2502 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6,
2503 0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93,
2504 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x27,
2505 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* a */
2506 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6,
2507 0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93,
2508 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x24,
2509 0xA7, 0xF5, 0x61, 0xE0, 0x38, 0xEB, 0x1E, 0xD5, 0x60, 0xB3, /* b */
2510 0xD1, 0x47, 0xDB, 0x78, 0x20, 0x13, 0x06, 0x4C, 0x19, 0xF2,
2511 0x7E, 0xD2, 0x7C, 0x67, 0x80, 0xAA, 0xF7, 0x7F, 0xB8, 0xA5,
2512 0x47, 0xCE, 0xB5, 0xB4, 0xFE, 0xF4, 0x22, 0x34, 0x03, 0x53,
2513 0x92, 0x5B, 0xE9, 0xFB, 0x01, 0xAF, 0xC6, 0xFB, 0x4D, 0x3E, /* x */
2514 0x7D, 0x49, 0x90, 0x01, 0x0F, 0x81, 0x34, 0x08, 0xAB, 0x10,
2515 0x6C, 0x4F, 0x09, 0xCB, 0x7E, 0xE0, 0x78, 0x68, 0xCC, 0x13,
2516 0x6F, 0xFF, 0x33, 0x57, 0xF6, 0x24, 0xA2, 0x1B, 0xED, 0x52,
2517 0x63, 0xBA, 0x3A, 0x7A, 0x27, 0x48, 0x3E, 0xBF, 0x66, 0x71, /* y */
2518 0xDB, 0xEF, 0x7A, 0xBB, 0x30, 0xEB, 0xEE, 0x08, 0x4E, 0x58,
2519 0xA0, 0xB0, 0x77, 0xAD, 0x42, 0xA5, 0xA0, 0x98, 0x9D, 0x1E,
2520 0xE7, 0x1B, 0x1B, 0x9B, 0xC0, 0x45, 0x5F, 0xB0, 0xD2, 0xC3,
2521 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, /* order */
2522 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5,
2523 0xB6, 0x8F, 0x12, 0xA3, 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86,
2524 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, 0x44, 0xC5, 0x93, 0x11
2525 }
2526};
2527
2528static const struct {
2529 EC_CURVE_DATA h;
2530 unsigned char data[0 + 48 * 6];
2531}
2532 _EC_brainpoolP384r1 = {
2533 {
2534 NID_X9_62_prime_field, 0, 48, 1
2535 },
2536 { /* no seed */
2537 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* p */
2538 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2539 0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7,
2540 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71,
2541 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53,
2542 0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, /* a */
2543 0x08, 0x0A, 0xCE, 0x05, 0xAF, 0xA0, 0xC2, 0xBE, 0xA2, 0x8E,
2544 0x4F, 0xB2, 0x27, 0x87, 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91,
2545 0xF9, 0x0F, 0x8A, 0xA5, 0x81, 0x4A, 0x50, 0x3A, 0xD4, 0xEB,
2546 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26,
2547 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, /* b */
2548 0xB5, 0x54, 0x16, 0xF0, 0x44, 0x7C, 0x2F, 0xB7, 0x7D, 0xE1,
2549 0x07, 0xDC, 0xD2, 0xA6, 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB,
2550 0x62, 0xD5, 0x7C, 0xB4, 0x39, 0x02, 0x95, 0xDB, 0xC9, 0x94,
2551 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11,
2552 0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, /* x */
2553 0x3A, 0x81, 0xB7, 0xC1, 0x3F, 0x6B, 0x88, 0x47, 0xA3, 0xE7,
2554 0x7E, 0xF1, 0x4F, 0xE3, 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD,
2555 0x10, 0xE8, 0xE8, 0x26, 0xE0, 0x34, 0x36, 0xD6, 0x46, 0xAA,
2556 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E,
2557 0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, /* y */
2558 0xEB, 0x8E, 0x95, 0xCF, 0xD5, 0x52, 0x62, 0xB7, 0x0B, 0x29,
2559 0xFE, 0xEC, 0x58, 0x64, 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91,
2560 0x29, 0x28, 0x0E, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11,
2561 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15,
2562 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* order */
2563 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2564 0xED, 0x54, 0x56, 0xB3, 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04,
2565 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10,
2566 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65
2567 }
2568};
2569
2570static const struct {
2571 EC_CURVE_DATA h;
2572 unsigned char data[0 + 48 * 6];
2573}
2574 _EC_brainpoolP384t1 = {
2575 {
2576 NID_X9_62_prime_field, 0, 48, 1
2577 },
2578 { /* no seed */
2579 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* p */
2580 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2581 0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7,
2582 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71,
2583 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53,
2584 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* a */
2585 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2586 0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7,
2587 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71,
2588 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x50,
2589 0x7F, 0x51, 0x9E, 0xAD, 0xA7, 0xBD, 0xA8, 0x1B, 0xD8, 0x26, /* b */
2590 0xDB, 0xA6, 0x47, 0x91, 0x0F, 0x8C, 0x4B, 0x93, 0x46, 0xED,
2591 0x8C, 0xCD, 0xC6, 0x4E, 0x4B, 0x1A, 0xBD, 0x11, 0x75, 0x6D,
2592 0xCE, 0x1D, 0x20, 0x74, 0xAA, 0x26, 0x3B, 0x88, 0x80, 0x5C,
2593 0xED, 0x70, 0x35, 0x5A, 0x33, 0xB4, 0x71, 0xEE,
2594 0x18, 0xDE, 0x98, 0xB0, 0x2D, 0xB9, 0xA3, 0x06, 0xF2, 0xAF, /* x */
2595 0xCD, 0x72, 0x35, 0xF7, 0x2A, 0x81, 0x9B, 0x80, 0xAB, 0x12,
2596 0xEB, 0xD6, 0x53, 0x17, 0x24, 0x76, 0xFE, 0xCD, 0x46, 0x2A,
2597 0xAB, 0xFF, 0xC4, 0xFF, 0x19, 0x1B, 0x94, 0x6A, 0x5F, 0x54,
2598 0xD8, 0xD0, 0xAA, 0x2F, 0x41, 0x88, 0x08, 0xCC,
2599 0x25, 0xAB, 0x05, 0x69, 0x62, 0xD3, 0x06, 0x51, 0xA1, 0x14, /* y */
2600 0xAF, 0xD2, 0x75, 0x5A, 0xD3, 0x36, 0x74, 0x7F, 0x93, 0x47,
2601 0x5B, 0x7A, 0x1F, 0xCA, 0x3B, 0x88, 0xF2, 0xB6, 0xA2, 0x08,
2602 0xCC, 0xFE, 0x46, 0x94, 0x08, 0x58, 0x4D, 0xC2, 0xB2, 0x91,
2603 0x26, 0x75, 0xBF, 0x5B, 0x9E, 0x58, 0x29, 0x28,
2604 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, /* order */
2605 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
2606 0xED, 0x54, 0x56, 0xB3, 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04,
2607 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10,
2608 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65
2609 }
2610};
2611
2612static const struct {
2613 EC_CURVE_DATA h;
2614 unsigned char data[0 + 64 * 6];
2615}
2616 _EC_brainpoolP512r1 = {
2617 {
2618 NID_X9_62_prime_field, 0, 64, 1
2619 },
2620 { /* no seed */
2621 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* p */
2622 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2623 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2624 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42,
2625 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, 0x28, 0x81,
2626 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
2627 0x58, 0x3A, 0x48, 0xF3,
2628 0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, /* a */
2629 0x71, 0x45, 0xAC, 0x23, 0x4C, 0xC5, 0x94, 0xCB, 0xDD, 0x8D,
2630 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98,
2631 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1,
2632 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11,
2633 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D,
2634 0x77, 0xFC, 0x94, 0xCA,
2635 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, /* b */
2636 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1,
2637 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11,
2638 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D,
2639 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67, 0x98, 0x40,
2640 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63,
2641 0x80, 0x16, 0xF7, 0x23,
2642 0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, /* x */
2643 0x32, 0x2E, 0x9C, 0x4C, 0x6A, 0x93, 0x85, 0xED, 0x9F, 0x70,
2644 0xB5, 0xD9, 0x16, 0xC1, 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0,
2645 0x09, 0x8E, 0xFF, 0x3B, 0x1F, 0x78, 0xE2, 0xD0, 0xD4, 0x8D,
2646 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F, 0x7C, 0x6D,
2647 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09,
2648 0xBC, 0xB9, 0xF8, 0x22,
2649 0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, /* y */
2650 0xBF, 0xA9, 0xCF, 0x78, 0x22, 0xFD, 0xF2, 0x09, 0xF7, 0x00,
2651 0x24, 0xA5, 0x7B, 0x1A, 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F,
2652 0x81, 0x11, 0xB2, 0xDC, 0xDE, 0x49, 0x4A, 0x5F, 0x48, 0x5E,
2653 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE, 0xD1, 0xCA,
2654 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F,
2655 0x3A, 0xD8, 0x08, 0x92,
2656 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* order */
2657 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2658 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2659 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19,
2660 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, 0x1D, 0xB1,
2661 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82,
2662 0x9C, 0xA9, 0x00, 0x69
2663 }
2664};
2665
2666static const struct {
2667 EC_CURVE_DATA h;
2668 unsigned char data[0 + 64 * 6];
2669}
2670 _EC_brainpoolP512t1 = {
2671 {
2672 NID_X9_62_prime_field, 0, 64, 1
2673 },
2674 { /* no seed */
2675 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* p */
2676 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2677 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2678 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42,
2679 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, 0x28, 0x81,
2680 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
2681 0x58, 0x3A, 0x48, 0xF3,
2682 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* a */
2683 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2684 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2685 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42,
2686 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, 0x28, 0x81,
2687 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
2688 0x58, 0x3A, 0x48, 0xF0,
2689 0x7C, 0xBB, 0xBC, 0xF9, 0x44, 0x1C, 0xFA, 0xB7, 0x6E, 0x18, /* b */
2690 0x90, 0xE4, 0x68, 0x84, 0xEA, 0xE3, 0x21, 0xF7, 0x0C, 0x0B,
2691 0xCB, 0x49, 0x81, 0x52, 0x78, 0x97, 0x50, 0x4B, 0xEC, 0x3E,
2692 0x36, 0xA6, 0x2B, 0xCD, 0xFA, 0x23, 0x04, 0x97, 0x65, 0x40,
2693 0xF6, 0x45, 0x00, 0x85, 0xF2, 0xDA, 0xE1, 0x45, 0xC2, 0x25,
2694 0x53, 0xB4, 0x65, 0x76, 0x36, 0x89, 0x18, 0x0E, 0xA2, 0x57,
2695 0x18, 0x67, 0x42, 0x3E,
2696 0x64, 0x0E, 0xCE, 0x5C, 0x12, 0x78, 0x87, 0x17, 0xB9, 0xC1, /* x */
2697 0xBA, 0x06, 0xCB, 0xC2, 0xA6, 0xFE, 0xBA, 0x85, 0x84, 0x24,
2698 0x58, 0xC5, 0x6D, 0xDE, 0x9D, 0xB1, 0x75, 0x8D, 0x39, 0xC0,
2699 0x31, 0x3D, 0x82, 0xBA, 0x51, 0x73, 0x5C, 0xDB, 0x3E, 0xA4,
2700 0x99, 0xAA, 0x77, 0xA7, 0xD6, 0x94, 0x3A, 0x64, 0xF7, 0xA3,
2701 0xF2, 0x5F, 0xE2, 0x6F, 0x06, 0xB5, 0x1B, 0xAA, 0x26, 0x96,
2702 0xFA, 0x90, 0x35, 0xDA,
2703 0x5B, 0x53, 0x4B, 0xD5, 0x95, 0xF5, 0xAF, 0x0F, 0xA2, 0xC8, /* y */
2704 0x92, 0x37, 0x6C, 0x84, 0xAC, 0xE1, 0xBB, 0x4E, 0x30, 0x19,
2705 0xB7, 0x16, 0x34, 0xC0, 0x11, 0x31, 0x15, 0x9C, 0xAE, 0x03,
2706 0xCE, 0xE9, 0xD9, 0x93, 0x21, 0x84, 0xBE, 0xEF, 0x21, 0x6B,
2707 0xD7, 0x1D, 0xF2, 0xDA, 0xDF, 0x86, 0xA6, 0x27, 0x30, 0x6E,
2708 0xCF, 0xF9, 0x6D, 0xBB, 0x8B, 0xAC, 0xE1, 0x98, 0xB6, 0x1E,
2709 0x00, 0xF8, 0xB3, 0x32,
2710 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, /* order */
2711 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
2712 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
2713 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19,
2714 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, 0x1D, 0xB1,
2715 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82,
2716 0x9C, 0xA9, 0x00, 0x69
2717 }
2718};
2719
2720static const struct {
2721 EC_CURVE_DATA h;
2722 unsigned char data[0 + 32 * 6];
2723}
2724 _EC_FRP256v1 = {
2725 {
2726 NID_X9_62_prime_field, 0, 32, 1
2727 },
2728 { /* no seed */
2729 0xF1, 0xFD, 0x17, 0x8C, 0x0B, 0x3A, 0xD5, 0x8F, 0x10, 0x12, /* p */
2730 0x6D, 0xE8, 0xCE, 0x42, 0x43, 0x5B, 0x39, 0x61, 0xAD, 0xBC,
2731 0xAB, 0xC8, 0xCA, 0x6D, 0xE8, 0xFC, 0xF3, 0x53, 0xD8, 0x6E,
2732 0x9C, 0x03,
2733 0xF1, 0xFD, 0x17, 0x8C, 0x0B, 0x3A, 0xD5, 0x8F, 0x10, 0x12, /* a */
2734 0x6D, 0xE8, 0xCE, 0x42, 0x43, 0x5B, 0x39, 0x61, 0xAD, 0xBC,
2735 0xAB, 0xC8, 0xCA, 0x6D, 0xE8, 0xFC, 0xF3, 0x53, 0xD8, 0x6E,
2736 0x9C, 0x00,
2737 0xEE, 0x35, 0x3F, 0xCA, 0x54, 0x28, 0xA9, 0x30, 0x0D, 0x4A, /* b */
2738 0xBA, 0x75, 0x4A, 0x44, 0xC0, 0x0F, 0xDF, 0xEC, 0x0C, 0x9A,
2739 0xE4, 0xB1, 0xA1, 0x80, 0x30, 0x75, 0xED, 0x96, 0x7B, 0x7B,
2740 0xB7, 0x3F,
2741 0xB6, 0xB3, 0xD4, 0xC3, 0x56, 0xC1, 0x39, 0xEB, 0x31, 0x18, /* x */
2742 0x3D, 0x47, 0x49, 0xD4, 0x23, 0x95, 0x8C, 0x27, 0xD2, 0xDC,
2743 0xAF, 0x98, 0xB7, 0x01, 0x64, 0xC9, 0x7A, 0x2D, 0xD9, 0x8F,
2744 0x5C, 0xFF,
2745 0x61, 0x42, 0xE0, 0xF7, 0xC8, 0xB2, 0x04, 0x91, 0x1F, 0x92, /* y */
2746 0x71, 0xF0, 0xF3, 0xEC, 0xEF, 0x8C, 0x27, 0x01, 0xC3, 0x07,
2747 0xE8, 0xE4, 0xC9, 0xE1, 0x83, 0x11, 0x5A, 0x15, 0x54, 0x06,
2748 0x2C, 0xFB,
2749 0xF1, 0xFD, 0x17, 0x8C, 0x0B, 0x3A, 0xD5, 0x8F, 0x10, 0x12, /* order */
2750 0x6D, 0xE8, 0xCE, 0x42, 0x43, 0x5B, 0x53, 0xDC, 0x67, 0xE1,
2751 0x40, 0xD2, 0xBF, 0x94, 0x1F, 0xFD, 0xD4, 0x59, 0xC6, 0xD6,
2752 0x55, 0xE1
2753 }
2754};
2755
2756#ifndef OPENSSL_NO_GOST
2757static const struct {
2758 EC_CURVE_DATA h;
2759 unsigned char data[0 + 32 * 6];
2760}
2761 _EC_GOST_2001_Test = {
2762 {
2763 NID_X9_62_prime_field, 0, 32, 1
2764 },
2765 { /* no seed */
2766 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2769 0x04, 0x31,
2770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2773 0x00, 0x07,
2774 0x5F, 0xBF, 0xF4, 0x98, 0xAA, 0x93, 0x8C, 0xE7, 0x39, 0xB8, /* b */
2775 0xE0, 0x22, 0xFB, 0xAF, 0xEF, 0x40, 0x56, 0x3F, 0x6E, 0x6A,
2776 0x34, 0x72, 0xFC, 0x2A, 0x51, 0x4C, 0x0C, 0xE9, 0xDA, 0xE2,
2777 0x3B, 0x7E,
2778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2781 0x00, 0x02,
2782 0x08, 0xE2, 0xA8, 0xA0, 0xE6, 0x51, 0x47, 0xD4, 0xBD, 0x63, /* y */
2783 0x16, 0x03, 0x0E, 0x16, 0xD1, 0x9C, 0x85, 0xC9, 0x7F, 0x0A,
2784 0x9C, 0xA2, 0x67, 0x12, 0x2B, 0x96, 0xAB, 0xBC, 0xEA, 0x7E,
2785 0x8F, 0xC8,
2786 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
2787 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0xFE, 0x8A, 0x18,
2788 0x92, 0x97, 0x61, 0x54, 0xC5, 0x9C, 0xFC, 0x19, 0x3A, 0xCC,
2789 0xF5, 0xB3,
2790 }
2791};
2792
2793static const struct {
2794 EC_CURVE_DATA h;
2795 unsigned char data[0 + 32 * 6];
2796}
2797 _EC_GOST_2001_CryptoPro_A = {
2798 {
2799 NID_X9_62_prime_field, 0, 32, 1
2800 },
2801 { /* no seed */
2802 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
2803 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2804 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2805 0xFD, 0x97,
2806 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
2807 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2808 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2809 0xFD, 0x94,
2810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2813 0x00, 0xA6,
2814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2817 0x00, 0x01,
2818 0x8D, 0x91, 0xE4, 0x71, 0xE0, 0x98, 0x9C, 0xDA, 0x27, 0xDF, /* y */
2819 0x50, 0x5A, 0x45, 0x3F, 0x2B, 0x76, 0x35, 0x29, 0x4F, 0x2D,
2820 0xDF, 0x23, 0xE3, 0xB1, 0x22, 0xAC, 0xC9, 0x9C, 0x9E, 0x9F,
2821 0x1E, 0x14,
2822 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* order */
2823 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6C, 0x61, 0x10, 0x70,
2824 0x99, 0x5A, 0xD1, 0x00, 0x45, 0x84, 0x1B, 0x09, 0xB7, 0x61,
2825 0xB8, 0x93,
2826 }
2827};
2828
2829static const struct {
2830 EC_CURVE_DATA h;
2831 unsigned char data[0 + 32 * 6];
2832}
2833 _EC_GOST_2001_CryptoPro_B = {
2834 {
2835 NID_X9_62_prime_field, 0, 32, 1
2836 },
2837 { /* no seed */
2838 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2841 0x0C, 0x99,
2842 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2845 0x0C, 0x96,
2846 0x3E, 0x1A, 0xF4, 0x19, 0xA2, 0x69, 0xA5, 0xF8, 0x66, 0xA7, /* b */
2847 0xD3, 0xC2, 0x5C, 0x3D, 0xF8, 0x0A, 0xE9, 0x79, 0x25, 0x93,
2848 0x73, 0xFF, 0x2B, 0x18, 0x2F, 0x49, 0xD4, 0xCE, 0x7E, 0x1B,
2849 0xBC, 0x8B,
2850 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2851 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2852 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2853 0x00, 0x01,
2854 0x3F, 0xA8, 0x12, 0x43, 0x59, 0xF9, 0x66, 0x80, 0xB8, 0x3D, /* y */
2855 0x1C, 0x3E, 0xB2, 0xC0, 0x70, 0xE5, 0xC5, 0x45, 0xC9, 0x85,
2856 0x8D, 0x03, 0xEC, 0xFB, 0x74, 0x4B, 0xF8, 0xD7, 0x17, 0x71,
2857 0x7E, 0xFC,
2858 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
2859 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5F, 0x70, 0x0C, 0xFF,
2860 0xF1, 0xA6, 0x24, 0xE5, 0xE4, 0x97, 0x16, 0x1B, 0xCC, 0x8A,
2861 0x19, 0x8F,
2862 }
2863};
2864
2865static const struct {
2866 EC_CURVE_DATA h;
2867 unsigned char data[0 + 32 * 6];
2868}
2869 _EC_GOST_2001_CryptoPro_C = {
2870 {
2871 NID_X9_62_prime_field, 0, 32, 1
2872 },
2873 { /* no seed */
2874 0x9B, 0x9F, 0x60, 0x5F, 0x5A, 0x85, 0x81, 0x07, 0xAB, 0x1E, /* p */
2875 0xC8, 0x5E, 0x6B, 0x41, 0xC8, 0xAA, 0xCF, 0x84, 0x6E, 0x86,
2876 0x78, 0x90, 0x51, 0xD3, 0x79, 0x98, 0xF7, 0xB9, 0x02, 0x2D,
2877 0x75, 0x9B,
2878 0x9B, 0x9F, 0x60, 0x5F, 0x5A, 0x85, 0x81, 0x07, 0xAB, 0x1E, /* a */
2879 0xC8, 0x5E, 0x6B, 0x41, 0xC8, 0xAA, 0xCF, 0x84, 0x6E, 0x86,
2880 0x78, 0x90, 0x51, 0xD3, 0x79, 0x98, 0xF7, 0xB9, 0x02, 0x2D,
2881 0x75, 0x98,
2882 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
2883 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2884 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2885 0x80, 0x5A,
2886 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2887 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2889 0x00, 0x00,
2890 0x41, 0xEC, 0xE5, 0x57, 0x43, 0x71, 0x1A, 0x8C, 0x3C, 0xBF, /* y */
2891 0x37, 0x83, 0xCD, 0x08, 0xC0, 0xEE, 0x4D, 0x4D, 0xC4, 0x40,
2892 0xD4, 0x64, 0x1A, 0x8F, 0x36, 0x6E, 0x55, 0x0D, 0xFD, 0xB3,
2893 0xBB, 0x67,
2894 0x9B, 0x9F, 0x60, 0x5F, 0x5A, 0x85, 0x81, 0x07, 0xAB, 0x1E, /* order */
2895 0xC8, 0x5E, 0x6B, 0x41, 0xC8, 0xAA, 0x58, 0x2C, 0xA3, 0x51,
2896 0x1E, 0xDD, 0xFB, 0x74, 0xF0, 0x2F, 0x3A, 0x65, 0x98, 0x98,
2897 0x0B, 0xB9,
2898 }
2899};
2900
2901static const struct {
2902 EC_CURVE_DATA h;
2903 unsigned char data[0 + 64 * 6];
2904}
2905 _EC_GOST_2012_TC26_A = {
2906 {
2907 NID_X9_62_prime_field, 0, 64, 1
2908 },
2909 { /* no seed */
2910 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */
2911 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2912 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
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, 0xfd, 0xc7,
2917 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a */
2918 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2919 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
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, 0xfd, 0xc4,
2924 0xe8, 0xc2, 0x50, 0x5d, 0xed, 0xfc, 0x86, 0xdd, 0xc1, 0xbd, /* b */
2925 0x0b, 0x2b, 0x66, 0x67, 0xf1, 0xda, 0x34, 0xb8, 0x25, 0x74,
2926 0x76, 0x1c, 0xb0, 0xe8, 0x79, 0xbd, 0x08, 0x1c, 0xfd, 0x0b,
2927 0x62, 0x65, 0xee, 0x3c, 0xb0, 0x90, 0xf3, 0x0d, 0x27, 0x61,
2928 0x4c, 0xb4, 0x57, 0x40, 0x10, 0xda, 0x90, 0xdd, 0x86, 0x2e,
2929 0xf9, 0xd4, 0xeb, 0xee, 0x47, 0x61, 0x50, 0x31, 0x90, 0x78,
2930 0x5a, 0x71, 0xc7, 0x60,
2931 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2932 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2933 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x03,
2938 0x75, 0x03, 0xcf, 0xe8, 0x7a, 0x83, 0x6a, 0xe3, 0xa6, 0x1b, /* y */
2939 0x88, 0x16, 0xe2, 0x54, 0x50, 0xe6, 0xce, 0x5e, 0x1c, 0x93,
2940 0xac, 0xf1, 0xab, 0xc1, 0x77, 0x80, 0x64, 0xfd, 0xcb, 0xef,
2941 0xa9, 0x21, 0xdf, 0x16, 0x26, 0xbe, 0x4f, 0xd0, 0x36, 0xe9,
2942 0x3d, 0x75, 0xe6, 0xa5, 0x0e, 0x3a, 0x41, 0xe9, 0x80, 0x28,
2943 0xfe, 0x5f, 0xc2, 0x35, 0xf5, 0xb8, 0x89, 0xa5, 0x89, 0xcb,
2944 0x52, 0x15, 0xf2, 0xa4,
2945 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* order */
2946 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2947 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2948 0xff, 0xff, 0x27, 0xe6, 0x95, 0x32, 0xf4, 0x8d, 0x89, 0x11,
2949 0x6f, 0xf2, 0x2b, 0x8d, 0x4e, 0x05, 0x60, 0x60, 0x9b, 0x4b,
2950 0x38, 0xab, 0xfa, 0xd2, 0xb8, 0x5d, 0xca, 0xcd, 0xb1, 0x41,
2951 0x1f, 0x10, 0xb2, 0x75
2952 }
2953};
2954
2955static const struct {
2956 EC_CURVE_DATA h;
2957 unsigned char data[0 + 64 * 6];
2958}
2959 _EC_GOST_2012_TC26_B = {
2960 {
2961 NID_X9_62_prime_field, 0, 64, 1
2962 },
2963 { /* no seed */
2964 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* p */
2965 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2966 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x6f,
2971 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
2972 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2973 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x6c,
2978 0x68, 0x7d, 0x1b, 0x45, 0x9d, 0xc8, 0x41, 0x45, 0x7e, 0x3e, /* b */
2979 0x06, 0xcf, 0x6f, 0x5e, 0x25, 0x17, 0xb9, 0x7c, 0x7d, 0x61,
2980 0x4a, 0xf1, 0x38, 0xbc, 0xbf, 0x85, 0xdc, 0x80, 0x6c, 0x4b,
2981 0x28, 0x9f, 0x3e, 0x96, 0x5d, 0x2d, 0xb1, 0x41, 0x6d, 0x21,
2982 0x7f, 0x8b, 0x27, 0x6f, 0xad, 0x1a, 0xb6, 0x9c, 0x50, 0xf7,
2983 0x8b, 0xee, 0x1f, 0xa3, 0x10, 0x6e, 0xfb, 0x8c, 0xcb, 0xc7,
2984 0xc5, 0x14, 0x01, 0x16,
2985 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */
2986 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x02,
2992 0x1a, 0x8f, 0x7e, 0xda, 0x38, 0x9b, 0x09, 0x4c, 0x2c, 0x07, /* y */
2993 0x1e, 0x36, 0x47, 0xa8, 0x94, 0x0f, 0x3c, 0x12, 0x3b, 0x69,
2994 0x75, 0x78, 0xc2, 0x13, 0xbe, 0x6d, 0xd9, 0xe6, 0xc8, 0xec,
2995 0x73, 0x35, 0xdc, 0xb2, 0x28, 0xfd, 0x1e, 0xdf, 0x4a, 0x39,
2996 0x15, 0x2c, 0xbc, 0xaa, 0xf8, 0xc0, 0x39, 0x88, 0x28, 0x04,
2997 0x10, 0x55, 0xf9, 0x4c, 0xee, 0xec, 0x7e, 0x21, 0x34, 0x07,
2998 0x80, 0xfe, 0x41, 0xbd,
2999 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* order */
3000 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3001 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3002 0x00, 0x01, 0x49, 0xa1, 0xec, 0x14, 0x25, 0x65, 0xa5, 0x45,
3003 0xac, 0xfd, 0xb7, 0x7b, 0xd9, 0xd4, 0x0c, 0xfa, 0x8b, 0x99,
3004 0x67, 0x12, 0x10, 0x1b, 0xea, 0x0e, 0xc6, 0x34, 0x6c, 0x54,
3005 0x37, 0x4f, 0x25, 0xbd
3006 }
3007};
3008
3009#endif
3010
3011typedef struct _ec_list_element_st {
3012 int nid;
3013 const EC_CURVE_DATA *data;
3014 const EC_METHOD *(*meth) (void);
3015 const char *comment;
3016} ec_list_element;
3017
3018static const ec_list_element curve_list[] = {
3019 /* prime field curves */
3020 /* secg curves */
3021 {NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field"},
3022 {NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0, "SECG curve over a 112 bit prime field"},
3023 {NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0, "SECG curve over a 128 bit prime field"},
3024 {NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0, "SECG curve over a 128 bit prime field"},
3025 {NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0, "SECG curve over a 160 bit prime field"},
3026 {NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0, "SECG curve over a 160 bit prime field"},
3027 {NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field"},
3028 /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
3029 {NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, "SECG curve over a 192 bit prime field"},
3030 {NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field"},
3031#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
3032 {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field"},
3033#else
3034 {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field"},
3035#endif
3036 {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field"},
3037 /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
3038 {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field"},
3039#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
3040 {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field"},
3041#else
3042 {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field"},
3043#endif
3044 /* X9.62 curves */
3045 {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field"},
3046 {NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, "X9.62 curve over a 192 bit prime field"},
3047 {NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0, "X9.62 curve over a 192 bit prime field"},
3048 {NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, "X9.62 curve over a 239 bit prime field"},
3049 {NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field"},
3050 {NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field"},
3051#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
3052 {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, "X9.62/SECG curve over a 256 bit prime field"},
3053#else
3054 {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field"},
3055#endif
3056#ifndef OPENSSL_NO_EC2M
3057 /* characteristic two field curves */
3058 /* NIST/SECG curves */
3059 {NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field"},
3060 {NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0, "SECG curve over a 113 bit binary field"},
3061 {NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0, "SECG/WTLS curve over a 131 bit binary field"},
3062 {NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0, "SECG curve over a 131 bit binary field"},
3063 {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field"},
3064 {NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0, "SECG curve over a 163 bit binary field"},
3065 {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, "NIST/SECG curve over a 163 bit binary field"},
3066 {NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0, "SECG curve over a 193 bit binary field"},
3067 {NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0, "SECG curve over a 193 bit binary field"},
3068 {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
3069 {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
3070 {NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0, "SECG curve over a 239 bit binary field"},
3071 {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, "NIST/SECG curve over a 283 bit binary field"},
3072 {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, "NIST/SECG curve over a 283 bit binary field"},
3073 {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, "NIST/SECG curve over a 409 bit binary field"},
3074 {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, "NIST/SECG curve over a 409 bit binary field"},
3075 {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, "NIST/SECG curve over a 571 bit binary field"},
3076 {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, "NIST/SECG curve over a 571 bit binary field"},
3077 /* X9.62 curves */
3078 {NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field"},
3079 {NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0, "X9.62 curve over a 163 bit binary field"},
3080 {NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0, "X9.62 curve over a 163 bit binary field"},
3081 {NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0, "X9.62 curve over a 176 bit binary field"},
3082 {NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0, "X9.62 curve over a 191 bit binary field"},
3083 {NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0, "X9.62 curve over a 191 bit binary field"},
3084 {NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0, "X9.62 curve over a 191 bit binary field"},
3085 {NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0, "X9.62 curve over a 208 bit binary field"},
3086 {NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0, "X9.62 curve over a 239 bit binary field"},
3087 {NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0, "X9.62 curve over a 239 bit binary field"},
3088 {NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0, "X9.62 curve over a 239 bit binary field"},
3089 {NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0, "X9.62 curve over a 272 bit binary field"},
3090 {NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0, "X9.62 curve over a 304 bit binary field"},
3091 {NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0, "X9.62 curve over a 359 bit binary field"},
3092 {NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0, "X9.62 curve over a 368 bit binary field"},
3093 {NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0, "X9.62 curve over a 431 bit binary field"},
3094 /*
3095 * the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves
3096 * from X9.62]
3097 */
3098 {NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0, "WTLS curve over a 113 bit binary field"},
3099 {NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field"},
3100 {NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field"},
3101 {NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field"},
3102#endif
3103 {NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field"},
3104 {NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field"},
3105 {NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, "WTLS curve over a 112 bit prime field"},
3106 {NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, "WTLS curve over a 160 bit prime field"},
3107#ifndef OPENSSL_NO_EC2M
3108 {NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
3109 {NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
3110#endif
3111 {NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, "WTLS curve over a 224 bit prime field"},
3112#ifndef OPENSSL_NO_EC2M
3113 /* IPSec curves */
3114 {NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
3115 "\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
3116 {NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
3117 "\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
3118#endif
3119 /* RFC 5639 curves */
3120 {NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0, "RFC 5639 curve over a 160 bit prime field"},
3121 {NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0, "RFC 5639 curve over a 160 bit prime field"},
3122 {NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0, "RFC 5639 curve over a 192 bit prime field"},
3123 {NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0, "RFC 5639 curve over a 192 bit prime field"},
3124 {NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0, "RFC 5639 curve over a 224 bit prime field"},
3125 {NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0, "RFC 5639 curve over a 224 bit prime field"},
3126 {NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0, "RFC 5639 curve over a 256 bit prime field"},
3127 {NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0, "RFC 5639 curve over a 256 bit prime field"},
3128 {NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0, "RFC 5639 curve over a 320 bit prime field"},
3129 {NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0, "RFC 5639 curve over a 320 bit prime field"},
3130 {NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0, "RFC 5639 curve over a 384 bit prime field"},
3131 {NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0, "RFC 5639 curve over a 384 bit prime field"},
3132 {NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0, "RFC 5639 curve over a 512 bit prime field"},
3133 {NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0, "RFC 5639 curve over a 512 bit prime field"},
3134 /* ANSSI */
3135 {NID_FRP256v1, &_EC_FRP256v1.h, 0, "FRP256v1"},
3136#ifndef OPENSSL_NO_GOST
3137 /* GOST R 34.10-2001 */
3138 {NID_id_GostR3410_2001_TestParamSet, &_EC_GOST_2001_Test.h, 0, "GOST R 34.10-2001 Test Curve"},
3139 {NID_id_GostR3410_2001_CryptoPro_A_ParamSet, &_EC_GOST_2001_CryptoPro_A.h, 0, "GOST R 34.10-2001 CryptoPro-A"},
3140 {NID_id_GostR3410_2001_CryptoPro_B_ParamSet, &_EC_GOST_2001_CryptoPro_B.h, 0, "GOST R 34.10-2001 CryptoPro-B"},
3141 {NID_id_GostR3410_2001_CryptoPro_C_ParamSet, &_EC_GOST_2001_CryptoPro_C.h, 0, "GOST R 34.10-2001 CryptoPro-C"},
3142 {NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, &_EC_GOST_2001_CryptoPro_A.h, 0, "GOST R 34.10-2001 CryptoPro-XchA"},
3143 {NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, &_EC_GOST_2001_CryptoPro_C.h, 0, "GOST R 34.10-2001 CryptoPro-XchB"},
3144 {NID_id_tc26_gost_3410_2012_512_paramSetA, &_EC_GOST_2012_TC26_A.h, 0, "GOST R 34.10-2012 TC26-A"},
3145 {NID_id_tc26_gost_3410_2012_512_paramSetB, &_EC_GOST_2012_TC26_B.h, 0, "GOST R 34.10-2012 TC26-B"},
3146#endif
3147};
3148
3149#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
3150
3151static EC_GROUP *
3152ec_group_new_from_data(const ec_list_element curve)
3153{
3154 EC_GROUP *group = NULL;
3155 EC_POINT *P = NULL;
3156 BN_CTX *ctx = NULL;
3157 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
3158 int ok = 0;
3159 int seed_len, param_len;
3160 const EC_METHOD *meth;
3161 const EC_CURVE_DATA *data;
3162 const unsigned char *params;
3163
3164 if ((ctx = BN_CTX_new()) == NULL) {
3165 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
3166 goto err;
3167 }
3168 data = curve.data;
3169 seed_len = data->seed_len;
3170 param_len = data->param_len;
3171 params = (const unsigned char *) (data + 1); /* skip header */
3172 params += seed_len; /* skip seed */
3173
3174 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
3175 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
3176 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
3177 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
3178 goto err;
3179 }
3180 if (curve.meth != 0) {
3181 meth = curve.meth();
3182 if (((group = EC_GROUP_new(meth)) == NULL) ||
3183 (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
3184 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3185 goto err;
3186 }
3187 } else if (data->field_type == NID_X9_62_prime_field) {
3188 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
3189 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3190 goto err;
3191 }
3192 }
3193#ifndef OPENSSL_NO_EC2M
3194 else { /* field_type ==
3195 * NID_X9_62_characteristic_two_field */
3196 if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) {
3197 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3198 goto err;
3199 }
3200 }
3201#endif
3202
3203 if ((P = EC_POINT_new(group)) == NULL) {
3204 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3205 goto err;
3206 }
3207 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL))
3208 || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
3209 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
3210 goto err;
3211 }
3212 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
3213 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3214 goto err;
3215 }
3216 if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL))
3217 || !BN_set_word(x, (BN_ULONG) data->cofactor)) {
3218 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
3219 goto err;
3220 }
3221 if (!EC_GROUP_set_generator(group, P, order, x)) {
3222 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3223 goto err;
3224 }
3225 if (seed_len) {
3226 if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) {
3227 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
3228 goto err;
3229 }
3230 }
3231 ok = 1;
3232err:
3233 if (!ok) {
3234 EC_GROUP_free(group);
3235 group = NULL;
3236 }
3237 EC_POINT_free(P);
3238 BN_CTX_free(ctx);
3239 BN_free(p);
3240 BN_free(a);
3241 BN_free(b);
3242 BN_free(order);
3243 BN_free(x);
3244 BN_free(y);
3245 return group;
3246}
3247
3248EC_GROUP *
3249EC_GROUP_new_by_curve_name(int nid)
3250{
3251 size_t i;
3252 EC_GROUP *ret = NULL;
3253
3254 if (nid <= 0)
3255 return NULL;
3256
3257 for (i = 0; i < curve_list_length; i++)
3258 if (curve_list[i].nid == nid) {
3259 ret = ec_group_new_from_data(curve_list[i]);
3260 break;
3261 }
3262 if (ret == NULL) {
3263 ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
3264 return NULL;
3265 }
3266 EC_GROUP_set_curve_name(ret, nid);
3267
3268 return ret;
3269}
3270
3271size_t
3272EC_get_builtin_curves(EC_builtin_curve * r, size_t nitems)
3273{
3274 size_t i, min;
3275
3276 if (r == NULL || nitems == 0)
3277 return curve_list_length;
3278
3279 min = nitems < curve_list_length ? nitems : curve_list_length;
3280
3281 for (i = 0; i < min; i++) {
3282 r[i].nid = curve_list[i].nid;
3283 r[i].comment = curve_list[i].comment;
3284 }
3285
3286 return curve_list_length;
3287}
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 45192c3231..0000000000
--- a/src/lib/libcrypto/ec/ec_key.c
+++ /dev/null
@@ -1,540 +0,0 @@
1/* $OpenBSD: ec_key.c,v 1.11 2015/02/09 15:49:22 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 OPENSSL_cleanse((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 8cf0f2241e..0000000000
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ /dev/null
@@ -1,1109 +0,0 @@
1/* $OpenBSD: ec_lib.c,v 1.16 2015/02/09 15:49:22 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 OPENSSL_cleanse(group->seed, group->seed_len);
156 free(group->seed);
157 }
158 OPENSSL_cleanse(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 if (!memcpy(dest->seed, src->seed, src->seed_len))
220 return 0;
221 dest->seed_len = src->seed_len;
222 } else {
223 free(dest->seed);
224 dest->seed = NULL;
225 dest->seed_len = 0;
226 }
227
228
229 return dest->meth->group_copy(dest, src);
230}
231
232
233EC_GROUP *
234EC_GROUP_dup(const EC_GROUP * a)
235{
236 EC_GROUP *t = NULL;
237 int ok = 0;
238
239 if (a == NULL)
240 return NULL;
241
242 if ((t = EC_GROUP_new(a->meth)) == NULL)
243 return (NULL);
244 if (!EC_GROUP_copy(t, a))
245 goto err;
246
247 ok = 1;
248
249err:
250 if (!ok) {
251 EC_GROUP_free(t);
252 return NULL;
253 } else
254 return t;
255}
256
257
258const EC_METHOD *
259EC_GROUP_method_of(const EC_GROUP *group)
260{
261 return group->meth;
262}
263
264
265int
266EC_METHOD_get_field_type(const EC_METHOD *meth)
267{
268 return meth->field_type;
269}
270
271
272int
273EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
274 const BIGNUM *order, const BIGNUM *cofactor)
275{
276 if (generator == NULL) {
277 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
278 return 0;
279 }
280 if (group->generator == NULL) {
281 group->generator = EC_POINT_new(group);
282 if (group->generator == NULL)
283 return 0;
284 }
285 if (!EC_POINT_copy(group->generator, generator))
286 return 0;
287
288 if (order != NULL) {
289 if (!BN_copy(&group->order, order))
290 return 0;
291 } else
292 BN_zero(&group->order);
293
294 if (cofactor != NULL) {
295 if (!BN_copy(&group->cofactor, cofactor))
296 return 0;
297 } else
298 BN_zero(&group->cofactor);
299
300 return 1;
301}
302
303
304const EC_POINT *
305EC_GROUP_get0_generator(const EC_GROUP *group)
306{
307 return group->generator;
308}
309
310
311int
312EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
313{
314 if (!BN_copy(order, &group->order))
315 return 0;
316
317 return !BN_is_zero(order);
318}
319
320
321int
322EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
323{
324 if (!BN_copy(cofactor, &group->cofactor))
325 return 0;
326
327 return !BN_is_zero(&group->cofactor);
328}
329
330
331void
332EC_GROUP_set_curve_name(EC_GROUP * group, int nid)
333{
334 group->curve_name = nid;
335}
336
337
338int
339EC_GROUP_get_curve_name(const EC_GROUP * group)
340{
341 return group->curve_name;
342}
343
344
345void
346EC_GROUP_set_asn1_flag(EC_GROUP * group, int flag)
347{
348 group->asn1_flag = flag;
349}
350
351
352int
353EC_GROUP_get_asn1_flag(const EC_GROUP * group)
354{
355 return group->asn1_flag;
356}
357
358
359void
360EC_GROUP_set_point_conversion_form(EC_GROUP * group,
361 point_conversion_form_t form)
362{
363 group->asn1_form = form;
364}
365
366
367point_conversion_form_t
368EC_GROUP_get_point_conversion_form(const EC_GROUP * group)
369{
370 return group->asn1_form;
371}
372
373
374size_t
375EC_GROUP_set_seed(EC_GROUP * group, const unsigned char *p, size_t len)
376{
377 if (group->seed) {
378 free(group->seed);
379 group->seed = NULL;
380 group->seed_len = 0;
381 }
382 if (!len || !p)
383 return 1;
384
385 if ((group->seed = malloc(len)) == NULL)
386 return 0;
387 memcpy(group->seed, p, len);
388 group->seed_len = len;
389
390 return len;
391}
392
393
394unsigned char *
395EC_GROUP_get0_seed(const EC_GROUP * group)
396{
397 return group->seed;
398}
399
400
401size_t
402EC_GROUP_get_seed_len(const EC_GROUP * group)
403{
404 return group->seed_len;
405}
406
407
408int
409EC_GROUP_set_curve_GFp(EC_GROUP * group, const BIGNUM * p, const BIGNUM * a,
410 const BIGNUM * b, BN_CTX * ctx)
411{
412 if (group->meth->group_set_curve == 0) {
413 ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
414 return 0;
415 }
416 return group->meth->group_set_curve(group, p, a, b, ctx);
417}
418
419
420int
421EC_GROUP_get_curve_GFp(const EC_GROUP * group, BIGNUM * p, BIGNUM * a,
422 BIGNUM * b, BN_CTX * ctx)
423{
424 if (group->meth->group_get_curve == 0) {
425 ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
426 return 0;
427 }
428 return group->meth->group_get_curve(group, p, a, b, ctx);
429}
430
431#ifndef OPENSSL_NO_EC2M
432int
433EC_GROUP_set_curve_GF2m(EC_GROUP * group, const BIGNUM * p, const BIGNUM * a,
434 const BIGNUM * b, BN_CTX * ctx)
435{
436 if (group->meth->group_set_curve == 0) {
437 ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
438 return 0;
439 }
440 return group->meth->group_set_curve(group, p, a, b, ctx);
441}
442
443
444int
445EC_GROUP_get_curve_GF2m(const EC_GROUP * group, BIGNUM * p, BIGNUM * a,
446 BIGNUM * b, BN_CTX * ctx)
447{
448 if (group->meth->group_get_curve == 0) {
449 ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
450 return 0;
451 }
452 return group->meth->group_get_curve(group, p, a, b, ctx);
453}
454#endif
455
456int
457EC_GROUP_get_degree(const EC_GROUP * group)
458{
459 if (group->meth->group_get_degree == 0) {
460 ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
461 return 0;
462 }
463 return group->meth->group_get_degree(group);
464}
465
466
467int
468EC_GROUP_check_discriminant(const EC_GROUP * group, BN_CTX * ctx)
469{
470 if (group->meth->group_check_discriminant == 0) {
471 ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
472 return 0;
473 }
474 return group->meth->group_check_discriminant(group, ctx);
475}
476
477
478int
479EC_GROUP_cmp(const EC_GROUP * a, const EC_GROUP * b, BN_CTX * ctx)
480{
481 int r = 0;
482 BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
483 BN_CTX *ctx_new = NULL;
484
485 /* compare the field types */
486 if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
487 EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
488 return 1;
489 /* compare the curve name (if present in both) */
490 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
491 EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
492 return 1;
493
494 if (!ctx)
495 ctx_new = ctx = BN_CTX_new();
496 if (!ctx)
497 return -1;
498
499 BN_CTX_start(ctx);
500 if ((a1 = BN_CTX_get(ctx)) == NULL)
501 goto err;
502 if ((a2 = BN_CTX_get(ctx)) == NULL)
503 goto err;
504 if ((a3 = BN_CTX_get(ctx)) == NULL)
505 goto err;
506 if ((b1 = BN_CTX_get(ctx)) == NULL)
507 goto err;
508 if ((b2 = BN_CTX_get(ctx)) == NULL)
509 goto err;
510 if ((b3 = BN_CTX_get(ctx)) == NULL)
511 goto err;
512
513 /*
514 * XXX This approach assumes that the external representation of
515 * curves over the same field type is the same.
516 */
517 if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
518 !b->meth->group_get_curve(b, b1, b2, b3, ctx))
519 r = 1;
520
521 if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
522 r = 1;
523
524 /* XXX EC_POINT_cmp() assumes that the methods are equal */
525 if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
526 EC_GROUP_get0_generator(b), ctx))
527 r = 1;
528
529 if (!r) {
530 /* compare the order and cofactor */
531 if (!EC_GROUP_get_order(a, a1, ctx) ||
532 !EC_GROUP_get_order(b, b1, ctx) ||
533 !EC_GROUP_get_cofactor(a, a2, ctx) ||
534 !EC_GROUP_get_cofactor(b, b2, ctx)) {
535 BN_CTX_end(ctx);
536 if (ctx_new)
537 BN_CTX_free(ctx);
538 return -1;
539 }
540 if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
541 r = 1;
542 }
543 BN_CTX_end(ctx);
544 if (ctx_new)
545 BN_CTX_free(ctx);
546
547 return r;
548
549err:
550 BN_CTX_end(ctx);
551 if (ctx_new)
552 BN_CTX_free(ctx);
553 return -1;
554}
555
556
557/* this has 'package' visibility */
558int
559EC_EX_DATA_set_data(EC_EXTRA_DATA ** ex_data, void *data,
560 void *(*dup_func) (void *),
561 void (*free_func) (void *),
562 void (*clear_free_func) (void *))
563{
564 EC_EXTRA_DATA *d;
565
566 if (ex_data == NULL)
567 return 0;
568
569 for (d = *ex_data; d != NULL; d = d->next) {
570 if (d->dup_func == dup_func && d->free_func == free_func &&
571 d->clear_free_func == clear_free_func) {
572 ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
573 return 0;
574 }
575 }
576
577 if (data == NULL)
578 /* no explicit entry needed */
579 return 1;
580
581 d = malloc(sizeof *d);
582 if (d == NULL)
583 return 0;
584
585 d->data = data;
586 d->dup_func = dup_func;
587 d->free_func = free_func;
588 d->clear_free_func = clear_free_func;
589
590 d->next = *ex_data;
591 *ex_data = d;
592
593 return 1;
594}
595
596/* this has 'package' visibility */
597void *
598EC_EX_DATA_get_data(const EC_EXTRA_DATA * ex_data,
599 void *(*dup_func) (void *),
600 void (*free_func) (void *),
601 void (*clear_free_func) (void *))
602{
603 const EC_EXTRA_DATA *d;
604
605 for (d = ex_data; d != NULL; d = d->next) {
606 if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
607 return d->data;
608 }
609
610 return NULL;
611}
612
613/* this has 'package' visibility */
614void
615EC_EX_DATA_free_data(EC_EXTRA_DATA ** ex_data,
616 void *(*dup_func) (void *),
617 void (*free_func) (void *),
618 void (*clear_free_func) (void *))
619{
620 EC_EXTRA_DATA **p;
621
622 if (ex_data == NULL)
623 return;
624
625 for (p = ex_data; *p != NULL; p = &((*p)->next)) {
626 if ((*p)->dup_func == dup_func &&
627 (*p)->free_func == free_func &&
628 (*p)->clear_free_func == clear_free_func) {
629 EC_EXTRA_DATA *next = (*p)->next;
630
631 (*p)->free_func((*p)->data);
632 free(*p);
633
634 *p = next;
635 return;
636 }
637 }
638}
639
640/* this has 'package' visibility */
641void
642EC_EX_DATA_clear_free_data(EC_EXTRA_DATA ** ex_data,
643 void *(*dup_func) (void *),
644 void (*free_func) (void *),
645 void (*clear_free_func) (void *))
646{
647 EC_EXTRA_DATA **p;
648
649 if (ex_data == NULL)
650 return;
651
652 for (p = ex_data; *p != NULL; p = &((*p)->next)) {
653 if ((*p)->dup_func == dup_func &&
654 (*p)->free_func == free_func &&
655 (*p)->clear_free_func == clear_free_func) {
656 EC_EXTRA_DATA *next = (*p)->next;
657
658 (*p)->clear_free_func((*p)->data);
659 free(*p);
660
661 *p = next;
662 return;
663 }
664 }
665}
666
667/* this has 'package' visibility */
668void
669EC_EX_DATA_free_all_data(EC_EXTRA_DATA ** ex_data)
670{
671 EC_EXTRA_DATA *d;
672
673 if (ex_data == NULL)
674 return;
675
676 d = *ex_data;
677 while (d) {
678 EC_EXTRA_DATA *next = d->next;
679
680 d->free_func(d->data);
681 free(d);
682
683 d = next;
684 }
685 *ex_data = NULL;
686}
687
688/* this has 'package' visibility */
689void
690EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA ** ex_data)
691{
692 EC_EXTRA_DATA *d;
693
694 if (ex_data == NULL)
695 return;
696
697 d = *ex_data;
698 while (d) {
699 EC_EXTRA_DATA *next = d->next;
700
701 d->clear_free_func(d->data);
702 free(d);
703
704 d = next;
705 }
706 *ex_data = NULL;
707}
708
709
710/* functions for EC_POINT objects */
711
712EC_POINT *
713EC_POINT_new(const EC_GROUP * group)
714{
715 EC_POINT *ret;
716
717 if (group == NULL) {
718 ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
719 return NULL;
720 }
721 if (group->meth->point_init == 0) {
722 ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
723 return NULL;
724 }
725 ret = malloc(sizeof *ret);
726 if (ret == NULL) {
727 ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
728 return NULL;
729 }
730 ret->meth = group->meth;
731
732 if (!ret->meth->point_init(ret)) {
733 free(ret);
734 return NULL;
735 }
736 return ret;
737}
738
739
740void
741EC_POINT_free(EC_POINT * point)
742{
743 if (!point)
744 return;
745
746 if (point->meth->point_finish != 0)
747 point->meth->point_finish(point);
748 free(point);
749}
750
751
752void
753EC_POINT_clear_free(EC_POINT * point)
754{
755 if (!point)
756 return;
757
758 if (point->meth->point_clear_finish != 0)
759 point->meth->point_clear_finish(point);
760 else if (point->meth->point_finish != 0)
761 point->meth->point_finish(point);
762 OPENSSL_cleanse(point, sizeof *point);
763 free(point);
764}
765
766
767int
768EC_POINT_copy(EC_POINT * dest, const EC_POINT * src)
769{
770 if (dest->meth->point_copy == 0) {
771 ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
772 return 0;
773 }
774 if (dest->meth != src->meth) {
775 ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
776 return 0;
777 }
778 if (dest == src)
779 return 1;
780 return dest->meth->point_copy(dest, src);
781}
782
783
784EC_POINT *
785EC_POINT_dup(const EC_POINT * a, const EC_GROUP * group)
786{
787 EC_POINT *t;
788 int r;
789
790 if (a == NULL)
791 return NULL;
792
793 t = EC_POINT_new(group);
794 if (t == NULL)
795 return (NULL);
796 r = EC_POINT_copy(t, a);
797 if (!r) {
798 EC_POINT_free(t);
799 return NULL;
800 } else
801 return t;
802}
803
804
805const EC_METHOD *
806EC_POINT_method_of(const EC_POINT * point)
807{
808 return point->meth;
809}
810
811
812int
813EC_POINT_set_to_infinity(const EC_GROUP * group, EC_POINT * point)
814{
815 if (group->meth->point_set_to_infinity == 0) {
816 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
817 return 0;
818 }
819 if (group->meth != point->meth) {
820 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
821 return 0;
822 }
823 return group->meth->point_set_to_infinity(group, point);
824}
825
826
827int
828EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
829 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
830{
831 if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
832 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
833 return 0;
834 }
835 if (group->meth != point->meth) {
836 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
837 return 0;
838 }
839 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
840}
841
842
843int
844EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
845 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
846{
847 if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
848 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
849 return 0;
850 }
851 if (group->meth != point->meth) {
852 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
853 return 0;
854 }
855 return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
856}
857
858
859int
860EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
861 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
862{
863 if (group->meth->point_set_affine_coordinates == 0) {
864 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
865 return 0;
866 }
867 if (group->meth != point->meth) {
868 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
869 return 0;
870 }
871 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
872}
873
874#ifndef OPENSSL_NO_EC2M
875int
876EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
877 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
878{
879 if (group->meth->point_set_affine_coordinates == 0) {
880 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
881 return 0;
882 }
883 if (group->meth != point->meth) {
884 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
885 return 0;
886 }
887 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
888}
889#endif
890
891int
892EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
893 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
894{
895 if (group->meth->point_get_affine_coordinates == 0) {
896 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
897 return 0;
898 }
899 if (group->meth != point->meth) {
900 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
901 return 0;
902 }
903 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
904}
905
906#ifndef OPENSSL_NO_EC2M
907int
908EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
909 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
910{
911 if (group->meth->point_get_affine_coordinates == 0) {
912 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
913 return 0;
914 }
915 if (group->meth != point->meth) {
916 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
917 return 0;
918 }
919 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
920}
921#endif
922
923int
924EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
925 const EC_POINT *b, BN_CTX *ctx)
926{
927 if (group->meth->add == 0) {
928 ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
929 return 0;
930 }
931 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) {
932 ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
933 return 0;
934 }
935 return group->meth->add(group, r, a, b, ctx);
936}
937
938
939int
940EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
941{
942 if (group->meth->dbl == 0) {
943 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
944 return 0;
945 }
946 if ((group->meth != r->meth) || (r->meth != a->meth)) {
947 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
948 return 0;
949 }
950 return group->meth->dbl(group, r, a, ctx);
951}
952
953
954int
955EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
956{
957 if (group->meth->invert == 0) {
958 ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
959 return 0;
960 }
961 if (group->meth != a->meth) {
962 ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
963 return 0;
964 }
965 return group->meth->invert(group, a, ctx);
966}
967
968
969int
970EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
971{
972 if (group->meth->is_at_infinity == 0) {
973 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
974 return 0;
975 }
976 if (group->meth != point->meth) {
977 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
978 return 0;
979 }
980 return group->meth->is_at_infinity(group, point);
981}
982
983
984int
985EC_POINT_is_on_curve(const EC_GROUP * group, const EC_POINT * point, BN_CTX * ctx)
986{
987 if (group->meth->is_on_curve == 0) {
988 ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
989 return 0;
990 }
991 if (group->meth != point->meth) {
992 ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
993 return 0;
994 }
995 return group->meth->is_on_curve(group, point, ctx);
996}
997
998
999int
1000EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
1001 BN_CTX * ctx)
1002{
1003 if (group->meth->point_cmp == 0) {
1004 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1005 return -1;
1006 }
1007 if ((group->meth != a->meth) || (a->meth != b->meth)) {
1008 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
1009 return -1;
1010 }
1011 return group->meth->point_cmp(group, a, b, ctx);
1012}
1013
1014
1015int
1016EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1017{
1018 if (group->meth->make_affine == 0) {
1019 ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1020 return 0;
1021 }
1022 if (group->meth != point->meth) {
1023 ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1024 return 0;
1025 }
1026 return group->meth->make_affine(group, point, ctx);
1027}
1028
1029
1030int
1031EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1032 BN_CTX *ctx)
1033{
1034 size_t i;
1035
1036 if (group->meth->points_make_affine == 0) {
1037 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1038 return 0;
1039 }
1040 for (i = 0; i < num; i++) {
1041 if (group->meth != points[i]->meth) {
1042 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1043 return 0;
1044 }
1045 }
1046 return group->meth->points_make_affine(group, num, points, ctx);
1047}
1048
1049
1050/* Functions for point multiplication.
1051 *
1052 * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
1053 * otherwise we dispatch through methods.
1054 */
1055
1056int
1057EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1058 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
1059{
1060 if (group->meth->mul == 0)
1061 /* use default */
1062 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
1063
1064 return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
1065}
1066
1067int
1068EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1069 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
1070{
1071 /* just a convenient interface to EC_POINTs_mul() */
1072
1073 const EC_POINT *points[1];
1074 const BIGNUM *scalars[1];
1075
1076 points[0] = point;
1077 scalars[0] = p_scalar;
1078
1079 return EC_POINTs_mul(group, r, g_scalar,
1080 (point != NULL && p_scalar != NULL),
1081 points, scalars, ctx);
1082}
1083
1084int
1085EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
1086{
1087 if (group->meth->mul == 0)
1088 /* use default */
1089 return ec_wNAF_precompute_mult(group, ctx);
1090
1091 if (group->meth->precompute_mult != 0)
1092 return group->meth->precompute_mult(group, ctx);
1093 else
1094 return 1; /* nothing to do, so report success */
1095}
1096
1097int
1098EC_GROUP_have_precompute_mult(const EC_GROUP * group)
1099{
1100 if (group->meth->mul == 0)
1101 /* use default */
1102 return ec_wNAF_have_precompute_mult(group);
1103
1104 if (group->meth->have_precompute_mult != 0)
1105 return group->meth->have_precompute_mult(group);
1106 else
1107 return 0; /* cannot tell whether precomputation has
1108 * been performed */
1109}
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
deleted file mode 100644
index 68f55cfcb3..0000000000
--- a/src/lib/libcrypto/ec/ec_mult.c
+++ /dev/null
@@ -1,886 +0,0 @@
1/* $OpenBSD: ec_mult.c,v 1.18 2015/02/15 08:44:35 miod 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 OPENSSL_cleanse(p, sizeof *p);
177 }
178 free(pre->points);
179 }
180 OPENSSL_cleanse(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 07933dc5fd..0000000000
--- a/src/lib/libcrypto/ec/ec_pmeth.c
+++ /dev/null
@@ -1,321 +0,0 @@
1/* $OpenBSD: ec_pmeth.c,v 1.8 2014/07/12 16:03:37 miod 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 = OBJ_sn2nid(value);
252 if (nid == NID_undef)
253 nid = OBJ_ln2nid(value);
254 if (nid == NID_undef) {
255 ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
256 return 0;
257 }
258 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
259 }
260 return -2;
261}
262
263static int
264pkey_ec_paramgen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey)
265{
266 EC_KEY *ec = NULL;
267 EC_PKEY_CTX *dctx = ctx->data;
268 int ret = 0;
269 if (dctx->gen_group == NULL) {
270 ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
271 return 0;
272 }
273 ec = EC_KEY_new();
274 if (!ec)
275 return 0;
276 ret = EC_KEY_set_group(ec, dctx->gen_group);
277 if (ret)
278 EVP_PKEY_assign_EC_KEY(pkey, ec);
279 else
280 EC_KEY_free(ec);
281 return ret;
282}
283
284static int
285pkey_ec_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey)
286{
287 EC_KEY *ec = NULL;
288 if (ctx->pkey == NULL) {
289 ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
290 return 0;
291 }
292 ec = EC_KEY_new();
293 if (!ec)
294 return 0;
295 EVP_PKEY_assign_EC_KEY(pkey, ec);
296 /* Note: if error return, pkey is freed by parent routine */
297 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
298 return 0;
299 return EC_KEY_generate_key(pkey->pkey.ec);
300}
301
302const EVP_PKEY_METHOD ec_pkey_meth = {
303 .pkey_id = EVP_PKEY_EC,
304
305 .init = pkey_ec_init,
306 .copy = pkey_ec_copy,
307 .cleanup = pkey_ec_cleanup,
308
309 .paramgen = pkey_ec_paramgen,
310
311 .keygen = pkey_ec_keygen,
312
313 .sign = pkey_ec_sign,
314
315 .verify = pkey_ec_verify,
316
317 .derive = pkey_ec_derive,
318
319 .ctrl = pkey_ec_ctrl,
320 .ctrl_str = pkey_ec_ctrl_str
321};
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 aa13d8b08c..0000000000
--- a/src/lib/libcrypto/ec/eck_prn.c
+++ /dev/null
@@ -1,362 +0,0 @@
1/* $OpenBSD: eck_prn.c,v 1.10 2014/07/12 16:03:37 miod 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
165 static const char *gen_compressed = "Generator (compressed):";
166 static const char *gen_uncompressed = "Generator (uncompressed):";
167 static const char *gen_hybrid = "Generator (hybrid):";
168
169 if (!x) {
170 reason = ERR_R_PASSED_NULL_PARAMETER;
171 goto err;
172 }
173 ctx = BN_CTX_new();
174 if (ctx == NULL) {
175 reason = ERR_R_MALLOC_FAILURE;
176 goto err;
177 }
178 if (EC_GROUP_get_asn1_flag(x)) {
179 /* the curve parameter are given by an asn1 OID */
180 int nid;
181
182 if (!BIO_indent(bp, off, 128))
183 goto err;
184
185 nid = EC_GROUP_get_curve_name(x);
186 if (nid == 0)
187 goto err;
188
189 if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
190 goto err;
191 if (BIO_printf(bp, "\n") <= 0)
192 goto err;
193 } else {
194 /* explicit parameters */
195 int is_char_two = 0;
196 point_conversion_form_t form;
197 int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
198
199 if (tmp_nid == NID_X9_62_characteristic_two_field)
200 is_char_two = 1;
201
202 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
203 (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
204 (cofactor = BN_new()) == NULL) {
205 reason = ERR_R_MALLOC_FAILURE;
206 goto err;
207 }
208#ifndef OPENSSL_NO_EC2M
209 if (is_char_two) {
210 if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
211 reason = ERR_R_EC_LIB;
212 goto err;
213 }
214 } else /* prime field */
215#endif
216 {
217 if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
218 reason = ERR_R_EC_LIB;
219 goto err;
220 }
221 }
222
223 if ((point = EC_GROUP_get0_generator(x)) == NULL) {
224 reason = ERR_R_EC_LIB;
225 goto err;
226 }
227 if (!EC_GROUP_get_order(x, order, NULL) ||
228 !EC_GROUP_get_cofactor(x, cofactor, NULL)) {
229 reason = ERR_R_EC_LIB;
230 goto err;
231 }
232 form = EC_GROUP_get_point_conversion_form(x);
233
234 if ((gen = EC_POINT_point2bn(x, point,
235 form, NULL, ctx)) == NULL) {
236 reason = ERR_R_EC_LIB;
237 goto err;
238 }
239 buf_len = (size_t) BN_num_bytes(p);
240 if (buf_len < (i = (size_t) BN_num_bytes(a)))
241 buf_len = i;
242 if (buf_len < (i = (size_t) BN_num_bytes(b)))
243 buf_len = i;
244 if (buf_len < (i = (size_t) BN_num_bytes(gen)))
245 buf_len = i;
246 if (buf_len < (i = (size_t) BN_num_bytes(order)))
247 buf_len = i;
248 if (buf_len < (i = (size_t) BN_num_bytes(cofactor)))
249 buf_len = i;
250
251 if ((seed = EC_GROUP_get0_seed(x)) != NULL)
252 seed_len = EC_GROUP_get_seed_len(x);
253
254 buf_len += 10;
255 if ((buffer = malloc(buf_len)) == NULL) {
256 reason = ERR_R_MALLOC_FAILURE;
257 goto err;
258 }
259 if (!BIO_indent(bp, off, 128))
260 goto err;
261
262 /* print the 'short name' of the field type */
263 if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
264 <= 0)
265 goto err;
266
267 if (is_char_two) {
268 /* print the 'short name' of the base type OID */
269 int basis_type = EC_GROUP_get_basis_type(x);
270 if (basis_type == 0)
271 goto err;
272
273 if (!BIO_indent(bp, off, 128))
274 goto err;
275
276 if (BIO_printf(bp, "Basis Type: %s\n",
277 OBJ_nid2sn(basis_type)) <= 0)
278 goto err;
279
280 /* print the polynomial */
281 if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
282 off))
283 goto err;
284 } else {
285 if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off))
286 goto err;
287 }
288 if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
289 goto err;
290 if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
291 goto err;
292 if (form == POINT_CONVERSION_COMPRESSED) {
293 if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
294 buffer, off))
295 goto err;
296 } else if (form == POINT_CONVERSION_UNCOMPRESSED) {
297 if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
298 buffer, off))
299 goto err;
300 } else { /* form == POINT_CONVERSION_HYBRID */
301 if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
302 buffer, off))
303 goto err;
304 }
305 if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
306 buffer, off))
307 goto err;
308 if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
309 buffer, off))
310 goto err;
311 if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
312 goto err;
313 }
314 ret = 1;
315err:
316 if (!ret)
317 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
318 BN_free(p);
319 BN_free(a);
320 BN_free(b);
321 BN_free(gen);
322 BN_free(order);
323 BN_free(cofactor);
324 BN_CTX_free(ctx);
325 free(buffer);
326 return (ret);
327}
328
329static int
330print_bin(BIO * fp, const char *name, const unsigned char *buf,
331 size_t len, int off)
332{
333 size_t i;
334 char str[128];
335
336 if (buf == NULL)
337 return 1;
338 if (off) {
339 if (off > 128)
340 off = 128;
341 memset(str, ' ', off);
342 if (BIO_write(fp, str, off) <= 0)
343 return 0;
344 }
345 if (BIO_printf(fp, "%s", name) <= 0)
346 return 0;
347
348 for (i = 0; i < len; i++) {
349 if ((i % 15) == 0) {
350 str[0] = '\n';
351 memset(&(str[1]), ' ', off + 4);
352 if (BIO_write(fp, str, off + 1 + 4) <= 0)
353 return 0;
354 }
355 if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= 0)
356 return 0;
357 }
358 if (BIO_write(fp, "\n", 1) <= 0)
359 return 0;
360
361 return 1;
362}
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 d29113045a..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistp224.c
+++ /dev/null
@@ -1,1693 +0,0 @@
1/* $OpenBSD: ecp_nistp224.c,v 1.16 2015/02/08 22:25:03 miod 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 OPENSSL_cleanse(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 23a2131980..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistp256.c
+++ /dev/null
@@ -1,2239 +0,0 @@
1/* $OpenBSD: ecp_nistp256.c,v 1.15 2015/02/08 22:25:03 miod 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 OPENSSL_cleanse(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 6382091cf9..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistp521.c
+++ /dev/null
@@ -1,2113 +0,0 @@
1/* $OpenBSD: ecp_nistp521.c,v 1.16 2015/02/08 22:25:03 miod 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 OPENSSL_cleanse(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}