]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/ec/ec_lib.c
typo in WIN16 section
[thirdparty/openssl.git] / crypto / ec / ec_lib.c
CommitLineData
65e81670 1/* crypto/ec/ec_lib.c */
35b73a1f
BM
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
65e81670 5/* ====================================================================
4d94ae00 6 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
65e81670
BM
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
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
18 * distribution.
19 *
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/)"
24 *
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.
29 *
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.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 *
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 * ====================================================================
52 *
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).
56 *
57 */
7793f30e
BM
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.
62 */
65e81670 63
c4b36ff4
BM
64#include <string.h>
65
0657bf9c 66#include <openssl/err.h>
bb62a8b0 67#include <openssl/opensslv.h>
0657bf9c 68
65e81670 69#include "ec_lcl.h"
0657bf9c 70
bb62a8b0
BM
71static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
72
0657bf9c
BM
73
74/* functions for EC_GROUP objects */
75
76EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
77 {
78 EC_GROUP *ret;
79
80 if (meth == NULL)
81 {
82 ECerr(EC_F_EC_GROUP_NEW, ERR_R_PASSED_NULL_PARAMETER);
83 return NULL;
84 }
85 if (meth->group_init == 0)
86 {
87 ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
88 return NULL;
89 }
90
91 ret = OPENSSL_malloc(sizeof *ret);
92 if (ret == NULL)
93 {
94 ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
95 return NULL;
96 }
97
98 ret->meth = meth;
df9cc153
BM
99
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;
945e15a2 104
b6db386f
BM
105 ret->generator = NULL;
106 BN_init(&ret->order);
107 BN_init(&ret->cofactor);
108
254ef80d
BM
109 ret->curve_name = 0;
110 ret->asn1_flag = 0;
5f3d6f70 111 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
458c2917
BM
112
113 ret->seed = NULL;
114 ret->seed_len = 0;
945e15a2 115
0657bf9c
BM
116 if (!meth->group_init(ret))
117 {
118 OPENSSL_free(ret);
119 return NULL;
120 }
121
122 return ret;
123 }
124
125
0657bf9c
BM
126void EC_GROUP_free(EC_GROUP *group)
127 {
7711de24
BM
128 if (!group) return;
129
0657bf9c
BM
130 if (group->meth->group_finish != 0)
131 group->meth->group_finish(group);
df9cc153
BM
132
133 EC_GROUP_free_extra_data(group);
134
b6db386f
BM
135 if (group->generator != NULL)
136 EC_POINT_free(group->generator);
137 BN_free(&group->order);
138 BN_free(&group->cofactor);
139
458c2917
BM
140 if (group->seed)
141 OPENSSL_free(group->seed);
142
0657bf9c
BM
143 OPENSSL_free(group);
144 }
145
146
147void EC_GROUP_clear_free(EC_GROUP *group)
148 {
7711de24
BM
149 if (!group) return;
150
0657bf9c
BM
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);
df9cc153
BM
155
156 EC_GROUP_clear_free_extra_data(group);
157
b6db386f
BM
158 if (group->generator != NULL)
159 EC_POINT_clear_free(group->generator);
160 BN_clear_free(&group->order);
161 BN_clear_free(&group->cofactor);
162
458c2917
BM
163 if (group->seed)
164 {
4579924b 165 OPENSSL_cleanse(group->seed, group->seed_len);
458c2917
BM
166 OPENSSL_free(group->seed);
167 }
168
4579924b 169 OPENSSL_cleanse(group, sizeof *group);
0657bf9c
BM
170 OPENSSL_free(group);
171 }
172
173
174int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
175 {
176 if (dest->meth->group_copy == 0)
177 {
178 ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
179 return 0;
180 }
181 if (dest->meth != src->meth)
182 {
183 ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
184 return 0;
185 }
1d5bd6cf
BM
186 if (dest == src)
187 return 1;
0657bf9c 188
df9cc153
BM
189 EC_GROUP_clear_free_extra_data(dest);
190 if (src->extra_data_dup_func)
191 {
192 if (src->extra_data != NULL)
193 {
194 dest->extra_data = src->extra_data_dup_func(src->extra_data);
195 if (dest->extra_data == NULL)
196 return 0;
197 }
198
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;
202 }
203
b6db386f
BM
204 if (src->generator != NULL)
205 {
206 if (dest->generator == NULL)
207 {
208 dest->generator = EC_POINT_new(dest);
209 if (dest->generator == NULL) return 0;
210 }
211 if (!EC_POINT_copy(dest->generator, src->generator)) return 0;
212 }
213 else
214 {
215 /* src->generator == NULL */
216 if (dest->generator != NULL)
217 {
218 EC_POINT_clear_free(dest->generator);
219 dest->generator = NULL;
220 }
221 }
222
223 if (!BN_copy(&dest->order, &src->order)) return 0;
224 if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0;
225
254ef80d
BM
226 dest->curve_name = src->curve_name;
227 dest->asn1_flag = src->asn1_flag;
228 dest->asn1_form = src->asn1_form;
458c2917
BM
229
230 if (src->seed)
231 {
232 if (dest->seed)
233 OPENSSL_free(dest->seed);
234 dest->seed = OPENSSL_malloc(src->seed_len);
235 if (dest->seed == NULL)
236 return 0;
237 if (!memcpy(dest->seed, src->seed, src->seed_len))
238 return 0;
239 dest->seed_len = src->seed_len;
240 }
241 else
242 {
243 if (dest->seed)
244 OPENSSL_free(dest->seed);
245 dest->seed = NULL;
246 dest->seed_len = 0;
247 }
248
b6db386f 249
0657bf9c
BM
250 return dest->meth->group_copy(dest, src);
251 }
252
253
7793f30e
BM
254EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
255 {
256 EC_GROUP *t = NULL;
257 int ok = 0;
258
259 if (a == NULL) return NULL;
260
261 if ((t = EC_GROUP_new(a->meth)) == NULL) return(NULL);
262 if (!EC_GROUP_copy(t, a)) goto err;
263
264 ok = 1;
265
266 err:
267 if (!ok)
268 {
269 if (t) EC_GROUP_free(t);
270 return NULL;
271 }
272 else return t;
273 }
274
275
48fe4d62
BM
276const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
277 {
278 return group->meth;
279 }
280
281
458c2917
BM
282int EC_METHOD_get_field_type(const EC_METHOD *meth)
283 {
284 return meth->field_type;
285 }
286
287
b6db386f 288int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
bb62a8b0 289 {
b6db386f 290 if (generator == NULL)
bb62a8b0 291 {
b6db386f
BM
292 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
293 return 0 ;
bb62a8b0 294 }
b6db386f
BM
295
296 if (group->generator == NULL)
297 {
298 group->generator = EC_POINT_new(group);
299 if (group->generator == NULL) return 0;
300 }
301 if (!EC_POINT_copy(group->generator, generator)) return 0;
302
303 if (order != NULL)
304 { if (!BN_copy(&group->order, order)) return 0; }
305 else
306 { if (!BN_zero(&group->order)) return 0; }
307
308 if (cofactor != NULL)
309 { if (!BN_copy(&group->cofactor, cofactor)) return 0; }
310 else
311 { if (!BN_zero(&group->cofactor)) return 0; }
312
313 return 1;
bb62a8b0
BM
314 }
315
316
b6db386f 317EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
bb62a8b0 318 {
b6db386f 319 return group->generator;
bb62a8b0
BM
320 }
321
322
b6db386f 323int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
0657bf9c 324 {
b6db386f 325 if (!BN_copy(order, &group->order))
0657bf9c 326 return 0;
b6db386f
BM
327
328 return !BN_is_zero(order);
0657bf9c
BM
329 }
330
331
b6db386f 332int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
48fe4d62 333 {
b6db386f 334 if (!BN_copy(cofactor, &group->cofactor))
48fe4d62 335 return 0;
b6db386f
BM
336
337 return !BN_is_zero(&group->cofactor);
48fe4d62
BM
338 }
339
340
b6db386f
BM
341void EC_GROUP_set_nid(EC_GROUP *group, int nid)
342 {
254ef80d 343 group->curve_name = nid;
b6db386f
BM
344 }
345
346
347int EC_GROUP_get_nid(const EC_GROUP *group)
348 {
254ef80d 349 return group->curve_name;
b6db386f
BM
350 }
351
352
458c2917
BM
353void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
354 {
355 group->asn1_flag = flag;
356 }
357
358
359int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
360 {
361 return group->asn1_flag;
362 }
363
364
254ef80d
BM
365void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
366 point_conversion_form_t form)
367 {
368 group->asn1_form = form;
369 }
370
371
372point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
373 {
374 return group->asn1_form;
375 }
376
377
5f3d6f70
BM
378size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
379 {
380 if (group->seed)
381 {
382 OPENSSL_free(group->seed);
383 group->seed = NULL;
384 group->seed_len = 0;
385 }
386
387 if (!len || !p)
388 return 1;
389
390 if ((group->seed = OPENSSL_malloc(len)) == NULL)
391 return 0;
392 memcpy(group->seed, p, len);
393 group->seed_len = len;
394
395 return len;
396 }
397
398
399unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
400 {
401 return group->seed;
402 }
403
404
405size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
406 {
407 return group->seed_len;
408 }
409
410
b6db386f 411int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
48fe4d62 412 {
7793f30e 413 if (group->meth->group_set_curve == 0)
48fe4d62 414 {
b6db386f 415 ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
48fe4d62
BM
416 return 0;
417 }
7793f30e 418 return group->meth->group_set_curve(group, p, a, b, ctx);
48fe4d62
BM
419 }
420
421
b6db386f 422int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
48fe4d62 423 {
7793f30e 424 if (group->meth->group_get_curve == 0)
48fe4d62 425 {
b6db386f 426 ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
48fe4d62
BM
427 return 0;
428 }
7793f30e
BM
429 return group->meth->group_get_curve(group, p, a, b, ctx);
430 }
431
432
433int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
434 {
435 if (group->meth->group_set_curve == 0)
436 {
437 ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
438 return 0;
439 }
440 return group->meth->group_set_curve(group, p, a, b, ctx);
441 }
442
443
444int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
445 {
446 if (group->meth->group_get_curve == 0)
447 {
448 ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
449 return 0;
450 }
451 return group->meth->group_get_curve(group, p, a, b, ctx);
452 }
453
454
455int EC_GROUP_get_degree(const EC_GROUP *group)
456 {
457 if (group->meth->group_get_degree == 0)
458 {
459 ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
460 return 0;
461 }
462 return group->meth->group_get_degree(group);
48fe4d62
BM
463 }
464
465
17d6bb81 466int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
af28dd6c 467 {
17d6bb81 468 if (group->meth->group_check_discriminant == 0)
af28dd6c 469 {
17d6bb81 470 ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
af28dd6c
BM
471 return 0;
472 }
17d6bb81 473 return group->meth->group_check_discriminant(group, ctx);
af28dd6c
BM
474 }
475
476
df9cc153
BM
477/* this has 'package' visibility */
478int 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 *))
480 {
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))
485 {
486 ECerr(EC_F_EC_GROUP_SET_EXTRA_DATA, EC_R_SLOT_FULL);
487 return 0;
488 }
489
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;
494 return 1;
495 }
496
497
498/* this has 'package' visibility */
48fe4d62 499void *EC_GROUP_get_extra_data(const EC_GROUP *group, void *(*extra_data_dup_func)(void *),
df9cc153
BM
500 void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
501 {
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))
505 {
506 ECerr(EC_F_EC_GROUP_GET_EXTRA_DATA, EC_R_NO_SUCH_EXTRA_DATA);
507 return NULL;
508 }
509
510 return group->extra_data;
511 }
512
513
514/* this has 'package' visibility */
515void EC_GROUP_free_extra_data(EC_GROUP *group)
516 {
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;
523 }
524
525
526/* this has 'package' visibility */
527void EC_GROUP_clear_free_extra_data(EC_GROUP *group)
528 {
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;
537 }
538
0657bf9c
BM
539
540/* functions for EC_POINT objects */
541
542EC_POINT *EC_POINT_new(const EC_GROUP *group)
543 {
544 EC_POINT *ret;
545
546 if (group == NULL)
547 {
548 ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
549 return NULL;
550 }
551 if (group->meth->point_init == 0)
552 {
553 ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
554 return NULL;
555 }
556
557 ret = OPENSSL_malloc(sizeof *ret);
558 if (ret == NULL)
559 {
560 ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
561 return NULL;
562 }
563
564 ret->meth = group->meth;
565
566 if (!ret->meth->point_init(ret))
567 {
568 OPENSSL_free(ret);
569 return NULL;
570 }
571
572 return ret;
573 }
574
575
576void EC_POINT_free(EC_POINT *point)
577 {
7711de24
BM
578 if (!point) return;
579
0657bf9c
BM
580 if (point->meth->point_finish != 0)
581 point->meth->point_finish(point);
582 OPENSSL_free(point);
583 }
584
585
586void EC_POINT_clear_free(EC_POINT *point)
587 {
7711de24
BM
588 if (!point) return;
589
0657bf9c
BM
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);
4579924b 594 OPENSSL_cleanse(point, sizeof *point);
0657bf9c
BM
595 OPENSSL_free(point);
596 }
597
598
599int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
600 {
601 if (dest->meth->point_copy == 0)
602 {
603 ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
604 return 0;
605 }
606 if (dest->meth != src->meth)
607 {
608 ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
609 return 0;
610 }
91f29a38
BM
611 if (dest == src)
612 return 1;
0657bf9c
BM
613 return dest->meth->point_copy(dest, src);
614 }
615
616
7793f30e
BM
617EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
618 {
619 EC_POINT *t;
620 int r;
621
622 if (a == NULL) return NULL;
623
624 t = EC_POINT_new(group);
625 if (t == NULL) return(NULL);
626 r = EC_POINT_copy(t, a);
627 if (!r)
628 {
629 EC_POINT_free(t);
630 return NULL;
631 }
632 else return t;
633 }
634
635
48fe4d62
BM
636const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
637 {
638 return point->meth;
639 }
640
641
226cc7de
BM
642int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
643 {
644 if (group->meth->point_set_to_infinity == 0)
645 {
646 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
647 return 0;
648 }
649 if (group->meth != point->meth)
650 {
651 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
652 return 0;
653 }
654 return group->meth->point_set_to_infinity(group, point);
655 }
656
657
1d5bd6cf
BM
658int 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)
660 {
35b73a1f 661 if (group->meth->point_set_Jprojective_coordinates_GFp == 0)
1d5bd6cf
BM
662 {
663 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
664 return 0;
665 }
666 if (group->meth != point->meth)
667 {
668 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
669 return 0;
670 }
35b73a1f 671 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
1d5bd6cf
BM
672 }
673
674
675int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
676 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
677 {
35b73a1f 678 if (group->meth->point_get_Jprojective_coordinates_GFp == 0)
1d5bd6cf
BM
679 {
680 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
681 return 0;
682 }
683 if (group->meth != point->meth)
684 {
685 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
686 return 0;
687 }
35b73a1f 688 return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
1d5bd6cf
BM
689 }
690
691
226cc7de
BM
692int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
693 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
694 {
7793f30e 695 if (group->meth->point_set_affine_coordinates == 0)
226cc7de
BM
696 {
697 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
698 return 0;
699 }
700 if (group->meth != point->meth)
701 {
702 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
703 return 0;
704 }
7793f30e 705 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
226cc7de
BM
706 }
707
708
35b73a1f
BM
709int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
710 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
7793f30e 711 {
35b73a1f 712 if (group->meth->point_set_affine_coordinates == 0)
7793f30e 713 {
35b73a1f 714 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
7793f30e
BM
715 return 0;
716 }
717 if (group->meth != point->meth)
718 {
35b73a1f 719 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
7793f30e
BM
720 return 0;
721 }
35b73a1f 722 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
7793f30e
BM
723 }
724
725
35b73a1f
BM
726int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
727 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
7793f30e 728 {
35b73a1f 729 if (group->meth->point_get_affine_coordinates == 0)
7793f30e 730 {
35b73a1f 731 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
7793f30e
BM
732 return 0;
733 }
734 if (group->meth != point->meth)
735 {
35b73a1f 736 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
7793f30e
BM
737 return 0;
738 }
35b73a1f 739 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
7793f30e
BM
740 }
741
742
35b73a1f
BM
743int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
744 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
7793f30e 745 {
35b73a1f 746 if (group->meth->point_get_affine_coordinates == 0)
7793f30e 747 {
35b73a1f 748 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
7793f30e
BM
749 return 0;
750 }
751 if (group->meth != point->meth)
752 {
35b73a1f 753 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
7793f30e
BM
754 return 0;
755 }
35b73a1f 756 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
7793f30e
BM
757 }
758
759
35b73a1f
BM
760int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
761 const BIGNUM *x, int y_bit, BN_CTX *ctx)
7793f30e 762 {
35b73a1f 763 if (group->meth->point_set_compressed_coordinates == 0)
7793f30e 764 {
35b73a1f 765 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
7793f30e
BM
766 return 0;
767 }
768 if (group->meth != point->meth)
769 {
35b73a1f 770 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
7793f30e
BM
771 return 0;
772 }
35b73a1f 773 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
7793f30e
BM
774 }
775
776
777int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
778 const BIGNUM *x, int y_bit, BN_CTX *ctx)
779 {
780 if (group->meth->point_set_compressed_coordinates == 0)
781 {
782 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
783 return 0;
784 }
785 if (group->meth != point->meth)
786 {
787 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
788 return 0;
789 }
790 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
1d5bd6cf 791 }
0657bf9c
BM
792
793
794size_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)
796 {
797 if (group->meth->point2oct == 0)
798 {
799 ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
800 return 0;
801 }
802 if (group->meth != point->meth)
803 {
804 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
805 return 0;
806 }
807 return group->meth->point2oct(group, point, form, buf, len, ctx);
808 }
809
810
811int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
812 const unsigned char *buf, size_t len, BN_CTX *ctx)
813 {
814 if (group->meth->oct2point == 0)
815 {
816 ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
817 return 0;
818 }
819 if (group->meth != point->meth)
820 {
821 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
822 return 0;
823 }
824 return group->meth->oct2point(group, point, buf, len, ctx);
825 }
826
827
828int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
829 {
830 if (group->meth->add == 0)
831 {
832 ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
833 return 0;
834 }
835 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth))
836 {
837 ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
838 return 0;
839 }
840 return group->meth->add(group, r, a, b, ctx);
841 }
842
843
844int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
845 {
846 if (group->meth->dbl == 0)
847 {
848 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
849 return 0;
850 }
851 if ((group->meth != r->meth) || (r->meth != a->meth))
852 {
853 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
854 return 0;
855 }
856 return group->meth->dbl(group, r, a, ctx);
857 }
858
859
1d5bd6cf
BM
860int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
861 {
862 if (group->meth->dbl == 0)
863 {
864 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
865 return 0;
866 }
867 if (group->meth != a->meth)
868 {
869 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
870 return 0;
871 }
872 return group->meth->invert(group, a, ctx);
873 }
874
875
0657bf9c
BM
876int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
877 {
878 if (group->meth->is_at_infinity == 0)
879 {
880 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
881 return 0;
882 }
883 if (group->meth != point->meth)
884 {
885 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
886 return 0;
887 }
888 return group->meth->is_at_infinity(group, point);
889 }
890
891
892int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
893 {
894 if (group->meth->is_on_curve == 0)
895 {
896 ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
897 return 0;
898 }
899 if (group->meth != point->meth)
900 {
901 ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
902 return 0;
903 }
904 return group->meth->is_on_curve(group, point, ctx);
905 }
906
907
1d5bd6cf
BM
908int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
909 {
910 if (group->meth->point_cmp == 0)
911 {
912 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
913 return 0;
914 }
915 if ((group->meth != a->meth) || (a->meth != b->meth))
916 {
917 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
918 return 0;
919 }
920 return group->meth->point_cmp(group, a, b, ctx);
921 }
922
923
e869d4bd 924int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
0657bf9c
BM
925 {
926 if (group->meth->make_affine == 0)
927 {
928 ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
929 return 0;
930 }
931 if (group->meth != point->meth)
932 {
933 ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
934 return 0;
935 }
936 return group->meth->make_affine(group, point, ctx);
937 }
48fe4d62
BM
938
939
940int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
941 {
942 size_t i;
943
944 if (group->meth->points_make_affine == 0)
945 {
946 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
947 return 0;
948 }
949 for (i = 0; i < num; i++)
950 {
951 if (group->meth != points[i]->meth)
952 {
953 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
954 return 0;
955 }
956 }
957 return group->meth->points_make_affine(group, num, points, ctx);
958 }