Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / third_party / boringssl / crypto / fipsmodule / ec / ec.c
1 /* Originally written by Bodo Moeller for the OpenSSL project.
2  * ====================================================================
3  * Copyright (c) 1998-2005 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  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
57  *
58  * Portions of the attached software ("Contribution") are developed by
59  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
60  *
61  * The Contribution is licensed pursuant to the OpenSSL open source
62  * license provided above.
63  *
64  * The elliptic curve binary polynomial software is originally written by
65  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
66  * Laboratories. */
67
68 #include <openssl/ec.h>
69
70 #include <assert.h>
71 #include <string.h>
72
73 #include <openssl/bn.h>
74 #include <openssl/err.h>
75 #include <openssl/mem.h>
76 #include <openssl/nid.h>
77
78 #include "internal.h"
79 #include "../../internal.h"
80 #include "../bn/internal.h"
81 #include "../delocate.h"
82
83
84 static void ec_point_free(EC_POINT *point, int free_group);
85
86 static const uint8_t kP224Params[6 * 28] = {
87     // p
88     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
89     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90     0x00, 0x00, 0x00, 0x01,
91     // a
92     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
93     0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
94     0xFF, 0xFF, 0xFF, 0xFE,
95     // b
96     0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
97     0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
98     0x23, 0x55, 0xFF, 0xB4,
99     // x
100     0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
101     0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
102     0x11, 0x5C, 0x1D, 0x21,
103     // y
104     0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
105     0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
106     0x85, 0x00, 0x7e, 0x34,
107     // order
108     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
109     0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
110     0x5C, 0x5C, 0x2A, 0x3D,
111 };
112
113 static const uint8_t kP256Params[6 * 32] = {
114     // p
115     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
116     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
117     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
118     // a
119     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
120     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
121     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
122     // b
123     0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
124     0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
125     0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
126     // x
127     0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
128     0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
129     0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
130     // y
131     0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
132     0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
133     0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
134     // order
135     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
136     0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
137     0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51,
138 };
139
140 static const uint8_t kP384Params[6 * 48] = {
141     // p
142     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
143     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
144     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
145     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
146     // a
147     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
148     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
149     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
150     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
151     // b
152     0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
153     0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
154     0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
155     0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
156     // x
157     0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
158     0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
159     0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
160     0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
161     // y
162     0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
163     0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
164     0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
165     0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
166     // order
167     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
168     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
169     0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
170     0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73,
171 };
172
173 static const uint8_t kP521Params[6 * 66] = {
174     // p
175     0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
176     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
177     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
178     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
179     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
180     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
181     // a
182     0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
183     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
184     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
185     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
186     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
187     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
188     // b
189     0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
190     0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
191     0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
192     0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
193     0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
194     0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
195     // x
196     0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
197     0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
198     0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
199     0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
200     0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
201     0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
202     // y
203     0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
204     0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
205     0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
206     0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
207     0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
208     0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
209     // order
210     0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
211     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
212     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
213     0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
214     0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
215     0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09,
216 };
217
218 DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) {
219   // 1.3.132.0.35
220   static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23};
221   out->curves[0].nid = NID_secp521r1;
222   out->curves[0].oid = kOIDP521;
223   out->curves[0].oid_len = sizeof(kOIDP521);
224   out->curves[0].comment = "NIST P-521";
225   out->curves[0].param_len = 66;
226   out->curves[0].params = kP521Params;
227   out->curves[0].method = EC_GFp_mont_method();
228
229   // 1.3.132.0.34
230   static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22};
231   out->curves[1].nid = NID_secp384r1;
232   out->curves[1].oid = kOIDP384;
233   out->curves[1].oid_len = sizeof(kOIDP384);
234   out->curves[1].comment = "NIST P-384";
235   out->curves[1].param_len = 48;
236   out->curves[1].params = kP384Params;
237   out->curves[1].method = EC_GFp_mont_method();
238
239   // 1.2.840.10045.3.1.7
240   static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce,
241                                      0x3d, 0x03, 0x01, 0x07};
242   out->curves[2].nid = NID_X9_62_prime256v1;
243   out->curves[2].oid = kOIDP256;
244   out->curves[2].oid_len = sizeof(kOIDP256);
245   out->curves[2].comment = "NIST P-256";
246   out->curves[2].param_len = 32;
247   out->curves[2].params = kP256Params;
248   out->curves[2].method =
249 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
250     !defined(OPENSSL_SMALL)
251       EC_GFp_nistz256_method();
252 #else
253       EC_GFp_nistp256_method();
254 #endif
255
256   // 1.3.132.0.33
257   static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21};
258   out->curves[3].nid = NID_secp224r1;
259   out->curves[3].oid = kOIDP224;
260   out->curves[3].oid_len = sizeof(kOIDP224);
261   out->curves[3].comment = "NIST P-224";
262   out->curves[3].param_len = 28;
263   out->curves[3].params = kP224Params;
264   out->curves[3].method =
265 #if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
266       EC_GFp_nistp224_method();
267 #else
268       EC_GFp_mont_method();
269 #endif
270 }
271
272 EC_GROUP *ec_group_new(const EC_METHOD *meth) {
273   EC_GROUP *ret;
274
275   if (meth == NULL) {
276     OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
277     return NULL;
278   }
279
280   if (meth->group_init == 0) {
281     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
282     return NULL;
283   }
284
285   ret = OPENSSL_malloc(sizeof(EC_GROUP));
286   if (ret == NULL) {
287     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
288     return NULL;
289   }
290   OPENSSL_memset(ret, 0, sizeof(EC_GROUP));
291
292   ret->references = 1;
293   ret->meth = meth;
294   BN_init(&ret->order);
295
296   if (!meth->group_init(ret)) {
297     OPENSSL_free(ret);
298     return NULL;
299   }
300
301   return ret;
302 }
303
304 static void ec_group_set0_generator(EC_GROUP *group, EC_POINT *generator) {
305   assert(group->generator == NULL);
306   assert(group == generator->group);
307
308   // Avoid a reference cycle. |group->generator| does not maintain an owning
309   // pointer to |group|.
310   group->generator = generator;
311   int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references);
312
313   assert(!is_zero);
314   (void)is_zero;
315 }
316
317 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
318                                  const BIGNUM *b, BN_CTX *ctx) {
319   if (BN_num_bytes(p) > EC_MAX_SCALAR_BYTES) {
320     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
321     return NULL;
322   }
323
324   EC_GROUP *ret = ec_group_new(EC_GFp_mont_method());
325   if (ret == NULL) {
326     return NULL;
327   }
328
329   if (ret->meth->group_set_curve == NULL) {
330     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
331     EC_GROUP_free(ret);
332     return NULL;
333   }
334   if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
335     EC_GROUP_free(ret);
336     return NULL;
337   }
338   return ret;
339 }
340
341 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
342                            const BIGNUM *order, const BIGNUM *cofactor) {
343   if (group->curve_name != NID_undef || group->generator != NULL ||
344       generator->group != group) {
345     // |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
346     // |EC_GROUP_new_curve_GFp| and may only used once on each group.
347     // Additionally, |generator| must been created from
348     // |EC_GROUP_new_curve_GFp|, not a copy, so that
349     // |generator->group->generator| is set correctly.
350     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
351     return 0;
352   }
353
354   if (BN_num_bytes(order) > EC_MAX_SCALAR_BYTES) {
355     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
356     return 0;
357   }
358
359   // Require a cofactor of one for custom curves, which implies prime order.
360   if (!BN_is_one(cofactor)) {
361     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR);
362     return 0;
363   }
364
365   // Require that p < 2×order. This simplifies some ECDSA operations.
366   //
367   // Note any curve which did not satisfy this must have been invalid or use a
368   // tiny prime (less than 17). See the proof in |field_element_to_scalar| in
369   // the ECDSA implementation.
370   BIGNUM *tmp = BN_new();
371   if (tmp == NULL ||
372       !BN_lshift1(tmp, order)) {
373     BN_free(tmp);
374     return 0;
375   }
376   int ok = BN_cmp(tmp, &group->field) > 0;
377   BN_free(tmp);
378   if (!ok) {
379     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
380     return 0;
381   }
382
383   EC_POINT *copy = EC_POINT_new(group);
384   if (copy == NULL ||
385       !EC_POINT_copy(copy, generator) ||
386       !BN_copy(&group->order, order)) {
387     EC_POINT_free(copy);
388     return 0;
389   }
390   // Store the order in minimal form, so it can be used with |BN_ULONG| arrays.
391   bn_set_minimal_width(&group->order);
392
393   BN_MONT_CTX_free(group->order_mont);
394   group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL);
395   if (group->order_mont == NULL) {
396     return 0;
397   }
398
399   ec_group_set0_generator(group, copy);
400   return 1;
401 }
402
403 static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
404   EC_GROUP *group = NULL;
405   EC_POINT *P = NULL;
406   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
407   int ok = 0;
408
409   BN_CTX *ctx = BN_CTX_new();
410   if (ctx == NULL) {
411     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
412     goto err;
413   }
414
415   const unsigned param_len = curve->param_len;
416   const uint8_t *params = curve->params;
417
418   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
419       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
420       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
421     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
422     goto err;
423   }
424
425   group = ec_group_new(curve->method);
426   if (group == NULL ||
427       !group->meth->group_set_curve(group, p, a, b, ctx)) {
428     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
429     goto err;
430   }
431
432   if ((P = EC_POINT_new(group)) == NULL) {
433     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
434     goto err;
435   }
436
437   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
438       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
439     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
440     goto err;
441   }
442
443   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
444     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
445     goto err;
446   }
447   if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) {
448     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
449     goto err;
450   }
451
452   group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, ctx);
453   if (group->order_mont == NULL) {
454     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
455     goto err;
456   }
457
458   ec_group_set0_generator(group, P);
459   P = NULL;
460   ok = 1;
461
462 err:
463   if (!ok) {
464     EC_GROUP_free(group);
465     group = NULL;
466   }
467   EC_POINT_free(P);
468   BN_CTX_free(ctx);
469   BN_free(p);
470   BN_free(a);
471   BN_free(b);
472   BN_free(x);
473   BN_free(y);
474   return group;
475 }
476
477 // Built-in groups are allocated lazily and static once allocated.
478 // TODO(davidben): Make these actually static. https://crbug.com/boringssl/20.
479 struct built_in_groups_st {
480   EC_GROUP *groups[OPENSSL_NUM_BUILT_IN_CURVES];
481 };
482 DEFINE_BSS_GET(struct built_in_groups_st, built_in_groups);
483 DEFINE_STATIC_MUTEX(built_in_groups_lock);
484
485 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
486   struct built_in_groups_st *groups = built_in_groups_bss_get();
487   EC_GROUP **group_ptr = NULL;
488   const struct built_in_curves *const curves = OPENSSL_built_in_curves();
489   const struct built_in_curve *curve = NULL;
490   for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
491     if (curves->curves[i].nid == nid) {
492       curve = &curves->curves[i];
493       group_ptr = &groups->groups[i];
494       break;
495     }
496   }
497
498   if (curve == NULL) {
499     OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
500     return NULL;
501   }
502
503   CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get());
504   EC_GROUP *ret = *group_ptr;
505   CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get());
506   if (ret != NULL) {
507     return ret;
508   }
509
510   ret = ec_group_new_from_data(curve);
511   if (ret == NULL) {
512     return NULL;
513   }
514
515   EC_GROUP *to_free = NULL;
516   CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get());
517   if (*group_ptr == NULL) {
518     *group_ptr = ret;
519     // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup|
520     // into no-ops. At this point, |ret| is considered static.
521     ret->curve_name = nid;
522   } else {
523     to_free = ret;
524     ret = *group_ptr;
525   }
526   CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get());
527
528   EC_GROUP_free(to_free);
529   return ret;
530 }
531
532 void EC_GROUP_free(EC_GROUP *group) {
533   if (group == NULL ||
534       // Built-in curves are static.
535       group->curve_name != NID_undef ||
536       !CRYPTO_refcount_dec_and_test_zero(&group->references)) {
537     return;
538   }
539
540   if (group->meth->group_finish != NULL) {
541     group->meth->group_finish(group);
542   }
543
544   ec_point_free(group->generator, 0 /* don't free group */);
545   BN_free(&group->order);
546   BN_MONT_CTX_free(group->order_mont);
547
548   OPENSSL_free(group);
549 }
550
551 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
552   if (a == NULL ||
553       // Built-in curves are static.
554       a->curve_name != NID_undef) {
555     return (EC_GROUP *)a;
556   }
557
558   // Groups are logically immutable (but for |EC_GROUP_set_generator| which must
559   // be called early on), so we simply take a reference.
560   EC_GROUP *group = (EC_GROUP *)a;
561   CRYPTO_refcount_inc(&group->references);
562   return group;
563 }
564
565 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
566   // Note this function returns 0 if equal and non-zero otherwise.
567   if (a == b) {
568     return 0;
569   }
570   if (a->curve_name != b->curve_name) {
571     return 1;
572   }
573   if (a->curve_name != NID_undef) {
574     // Built-in curves may be compared by curve name alone.
575     return 0;
576   }
577
578   // |a| and |b| are both custom curves. We compare the entire curve
579   // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes,
580   // custom curve construction is sadly done in two parts) but otherwise not the
581   // same object, we consider them always unequal.
582   return a->generator == NULL ||
583          b->generator == NULL ||
584          BN_cmp(&a->order, &b->order) != 0 ||
585          BN_cmp(&a->field, &b->field) != 0 ||
586          BN_cmp(&a->a, &b->a) != 0 ||
587          BN_cmp(&a->b, &b->b) != 0 ||
588          ec_GFp_simple_cmp(a, a->generator, b->generator, NULL) != 0;
589 }
590
591 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
592   return group->generator;
593 }
594
595 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
596   assert(!BN_is_zero(&group->order));
597   return &group->order;
598 }
599
600 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
601   if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
602     return 0;
603   }
604   return 1;
605 }
606
607 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
608                           BN_CTX *ctx) {
609   // All |EC_GROUP|s have cofactor 1.
610   return BN_set_word(cofactor, 1);
611 }
612
613 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
614                            BIGNUM *out_b, BN_CTX *ctx) {
615   return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
616 }
617
618 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
619
620 unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
621   return ec_GFp_simple_group_get_degree(group);
622 }
623
624 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
625   EC_POINT *ret;
626
627   if (group == NULL) {
628     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
629     return NULL;
630   }
631
632   ret = OPENSSL_malloc(sizeof *ret);
633   if (ret == NULL) {
634     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
635     return NULL;
636   }
637
638   ret->group = EC_GROUP_dup(group);
639   if (ret->group == NULL ||
640       !ec_GFp_simple_point_init(ret)) {
641     OPENSSL_free(ret);
642     return NULL;
643   }
644
645   return ret;
646 }
647
648 static void ec_point_free(EC_POINT *point, int free_group) {
649   if (!point) {
650     return;
651   }
652   ec_GFp_simple_point_finish(point);
653   if (free_group) {
654     EC_GROUP_free(point->group);
655   }
656   OPENSSL_free(point);
657 }
658
659 void EC_POINT_free(EC_POINT *point) {
660   ec_point_free(point, 1 /* free group */);
661 }
662
663 void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); }
664
665 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
666   if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) {
667     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
668     return 0;
669   }
670   if (dest == src) {
671     return 1;
672   }
673   return ec_GFp_simple_point_copy(dest, src);
674 }
675
676 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
677   if (a == NULL) {
678     return NULL;
679   }
680
681   EC_POINT *ret = EC_POINT_new(group);
682   if (ret == NULL ||
683       !EC_POINT_copy(ret, a)) {
684     EC_POINT_free(ret);
685     return NULL;
686   }
687
688   return ret;
689 }
690
691 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
692   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
693     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
694     return 0;
695   }
696   return ec_GFp_simple_point_set_to_infinity(group, point);
697 }
698
699 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
700   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
701     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
702     return 0;
703   }
704   return ec_GFp_simple_is_at_infinity(group, point);
705 }
706
707 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
708                          BN_CTX *ctx) {
709   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
710     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
711     return 0;
712   }
713   return ec_GFp_simple_is_on_curve(group, point, ctx);
714 }
715
716 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
717                  BN_CTX *ctx) {
718   if (EC_GROUP_cmp(group, a->group, NULL) != 0 ||
719       EC_GROUP_cmp(group, b->group, NULL) != 0) {
720     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
721     return -1;
722   }
723   return ec_GFp_simple_cmp(group, a, b, ctx);
724 }
725
726 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
727   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
728     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
729     return 0;
730   }
731   return ec_GFp_simple_make_affine(group, point, ctx);
732 }
733
734 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
735                           BN_CTX *ctx) {
736   for (size_t i = 0; i < num; i++) {
737     if (EC_GROUP_cmp(group, points[i]->group, NULL) != 0) {
738       OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
739       return 0;
740     }
741   }
742   return ec_GFp_simple_points_make_affine(group, num, points, ctx);
743 }
744
745 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
746                                         const EC_POINT *point, BIGNUM *x,
747                                         BIGNUM *y, BN_CTX *ctx) {
748   if (group->meth->point_get_affine_coordinates == 0) {
749     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
750     return 0;
751   }
752   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
753     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
754     return 0;
755   }
756   return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
757 }
758
759 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
760                                         const BIGNUM *x, const BIGNUM *y,
761                                         BN_CTX *ctx) {
762   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
763     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
764     return 0;
765   }
766   if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
767     return 0;
768   }
769
770   if (!EC_POINT_is_on_curve(group, point, ctx)) {
771     // In the event of an error, defend against the caller not checking the
772     // return value by setting a known safe value: the base point.
773     const EC_POINT *generator = EC_GROUP_get0_generator(group);
774     // The generator can be missing if the caller is in the process of
775     // constructing an arbitrary group. In this, we give up and hope they're
776     // checking the return value.
777     if (generator) {
778       EC_POINT_copy(point, generator);
779     }
780     OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
781     return 0;
782   }
783
784   return 1;
785 }
786
787 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
788                  const EC_POINT *b, BN_CTX *ctx) {
789   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
790       EC_GROUP_cmp(group, a->group, NULL) != 0 ||
791       EC_GROUP_cmp(group, b->group, NULL) != 0) {
792     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
793     return 0;
794   }
795   return ec_GFp_simple_add(group, r, a, b, ctx);
796 }
797
798
799 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
800                  BN_CTX *ctx) {
801   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
802       EC_GROUP_cmp(group, a->group, NULL) != 0) {
803     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
804     return 0;
805   }
806   return ec_GFp_simple_dbl(group, r, a, ctx);
807 }
808
809
810 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
811   if (EC_GROUP_cmp(group, a->group, NULL) != 0) {
812     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
813     return 0;
814   }
815   return ec_GFp_simple_invert(group, a, ctx);
816 }
817
818 static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
819                                       const BIGNUM *in, BN_CTX *ctx) {
820   if (ec_bignum_to_scalar(group, out, in)) {
821     return 1;
822   }
823
824   ERR_clear_error();
825
826   // This is an unusual input, so we do not guarantee constant-time processing.
827   const BIGNUM *order = &group->order;
828   BN_CTX_start(ctx);
829   BIGNUM *tmp = BN_CTX_get(ctx);
830   int ok = tmp != NULL &&
831            BN_nnmod(tmp, in, order, ctx) &&
832            ec_bignum_to_scalar_unchecked(group, out, tmp);
833   BN_CTX_end(ctx);
834   return ok;
835 }
836
837 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
838                  const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
839   // Previously, this function set |r| to the point at infinity if there was
840   // nothing to multiply. But, nobody should be calling this function with
841   // nothing to multiply in the first place.
842   if ((g_scalar == NULL && p_scalar == NULL) ||
843       (p == NULL) != (p_scalar == NULL))  {
844     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
845     return 0;
846   }
847
848   int ret = 0;
849   EC_SCALAR g_scalar_storage, p_scalar_storage;
850   EC_SCALAR *g_scalar_arg = NULL, *p_scalar_arg = NULL;
851   BN_CTX *new_ctx = NULL;
852   if (ctx == NULL) {
853     new_ctx = BN_CTX_new();
854     if (new_ctx == NULL) {
855       goto err;
856     }
857     ctx = new_ctx;
858   }
859
860   if (g_scalar != NULL) {
861     if (!arbitrary_bignum_to_scalar(group, &g_scalar_storage, g_scalar, ctx)) {
862       goto err;
863     }
864     g_scalar_arg = &g_scalar_storage;
865   }
866
867   if (p_scalar != NULL) {
868     if (!arbitrary_bignum_to_scalar(group, &p_scalar_storage, p_scalar, ctx)) {
869       goto err;
870     }
871     p_scalar_arg = &p_scalar_storage;
872   }
873
874   ret = ec_point_mul_scalar(group, r, g_scalar_arg, p, p_scalar_arg, ctx);
875
876 err:
877   BN_CTX_free(new_ctx);
878   OPENSSL_cleanse(&g_scalar_storage, sizeof(g_scalar_storage));
879   OPENSSL_cleanse(&p_scalar_storage, sizeof(p_scalar_storage));
880   return ret;
881 }
882
883 int ec_point_mul_scalar_public(const EC_GROUP *group, EC_POINT *r,
884                                const EC_SCALAR *g_scalar, const EC_POINT *p,
885                                const EC_SCALAR *p_scalar, BN_CTX *ctx) {
886   if ((g_scalar == NULL && p_scalar == NULL) ||
887       (p == NULL) != (p_scalar == NULL))  {
888     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
889     return 0;
890   }
891
892   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
893       (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
894     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
895     return 0;
896   }
897
898   return group->meth->mul_public(group, r, g_scalar, p, p_scalar, ctx);
899 }
900
901 int ec_point_mul_scalar(const EC_GROUP *group, EC_POINT *r,
902                         const EC_SCALAR *g_scalar, const EC_POINT *p,
903                         const EC_SCALAR *p_scalar, BN_CTX *ctx) {
904   if ((g_scalar == NULL && p_scalar == NULL) ||
905       (p == NULL) != (p_scalar == NULL))  {
906     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
907     return 0;
908   }
909
910   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
911       (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
912     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
913     return 0;
914   }
915
916   return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
917 }
918
919 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
920
921 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
922   return NULL;
923 }
924
925 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
926   return NID_X9_62_prime_field;
927 }
928
929 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
930                                         point_conversion_form_t form) {
931   if (form != POINT_CONVERSION_UNCOMPRESSED) {
932     abort();
933   }
934 }
935
936 size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
937                              size_t max_num_curves) {
938   const struct built_in_curves *const curves = OPENSSL_built_in_curves();
939
940   for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES;
941        i++) {
942     out_curves[i].comment = curves->curves[i].comment;
943     out_curves[i].nid = curves->curves[i].nid;
944   }
945
946   return OPENSSL_NUM_BUILT_IN_CURVES;
947 }
948
949 int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
950                         const BIGNUM *in) {
951   if (!ec_bignum_to_scalar_unchecked(group, out, in)) {
952     return 0;
953   }
954   if (!bn_less_than_words(out->words, group->order.d, group->order.width)) {
955     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
956     return 0;
957   }
958   return 1;
959 }
960
961 int ec_bignum_to_scalar_unchecked(const EC_GROUP *group, EC_SCALAR *out,
962                                   const BIGNUM *in) {
963   if (!bn_copy_words(out->words, group->order.width, in)) {
964     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
965     return 0;
966   }
967   return 1;
968 }
969
970 int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out,
971                              const uint8_t additional_data[32]) {
972   return bn_rand_range_words(out->words, 1, group->order.d, group->order.width,
973                              additional_data);
974 }