1 /* Originally written by Bodo Moeller for the OpenSSL project.
2 * ====================================================================
3 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
31 * 6. Redistributions of any form whatsoever must retain the following
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
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 * ====================================================================
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).
55 /* ====================================================================
56 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
58 * Portions of the attached software ("Contribution") are developed by
59 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
61 * The Contribution is licensed pursuant to the OpenSSL open source
62 * license provided above.
64 * The elliptic curve binary polynomial software is originally written by
65 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
68 #include <openssl/ec.h>
70 #include <openssl/bn.h>
71 #include <openssl/err.h>
72 #include <openssl/mem.h>
73 #include <openssl/obj.h>
78 static const struct curve_data P224 = {
83 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
84 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x01,
87 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
88 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
89 0xFF, 0xFF, 0xFF, 0xFE,
91 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
92 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
93 0x23, 0x55, 0xFF, 0xB4,
95 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
96 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
97 0x11, 0x5C, 0x1D, 0x21,
99 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
100 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
101 0x85, 0x00, 0x7e, 0x34,
103 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
104 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
105 0x5C, 0x5C, 0x2A, 0x3D,
108 static const struct curve_data P256 = {
113 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
115 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
117 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
119 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
121 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
122 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
123 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
125 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
126 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
127 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
129 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
130 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
131 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
133 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
134 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
135 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}};
137 static const struct curve_data P384 = {
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,
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,
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,
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,
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,
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}};
172 static const struct curve_data P521 = {
177 0x01, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
181 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
182 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
184 0x01, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
188 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
189 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
191 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
192 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
193 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
194 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
195 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
196 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
198 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
199 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
200 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
201 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
202 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
203 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
205 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
206 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
207 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
208 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
209 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
210 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
212 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
213 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
214 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
215 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
216 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
217 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}};
219 const struct built_in_curve OPENSSL_built_in_curves[] = {
220 {NID_secp224r1, &P224, 0},
221 {NID_X9_62_prime256v1, &P256, 0},
222 {NID_secp384r1, &P384, 0},
223 {NID_secp521r1, &P521, 0},
227 EC_GROUP *ec_group_new(const EC_METHOD *meth) {
231 OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL);
235 if (meth->group_init == 0) {
236 OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
240 ret = OPENSSL_malloc(sizeof(EC_GROUP));
242 OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE);
245 memset(ret, 0, sizeof(EC_GROUP));
248 BN_init(&ret->order);
249 BN_init(&ret->cofactor);
250 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
252 if (!meth->group_init(ret)) {
260 static EC_GROUP *ec_group_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
261 const BIGNUM *b, BN_CTX *ctx) {
262 const EC_METHOD *meth = EC_GFp_mont_method();
265 ret = ec_group_new(meth);
270 if (ret->meth->group_set_curve == 0) {
271 OPENSSL_PUT_ERROR(EC, ec_group_new_curve_GFp,
272 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
275 if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
282 static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
283 EC_GROUP *group = NULL;
286 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
289 const EC_METHOD *meth;
290 const struct curve_data *data;
291 const uint8_t *params;
293 if ((ctx = BN_CTX_new()) == NULL) {
294 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE);
299 param_len = data->param_len;
302 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
303 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
304 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
305 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
309 if (curve->method != 0) {
310 meth = curve->method();
311 if (((group = ec_group_new(meth)) == NULL) ||
312 (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
313 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
317 if ((group = ec_group_new_curve_GFp(p, a, b, ctx)) == NULL) {
318 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
323 if ((P = EC_POINT_new(group)) == NULL) {
324 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
328 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
329 !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
330 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
334 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
335 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
338 if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) ||
339 !BN_set_word(x, (BN_ULONG)data->cofactor)) {
340 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
344 group->generator = P;
346 if (!BN_copy(&group->order, order) ||
347 !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
348 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
356 EC_GROUP_free(group);
378 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
380 const struct built_in_curve *curve;
381 EC_GROUP *ret = NULL;
383 for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
384 curve = &OPENSSL_built_in_curves[i];
385 if (curve->nid == nid) {
386 ret = ec_group_new_from_data(curve);
392 OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP);
396 ret->curve_name = nid;
400 void EC_GROUP_free(EC_GROUP *group) {
405 if (group->meth->group_finish != 0) {
406 group->meth->group_finish(group);
409 ec_pre_comp_free(group->pre_comp);
411 if (group->generator != NULL) {
412 EC_POINT_free(group->generator);
414 BN_free(&group->order);
415 BN_free(&group->cofactor);
420 int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) {
421 if (dest->meth->group_copy == 0) {
422 OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
425 if (dest->meth != src->meth) {
426 OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS);
433 ec_pre_comp_free(dest->pre_comp);
434 dest->pre_comp = ec_pre_comp_dup(src->pre_comp);
436 if (src->generator != NULL) {
437 if (dest->generator == NULL) {
438 dest->generator = EC_POINT_new(dest);
439 if (dest->generator == NULL) {
443 if (!EC_POINT_copy(dest->generator, src->generator)) {
447 /* src->generator == NULL */
448 if (dest->generator != NULL) {
449 EC_POINT_clear_free(dest->generator);
450 dest->generator = NULL;
454 if (!BN_copy(&dest->order, &src->order) ||
455 !BN_copy(&dest->cofactor, &src->cofactor)) {
459 dest->curve_name = src->curve_name;
460 dest->asn1_form = src->asn1_form;
462 return dest->meth->group_copy(dest, src);
465 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
473 t = ec_group_new(a->meth);
477 if (!EC_GROUP_copy(t, a)) {
494 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b) {
495 if (a->curve_name == NID_undef || b->curve_name == NID_undef) {
498 return a->curve_name == b->curve_name;
501 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
502 return group->generator;
505 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
506 if (!BN_copy(order, &group->order)) {
510 return !BN_is_zero(order);
513 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
515 if (!BN_copy(cofactor, &group->cofactor)) {
519 return !BN_is_zero(&group->cofactor);
522 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
524 int EC_GROUP_get_degree(const EC_GROUP *group) {
525 if (group->meth->group_get_degree == 0) {
526 OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree,
527 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
530 return group->meth->group_get_degree(group);
533 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
534 point_conversion_form_t form) {
535 group->asn1_form = form;
538 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
539 if (group->meth->mul == 0) {
541 return ec_wNAF_precompute_mult(group, ctx);
544 if (group->meth->precompute_mult != 0) {
545 return group->meth->precompute_mult(group, ctx);
548 return 1; /* nothing to do, so report success */
551 int EC_GROUP_have_precompute_mult(const EC_GROUP *group) {
552 if (group->meth->mul == 0) {
554 return ec_wNAF_have_precompute_mult(group);
557 if (group->meth->have_precompute_mult != 0) {
558 return group->meth->have_precompute_mult(group);
561 return 0; /* cannot tell whether precomputation has been performed */
564 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
568 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER);
571 if (group->meth->point_init == 0) {
572 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
576 ret = OPENSSL_malloc(sizeof *ret);
578 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE);
582 ret->meth = group->meth;
584 if (!ret->meth->point_init(ret)) {
592 void EC_POINT_free(EC_POINT *point) {
597 if (point->meth->point_finish != 0) {
598 point->meth->point_finish(point);
603 void EC_POINT_clear_free(EC_POINT *point) {
608 if (point->meth->point_clear_finish != 0) {
609 point->meth->point_clear_finish(point);
610 } else if (point->meth->point_finish != 0) {
611 point->meth->point_finish(point);
613 OPENSSL_cleanse(point, sizeof *point);
617 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
618 if (dest->meth->point_copy == 0) {
619 OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
622 if (dest->meth != src->meth) {
623 OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS);
629 return dest->meth->point_copy(dest, src);
632 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
640 t = EC_POINT_new(group);
642 OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE);
645 r = EC_POINT_copy(t, a);
654 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
655 if (group->meth->point_set_to_infinity == 0) {
656 OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity,
657 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
660 if (group->meth != point->meth) {
661 OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS);
664 return group->meth->point_set_to_infinity(group, point);
667 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
668 if (group->meth->is_at_infinity == 0) {
669 OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity,
670 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
673 if (group->meth != point->meth) {
674 OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS);
677 return group->meth->is_at_infinity(group, point);
680 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
682 if (group->meth->is_on_curve == 0) {
683 OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve,
684 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
687 if (group->meth != point->meth) {
688 OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS);
691 return group->meth->is_on_curve(group, point, ctx);
694 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
696 if (group->meth->point_cmp == 0) {
697 OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
700 if ((group->meth != a->meth) || (a->meth != b->meth)) {
701 OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS);
704 return group->meth->point_cmp(group, a, b, ctx);
707 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
708 if (group->meth->make_affine == 0) {
709 OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine,
710 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
713 if (group->meth != point->meth) {
714 OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
717 return group->meth->make_affine(group, point, ctx);
720 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
724 if (group->meth->points_make_affine == 0) {
725 OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine,
726 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
729 for (i = 0; i < num; i++) {
730 if (group->meth != points[i]->meth) {
731 OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
735 return group->meth->points_make_affine(group, num, points, ctx);
738 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
739 const EC_POINT *point, BIGNUM *x,
740 BIGNUM *y, BN_CTX *ctx) {
741 if (group->meth->point_get_affine_coordinates == 0) {
742 OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
743 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
746 if (group->meth != point->meth) {
747 OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
748 EC_R_INCOMPATIBLE_OBJECTS);
751 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
754 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
755 const BIGNUM *x, const BIGNUM *y,
757 if (group->meth->point_set_affine_coordinates == 0) {
758 OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
759 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
762 if (group->meth != point->meth) {
763 OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
764 EC_R_INCOMPATIBLE_OBJECTS);
767 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
770 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
771 const EC_POINT *b, BN_CTX *ctx) {
772 if (group->meth->add == 0) {
773 OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
776 if ((group->meth != r->meth) || (r->meth != a->meth) ||
777 (a->meth != b->meth)) {
778 OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS);
781 return group->meth->add(group, r, a, b, ctx);
785 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
787 if (group->meth->dbl == 0) {
788 OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
791 if ((group->meth != r->meth) || (r->meth != a->meth)) {
792 OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS);
795 return group->meth->dbl(group, r, a, ctx);
799 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
800 if (group->meth->invert == 0) {
801 OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
804 if (group->meth != a->meth) {
805 OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS);
808 return group->meth->invert(group, a, ctx);
811 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
812 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) {
813 /* just a convenient interface to EC_POINTs_mul() */
815 const EC_POINT *points[1];
816 const BIGNUM *scalars[1];
819 scalars[0] = p_scalar;
821 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL),
822 points, scalars, ctx);
825 int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
826 size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
828 if (group->meth->mul == 0) {
829 /* use default. Warning, not constant-time. */
830 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
833 return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
836 int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
837 const BIGNUM *x, const BIGNUM *y,
838 const BIGNUM *z, BN_CTX *ctx) {
839 if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
840 OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
841 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
844 if (group->meth != point->meth) {
845 OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
846 EC_R_INCOMPATIBLE_OBJECTS);
849 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,