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.
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 OPENSSL_cleanse(group
->seed
, group
->seed_len
);
166 OPENSSL_free(group
->seed
);
169 OPENSSL_cleanse(group
, 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 #if 0 /* this was an error in 0.9.7, but that does not make a lot of sense */
507 ECerr(EC_F_EC_GROUP_GET_EXTRA_DATA
, EC_R_NO_SUCH_EXTRA_DATA
);
512 return group
->extra_data
;
516 /* this has 'package' visibility */
517 void EC_GROUP_free_extra_data(EC_GROUP
*group
)
519 if (group
->extra_data_free_func
)
520 group
->extra_data_free_func(group
->extra_data
);
521 group
->extra_data
= NULL
;
522 group
->extra_data_dup_func
= 0;
523 group
->extra_data_free_func
= 0;
524 group
->extra_data_clear_free_func
= 0;
528 /* this has 'package' visibility */
529 void EC_GROUP_clear_free_extra_data(EC_GROUP
*group
)
531 if (group
->extra_data_clear_free_func
)
532 group
->extra_data_clear_free_func(group
->extra_data
);
533 else if (group
->extra_data_free_func
)
534 group
->extra_data_free_func(group
->extra_data
);
535 group
->extra_data
= NULL
;
536 group
->extra_data_dup_func
= 0;
537 group
->extra_data_free_func
= 0;
538 group
->extra_data_clear_free_func
= 0;
542 /* functions for EC_POINT objects */
544 EC_POINT
*EC_POINT_new(const EC_GROUP
*group
)
550 ECerr(EC_F_EC_POINT_NEW
, ERR_R_PASSED_NULL_PARAMETER
);
553 if (group
->meth
->point_init
== 0)
555 ECerr(EC_F_EC_POINT_NEW
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
559 ret
= OPENSSL_malloc(sizeof *ret
);
562 ECerr(EC_F_EC_POINT_NEW
, ERR_R_MALLOC_FAILURE
);
566 ret
->meth
= group
->meth
;
568 if (!ret
->meth
->point_init(ret
))
578 void EC_POINT_free(EC_POINT
*point
)
582 if (point
->meth
->point_finish
!= 0)
583 point
->meth
->point_finish(point
);
588 void EC_POINT_clear_free(EC_POINT
*point
)
592 if (point
->meth
->point_clear_finish
!= 0)
593 point
->meth
->point_clear_finish(point
);
594 else if (point
->meth
!= NULL
&& point
->meth
->point_finish
!= 0)
595 point
->meth
->point_finish(point
);
596 OPENSSL_cleanse(point
, sizeof *point
);
601 int EC_POINT_copy(EC_POINT
*dest
, const EC_POINT
*src
)
603 if (dest
->meth
->point_copy
== 0)
605 ECerr(EC_F_EC_POINT_COPY
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
608 if (dest
->meth
!= src
->meth
)
610 ECerr(EC_F_EC_POINT_COPY
, EC_R_INCOMPATIBLE_OBJECTS
);
615 return dest
->meth
->point_copy(dest
, src
);
619 EC_POINT
*EC_POINT_dup(const EC_POINT
*a
, const EC_GROUP
*group
)
624 if (a
== NULL
) return NULL
;
626 t
= EC_POINT_new(group
);
627 if (t
== NULL
) return(NULL
);
628 r
= EC_POINT_copy(t
, a
);
638 const EC_METHOD
*EC_POINT_method_of(const EC_POINT
*point
)
644 int EC_POINT_set_to_infinity(const EC_GROUP
*group
, EC_POINT
*point
)
646 if (group
->meth
->point_set_to_infinity
== 0)
648 ECerr(EC_F_EC_POINT_SET_TO_INFINITY
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
651 if (group
->meth
!= point
->meth
)
653 ECerr(EC_F_EC_POINT_SET_TO_INFINITY
, EC_R_INCOMPATIBLE_OBJECTS
);
656 return group
->meth
->point_set_to_infinity(group
, point
);
660 int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP
*group
, EC_POINT
*point
,
661 const BIGNUM
*x
, const BIGNUM
*y
, const BIGNUM
*z
, BN_CTX
*ctx
)
663 if (group
->meth
->point_set_Jprojective_coordinates_GFp
== 0)
665 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
668 if (group
->meth
!= point
->meth
)
670 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP
, EC_R_INCOMPATIBLE_OBJECTS
);
673 return group
->meth
->point_set_Jprojective_coordinates_GFp(group
, point
, x
, y
, z
, ctx
);
677 int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP
*group
, const EC_POINT
*point
,
678 BIGNUM
*x
, BIGNUM
*y
, BIGNUM
*z
, BN_CTX
*ctx
)
680 if (group
->meth
->point_get_Jprojective_coordinates_GFp
== 0)
682 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
685 if (group
->meth
!= point
->meth
)
687 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP
, EC_R_INCOMPATIBLE_OBJECTS
);
690 return group
->meth
->point_get_Jprojective_coordinates_GFp(group
, point
, x
, y
, z
, ctx
);
694 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP
*group
, EC_POINT
*point
,
695 const BIGNUM
*x
, const BIGNUM
*y
, BN_CTX
*ctx
)
697 if (group
->meth
->point_set_affine_coordinates
== 0)
699 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
702 if (group
->meth
!= point
->meth
)
704 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP
, EC_R_INCOMPATIBLE_OBJECTS
);
707 return group
->meth
->point_set_affine_coordinates(group
, point
, x
, y
, ctx
);
711 int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP
*group
, EC_POINT
*point
,
712 const BIGNUM
*x
, const BIGNUM
*y
, BN_CTX
*ctx
)
714 if (group
->meth
->point_set_affine_coordinates
== 0)
716 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
719 if (group
->meth
!= point
->meth
)
721 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M
, EC_R_INCOMPATIBLE_OBJECTS
);
724 return group
->meth
->point_set_affine_coordinates(group
, point
, x
, y
, ctx
);
728 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP
*group
, const EC_POINT
*point
,
729 BIGNUM
*x
, BIGNUM
*y
, BN_CTX
*ctx
)
731 if (group
->meth
->point_get_affine_coordinates
== 0)
733 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
736 if (group
->meth
!= point
->meth
)
738 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP
, EC_R_INCOMPATIBLE_OBJECTS
);
741 return group
->meth
->point_get_affine_coordinates(group
, point
, x
, y
, ctx
);
745 int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP
*group
, const EC_POINT
*point
,
746 BIGNUM
*x
, BIGNUM
*y
, BN_CTX
*ctx
)
748 if (group
->meth
->point_get_affine_coordinates
== 0)
750 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
753 if (group
->meth
!= point
->meth
)
755 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M
, EC_R_INCOMPATIBLE_OBJECTS
);
758 return group
->meth
->point_get_affine_coordinates(group
, point
, x
, y
, ctx
);
762 int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP
*group
, EC_POINT
*point
,
763 const BIGNUM
*x
, int y_bit
, BN_CTX
*ctx
)
765 if (group
->meth
->point_set_compressed_coordinates
== 0)
767 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
770 if (group
->meth
!= point
->meth
)
772 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP
, EC_R_INCOMPATIBLE_OBJECTS
);
775 return group
->meth
->point_set_compressed_coordinates(group
, point
, x
, y_bit
, ctx
);
779 int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP
*group
, EC_POINT
*point
,
780 const BIGNUM
*x
, int y_bit
, BN_CTX
*ctx
)
782 if (group
->meth
->point_set_compressed_coordinates
== 0)
784 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
787 if (group
->meth
!= point
->meth
)
789 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M
, EC_R_INCOMPATIBLE_OBJECTS
);
792 return group
->meth
->point_set_compressed_coordinates(group
, point
, x
, y_bit
, ctx
);
796 size_t EC_POINT_point2oct(const EC_GROUP
*group
, const EC_POINT
*point
, point_conversion_form_t form
,
797 unsigned char *buf
, size_t len
, BN_CTX
*ctx
)
799 if (group
->meth
->point2oct
== 0)
801 ECerr(EC_F_EC_POINT_POINT2OCT
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
804 if (group
->meth
!= point
->meth
)
806 ECerr(EC_F_EC_POINT_POINT2OCT
, EC_R_INCOMPATIBLE_OBJECTS
);
809 return group
->meth
->point2oct(group
, point
, form
, buf
, len
, ctx
);
813 int EC_POINT_oct2point(const EC_GROUP
*group
, EC_POINT
*point
,
814 const unsigned char *buf
, size_t len
, BN_CTX
*ctx
)
816 if (group
->meth
->oct2point
== 0)
818 ECerr(EC_F_EC_POINT_OCT2POINT
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
821 if (group
->meth
!= point
->meth
)
823 ECerr(EC_F_EC_POINT_OCT2POINT
, EC_R_INCOMPATIBLE_OBJECTS
);
826 return group
->meth
->oct2point(group
, point
, buf
, len
, ctx
);
830 int EC_POINT_add(const EC_GROUP
*group
, EC_POINT
*r
, const EC_POINT
*a
, const EC_POINT
*b
, BN_CTX
*ctx
)
832 if (group
->meth
->add
== 0)
834 ECerr(EC_F_EC_POINT_ADD
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
837 if ((group
->meth
!= r
->meth
) || (r
->meth
!= a
->meth
) || (a
->meth
!= b
->meth
))
839 ECerr(EC_F_EC_POINT_ADD
, EC_R_INCOMPATIBLE_OBJECTS
);
842 return group
->meth
->add(group
, r
, a
, b
, ctx
);
846 int EC_POINT_dbl(const EC_GROUP
*group
, EC_POINT
*r
, const EC_POINT
*a
, BN_CTX
*ctx
)
848 if (group
->meth
->dbl
== 0)
850 ECerr(EC_F_EC_POINT_DBL
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
853 if ((group
->meth
!= r
->meth
) || (r
->meth
!= a
->meth
))
855 ECerr(EC_F_EC_POINT_DBL
, EC_R_INCOMPATIBLE_OBJECTS
);
858 return group
->meth
->dbl(group
, r
, a
, ctx
);
862 int EC_POINT_invert(const EC_GROUP
*group
, EC_POINT
*a
, BN_CTX
*ctx
)
864 if (group
->meth
->dbl
== 0)
866 ECerr(EC_F_EC_POINT_DBL
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
869 if (group
->meth
!= a
->meth
)
871 ECerr(EC_F_EC_POINT_DBL
, EC_R_INCOMPATIBLE_OBJECTS
);
874 return group
->meth
->invert(group
, a
, ctx
);
878 int EC_POINT_is_at_infinity(const EC_GROUP
*group
, const EC_POINT
*point
)
880 if (group
->meth
->is_at_infinity
== 0)
882 ECerr(EC_F_EC_POINT_IS_AT_INFINITY
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
885 if (group
->meth
!= point
->meth
)
887 ECerr(EC_F_EC_POINT_IS_AT_INFINITY
, EC_R_INCOMPATIBLE_OBJECTS
);
890 return group
->meth
->is_at_infinity(group
, point
);
894 int EC_POINT_is_on_curve(const EC_GROUP
*group
, const EC_POINT
*point
, BN_CTX
*ctx
)
896 if (group
->meth
->is_on_curve
== 0)
898 ECerr(EC_F_EC_POINT_IS_ON_CURVE
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
901 if (group
->meth
!= point
->meth
)
903 ECerr(EC_F_EC_POINT_IS_ON_CURVE
, EC_R_INCOMPATIBLE_OBJECTS
);
906 return group
->meth
->is_on_curve(group
, point
, ctx
);
910 int EC_POINT_cmp(const EC_GROUP
*group
, const EC_POINT
*a
, const EC_POINT
*b
, BN_CTX
*ctx
)
912 if (group
->meth
->point_cmp
== 0)
914 ECerr(EC_F_EC_POINT_CMP
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
917 if ((group
->meth
!= a
->meth
) || (a
->meth
!= b
->meth
))
919 ECerr(EC_F_EC_POINT_CMP
, EC_R_INCOMPATIBLE_OBJECTS
);
922 return group
->meth
->point_cmp(group
, a
, b
, ctx
);
926 int EC_POINT_make_affine(const EC_GROUP
*group
, EC_POINT
*point
, BN_CTX
*ctx
)
928 if (group
->meth
->make_affine
== 0)
930 ECerr(EC_F_EC_POINT_MAKE_AFFINE
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
933 if (group
->meth
!= point
->meth
)
935 ECerr(EC_F_EC_POINT_MAKE_AFFINE
, EC_R_INCOMPATIBLE_OBJECTS
);
938 return group
->meth
->make_affine(group
, point
, ctx
);
942 int EC_POINTs_make_affine(const EC_GROUP
*group
, size_t num
, EC_POINT
*points
[], BN_CTX
*ctx
)
946 if (group
->meth
->points_make_affine
== 0)
948 ECerr(EC_F_EC_POINTS_MAKE_AFFINE
, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
);
951 for (i
= 0; i
< num
; i
++)
953 if (group
->meth
!= points
[i
]->meth
)
955 ECerr(EC_F_EC_POINTS_MAKE_AFFINE
, EC_R_INCOMPATIBLE_OBJECTS
);
959 return group
->meth
->points_make_affine(group
, num
, points
, ctx
);
963 /* Functions for point multiplication.
965 * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
966 * otherwise we dispatch through methods.
969 int EC_POINTs_mul(const EC_GROUP
*group
, EC_POINT
*r
, const BIGNUM
*scalar
,
970 size_t num
, const EC_POINT
*points
[], const BIGNUM
*scalars
[], BN_CTX
*ctx
)
972 if (group
->meth
->mul
== 0)
974 return ec_wNAF_mul(group
, r
, scalar
, num
, points
, scalars
, ctx
);
976 return group
->meth
->mul(group
, r
, scalar
, num
, points
, scalars
, ctx
);
979 int EC_POINT_mul(const EC_GROUP
*group
, EC_POINT
*r
, const BIGNUM
*g_scalar
,
980 const EC_POINT
*point
, const BIGNUM
*p_scalar
, BN_CTX
*ctx
)
982 /* just a convenient interface to EC_POINTs_mul() */
984 const EC_POINT
*points
[1];
985 const BIGNUM
*scalars
[1];
988 scalars
[0] = p_scalar
;
990 return EC_POINTs_mul(group
, r
, g_scalar
, (point
!= NULL
&& p_scalar
!= NULL
), points
, scalars
, ctx
);
993 int EC_GROUP_precompute_mult(EC_GROUP
*group
, BN_CTX
*ctx
)
995 if (group
->meth
->mul
== 0)
997 return ec_wNAF_precompute_mult(group
, ctx
);
999 if (group
->meth
->precompute_mult
!= 0)
1000 return group
->meth
->precompute_mult(group
, ctx
);
1002 return 1; /* nothing to do, so report success */
1005 int EC_GROUP_have_precompute_mult(const EC_GROUP
*group
)
1007 if (group
->meth
->mul
== 0)
1009 return ec_wNAF_have_precompute_mult(group
);
1011 if (group
->meth
->have_precompute_mult
!= 0)
1012 return group
->meth
->have_precompute_mult(group
);
1014 return 0; /* cannot tell whether precomputation has been performed */