1 /* crypto/ec/ec_lib.c */
3 * Originally written by Bodo Moeller for the OpenSSL project.
5 /* ====================================================================
6 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
34 * 6. Redistributions of any form whatsoever must retain the following
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
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 * ====================================================================
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).
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.
68 #include <openssl/err.h>
69 #include <openssl/opensslv.h>
73 static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
76 /* functions for EC_GROUP objects */
78 EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
84 ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
87 if (meth->group_init == 0)
89 ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
93 ret = OPENSSL_malloc(sizeof *ret);
96 ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
102 ret->extra_data = NULL;
103 ret->mont_data = NULL;
105 ret->generator = NULL;
106 ret->order = BN_new();
107 ret->cofactor = NULL;
108 if(!ret->order) goto err;
109 ret->cofactor = BN_new();
110 if(!ret->cofactor) goto err;
114 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
119 if (!meth->group_init(ret)) goto err;
123 if(ret->order) BN_free(ret->order);
124 if(ret->cofactor) BN_free(ret->cofactor);
130 void EC_GROUP_free(EC_GROUP *group)
134 if (group->meth->group_finish != 0)
135 group->meth->group_finish(group);
137 EC_EX_DATA_free_all_data(&group->extra_data);
139 if (group->mont_data)
140 BN_MONT_CTX_free(group->mont_data);
142 if (group->generator != NULL)
143 EC_POINT_free(group->generator);
144 BN_free(group->order);
145 BN_free(group->cofactor);
148 OPENSSL_free(group->seed);
154 void EC_GROUP_clear_free(EC_GROUP *group)
158 if (group->meth->group_clear_finish != 0)
159 group->meth->group_clear_finish(group);
160 else if (group->meth->group_finish != 0)
161 group->meth->group_finish(group);
163 EC_EX_DATA_clear_free_all_data(&group->extra_data);
165 if (group->mont_data)
166 BN_MONT_CTX_free(group->mont_data);
168 if (group->generator != NULL)
169 EC_POINT_clear_free(group->generator);
170 BN_clear_free(group->order);
171 BN_clear_free(group->cofactor);
175 OPENSSL_cleanse(group->seed, group->seed_len);
176 OPENSSL_free(group->seed);
179 OPENSSL_cleanse(group, sizeof *group);
184 int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
188 if (dest->meth->group_copy == 0)
190 ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
193 if (dest->meth != src->meth)
195 ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
201 EC_EX_DATA_free_all_data(&dest->extra_data);
203 for (d = src->extra_data; d != NULL; d = d->next)
205 void *t = d->dup_func(d->data);
209 if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func, d->free_func, d->clear_free_func))
213 if (src->mont_data != NULL)
215 if (dest->mont_data == NULL)
217 dest->mont_data = BN_MONT_CTX_new();
218 if (dest->mont_data == NULL) return 0;
220 if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) return 0;
224 /* src->generator == NULL */
225 if (dest->mont_data != NULL)
227 BN_MONT_CTX_free(dest->mont_data);
228 dest->mont_data = NULL;
232 if (src->generator != NULL)
234 if (dest->generator == NULL)
236 dest->generator = EC_POINT_new(dest);
237 if (dest->generator == NULL) return 0;
239 if (!EC_POINT_copy(dest->generator, src->generator)) return 0;
243 /* src->generator == NULL */
244 if (dest->generator != NULL)
246 EC_POINT_clear_free(dest->generator);
247 dest->generator = NULL;
251 if (!BN_copy(dest->order, src->order)) return 0;
252 if (!BN_copy(dest->cofactor, src->cofactor)) return 0;
254 dest->curve_name = src->curve_name;
255 dest->asn1_flag = src->asn1_flag;
256 dest->asn1_form = src->asn1_form;
261 OPENSSL_free(dest->seed);
262 dest->seed = OPENSSL_malloc(src->seed_len);
263 if (dest->seed == NULL)
265 if (!memcpy(dest->seed, src->seed, src->seed_len))
267 dest->seed_len = src->seed_len;
272 OPENSSL_free(dest->seed);
278 return dest->meth->group_copy(dest, src);
282 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
287 if (a == NULL) return NULL;
289 if ((t = EC_GROUP_new(a->meth)) == NULL) return(NULL);
290 if (!EC_GROUP_copy(t, a)) goto err;
297 if (t) EC_GROUP_free(t);
304 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
310 int EC_METHOD_get_field_type(const EC_METHOD *meth)
312 return meth->field_type;
316 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
318 if (generator == NULL)
320 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
324 if (group->generator == NULL)
326 group->generator = EC_POINT_new(group);
327 if (group->generator == NULL) return 0;
329 if (!EC_POINT_copy(group->generator, generator)) return 0;
332 { if (!BN_copy(group->order, order)) return 0; }
334 BN_zero(group->order);
336 if (cofactor != NULL)
337 { if (!BN_copy(group->cofactor, cofactor)) return 0; }
339 BN_zero(group->cofactor);
341 /* We ignore the return value because some groups have an order with
342 * factors of two, which makes the Montgomery setup fail.
343 * |group->mont_data| will be NULL in this case. */
344 ec_precompute_mont_data(group);
350 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
352 return group->generator;
355 BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
357 return group->mont_data;
360 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
362 if (!BN_copy(order, group->order))
365 return !BN_is_zero(order);
369 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
371 if (!BN_copy(cofactor, group->cofactor))
374 return !BN_is_zero(group->cofactor);
378 void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
380 group->curve_name = nid;
384 int EC_GROUP_get_curve_name(const EC_GROUP *group)
386 return group->curve_name;
390 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
392 group->asn1_flag = flag;
396 int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
398 return group->asn1_flag;
402 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
403 point_conversion_form_t form)
405 group->asn1_form = form;
409 point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
411 return group->asn1_form;
415 size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
419 OPENSSL_free(group->seed);
427 if ((group->seed = OPENSSL_malloc(len)) == NULL)
429 memcpy(group->seed, p, len);
430 group->seed_len = len;
436 unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
442 size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
444 return group->seed_len;
448 int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
450 if (group->meth->group_set_curve == 0)
452 ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
455 return group->meth->group_set_curve(group, p, a, b, ctx);
459 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
461 if (group->meth->group_get_curve == 0)
463 ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
466 return group->meth->group_get_curve(group, p, a, b, ctx);
469 #ifndef OPENSSL_NO_EC2M
470 int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
472 if (group->meth->group_set_curve == 0)
474 ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
477 return group->meth->group_set_curve(group, p, a, b, ctx);
481 int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
483 if (group->meth->group_get_curve == 0)
485 ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
488 return group->meth->group_get_curve(group, p, a, b, ctx);
492 int EC_GROUP_get_degree(const EC_GROUP *group)
494 if (group->meth->group_get_degree == 0)
496 ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
499 return group->meth->group_get_degree(group);
503 int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
505 if (group->meth->group_check_discriminant == 0)
507 ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
510 return group->meth->group_check_discriminant(group, ctx);
514 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
517 BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
518 BN_CTX *ctx_new = NULL;
520 /* compare the field types*/
521 if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
522 EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
524 /* compare the curve name (if present in both) */
525 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
526 EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
530 ctx_new = ctx = BN_CTX_new();
535 a1 = BN_CTX_get(ctx);
536 a2 = BN_CTX_get(ctx);
537 a3 = BN_CTX_get(ctx);
538 b1 = BN_CTX_get(ctx);
539 b2 = BN_CTX_get(ctx);
540 b3 = BN_CTX_get(ctx);
549 /* XXX This approach assumes that the external representation
550 * of curves over the same field type is the same.
552 if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
553 !b->meth->group_get_curve(b, b1, b2, b3, ctx))
556 if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
559 /* XXX EC_POINT_cmp() assumes that the methods are equal */
560 if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
561 EC_GROUP_get0_generator(b), ctx))
566 /* compare the order and cofactor */
567 if (!EC_GROUP_get_order(a, a1, ctx) ||
568 !EC_GROUP_get_order(b, b1, ctx) ||
569 !EC_GROUP_get_cofactor(a, a2, ctx) ||
570 !EC_GROUP_get_cofactor(b, b2, ctx))
577 if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
589 /* this has 'package' visibility */
590 int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
591 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
598 for (d = *ex_data; d != NULL; d = d->next)
600 if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
602 ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
608 /* no explicit entry needed */
611 d = OPENSSL_malloc(sizeof *d);
616 d->dup_func = dup_func;
617 d->free_func = free_func;
618 d->clear_free_func = clear_free_func;
626 /* this has 'package' visibility */
627 void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
628 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
630 const EC_EXTRA_DATA *d;
632 for (d = ex_data; d != NULL; d = d->next)
634 if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
641 /* this has 'package' visibility */
642 void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
643 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
650 for (p = ex_data; *p != NULL; p = &((*p)->next))
652 if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
654 EC_EXTRA_DATA *next = (*p)->next;
656 (*p)->free_func((*p)->data);
665 /* this has 'package' visibility */
666 void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
667 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
674 for (p = ex_data; *p != NULL; p = &((*p)->next))
676 if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
678 EC_EXTRA_DATA *next = (*p)->next;
680 (*p)->clear_free_func((*p)->data);
689 /* this has 'package' visibility */
690 void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
700 EC_EXTRA_DATA *next = d->next;
702 d->free_func(d->data);
710 /* this has 'package' visibility */
711 void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
721 EC_EXTRA_DATA *next = d->next;
723 d->clear_free_func(d->data);
732 /* functions for EC_POINT objects */
734 EC_POINT *EC_POINT_new(const EC_GROUP *group)
740 ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
743 if (group->meth->point_init == 0)
745 ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
749 ret = OPENSSL_malloc(sizeof *ret);
752 ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
756 ret->meth = group->meth;
758 if (!ret->meth->point_init(ret))
768 void EC_POINT_free(EC_POINT *point)
772 if (point->meth->point_finish != 0)
773 point->meth->point_finish(point);
778 void EC_POINT_clear_free(EC_POINT *point)
782 if (point->meth->point_clear_finish != 0)
783 point->meth->point_clear_finish(point);
784 else if (point->meth->point_finish != 0)
785 point->meth->point_finish(point);
786 OPENSSL_cleanse(point, sizeof *point);
791 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
793 if (dest->meth->point_copy == 0)
795 ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
798 if (dest->meth != src->meth)
800 ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
805 return dest->meth->point_copy(dest, src);
809 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
814 if (a == NULL) return NULL;
816 t = EC_POINT_new(group);
817 if (t == NULL) return(NULL);
818 r = EC_POINT_copy(t, a);
828 const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
834 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
836 if (group->meth->point_set_to_infinity == 0)
838 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
841 if (group->meth != point->meth)
843 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
846 return group->meth->point_set_to_infinity(group, point);
850 int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
851 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
853 if (group->meth->point_set_Jprojective_coordinates_GFp == 0)
855 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
858 if (group->meth != point->meth)
860 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
863 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
867 int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
868 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
870 if (group->meth->point_get_Jprojective_coordinates_GFp == 0)
872 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
875 if (group->meth != point->meth)
877 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
880 return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
884 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
885 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
887 if (group->meth->point_set_affine_coordinates == 0)
889 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
892 if (group->meth != point->meth)
894 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
897 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
900 #ifndef OPENSSL_NO_EC2M
901 int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
902 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
904 if (group->meth->point_set_affine_coordinates == 0)
906 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
909 if (group->meth != point->meth)
911 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
914 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
918 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
919 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
921 if (group->meth->point_get_affine_coordinates == 0)
923 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
926 if (group->meth != point->meth)
928 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
931 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
934 #ifndef OPENSSL_NO_EC2M
935 int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
936 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
938 if (group->meth->point_get_affine_coordinates == 0)
940 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
943 if (group->meth != point->meth)
945 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
948 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
952 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
954 if (group->meth->add == 0)
956 ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
959 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth))
961 ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
964 return group->meth->add(group, r, a, b, ctx);
968 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
970 if (group->meth->dbl == 0)
972 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
975 if ((group->meth != r->meth) || (r->meth != a->meth))
977 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
980 return group->meth->dbl(group, r, a, ctx);
984 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
986 if (group->meth->invert == 0)
988 ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
991 if (group->meth != a->meth)
993 ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
996 return group->meth->invert(group, a, ctx);
1000 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1002 if (group->meth->is_at_infinity == 0)
1004 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1007 if (group->meth != point->meth)
1009 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
1012 return group->meth->is_at_infinity(group, point);
1016 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
1018 if (group->meth->is_on_curve == 0)
1020 ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1023 if (group->meth != point->meth)
1025 ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
1028 return group->meth->is_on_curve(group, point, ctx);
1032 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
1034 if (group->meth->point_cmp == 0)
1036 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1039 if ((group->meth != a->meth) || (a->meth != b->meth))
1041 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
1044 return group->meth->point_cmp(group, a, b, ctx);
1048 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1050 if (group->meth->make_affine == 0)
1052 ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1055 if (group->meth != point->meth)
1057 ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1060 return group->meth->make_affine(group, point, ctx);
1064 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
1068 if (group->meth->points_make_affine == 0)
1070 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1073 for (i = 0; i < num; i++)
1075 if (group->meth != points[i]->meth)
1077 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1081 return group->meth->points_make_affine(group, num, points, ctx);
1085 /* Functions for point multiplication.
1087 * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
1088 * otherwise we dispatch through methods.
1091 int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1092 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
1094 if (group->meth->mul == 0)
1096 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
1098 return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
1101 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1102 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
1104 /* just a convenient interface to EC_POINTs_mul() */
1106 const EC_POINT *points[1];
1107 const BIGNUM *scalars[1];
1110 scalars[0] = p_scalar;
1112 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), points, scalars, ctx);
1115 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
1117 if (group->meth->mul == 0)
1119 return ec_wNAF_precompute_mult(group, ctx);
1121 if (group->meth->precompute_mult != 0)
1122 return group->meth->precompute_mult(group, ctx);
1124 return 1; /* nothing to do, so report success */
1127 int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
1129 if (group->meth->mul == 0)
1131 return ec_wNAF_have_precompute_mult(group);
1133 if (group->meth->have_precompute_mult != 0)
1134 return group->meth->have_precompute_mult(group);
1136 return 0; /* cannot tell whether precomputation has been performed */
1139 /* ec_precompute_mont_data sets |group->mont_data| from |group->order| and
1140 * returns one on success. On error it returns zero. */
1141 int ec_precompute_mont_data(EC_GROUP *group)
1143 BN_CTX *ctx = BN_CTX_new();
1146 if (group->mont_data)
1148 BN_MONT_CTX_free(group->mont_data);
1149 group->mont_data = NULL;
1155 group->mont_data = BN_MONT_CTX_new();
1156 if (!group->mont_data)
1159 if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx))
1161 BN_MONT_CTX_free(group->mont_data);
1162 group->mont_data = NULL;