1 /* crypto/ec/ec_lib.c */
3 * Originally written by Bodo Moeller for the OpenSSL project.
5 /* ====================================================================
6 * Copyright (c) 1998-2002 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.
66 #include <openssl/err.h>
67 #include <openssl/opensslv.h>
71 static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
74 /* functions for EC_GROUP objects */
76 EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
82 ECerr(EC_F_EC_GROUP_NEW, ERR_R_PASSED_NULL_PARAMETER);
85 if (meth->group_init == 0)
87 ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
91 ret = OPENSSL_malloc(sizeof *ret);
94 ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
100 ret->extra_data = NULL;
101 ret->extra_data_dup_func = 0;
102 ret->extra_data_free_func = 0;
103 ret->extra_data_clear_free_func = 0;
105 ret->generator = NULL;
106 BN_init(&ret->order);
107 BN_init(&ret->cofactor);
111 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
116 if (!meth->group_init(ret))
126 void EC_GROUP_free(EC_GROUP *group)
130 if (group->meth->group_finish != 0)
131 group->meth->group_finish(group);
133 EC_GROUP_free_extra_data(group);
135 if (group->generator != NULL)
136 EC_POINT_free(group->generator);
137 BN_free(&group->order);
138 BN_free(&group->cofactor);
141 OPENSSL_free(group->seed);
147 void EC_GROUP_clear_free(EC_GROUP *group)
151 if (group->meth->group_clear_finish != 0)
152 group->meth->group_clear_finish(group);
153 else if (group->meth != NULL && group->meth->group_finish != 0)
154 group->meth->group_finish(group);
156 EC_GROUP_clear_free_extra_data(group);
158 if (group->generator != NULL)
159 EC_POINT_clear_free(group->generator);
160 BN_clear_free(&group->order);
161 BN_clear_free(&group->cofactor);
165 memset(group->seed, 0, group->seed_len);
166 OPENSSL_free(group->seed);
169 memset(group, 0, sizeof *group);
174 int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
176 if (dest->meth->group_copy == 0)
178 ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
181 if (dest->meth != src->meth)
183 ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
189 EC_GROUP_clear_free_extra_data(dest);
190 if (src->extra_data_dup_func)
192 if (src->extra_data != NULL)
194 dest->extra_data = src->extra_data_dup_func(src->extra_data);
195 if (dest->extra_data == NULL)
199 dest->extra_data_dup_func = src->extra_data_dup_func;
200 dest->extra_data_free_func = src->extra_data_free_func;
201 dest->extra_data_clear_free_func = src->extra_data_clear_free_func;
204 if (src->generator != NULL)
206 if (dest->generator == NULL)
208 dest->generator = EC_POINT_new(dest);
209 if (dest->generator == NULL) return 0;
211 if (!EC_POINT_copy(dest->generator, src->generator)) return 0;
215 /* src->generator == NULL */
216 if (dest->generator != NULL)
218 EC_POINT_clear_free(dest->generator);
219 dest->generator = NULL;
223 if (!BN_copy(&dest->order, &src->order)) return 0;
224 if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0;
226 dest->curve_name = src->curve_name;
227 dest->asn1_flag = src->asn1_flag;
228 dest->asn1_form = src->asn1_form;
233 OPENSSL_free(dest->seed);
234 dest->seed = OPENSSL_malloc(src->seed_len);
235 if (dest->seed == NULL)
237 if (!memcpy(dest->seed, src->seed, src->seed_len))
239 dest->seed_len = src->seed_len;
244 OPENSSL_free(dest->seed);
250 return dest->meth->group_copy(dest, src);
254 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
259 if (a == NULL) return NULL;
261 if ((t = EC_GROUP_new(a->meth)) == NULL) return(NULL);
262 if (!EC_GROUP_copy(t, a)) goto err;
269 if (t) EC_GROUP_free(t);
276 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
282 int EC_METHOD_get_field_type(const EC_METHOD *meth)
284 return meth->field_type;
288 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
290 if (generator == NULL)
292 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
296 if (group->generator == NULL)
298 group->generator = EC_POINT_new(group);
299 if (group->generator == NULL) return 0;
301 if (!EC_POINT_copy(group->generator, generator)) return 0;
304 { if (!BN_copy(&group->order, order)) return 0; }
306 { if (!BN_zero(&group->order)) return 0; }
308 if (cofactor != NULL)
309 { if (!BN_copy(&group->cofactor, cofactor)) return 0; }
311 { if (!BN_zero(&group->cofactor)) return 0; }
317 EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
319 return group->generator;
323 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
325 if (!BN_copy(order, &group->order))
328 return !BN_is_zero(order);
332 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
334 if (!BN_copy(cofactor, &group->cofactor))
337 return !BN_is_zero(&group->cofactor);
341 void EC_GROUP_set_nid(EC_GROUP *group, int nid)
343 group->curve_name = nid;
347 int EC_GROUP_get_nid(const EC_GROUP *group)
349 return group->curve_name;
353 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
355 group->asn1_flag = flag;
359 int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
361 return group->asn1_flag;
365 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
366 point_conversion_form_t form)
368 group->asn1_form = form;
372 point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
374 return group->asn1_form;
378 size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
382 OPENSSL_free(group->seed);
390 if ((group->seed = OPENSSL_malloc(len)) == NULL)
392 memcpy(group->seed, p, len);
393 group->seed_len = len;
399 unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
405 size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
407 return group->seed_len;
411 int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
413 if (group->meth->group_set_curve == 0)
415 ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
418 return group->meth->group_set_curve(group, p, a, b, ctx);
422 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
424 if (group->meth->group_get_curve == 0)
426 ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
429 return group->meth->group_get_curve(group, p, a, b, ctx);
433 int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
435 if (group->meth->group_set_curve == 0)
437 ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
440 return group->meth->group_set_curve(group, p, a, b, ctx);
444 int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
446 if (group->meth->group_get_curve == 0)
448 ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
451 return group->meth->group_get_curve(group, p, a, b, ctx);
455 int EC_GROUP_get_degree(const EC_GROUP *group)
457 if (group->meth->group_get_degree == 0)
459 ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
462 return group->meth->group_get_degree(group);
466 int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
468 if (group->meth->group_check_discriminant == 0)
470 ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
473 return group->meth->group_check_discriminant(group, ctx);
477 /* this has 'package' visibility */
478 int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *),
479 void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
481 if ((group->extra_data != NULL)
482 || (group->extra_data_dup_func != 0)
483 || (group->extra_data_free_func != 0)
484 || (group->extra_data_clear_free_func != 0))
486 ECerr(EC_F_EC_GROUP_SET_EXTRA_DATA, EC_R_SLOT_FULL);
490 group->extra_data = extra_data;
491 group->extra_data_dup_func = extra_data_dup_func;
492 group->extra_data_free_func = extra_data_free_func;
493 group->extra_data_clear_free_func = extra_data_clear_free_func;
498 /* this has 'package' visibility */
499 void *EC_GROUP_get_extra_data(const EC_GROUP *group, void *(*extra_data_dup_func)(void *),
500 void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
502 if ((group->extra_data_dup_func != extra_data_dup_func)
503 || (group->extra_data_free_func != extra_data_free_func)
504 || (group->extra_data_clear_free_func != extra_data_clear_free_func))
506 ECerr(EC_F_EC_GROUP_GET_EXTRA_DATA, EC_R_NO_SUCH_EXTRA_DATA);
510 return group->extra_data;
514 /* this has 'package' visibility */
515 void EC_GROUP_free_extra_data(EC_GROUP *group)
517 if (group->extra_data_free_func)
518 group->extra_data_free_func(group->extra_data);
519 group->extra_data = NULL;
520 group->extra_data_dup_func = 0;
521 group->extra_data_free_func = 0;
522 group->extra_data_clear_free_func = 0;
526 /* this has 'package' visibility */
527 void EC_GROUP_clear_free_extra_data(EC_GROUP *group)
529 if (group->extra_data_clear_free_func)
530 group->extra_data_clear_free_func(group->extra_data);
531 else if (group->extra_data_free_func)
532 group->extra_data_free_func(group->extra_data);
533 group->extra_data = NULL;
534 group->extra_data_dup_func = 0;
535 group->extra_data_free_func = 0;
536 group->extra_data_clear_free_func = 0;
540 /* functions for EC_POINT objects */
542 EC_POINT *EC_POINT_new(const EC_GROUP *group)
548 ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
551 if (group->meth->point_init == 0)
553 ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
557 ret = OPENSSL_malloc(sizeof *ret);
560 ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
564 ret->meth = group->meth;
566 if (!ret->meth->point_init(ret))
576 void EC_POINT_free(EC_POINT *point)
580 if (point->meth->point_finish != 0)
581 point->meth->point_finish(point);
586 void EC_POINT_clear_free(EC_POINT *point)
590 if (point->meth->point_clear_finish != 0)
591 point->meth->point_clear_finish(point);
592 else if (point->meth != NULL && point->meth->point_finish != 0)
593 point->meth->point_finish(point);
594 memset(point, 0, sizeof *point);
599 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
601 if (dest->meth->point_copy == 0)
603 ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
606 if (dest->meth != src->meth)
608 ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
613 return dest->meth->point_copy(dest, src);
617 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
622 if (a == NULL) return NULL;
624 t = EC_POINT_new(group);
625 if (t == NULL) return(NULL);
626 r = EC_POINT_copy(t, a);
636 const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
642 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
644 if (group->meth->point_set_to_infinity == 0)
646 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
649 if (group->meth != point->meth)
651 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
654 return group->meth->point_set_to_infinity(group, point);
658 int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
659 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
661 if (group->meth->point_set_Jprojective_coordinates_GFp == 0)
663 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
666 if (group->meth != point->meth)
668 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
671 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
675 int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
676 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
678 if (group->meth->point_get_Jprojective_coordinates_GFp == 0)
680 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
683 if (group->meth != point->meth)
685 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
688 return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
692 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
693 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
695 if (group->meth->point_set_affine_coordinates == 0)
697 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
700 if (group->meth != point->meth)
702 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
705 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
709 int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
710 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
712 if (group->meth->point_set_affine_coordinates == 0)
714 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
717 if (group->meth != point->meth)
719 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
722 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
726 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
727 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
729 if (group->meth->point_get_affine_coordinates == 0)
731 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
734 if (group->meth != point->meth)
736 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
739 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
743 int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
744 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
746 if (group->meth->point_get_affine_coordinates == 0)
748 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
751 if (group->meth != point->meth)
753 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
756 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
760 int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
761 const BIGNUM *x, int y_bit, BN_CTX *ctx)
763 if (group->meth->point_set_compressed_coordinates == 0)
765 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
768 if (group->meth != point->meth)
770 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
773 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
777 int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
778 const BIGNUM *x, int y_bit, BN_CTX *ctx)
780 if (group->meth->point_set_compressed_coordinates == 0)
782 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
785 if (group->meth != point->meth)
787 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
790 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
794 size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
795 unsigned char *buf, size_t len, BN_CTX *ctx)
797 if (group->meth->point2oct == 0)
799 ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
802 if (group->meth != point->meth)
804 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
807 return group->meth->point2oct(group, point, form, buf, len, ctx);
811 int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
812 const unsigned char *buf, size_t len, BN_CTX *ctx)
814 if (group->meth->oct2point == 0)
816 ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
819 if (group->meth != point->meth)
821 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
824 return group->meth->oct2point(group, point, buf, len, ctx);
828 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
830 if (group->meth->add == 0)
832 ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
835 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth))
837 ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
840 return group->meth->add(group, r, a, b, ctx);
844 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
846 if (group->meth->dbl == 0)
848 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
851 if ((group->meth != r->meth) || (r->meth != a->meth))
853 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
856 return group->meth->dbl(group, r, a, ctx);
860 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
862 if (group->meth->dbl == 0)
864 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
867 if (group->meth != a->meth)
869 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
872 return group->meth->invert(group, a, ctx);
876 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
878 if (group->meth->is_at_infinity == 0)
880 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
883 if (group->meth != point->meth)
885 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
888 return group->meth->is_at_infinity(group, point);
892 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
894 if (group->meth->is_on_curve == 0)
896 ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
899 if (group->meth != point->meth)
901 ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
904 return group->meth->is_on_curve(group, point, ctx);
908 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
910 if (group->meth->point_cmp == 0)
912 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
915 if ((group->meth != a->meth) || (a->meth != b->meth))
917 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
920 return group->meth->point_cmp(group, a, b, ctx);
924 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
926 if (group->meth->make_affine == 0)
928 ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
931 if (group->meth != point->meth)
933 ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
936 return group->meth->make_affine(group, point, ctx);
940 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
944 if (group->meth->points_make_affine == 0)
946 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
949 for (i = 0; i < num; i++)
951 if (group->meth != points[i]->meth)
953 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
957 return group->meth->points_make_affine(group, num, points, ctx);