xref: /openbsd-src/lib/libcrypto/ec/ec_lib.c (revision 53555c846a0a6f917dbd0a191f826da995ab1c42)
1 /* $OpenBSD: ec_lib.c,v 1.111 2025/01/11 15:26:07 tb Exp $ */
2 /*
3  * Originally written by Bodo Moeller for the OpenSSL project.
4  */
5 /* ====================================================================
6  * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
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  */
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  */
63 
64 #include <stdlib.h>
65 #include <string.h>
66 
67 #include <openssl/opensslconf.h>
68 
69 #include <openssl/bn.h>
70 #include <openssl/ec.h>
71 #include <openssl/err.h>
72 #include <openssl/objects.h>
73 #include <openssl/opensslv.h>
74 
75 #include "bn_local.h"
76 #include "ec_local.h"
77 
78 EC_GROUP *
79 EC_GROUP_new(const EC_METHOD *meth)
80 {
81 	EC_GROUP *group = NULL;
82 
83 	if (meth == NULL) {
84 		ECerror(EC_R_SLOT_FULL);
85 		goto err;
86 	}
87 	if ((group = calloc(1, sizeof(*group))) == NULL) {
88 		ECerror(ERR_R_MALLOC_FAILURE);
89 		goto err;
90 	}
91 
92 	group->meth = meth;
93 
94 	group->asn1_flag = OPENSSL_EC_NAMED_CURVE;
95 	group->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
96 
97 	if ((group->p = BN_new()) == NULL)
98 		goto err;
99 	if ((group->a = BN_new()) == NULL)
100 		goto err;
101 	if ((group->b = BN_new()) == NULL)
102 		goto err;
103 
104 	if ((group->order = BN_new()) == NULL)
105 		goto err;
106 	if ((group->cofactor = BN_new()) == NULL)
107 		goto err;
108 
109 	/*
110 	 * generator, seed and mont_ctx are optional.
111 	 */
112 
113 	return group;
114 
115  err:
116 	EC_GROUP_free(group);
117 
118 	return NULL;
119 }
120 LCRYPTO_ALIAS(EC_GROUP_new);
121 
122 void
123 EC_GROUP_free(EC_GROUP *group)
124 {
125 	if (group == NULL)
126 		return;
127 
128 	BN_free(group->p);
129 	BN_free(group->a);
130 	BN_free(group->b);
131 
132 	BN_MONT_CTX_free(group->mont_ctx);
133 
134 	EC_POINT_free(group->generator);
135 	BN_free(group->order);
136 	BN_free(group->cofactor);
137 
138 	freezero(group->seed, group->seed_len);
139 	freezero(group, sizeof *group);
140 }
141 LCRYPTO_ALIAS(EC_GROUP_free);
142 
143 void
144 EC_GROUP_clear_free(EC_GROUP *group)
145 {
146 	EC_GROUP_free(group);
147 }
148 LCRYPTO_ALIAS(EC_GROUP_clear_free);
149 
150 int
151 EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src)
152 {
153 	if (dst->meth != src->meth) {
154 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
155 		return 0;
156 	}
157 	if (dst == src)
158 		return 1;
159 
160 	if (!bn_copy(dst->p, src->p))
161 		return 0;
162 	if (!bn_copy(dst->a, src->a))
163 		return 0;
164 	if (!bn_copy(dst->b, src->b))
165 		return 0;
166 
167 	dst->a_is_minus3 = src->a_is_minus3;
168 
169 	BN_MONT_CTX_free(dst->mont_ctx);
170 	dst->mont_ctx = NULL;
171 	if (src->mont_ctx != NULL) {
172 		if ((dst->mont_ctx = BN_MONT_CTX_new()) == NULL)
173 			return 0;
174 		if (!BN_MONT_CTX_copy(dst->mont_ctx, src->mont_ctx))
175 			return 0;
176 	}
177 
178 	EC_POINT_free(dst->generator);
179 	dst->generator = NULL;
180 	if (src->generator != NULL) {
181 		if (!EC_GROUP_set_generator(dst, src->generator, src->order,
182 		    src->cofactor))
183 			return 0;
184 	} else {
185 		/* XXX - should do the sanity checks as in set_generator() */
186 		if (!bn_copy(dst->order, src->order))
187 			return 0;
188 		if (!bn_copy(dst->cofactor, src->cofactor))
189 			return 0;
190 	}
191 
192 	dst->nid = src->nid;
193 	dst->asn1_flag = src->asn1_flag;
194 	dst->asn1_form = src->asn1_form;
195 
196 	if (!EC_GROUP_set_seed(dst, src->seed, src->seed_len))
197 		return 0;
198 
199 	return 1;
200 }
201 LCRYPTO_ALIAS(EC_GROUP_copy);
202 
203 EC_GROUP *
204 EC_GROUP_dup(const EC_GROUP *in_group)
205 {
206 	EC_GROUP *group = NULL;
207 
208 	if (in_group == NULL)
209 		goto err;
210 
211 	if ((group = EC_GROUP_new(in_group->meth)) == NULL)
212 		goto err;
213 	if (!EC_GROUP_copy(group, in_group))
214 		goto err;
215 
216 	return group;
217 
218  err:
219 	EC_GROUP_free(group);
220 
221 	return NULL;
222 }
223 LCRYPTO_ALIAS(EC_GROUP_dup);
224 
225 const EC_METHOD *
226 EC_GROUP_method_of(const EC_GROUP *group)
227 {
228 	return group->meth;
229 }
230 LCRYPTO_ALIAS(EC_GROUP_method_of);
231 
232 int
233 EC_METHOD_get_field_type(const EC_METHOD *meth)
234 {
235 	return meth->field_type;
236 }
237 LCRYPTO_ALIAS(EC_METHOD_get_field_type);
238 
239 int
240 ec_group_get_field_type(const EC_GROUP *group)
241 {
242 	if (group == NULL || group->meth == NULL)
243 		return NID_undef;
244 
245 	return group->meth->field_type;
246 }
247 
248 /*
249  * If there is a user-provided cofactor, sanity check and use it. Otherwise
250  * try computing the cofactor from generator order n and field cardinality p.
251  * This works for all curves of cryptographic interest.
252  *
253  * Hasse's theorem: | h * n - (p + 1) | <= 2 * sqrt(p)
254  *
255  * So: h_min = (p + 1 - 2*sqrt(p)) / n and h_max = (p + 1 + 2*sqrt(p)) / n and
256  * therefore h_max - h_min = 4*sqrt(p) / n. So if n > 4*sqrt(p) holds, there is
257  * only one possible value for h:
258  *
259  *	h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (p + 1)/n \rceil
260  *
261  * Otherwise, zero cofactor and return success.
262  */
263 static int
264 ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor)
265 {
266 	BN_CTX *ctx = NULL;
267 	BIGNUM *cofactor;
268 	int ret = 0;
269 
270 	BN_zero(group->cofactor);
271 
272 	if ((ctx = BN_CTX_new()) == NULL)
273 		goto err;
274 
275 	BN_CTX_start(ctx);
276 	if ((cofactor = BN_CTX_get(ctx)) == NULL)
277 		goto err;
278 
279 	/*
280 	 * Unfortunately, the cofactor is an optional field in many standards.
281 	 * Internally, the library uses a 0 cofactor as a marker for "unknown
282 	 * cofactor".  So accept in_cofactor == NULL or in_cofactor >= 0.
283 	 */
284 	if (in_cofactor != NULL && !BN_is_zero(in_cofactor)) {
285 		if (BN_is_negative(in_cofactor)) {
286 			ECerror(EC_R_UNKNOWN_COFACTOR);
287 			goto err;
288 		}
289 		if (!bn_copy(cofactor, in_cofactor))
290 			goto err;
291 		goto done;
292 	}
293 
294 	/*
295 	 * If the cofactor is too large, we cannot guess it and default to zero.
296 	 * The RHS of below is a strict overestimate of log(4 * sqrt(p)).
297 	 */
298 	if (BN_num_bits(group->order) <= (BN_num_bits(group->p) + 1) / 2 + 3)
299 		goto done;
300 
301 	/*
302 	 * Compute
303 	 *     h = \lfloor (p + 1)/n \rceil = \lfloor (p + 1 + n/2) / n \rfloor.
304 	 */
305 
306 	/* h = n/2 */
307 	if (!BN_rshift1(cofactor, group->order))
308 		goto err;
309 	/* h = 1 + n/2 */
310 	if (!BN_add_word(cofactor, 1))
311 		goto err;
312 	/* h = p + 1 + n/2 */
313 	if (!BN_add(cofactor, cofactor, group->p))
314 		goto err;
315 	/* h = (p + 1 + n/2) / n */
316 	if (!BN_div_ct(cofactor, NULL, cofactor, group->order, ctx))
317 		goto err;
318 
319  done:
320 	/* Use Hasse's theorem to bound the cofactor. */
321 	if (BN_num_bits(cofactor) > BN_num_bits(group->p) + 1) {
322 		ECerror(EC_R_INVALID_GROUP_ORDER);
323 		goto err;
324 	}
325 
326 	if (!bn_copy(group->cofactor, cofactor))
327 		goto err;
328 
329 	ret = 1;
330 
331  err:
332 	BN_CTX_end(ctx);
333 	BN_CTX_free(ctx);
334 
335 	return ret;
336 }
337 
338 int
339 EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
340     const BIGNUM *order, const BIGNUM *cofactor)
341 {
342 	if (generator == NULL) {
343 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
344 		return 0;
345 	}
346 
347 	/* Require p >= 1. */
348 	if (BN_is_zero(group->p) || BN_is_negative(group->p)) {
349 		ECerror(EC_R_INVALID_FIELD);
350 		return 0;
351 	}
352 
353 	/*
354 	 * Require order > 1 and enforce an upper bound of at most one bit more
355 	 * than the field cardinality due to Hasse's theorem.
356 	 */
357 	if (order == NULL || BN_cmp(order, BN_value_one()) <= 0 ||
358 	    BN_num_bits(order) > BN_num_bits(group->p) + 1) {
359 		ECerror(EC_R_INVALID_GROUP_ORDER);
360 		return 0;
361 	}
362 
363 	if (group->generator == NULL)
364 		group->generator = EC_POINT_new(group);
365 	if (group->generator == NULL)
366 		return 0;
367 
368 	if (!EC_POINT_copy(group->generator, generator))
369 		return 0;
370 
371 	if (!bn_copy(group->order, order))
372 		return 0;
373 
374 	if (!ec_set_cofactor(group, cofactor))
375 		return 0;
376 
377 	return 1;
378 }
379 LCRYPTO_ALIAS(EC_GROUP_set_generator);
380 
381 const EC_POINT *
382 EC_GROUP_get0_generator(const EC_GROUP *group)
383 {
384 	return group->generator;
385 }
386 LCRYPTO_ALIAS(EC_GROUP_get0_generator);
387 
388 int
389 EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
390 {
391 	if (!bn_copy(order, group->order))
392 		return 0;
393 
394 	return !BN_is_zero(order);
395 }
396 LCRYPTO_ALIAS(EC_GROUP_get_order);
397 
398 const BIGNUM *
399 EC_GROUP_get0_order(const EC_GROUP *group)
400 {
401 	return group->order;
402 }
403 
404 int
405 EC_GROUP_order_bits(const EC_GROUP *group)
406 {
407 	return BN_num_bits(group->order);
408 }
409 LCRYPTO_ALIAS(EC_GROUP_order_bits);
410 
411 int
412 EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
413 {
414 	if (!bn_copy(cofactor, group->cofactor))
415 		return 0;
416 
417 	return !BN_is_zero(group->cofactor);
418 }
419 LCRYPTO_ALIAS(EC_GROUP_get_cofactor);
420 
421 const BIGNUM *
422 EC_GROUP_get0_cofactor(const EC_GROUP *group)
423 {
424 	return group->cofactor;
425 }
426 
427 void
428 EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
429 {
430 	group->nid = nid;
431 }
432 LCRYPTO_ALIAS(EC_GROUP_set_curve_name);
433 
434 int
435 EC_GROUP_get_curve_name(const EC_GROUP *group)
436 {
437 	return group->nid;
438 }
439 LCRYPTO_ALIAS(EC_GROUP_get_curve_name);
440 
441 void
442 EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
443 {
444 	group->asn1_flag = flag;
445 }
446 LCRYPTO_ALIAS(EC_GROUP_set_asn1_flag);
447 
448 int
449 EC_GROUP_get_asn1_flag(const EC_GROUP *group)
450 {
451 	return group->asn1_flag;
452 }
453 LCRYPTO_ALIAS(EC_GROUP_get_asn1_flag);
454 
455 void
456 EC_GROUP_set_point_conversion_form(EC_GROUP *group,
457     point_conversion_form_t form)
458 {
459 	group->asn1_form = form;
460 }
461 LCRYPTO_ALIAS(EC_GROUP_set_point_conversion_form);
462 
463 point_conversion_form_t
464 EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
465 {
466 	return group->asn1_form;
467 }
468 LCRYPTO_ALIAS(EC_GROUP_get_point_conversion_form);
469 
470 size_t
471 EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *seed, size_t len)
472 {
473 	free(group->seed);
474 	group->seed = NULL;
475 	group->seed_len = 0;
476 
477 	if (seed == NULL || len == 0)
478 		return 1;
479 
480 	if ((group->seed = malloc(len)) == NULL)
481 		return 0;
482 	memcpy(group->seed, seed, len);
483 	group->seed_len = len;
484 
485 	return len;
486 }
487 LCRYPTO_ALIAS(EC_GROUP_set_seed);
488 
489 unsigned char *
490 EC_GROUP_get0_seed(const EC_GROUP *group)
491 {
492 	return group->seed;
493 }
494 LCRYPTO_ALIAS(EC_GROUP_get0_seed);
495 
496 size_t
497 EC_GROUP_get_seed_len(const EC_GROUP *group)
498 {
499 	return group->seed_len;
500 }
501 LCRYPTO_ALIAS(EC_GROUP_get_seed_len);
502 
503 int
504 EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
505     const BIGNUM *b, BN_CTX *ctx_in)
506 {
507 	BN_CTX *ctx;
508 	int ret = 0;
509 
510 	if ((ctx = ctx_in) == NULL)
511 		ctx = BN_CTX_new();
512 	if (ctx == NULL)
513 		goto err;
514 
515 	if (group->meth->group_set_curve == NULL) {
516 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
517 		goto err;
518 	}
519 	ret = group->meth->group_set_curve(group, p, a, b, ctx);
520 
521  err:
522 	if (ctx != ctx_in)
523 		BN_CTX_free(ctx);
524 
525 	return ret;
526 }
527 LCRYPTO_ALIAS(EC_GROUP_set_curve);
528 
529 int
530 EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
531     BN_CTX *ctx_in)
532 {
533 	BN_CTX *ctx;
534 	int ret = 0;
535 
536 	if ((ctx = ctx_in) == NULL)
537 		ctx = BN_CTX_new();
538 	if (ctx == NULL)
539 		goto err;
540 
541 	if (group->meth->group_get_curve == NULL) {
542 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
543 		goto err;
544 	}
545 	ret = group->meth->group_get_curve(group, p, a, b, ctx);
546 
547  err:
548 	if (ctx != ctx_in)
549 		BN_CTX_free(ctx);
550 
551 	return ret;
552 }
553 LCRYPTO_ALIAS(EC_GROUP_get_curve);
554 
555 int
556 EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
557     const BIGNUM *b, BN_CTX *ctx)
558 {
559 	return EC_GROUP_set_curve(group, p, a, b, ctx);
560 }
561 LCRYPTO_ALIAS(EC_GROUP_set_curve_GFp);
562 
563 int
564 EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
565     BN_CTX *ctx)
566 {
567 	return EC_GROUP_get_curve(group, p, a, b, ctx);
568 }
569 LCRYPTO_ALIAS(EC_GROUP_get_curve_GFp);
570 
571 EC_GROUP *
572 EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b,
573     BN_CTX *ctx)
574 {
575 	EC_GROUP *group;
576 
577 	if ((group = EC_GROUP_new(EC_GFp_mont_method())) == NULL)
578 		goto err;
579 
580 	if (!EC_GROUP_set_curve(group, p, a, b, ctx))
581 		goto err;
582 
583 	return group;
584 
585  err:
586 	EC_GROUP_free(group);
587 
588 	return NULL;
589 }
590 LCRYPTO_ALIAS(EC_GROUP_new_curve_GFp);
591 
592 int
593 EC_GROUP_get_degree(const EC_GROUP *group)
594 {
595 	return BN_num_bits(group->p);
596 }
597 LCRYPTO_ALIAS(EC_GROUP_get_degree);
598 
599 int
600 EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx_in)
601 {
602 	BN_CTX *ctx;
603 	BIGNUM *p, *a, *b, *discriminant;
604 	int ret = 0;
605 
606 	if ((ctx = ctx_in) == NULL)
607 		ctx = BN_CTX_new();
608 	if (ctx == NULL)
609 		goto err;
610 
611 	BN_CTX_start(ctx);
612 
613 	if ((p = BN_CTX_get(ctx)) == NULL)
614 		goto err;
615 	if ((a = BN_CTX_get(ctx)) == NULL)
616 		goto err;
617 	if ((b = BN_CTX_get(ctx)) == NULL)
618 		goto err;
619 	if ((discriminant = BN_CTX_get(ctx)) == NULL)
620 		goto err;
621 
622 	if (!EC_GROUP_get_curve(group, p, a, b, ctx))
623 		goto err;
624 
625 	/*
626 	 * Check that the discriminant 4a^3 + 27b^2 is non-zero modulo p
627 	 * assuming that p > 3 is prime and that a and b are in [0, p).
628 	 */
629 
630 	if (BN_is_zero(a) && BN_is_zero(b))
631 		goto err;
632 	if (BN_is_zero(a) || BN_is_zero(b))
633 		goto done;
634 
635 	/* Compute the discriminant: first 4a^3, then 27b^2, then their sum. */
636 	if (!BN_mod_sqr(discriminant, a, p, ctx))
637 		goto err;
638 	if (!BN_mod_mul(discriminant, discriminant, a, p, ctx))
639 		goto err;
640 	if (!BN_lshift(discriminant, discriminant, 2))
641 		goto err;
642 
643 	if (!BN_mod_sqr(b, b, p, ctx))
644 		goto err;
645 	if (!BN_mul_word(b, 27))
646 		goto err;
647 
648 	if (!BN_mod_add(discriminant, discriminant, b, p, ctx))
649 		goto err;
650 
651 	if (BN_is_zero(discriminant))
652 		goto err;
653 
654  done:
655 	ret = 1;
656 
657  err:
658 	if (ctx != ctx_in)
659 		BN_CTX_free(ctx);
660 
661 	return ret;
662 }
663 LCRYPTO_ALIAS(EC_GROUP_check_discriminant);
664 
665 int
666 EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx_in)
667 {
668 	BN_CTX *ctx;
669 	EC_POINT *point = NULL;
670 	const BIGNUM *order;
671 	int ret = 0;
672 
673 	if ((ctx = ctx_in) == NULL)
674 		ctx = BN_CTX_new();
675 	if (ctx == NULL)
676 		goto err;
677 
678 	if (!EC_GROUP_check_discriminant(group, ctx)) {
679 		ECerror(EC_R_DISCRIMINANT_IS_ZERO);
680 		goto err;
681 	}
682 
683 	if (group->generator == NULL) {
684 		ECerror(EC_R_UNDEFINED_GENERATOR);
685 		goto err;
686 	}
687 	if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
688 		ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
689 		goto err;
690 	}
691 
692 	if ((point = EC_POINT_new(group)) == NULL)
693 		goto err;
694 	if ((order = EC_GROUP_get0_order(group)) == NULL)
695 		goto err;
696 	if (BN_is_zero(order)) {
697 		ECerror(EC_R_UNDEFINED_ORDER);
698 		goto err;
699 	}
700 	if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
701 		goto err;
702 	if (!EC_POINT_is_at_infinity(group, point)) {
703 		ECerror(EC_R_INVALID_GROUP_ORDER);
704 		goto err;
705 	}
706 
707 	ret = 1;
708 
709  err:
710 	if (ctx != ctx_in)
711 		BN_CTX_free(ctx);
712 
713 	EC_POINT_free(point);
714 
715 	return ret;
716 }
717 LCRYPTO_ALIAS(EC_GROUP_check);
718 
719 /*
720  * Returns -1 on error, 0 if the groups are equal, 1 if they are distinct.
721  */
722 int
723 EC_GROUP_cmp(const EC_GROUP *group1, const EC_GROUP *group2, BN_CTX *ctx_in)
724 {
725 	BN_CTX *ctx = NULL;
726 	BIGNUM *p1, *a1, *b1, *p2, *a2, *b2;
727 	const EC_POINT *generator1, *generator2;
728 	const BIGNUM *order1, *order2, *cofactor1, *cofactor2;
729 	int nid1, nid2;
730 	int cmp = 1;
731 	int ret = -1;
732 
733 	if ((ctx = ctx_in) == NULL)
734 		ctx = BN_CTX_new();
735 	if (ctx == NULL)
736 		goto err;
737 
738 	BN_CTX_start(ctx);
739 
740 	if (ec_group_get_field_type(group1) != ec_group_get_field_type(group2))
741 		goto distinct;
742 	if ((nid1 = EC_GROUP_get_curve_name(group1)) != NID_undef &&
743 	    (nid2 = EC_GROUP_get_curve_name(group2)) != NID_undef) {
744 		if (nid1 != nid2)
745 			goto distinct;
746 	}
747 
748 	if ((p1 = BN_CTX_get(ctx)) == NULL)
749 		goto err;
750 	if ((a1 = BN_CTX_get(ctx)) == NULL)
751 		goto err;
752 	if ((b1 = BN_CTX_get(ctx)) == NULL)
753 		goto err;
754 	if ((p2 = BN_CTX_get(ctx)) == NULL)
755 		goto err;
756 	if ((a2 = BN_CTX_get(ctx)) == NULL)
757 		goto err;
758 	if ((b2 = BN_CTX_get(ctx)) == NULL)
759 		goto err;
760 
761 	/*
762 	 * If we ever support curves in non-Weierstrass form, this check needs
763 	 * to be adjusted. The comparison of the generators will fail anyway.
764 	 */
765 	if (!EC_GROUP_get_curve(group1, p1, a1, b1, ctx))
766 		goto err;
767 	if (!EC_GROUP_get_curve(group2, p2, a2, b2, ctx))
768 		goto err;
769 
770 	if (BN_cmp(p1, p2) != 0 || BN_cmp(a1, a2) != 0 || BN_cmp(b1, b2) != 0)
771 		goto distinct;
772 
773 	if ((generator1 = EC_GROUP_get0_generator(group1)) == NULL)
774 		goto err;
775 	if ((generator2 = EC_GROUP_get0_generator(group2)) == NULL)
776 		goto err;
777 
778 	/*
779 	 * It does not matter whether group1 or group2 is used: both points must
780 	 * have a matching method for this to succeed.
781 	 */
782 	if ((cmp = EC_POINT_cmp(group1, generator1, generator2, ctx)) < 0)
783 		goto err;
784 	if (cmp == 1)
785 		goto distinct;
786 	cmp = 1;
787 
788 	if ((order1 = EC_GROUP_get0_order(group1)) == NULL)
789 		goto err;
790 	if ((order2 = EC_GROUP_get0_order(group2)) == NULL)
791 		goto err;
792 
793 	if ((cofactor1 = EC_GROUP_get0_cofactor(group1)) == NULL)
794 		goto err;
795 	if ((cofactor2 = EC_GROUP_get0_cofactor(group2)) == NULL)
796 		goto err;
797 
798 	if (BN_cmp(order1, order2) != 0 || BN_cmp(cofactor1, cofactor2) != 0)
799 		goto distinct;
800 
801 	/* All parameters match: the groups are equal. */
802 	cmp = 0;
803 
804  distinct:
805 	ret = cmp;
806 
807  err:
808 	BN_CTX_end(ctx);
809 
810 	if (ctx != ctx_in)
811 		BN_CTX_free(ctx);
812 
813 	return ret;
814 }
815 LCRYPTO_ALIAS(EC_GROUP_cmp);
816 
817 EC_POINT *
818 EC_POINT_new(const EC_GROUP *group)
819 {
820 	EC_POINT *point = NULL;
821 
822 	if (group == NULL) {
823 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
824 		goto err;
825 	}
826 
827 	if ((point = calloc(1, sizeof(*point))) == NULL) {
828 		ECerror(ERR_R_MALLOC_FAILURE);
829 		goto err;
830 	}
831 
832 	if ((point->X = BN_new()) == NULL)
833 		goto err;
834 	if ((point->Y = BN_new()) == NULL)
835 		goto err;
836 	if ((point->Z = BN_new()) == NULL)
837 		goto err;
838 
839 	point->meth = group->meth;
840 
841 	return point;
842 
843  err:
844 	EC_POINT_free(point);
845 
846 	return NULL;
847 }
848 LCRYPTO_ALIAS(EC_POINT_new);
849 
850 void
851 EC_POINT_free(EC_POINT *point)
852 {
853 	if (point == NULL)
854 		return;
855 
856 	BN_free(point->X);
857 	BN_free(point->Y);
858 	BN_free(point->Z);
859 
860 	freezero(point, sizeof *point);
861 }
862 LCRYPTO_ALIAS(EC_POINT_free);
863 
864 void
865 EC_POINT_clear_free(EC_POINT *point)
866 {
867 	EC_POINT_free(point);
868 }
869 LCRYPTO_ALIAS(EC_POINT_clear_free);
870 
871 int
872 EC_POINT_copy(EC_POINT *dst, const EC_POINT *src)
873 {
874 	if (dst->meth != src->meth) {
875 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
876 		return 0;
877 	}
878 	if (dst == src)
879 		return 1;
880 
881 	if (!bn_copy(dst->X, src->X))
882 		return 0;
883 	if (!bn_copy(dst->Y, src->Y))
884 		return 0;
885 	if (!bn_copy(dst->Z, src->Z))
886 		return 0;
887 	dst->Z_is_one = src->Z_is_one;
888 
889 	return 1;
890 }
891 LCRYPTO_ALIAS(EC_POINT_copy);
892 
893 EC_POINT *
894 EC_POINT_dup(const EC_POINT *in_point, const EC_GROUP *group)
895 {
896 	EC_POINT *point = NULL;
897 
898 	if (in_point == NULL)
899 		goto err;
900 
901 	if ((point = EC_POINT_new(group)) == NULL)
902 		goto err;
903 
904 	if (!EC_POINT_copy(point, in_point))
905 		goto err;
906 
907 	return point;
908 
909  err:
910 	EC_POINT_free(point);
911 
912 	return NULL;
913 }
914 LCRYPTO_ALIAS(EC_POINT_dup);
915 
916 const EC_METHOD *
917 EC_POINT_method_of(const EC_POINT *point)
918 {
919 	return point->meth;
920 }
921 LCRYPTO_ALIAS(EC_POINT_method_of);
922 
923 int
924 EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
925 {
926 	if (group->meth != point->meth) {
927 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
928 		return 0;
929 	}
930 
931 	BN_zero(point->Z);
932 	point->Z_is_one = 0;
933 
934 	return 1;
935 }
936 LCRYPTO_ALIAS(EC_POINT_set_to_infinity);
937 
938 int
939 EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
940     const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx_in)
941 {
942 	BN_CTX *ctx;
943 	int ret = 0;
944 
945 	if ((ctx = ctx_in) == NULL)
946 		ctx = BN_CTX_new();
947 	if (ctx == NULL)
948 		goto err;
949 
950 	if (group->meth->point_set_affine_coordinates == NULL) {
951 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
952 		goto err;
953 	}
954 	if (group->meth != point->meth) {
955 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
956 		goto err;
957 	}
958 	if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
959 		goto err;
960 
961 	if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
962 		ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
963 		goto err;
964 	}
965 
966 	ret = 1;
967 
968  err:
969 	if (ctx != ctx_in)
970 		BN_CTX_free(ctx);
971 
972 	return ret;
973 }
974 LCRYPTO_ALIAS(EC_POINT_set_affine_coordinates);
975 
976 int
977 EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
978     const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
979 {
980 	return EC_POINT_set_affine_coordinates(group, point, x, y, ctx);
981 }
982 LCRYPTO_ALIAS(EC_POINT_set_affine_coordinates_GFp);
983 
984 int
985 EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
986     BIGNUM *x, BIGNUM *y, BN_CTX *ctx_in)
987 {
988 	BN_CTX *ctx = NULL;
989 	int ret = 0;
990 
991 	if (EC_POINT_is_at_infinity(group, point) > 0) {
992 		ECerror(EC_R_POINT_AT_INFINITY);
993 		goto err;
994 	}
995 
996 	if ((ctx = ctx_in) == NULL)
997 		ctx = BN_CTX_new();
998 	if (ctx == NULL)
999 		goto err;
1000 
1001 	if (group->meth->point_get_affine_coordinates == NULL) {
1002 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1003 		goto err;
1004 	}
1005 	if (group->meth != point->meth) {
1006 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1007 		goto err;
1008 	}
1009 	ret = group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
1010 
1011  err:
1012 	if (ctx != ctx_in)
1013 		BN_CTX_free(ctx);
1014 
1015 	return ret;
1016 }
1017 LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates);
1018 
1019 int
1020 EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
1021     BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
1022 {
1023 	return EC_POINT_get_affine_coordinates(group, point, x, y, ctx);
1024 }
1025 LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates_GFp);
1026 
1027 int
1028 EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
1029     const BIGNUM *in_x, int y_bit, BN_CTX *ctx_in)
1030 {
1031 	BIGNUM *p, *a, *b, *w, *x, *y;
1032 	BN_CTX *ctx;
1033 	int ret = 0;
1034 
1035 	if ((ctx = ctx_in) == NULL)
1036 		ctx = BN_CTX_new();
1037 	if (ctx == NULL)
1038 		goto err;
1039 
1040 	y_bit = (y_bit != 0);
1041 
1042 	BN_CTX_start(ctx);
1043 
1044 	if ((p = BN_CTX_get(ctx)) == NULL)
1045 		goto err;
1046 	if ((a = BN_CTX_get(ctx)) == NULL)
1047 		goto err;
1048 	if ((b = BN_CTX_get(ctx)) == NULL)
1049 		goto err;
1050 	if ((w = BN_CTX_get(ctx)) == NULL)
1051 		goto err;
1052 	if ((x = BN_CTX_get(ctx)) == NULL)
1053 		goto err;
1054 	if ((y = BN_CTX_get(ctx)) == NULL)
1055 		goto err;
1056 
1057 	/*
1058 	 * Weierstrass equation: y^2 = x^3 + ax + b, so y is one of the
1059 	 * square roots of x^3 + ax + b. The y-bit indicates which one.
1060 	 */
1061 
1062 	if (!EC_GROUP_get_curve(group, p, a, b, ctx))
1063 		goto err;
1064 
1065 	/* XXX - should we not insist on 0 <= x < p instead? */
1066 	if (!BN_nnmod(x, in_x, p, ctx))
1067 		goto err;
1068 
1069 	/* y = x^3 */
1070 	if (!BN_mod_sqr(y, x, p, ctx))
1071 		goto err;
1072 	if (!BN_mod_mul(y, y, x, p, ctx))
1073 		goto err;
1074 
1075 	/* y += ax */
1076 	if (group->a_is_minus3) {
1077 		if (!BN_mod_lshift1_quick(w, x, p))
1078 			goto err;
1079 		if (!BN_mod_add_quick(w, w, x, p))
1080 			goto err;
1081 		if (!BN_mod_sub_quick(y, y, w, p))
1082 			goto err;
1083 	} else {
1084 		if (!BN_mod_mul(w, a, x, p, ctx))
1085 			goto err;
1086 		if (!BN_mod_add_quick(y, y, w, p))
1087 			goto err;
1088 	}
1089 
1090 	/* y += b */
1091 	if (!BN_mod_add_quick(y, y, b, p))
1092 		goto err;
1093 
1094 	if (!BN_mod_sqrt(y, y, p, ctx)) {
1095 		ECerror(EC_R_INVALID_COMPRESSED_POINT);
1096 		goto err;
1097 	}
1098 
1099 	if (y_bit == BN_is_odd(y))
1100 		goto done;
1101 
1102 	if (BN_is_zero(y)) {
1103 		ECerror(EC_R_INVALID_COMPRESSION_BIT);
1104 		goto err;
1105 	}
1106 	if (!BN_usub(y, p, y))
1107 		goto err;
1108 
1109 	if (y_bit != BN_is_odd(y)) {
1110 		/* Can only happen if p is even and should not be reachable. */
1111 		ECerror(ERR_R_INTERNAL_ERROR);
1112 		goto err;
1113 	}
1114 
1115  done:
1116 	if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
1117 		goto err;
1118 
1119 	ret = 1;
1120 
1121  err:
1122 	BN_CTX_end(ctx);
1123 
1124 	if (ctx != ctx_in)
1125 		BN_CTX_free(ctx);
1126 
1127 	return ret;
1128 }
1129 LCRYPTO_ALIAS(EC_POINT_set_compressed_coordinates);
1130 
1131 int
1132 EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
1133     const BIGNUM *x, int y_bit, BN_CTX *ctx)
1134 {
1135 	return EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx);
1136 }
1137 LCRYPTO_ALIAS(EC_POINT_set_compressed_coordinates_GFp);
1138 
1139 int
1140 EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1141     const EC_POINT *b, BN_CTX *ctx_in)
1142 {
1143 	BN_CTX *ctx;
1144 	int ret = 0;
1145 
1146 	if ((ctx = ctx_in) == NULL)
1147 		ctx = BN_CTX_new();
1148 	if (ctx == NULL)
1149 		goto err;
1150 
1151 	if (group->meth->add == NULL) {
1152 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1153 		goto err;
1154 	}
1155 	if (group->meth != r->meth || group->meth != a->meth ||
1156 	    group->meth != b->meth) {
1157 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1158 		goto err;
1159 	}
1160 	ret = group->meth->add(group, r, a, b, ctx);
1161 
1162  err:
1163 	if (ctx != ctx_in)
1164 		BN_CTX_free(ctx);
1165 
1166 	return ret;
1167 }
1168 LCRYPTO_ALIAS(EC_POINT_add);
1169 
1170 int
1171 EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1172     BN_CTX *ctx_in)
1173 {
1174 	BN_CTX *ctx;
1175 	int ret = 0;
1176 
1177 	if ((ctx = ctx_in) == NULL)
1178 		ctx = BN_CTX_new();
1179 	if (ctx == NULL)
1180 		goto err;
1181 
1182 	if (group->meth->dbl == NULL) {
1183 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1184 		goto err;
1185 	}
1186 	if (group->meth != r->meth || r->meth != a->meth) {
1187 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1188 		goto err;
1189 	}
1190 	ret = group->meth->dbl(group, r, a, ctx);
1191 
1192  err:
1193 	if (ctx != ctx_in)
1194 		BN_CTX_free(ctx);
1195 
1196 	return ret;
1197 }
1198 LCRYPTO_ALIAS(EC_POINT_dbl);
1199 
1200 int
1201 EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx_in)
1202 {
1203 	BN_CTX *ctx;
1204 	int ret = 0;
1205 
1206 	if ((ctx = ctx_in) == NULL)
1207 		ctx = BN_CTX_new();
1208 	if (ctx == NULL)
1209 		goto err;
1210 
1211 	if (group->meth->invert == NULL) {
1212 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1213 		goto err;
1214 	}
1215 	if (group->meth != a->meth) {
1216 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1217 		goto err;
1218 	}
1219 	ret = group->meth->invert(group, a, ctx);
1220 
1221  err:
1222 	if (ctx != ctx_in)
1223 		BN_CTX_free(ctx);
1224 
1225 	return ret;
1226 }
1227 LCRYPTO_ALIAS(EC_POINT_invert);
1228 
1229 int
1230 EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1231 {
1232 	if (group->meth != point->meth) {
1233 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1234 		return 0;
1235 	}
1236 
1237 	return BN_is_zero(point->Z);
1238 }
1239 LCRYPTO_ALIAS(EC_POINT_is_at_infinity);
1240 
1241 int
1242 EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
1243     BN_CTX *ctx_in)
1244 {
1245 	BN_CTX *ctx;
1246 	int ret = -1;
1247 
1248 	if ((ctx = ctx_in) == NULL)
1249 		ctx = BN_CTX_new();
1250 	if (ctx == NULL)
1251 		goto err;
1252 
1253 	if (group->meth->point_is_on_curve == NULL) {
1254 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1255 		goto err;
1256 	}
1257 	if (group->meth != point->meth) {
1258 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1259 		goto err;
1260 	}
1261 	ret = group->meth->point_is_on_curve(group, point, ctx);
1262 
1263  err:
1264 	if (ctx != ctx_in)
1265 		BN_CTX_free(ctx);
1266 
1267 	return ret;
1268 }
1269 LCRYPTO_ALIAS(EC_POINT_is_on_curve);
1270 
1271 int
1272 EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
1273     BN_CTX *ctx_in)
1274 {
1275 	BN_CTX *ctx;
1276 	int ret = -1;
1277 
1278 	if ((ctx = ctx_in) == NULL)
1279 		ctx = BN_CTX_new();
1280 	if (ctx == NULL)
1281 		goto err;
1282 
1283 	if (group->meth->point_cmp == NULL) {
1284 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1285 		goto err;
1286 	}
1287 	if (group->meth != a->meth || a->meth != b->meth) {
1288 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1289 		goto err;
1290 	}
1291 	ret = group->meth->point_cmp(group, a, b, ctx);
1292 
1293  err:
1294 	if (ctx != ctx_in)
1295 		BN_CTX_free(ctx);
1296 
1297 	return ret;
1298 }
1299 LCRYPTO_ALIAS(EC_POINT_cmp);
1300 
1301 int
1302 EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx_in)
1303 {
1304 	BN_CTX *ctx;
1305 	BIGNUM *x, *y;
1306 	int ret = 0;
1307 
1308 	if ((ctx = ctx_in) == NULL)
1309 		ctx = BN_CTX_new();
1310 	if (ctx == NULL)
1311 		goto err;
1312 
1313 	BN_CTX_start(ctx);
1314 
1315 	if ((x = BN_CTX_get(ctx)) == NULL)
1316 		goto err;
1317 	if ((y = BN_CTX_get(ctx)) == NULL)
1318 		goto err;
1319 
1320 	if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
1321 		goto err;
1322 	if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
1323 		goto err;
1324 
1325 	ret = 1;
1326 
1327  err:
1328 	BN_CTX_end(ctx);
1329 
1330 	if (ctx != ctx_in)
1331 		BN_CTX_free(ctx);
1332 
1333 	return ret;
1334 }
1335 LCRYPTO_ALIAS(EC_POINT_make_affine);
1336 
1337 int
1338 EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1339     const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx_in)
1340 {
1341 	BN_CTX *ctx;
1342 	int ret = 0;
1343 
1344 	if ((ctx = ctx_in) == NULL)
1345 		ctx = BN_CTX_new();
1346 	if (ctx == NULL)
1347 		goto err;
1348 
1349 	if (group->meth->mul_generator_ct == NULL ||
1350 	    group->meth->mul_single_ct == NULL ||
1351 	    group->meth->mul_double_nonct == NULL) {
1352 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1353 		goto err;
1354 	}
1355 
1356 	if (g_scalar != NULL && point == NULL && p_scalar == NULL) {
1357 		/*
1358 		 * In this case we want to compute g_scalar * GeneratorPoint:
1359 		 * this codepath is reached most prominently by (ephemeral) key
1360 		 * generation of EC cryptosystems (i.e. ECDSA keygen and sign
1361 		 * setup, ECDH keygen/first half), where the scalar is always
1362 		 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually
1363 		 * set and we always call the constant time version.
1364 		 */
1365 		ret = group->meth->mul_generator_ct(group, r, g_scalar, ctx);
1366 	} else if (g_scalar == NULL && point != NULL && p_scalar != NULL) {
1367 		/*
1368 		 * In this case we want to compute p_scalar * GenericPoint:
1369 		 * this codepath is reached most prominently by the second half
1370 		 * of ECDH, where the secret scalar is multiplied by the peer's
1371 		 * public point. To protect the secret scalar, we ignore if
1372 		 * BN_FLG_CONSTTIME is actually set and we always call the
1373 		 * constant time version.
1374 		 */
1375 		ret = group->meth->mul_single_ct(group, r, p_scalar, point, ctx);
1376 	} else if (g_scalar != NULL && point != NULL && p_scalar != NULL) {
1377 		/*
1378 		 * In this case we want to compute
1379 		 *   g_scalar * GeneratorPoint + p_scalar * GenericPoint:
1380 		 * this codepath is reached most prominently by ECDSA signature
1381 		 * verification. So we call the non-ct version.
1382 		 */
1383 		ret = group->meth->mul_double_nonct(group, r, g_scalar,
1384 		    p_scalar, point, ctx);
1385 	} else {
1386 		/* Anything else is an error. */
1387 		ECerror(ERR_R_EC_LIB);
1388 		goto err;
1389 	}
1390 
1391  err:
1392 	if (ctx != ctx_in)
1393 		BN_CTX_free(ctx);
1394 
1395 	return ret;
1396 }
1397 LCRYPTO_ALIAS(EC_POINT_mul);
1398 
1399 int
1400 EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx_in)
1401 {
1402 	return 1;
1403 }
1404 LCRYPTO_ALIAS(EC_GROUP_precompute_mult);
1405 
1406 int
1407 EC_GROUP_have_precompute_mult(const EC_GROUP *group)
1408 {
1409 	return 0;
1410 }
1411 LCRYPTO_ALIAS(EC_GROUP_have_precompute_mult);
1412 
1413 /*
1414  * XXX - remove everything below in the next bump
1415  */
1416 
1417 int
1418 EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
1419     const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
1420 {
1421 	ECerror(ERR_R_DISABLED);
1422 	return 0;
1423 }
1424 LCRYPTO_ALIAS(EC_POINT_set_Jprojective_coordinates_GFp);
1425 
1426 int
1427 EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
1428     const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
1429 {
1430 	ECerror(ERR_R_DISABLED);
1431 	return 0;
1432 }
1433 LCRYPTO_ALIAS(EC_POINT_get_Jprojective_coordinates_GFp);
1434 
1435 int
1436 EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1437     BN_CTX *ctx_in)
1438 {
1439 	ECerror(ERR_R_DISABLED);
1440 	return 0;
1441 }
1442 LCRYPTO_ALIAS(EC_POINTs_make_affine);
1443 
1444 int
1445 EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1446     size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
1447     BN_CTX *ctx_in)
1448 {
1449 	ECerror(ERR_R_DISABLED);
1450 	return 0;
1451 }
1452 LCRYPTO_ALIAS(EC_POINTs_mul);
1453