xref: /openbsd-src/lib/libcrypto/ec/ecp_methods.c (revision 6d90e0461cad04c6e59ca2c12100afa402bffed9)
1 /* $OpenBSD: ecp_methods.c,v 1.42 2025/01/25 13:15:21 tb Exp $ */
2 /* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3  * for the OpenSSL project.
4  * Includes code written by Bodo Moeller for the OpenSSL project.
5  */
6 /* ====================================================================
7  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  *
21  * 3. All advertising materials mentioning features or use of this
22  *    software must display the following acknowledgment:
23  *    "This product includes software developed by the OpenSSL Project
24  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25  *
26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27  *    endorse or promote products derived from this software without
28  *    prior written permission. For written permission, please contact
29  *    openssl-core@openssl.org.
30  *
31  * 5. Products derived from this software may not be called "OpenSSL"
32  *    nor may "OpenSSL" appear in their names without prior written
33  *    permission of the OpenSSL Project.
34  *
35  * 6. Redistributions of any form whatsoever must retain the following
36  *    acknowledgment:
37  *    "This product includes software developed by the OpenSSL Project
38  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51  * OF THE POSSIBILITY OF SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This product includes cryptographic software written by Eric Young
55  * (eay@cryptsoft.com).  This product includes software written by Tim
56  * Hudson (tjh@cryptsoft.com).
57  *
58  */
59 /* ====================================================================
60  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
61  * Portions of this software developed by SUN MICROSYSTEMS, INC.,
62  * and contributed to the OpenSSL project.
63  */
64 
65 #include <stdlib.h>
66 
67 #include <openssl/bn.h>
68 #include <openssl/ec.h>
69 #include <openssl/err.h>
70 #include <openssl/objects.h>
71 
72 #include "bn_local.h"
73 #include "ec_local.h"
74 
75 /*
76  * Most method functions in this file are designed to work with non-trivial
77  * representations of field elements if necessary: while standard modular
78  * addition and subtraction are used, the field_mul and field_sqr methods will
79  * be used for multiplication, and field_encode and field_decode (if defined)
80  * will be used for converting between representations.
81  *
82  * The functions ec_points_make_affine() and ec_point_get_affine_coordinates()
83  * assume that if a non-trivial representation is used, it is a Montgomery
84  * representation (i.e. 'encoding' means multiplying by some factor R).
85  */
86 
87 static inline int
88 ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
89     BN_CTX *ctx)
90 {
91 	return group->meth->field_mul(group, r, a, b, ctx);
92 }
93 
94 static inline int
95 ec_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
96 {
97 	return group->meth->field_sqr(group, r, a, ctx);
98 }
99 
100 static int
101 ec_decode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx)
102 {
103 	if (bn == NULL)
104 		return 1;
105 
106 	if (group->meth->field_decode != NULL)
107 		return group->meth->field_decode(group, bn, x, ctx);
108 
109 	return bn_copy(bn, x);
110 }
111 
112 static int
113 ec_encode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx)
114 {
115 	if (!BN_nnmod(bn, x, group->p, ctx))
116 		return 0;
117 
118 	if (group->meth->field_encode != NULL)
119 		return group->meth->field_encode(group, bn, bn, ctx);
120 
121 	return 1;
122 }
123 
124 static int
125 ec_group_set_curve(EC_GROUP *group,
126     const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
127 {
128 	BIGNUM *a_plus_3;
129 	int ret = 0;
130 
131 	/* p must be a prime > 3 */
132 	if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
133 		ECerror(EC_R_INVALID_FIELD);
134 		return 0;
135 	}
136 
137 	BN_CTX_start(ctx);
138 
139 	if ((a_plus_3 = BN_CTX_get(ctx)) == NULL)
140 		goto err;
141 
142 	if (!bn_copy(group->p, p))
143 		goto err;
144 	BN_set_negative(group->p, 0);
145 
146 	if (!ec_encode_scalar(group, group->a, a, ctx))
147 		goto err;
148 	if (!ec_encode_scalar(group, group->b, b, ctx))
149 		goto err;
150 
151 	if (!BN_set_word(a_plus_3, 3))
152 		goto err;
153 	if (!BN_mod_add(a_plus_3, a_plus_3, a, group->p, ctx))
154 		goto err;
155 
156 	group->a_is_minus3 = BN_is_zero(a_plus_3);
157 
158 	ret = 1;
159 
160  err:
161 	BN_CTX_end(ctx);
162 
163 	return ret;
164 }
165 
166 static int
167 ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
168     BN_CTX *ctx)
169 {
170 	if (p != NULL) {
171 		if (!bn_copy(p, group->p))
172 			return 0;
173 	}
174 	if (!ec_decode_scalar(group, a, group->a, ctx))
175 		return 0;
176 	if (!ec_decode_scalar(group, b, group->b, ctx))
177 		return 0;
178 
179 	return 1;
180 }
181 
182 static int
183 ec_point_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
184 {
185 	BIGNUM *rh, *tmp, *Z4, *Z6;
186 	int ret = -1;
187 
188 	if (EC_POINT_is_at_infinity(group, point))
189 		return 1;
190 
191 	BN_CTX_start(ctx);
192 
193 	if ((rh = BN_CTX_get(ctx)) == NULL)
194 		goto err;
195 	if ((tmp = BN_CTX_get(ctx)) == NULL)
196 		goto err;
197 	if ((Z4 = BN_CTX_get(ctx)) == NULL)
198 		goto err;
199 	if ((Z6 = BN_CTX_get(ctx)) == NULL)
200 		goto err;
201 
202 	/*
203 	 * The curve is defined by a Weierstrass equation y^2 = x^3 + a*x + b.
204 	 * The point is given in Jacobian projective coordinates where (X, Y, Z)
205 	 * represents (x, y) = (X/Z^2, Y/Z^3). Substituting this and multiplying
206 	 * by Z^6 transforms the above into Y^2 = X^3 + a*X*Z^4 + b*Z^6.
207 	 */
208 
209 	/* rh := X^2 */
210 	if (!ec_field_sqr(group, rh, point->X, ctx))
211 		goto err;
212 
213 	if (!point->Z_is_one) {
214 		if (!ec_field_sqr(group, tmp, point->Z, ctx))
215 			goto err;
216 		if (!ec_field_sqr(group, Z4, tmp, ctx))
217 			goto err;
218 		if (!ec_field_mul(group, Z6, Z4, tmp, ctx))
219 			goto err;
220 
221 		/* rh := (rh + a*Z^4)*X */
222 		if (group->a_is_minus3) {
223 			if (!BN_mod_lshift1_quick(tmp, Z4, group->p))
224 				goto err;
225 			if (!BN_mod_add_quick(tmp, tmp, Z4, group->p))
226 				goto err;
227 			if (!BN_mod_sub_quick(rh, rh, tmp, group->p))
228 				goto err;
229 			if (!ec_field_mul(group, rh, rh, point->X, ctx))
230 				goto err;
231 		} else {
232 			if (!ec_field_mul(group, tmp, Z4, group->a, ctx))
233 				goto err;
234 			if (!BN_mod_add_quick(rh, rh, tmp, group->p))
235 				goto err;
236 			if (!ec_field_mul(group, rh, rh, point->X, ctx))
237 				goto err;
238 		}
239 
240 		/* rh := rh + b*Z^6 */
241 		if (!ec_field_mul(group, tmp, group->b, Z6, ctx))
242 			goto err;
243 		if (!BN_mod_add_quick(rh, rh, tmp, group->p))
244 			goto err;
245 	} else {
246 		/* point->Z_is_one */
247 
248 		/* rh := (rh + a)*X */
249 		if (!BN_mod_add_quick(rh, rh, group->a, group->p))
250 			goto err;
251 		if (!ec_field_mul(group, rh, rh, point->X, ctx))
252 			goto err;
253 		/* rh := rh + b */
254 		if (!BN_mod_add_quick(rh, rh, group->b, group->p))
255 			goto err;
256 	}
257 
258 	/* 'lh' := Y^2 */
259 	if (!ec_field_sqr(group, tmp, point->Y, ctx))
260 		goto err;
261 
262 	ret = (0 == BN_ucmp(tmp, rh));
263 
264  err:
265 	BN_CTX_end(ctx);
266 
267 	return ret;
268 }
269 
270 /*
271  * Returns -1 on error, 0 if the points are equal, 1 if the points are distinct.
272  */
273 
274 static int
275 ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
276     BN_CTX *ctx)
277 {
278 	BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
279 	const BIGNUM *tmp1_, *tmp2_;
280 	int ret = -1;
281 
282 	if (EC_POINT_is_at_infinity(group, a) && EC_POINT_is_at_infinity(group, b))
283 		return 0;
284 	if (EC_POINT_is_at_infinity(group, a) || EC_POINT_is_at_infinity(group, b))
285 		return 1;
286 
287 	if (a->Z_is_one && b->Z_is_one)
288 		return BN_cmp(a->X, b->X) != 0 || BN_cmp(a->Y, b->Y) != 0;
289 
290 	BN_CTX_start(ctx);
291 
292 	if ((tmp1 = BN_CTX_get(ctx)) == NULL)
293 		goto end;
294 	if ((tmp2 = BN_CTX_get(ctx)) == NULL)
295 		goto end;
296 	if ((Za23 = BN_CTX_get(ctx)) == NULL)
297 		goto end;
298 	if ((Zb23 = BN_CTX_get(ctx)) == NULL)
299 		goto end;
300 
301 	/*
302 	 * Decide whether (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), or
303 	 * equivalently, (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
304 	 */
305 
306 	if (!b->Z_is_one) {
307 		if (!ec_field_sqr(group, Zb23, b->Z, ctx))
308 			goto end;
309 		if (!ec_field_mul(group, tmp1, a->X, Zb23, ctx))
310 			goto end;
311 		tmp1_ = tmp1;
312 	} else
313 		tmp1_ = a->X;
314 	if (!a->Z_is_one) {
315 		if (!ec_field_sqr(group, Za23, a->Z, ctx))
316 			goto end;
317 		if (!ec_field_mul(group, tmp2, b->X, Za23, ctx))
318 			goto end;
319 		tmp2_ = tmp2;
320 	} else
321 		tmp2_ = b->X;
322 
323 	/* compare  X_a*Z_b^2  with  X_b*Z_a^2 */
324 	if (BN_cmp(tmp1_, tmp2_) != 0) {
325 		ret = 1;	/* points differ */
326 		goto end;
327 	}
328 	if (!b->Z_is_one) {
329 		if (!ec_field_mul(group, Zb23, Zb23, b->Z, ctx))
330 			goto end;
331 		if (!ec_field_mul(group, tmp1, a->Y, Zb23, ctx))
332 			goto end;
333 		/* tmp1_ = tmp1 */
334 	} else
335 		tmp1_ = a->Y;
336 	if (!a->Z_is_one) {
337 		if (!ec_field_mul(group, Za23, Za23, a->Z, ctx))
338 			goto end;
339 		if (!ec_field_mul(group, tmp2, b->Y, Za23, ctx))
340 			goto end;
341 		/* tmp2_ = tmp2 */
342 	} else
343 		tmp2_ = b->Y;
344 
345 	/* compare  Y_a*Z_b^3  with  Y_b*Z_a^3 */
346 	if (BN_cmp(tmp1_, tmp2_) != 0) {
347 		ret = 1;	/* points differ */
348 		goto end;
349 	}
350 	/* points are equal */
351 	ret = 0;
352 
353  end:
354 	BN_CTX_end(ctx);
355 
356 	return ret;
357 }
358 
359 static int
360 ec_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
361     const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
362 {
363 	int ret = 0;
364 
365 	if (x == NULL || y == NULL) {
366 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
367 		goto err;
368 	}
369 
370 	if (!ec_encode_scalar(group, point->X, x, ctx))
371 		goto err;
372 	if (!ec_encode_scalar(group, point->Y, y, ctx))
373 		goto err;
374 	if (!ec_encode_scalar(group, point->Z, BN_value_one(), ctx))
375 		goto err;
376 	point->Z_is_one = 1;
377 
378 	ret = 1;
379 
380  err:
381 	return ret;
382 }
383 
384 static int
385 ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
386     BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
387 {
388 	BIGNUM *z, *Z, *Z_1, *Z_2, *Z_3;
389 	int ret = 0;
390 
391 	BN_CTX_start(ctx);
392 
393 	if ((z = BN_CTX_get(ctx)) == NULL)
394 		goto err;
395 	if ((Z = BN_CTX_get(ctx)) == NULL)
396 		goto err;
397 	if ((Z_1 = BN_CTX_get(ctx)) == NULL)
398 		goto err;
399 	if ((Z_2 = BN_CTX_get(ctx)) == NULL)
400 		goto err;
401 	if ((Z_3 = BN_CTX_get(ctx)) == NULL)
402 		goto err;
403 
404 	/*
405 	 * Convert from Jacobian projective coordinates (X, Y, Z) into
406 	 * (X/Z^2, Y/Z^3).
407 	 */
408 
409 	if (!ec_decode_scalar(group, z, point->Z, ctx))
410 		goto err;
411 
412 	if (BN_is_one(z)) {
413 		if (!ec_decode_scalar(group, x, point->X, ctx))
414 			goto err;
415 		if (!ec_decode_scalar(group, y, point->Y, ctx))
416 			goto err;
417 		goto done;
418 	}
419 
420 	if (BN_mod_inverse_ct(Z_1, z, group->p, ctx) == NULL) {
421 		ECerror(ERR_R_BN_LIB);
422 		goto err;
423 	}
424 	if (group->meth->field_encode == NULL) {
425 		/* field_sqr works on standard representation */
426 		if (!ec_field_sqr(group, Z_2, Z_1, ctx))
427 			goto err;
428 	} else {
429 		if (!BN_mod_sqr(Z_2, Z_1, group->p, ctx))
430 			goto err;
431 	}
432 
433 	if (x != NULL) {
434 		/*
435 		 * in the Montgomery case, field_mul will cancel out
436 		 * Montgomery factor in X:
437 		 */
438 		if (!ec_field_mul(group, x, point->X, Z_2, ctx))
439 			goto err;
440 	}
441 	if (y != NULL) {
442 		if (group->meth->field_encode == NULL) {
443 			/* field_mul works on standard representation */
444 			if (!ec_field_mul(group, Z_3, Z_2, Z_1, ctx))
445 				goto err;
446 		} else {
447 			if (!BN_mod_mul(Z_3, Z_2, Z_1, group->p, ctx))
448 				goto err;
449 		}
450 
451 		/*
452 		 * in the Montgomery case, field_mul will cancel out
453 		 * Montgomery factor in Y:
454 		 */
455 		if (!ec_field_mul(group, y, point->Y, Z_3, ctx))
456 			goto err;
457 	}
458 
459  done:
460 	ret = 1;
461 
462  err:
463 	BN_CTX_end(ctx);
464 
465 	return ret;
466 }
467 
468 static int
469 ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT **points,
470     BN_CTX *ctx)
471 {
472 	BIGNUM **prod_Z = NULL;
473 	BIGNUM *one, *tmp, *tmp_Z;
474 	size_t i;
475 	int ret = 0;
476 
477 	if (num == 0)
478 		return 1;
479 
480 	BN_CTX_start(ctx);
481 
482 	if ((one = BN_CTX_get(ctx)) == NULL)
483 		goto err;
484 	if ((tmp = BN_CTX_get(ctx)) == NULL)
485 		goto err;
486 	if ((tmp_Z = BN_CTX_get(ctx)) == NULL)
487 		goto err;
488 
489 	if (!ec_encode_scalar(group, one, BN_value_one(), ctx))
490 		goto err;
491 
492 	if ((prod_Z = calloc(num, sizeof *prod_Z)) == NULL)
493 		goto err;
494 	for (i = 0; i < num; i++) {
495 		if ((prod_Z[i] = BN_CTX_get(ctx)) == NULL)
496 			goto err;
497 	}
498 
499 	/*
500 	 * Set prod_Z[i] to the product of points[0]->Z, ..., points[i]->Z,
501 	 * skipping any zero-valued inputs (pretend that they're 1).
502 	 */
503 
504 	if (!BN_is_zero(points[0]->Z)) {
505 		if (!bn_copy(prod_Z[0], points[0]->Z))
506 			goto err;
507 	} else {
508 		if (!bn_copy(prod_Z[0], one))
509 			goto err;
510 	}
511 
512 	for (i = 1; i < num; i++) {
513 		if (!BN_is_zero(points[i]->Z)) {
514 			if (!ec_field_mul(group, prod_Z[i],
515 			    prod_Z[i - 1], points[i]->Z, ctx))
516 				goto err;
517 		} else {
518 			if (!bn_copy(prod_Z[i], prod_Z[i - 1]))
519 				goto err;
520 		}
521 	}
522 
523 	/*
524 	 * Now use a single explicit inversion to replace every non-zero
525 	 * points[i]->Z by its inverse.
526 	 */
527 	if (!BN_mod_inverse_nonct(tmp, prod_Z[num - 1], group->p, ctx)) {
528 		ECerror(ERR_R_BN_LIB);
529 		goto err;
530 	}
531 
532 	if (group->meth->field_encode != NULL) {
533 		/*
534 		 * In the Montgomery case we just turned R*H (representing H)
535 		 * into 1/(R*H), but we need R*(1/H) (representing 1/H); i.e.,
536 		 * we need to multiply by the Montgomery factor twice.
537 		 */
538 		if (!group->meth->field_encode(group, tmp, tmp, ctx))
539 			goto err;
540 		if (!group->meth->field_encode(group, tmp, tmp, ctx))
541 			goto err;
542 	}
543 
544 	for (i = num - 1; i > 0; i--) {
545 		/*
546 		 * Loop invariant: tmp is the product of the inverses of
547 		 * points[0]->Z, ..., points[i]->Z (zero-valued inputs skipped).
548 		 */
549 		if (BN_is_zero(points[i]->Z))
550 			continue;
551 
552 		/* Set tmp_Z to the inverse of points[i]->Z. */
553 		if (!ec_field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
554 			goto err;
555 		/* Adjust tmp to satisfy loop invariant. */
556 		if (!ec_field_mul(group, tmp, tmp, points[i]->Z, ctx))
557 			goto err;
558 		/* Replace points[i]->Z by its inverse. */
559 		if (!bn_copy(points[i]->Z, tmp_Z))
560 			goto err;
561 	}
562 
563 	if (!BN_is_zero(points[0]->Z)) {
564 		/* Replace points[0]->Z by its inverse. */
565 		if (!bn_copy(points[0]->Z, tmp))
566 			goto err;
567 	}
568 
569 	/* Finally, fix up the X and Y coordinates for all points. */
570 	for (i = 0; i < num; i++) {
571 		EC_POINT *p = points[i];
572 
573 		if (BN_is_zero(p->Z))
574 			continue;
575 
576 		/* turn  (X, Y, 1/Z)  into  (X/Z^2, Y/Z^3, 1) */
577 
578 		if (!ec_field_sqr(group, tmp, p->Z, ctx))
579 			goto err;
580 		if (!ec_field_mul(group, p->X, p->X, tmp, ctx))
581 			goto err;
582 
583 		if (!ec_field_mul(group, tmp, tmp, p->Z, ctx))
584 			goto err;
585 		if (!ec_field_mul(group, p->Y, p->Y, tmp, ctx))
586 			goto err;
587 
588 		if (!bn_copy(p->Z, one))
589 			goto err;
590 		p->Z_is_one = 1;
591 	}
592 
593 	ret = 1;
594 
595  err:
596 	BN_CTX_end(ctx);
597 	free(prod_Z);
598 
599 	return ret;
600 }
601 
602 static int
603 ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b,
604     BN_CTX *ctx)
605 {
606 	BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
607 	int ret = 0;
608 
609 	if (a == b)
610 		return EC_POINT_dbl(group, r, a, ctx);
611 	if (EC_POINT_is_at_infinity(group, a))
612 		return EC_POINT_copy(r, b);
613 	if (EC_POINT_is_at_infinity(group, b))
614 		return EC_POINT_copy(r, a);
615 
616 	BN_CTX_start(ctx);
617 
618 	if ((n0 = BN_CTX_get(ctx)) == NULL)
619 		goto end;
620 	if ((n1 = BN_CTX_get(ctx)) == NULL)
621 		goto end;
622 	if ((n2 = BN_CTX_get(ctx)) == NULL)
623 		goto end;
624 	if ((n3 = BN_CTX_get(ctx)) == NULL)
625 		goto end;
626 	if ((n4 = BN_CTX_get(ctx)) == NULL)
627 		goto end;
628 	if ((n5 = BN_CTX_get(ctx)) == NULL)
629 		goto end;
630 	if ((n6 = BN_CTX_get(ctx)) == NULL)
631 		goto end;
632 
633 	/*
634 	 * Note that in this function we must not read components of 'a' or
635 	 * 'b' once we have written the corresponding components of 'r'. ('r'
636 	 * might be one of 'a' or 'b'.)
637 	 */
638 
639 	/* n1, n2 */
640 	if (b->Z_is_one) {
641 		if (!bn_copy(n1, a->X))
642 			goto end;
643 		if (!bn_copy(n2, a->Y))
644 			goto end;
645 		/* n1 = X_a */
646 		/* n2 = Y_a */
647 	} else {
648 		if (!ec_field_sqr(group, n0, b->Z, ctx))
649 			goto end;
650 		if (!ec_field_mul(group, n1, a->X, n0, ctx))
651 			goto end;
652 		/* n1 = X_a * Z_b^2 */
653 
654 		if (!ec_field_mul(group, n0, n0, b->Z, ctx))
655 			goto end;
656 		if (!ec_field_mul(group, n2, a->Y, n0, ctx))
657 			goto end;
658 		/* n2 = Y_a * Z_b^3 */
659 	}
660 
661 	/* n3, n4 */
662 	if (a->Z_is_one) {
663 		if (!bn_copy(n3, b->X))
664 			goto end;
665 		if (!bn_copy(n4, b->Y))
666 			goto end;
667 		/* n3 = X_b */
668 		/* n4 = Y_b */
669 	} else {
670 		if (!ec_field_sqr(group, n0, a->Z, ctx))
671 			goto end;
672 		if (!ec_field_mul(group, n3, b->X, n0, ctx))
673 			goto end;
674 		/* n3 = X_b * Z_a^2 */
675 
676 		if (!ec_field_mul(group, n0, n0, a->Z, ctx))
677 			goto end;
678 		if (!ec_field_mul(group, n4, b->Y, n0, ctx))
679 			goto end;
680 		/* n4 = Y_b * Z_a^3 */
681 	}
682 
683 	/* n5, n6 */
684 	if (!BN_mod_sub_quick(n5, n1, n3, group->p))
685 		goto end;
686 	if (!BN_mod_sub_quick(n6, n2, n4, group->p))
687 		goto end;
688 	/* n5 = n1 - n3 */
689 	/* n6 = n2 - n4 */
690 
691 	if (BN_is_zero(n5)) {
692 		if (BN_is_zero(n6)) {
693 			/* a is the same point as b */
694 			BN_CTX_end(ctx);
695 			ret = EC_POINT_dbl(group, r, a, ctx);
696 			ctx = NULL;
697 			goto end;
698 		} else {
699 			/* a is the inverse of b */
700 			BN_zero(r->Z);
701 			r->Z_is_one = 0;
702 			ret = 1;
703 			goto end;
704 		}
705 	}
706 	/* 'n7', 'n8' */
707 	if (!BN_mod_add_quick(n1, n1, n3, group->p))
708 		goto end;
709 	if (!BN_mod_add_quick(n2, n2, n4, group->p))
710 		goto end;
711 	/* 'n7' = n1 + n3 */
712 	/* 'n8' = n2 + n4 */
713 
714 	/* Z_r */
715 	if (a->Z_is_one && b->Z_is_one) {
716 		if (!bn_copy(r->Z, n5))
717 			goto end;
718 	} else {
719 		if (a->Z_is_one) {
720 			if (!bn_copy(n0, b->Z))
721 				goto end;
722 		} else if (b->Z_is_one) {
723 			if (!bn_copy(n0, a->Z))
724 				goto end;
725 		} else {
726 			if (!ec_field_mul(group, n0, a->Z, b->Z, ctx))
727 				goto end;
728 		}
729 		if (!ec_field_mul(group, r->Z, n0, n5, ctx))
730 			goto end;
731 	}
732 	r->Z_is_one = 0;
733 	/* Z_r = Z_a * Z_b * n5 */
734 
735 	/* X_r */
736 	if (!ec_field_sqr(group, n0, n6, ctx))
737 		goto end;
738 	if (!ec_field_sqr(group, n4, n5, ctx))
739 		goto end;
740 	if (!ec_field_mul(group, n3, n1, n4, ctx))
741 		goto end;
742 	if (!BN_mod_sub_quick(r->X, n0, n3, group->p))
743 		goto end;
744 	/* X_r = n6^2 - n5^2 * 'n7' */
745 
746 	/* 'n9' */
747 	if (!BN_mod_lshift1_quick(n0, r->X, group->p))
748 		goto end;
749 	if (!BN_mod_sub_quick(n0, n3, n0, group->p))
750 		goto end;
751 	/* n9 = n5^2 * 'n7' - 2 * X_r */
752 
753 	/* Y_r */
754 	if (!ec_field_mul(group, n0, n0, n6, ctx))
755 		goto end;
756 	if (!ec_field_mul(group, n5, n4, n5, ctx))
757 		goto end;	/* now n5 is n5^3 */
758 	if (!ec_field_mul(group, n1, n2, n5, ctx))
759 		goto end;
760 	if (!BN_mod_sub_quick(n0, n0, n1, group->p))
761 		goto end;
762 	if (BN_is_odd(n0))
763 		if (!BN_add(n0, n0, group->p))
764 			goto end;
765 	/* now  0 <= n0 < 2*p,  and n0 is even */
766 	if (!BN_rshift1(r->Y, n0))
767 		goto end;
768 	/* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
769 
770 	ret = 1;
771 
772  end:
773 	BN_CTX_end(ctx);
774 
775 	return ret;
776 }
777 
778 static int
779 ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
780 {
781 	BIGNUM *n0, *n1, *n2, *n3;
782 	int ret = 0;
783 
784 	if (EC_POINT_is_at_infinity(group, a))
785 		return EC_POINT_set_to_infinity(group, r);
786 
787 	BN_CTX_start(ctx);
788 
789 	if ((n0 = BN_CTX_get(ctx)) == NULL)
790 		goto err;
791 	if ((n1 = BN_CTX_get(ctx)) == NULL)
792 		goto err;
793 	if ((n2 = BN_CTX_get(ctx)) == NULL)
794 		goto err;
795 	if ((n3 = BN_CTX_get(ctx)) == NULL)
796 		goto err;
797 
798 	/*
799 	 * Note that in this function we must not read components of 'a' once
800 	 * we have written the corresponding components of 'r'. ('r' might
801 	 * the same as 'a'.)
802 	 */
803 
804 	/* n1 */
805 	if (a->Z_is_one) {
806 		if (!ec_field_sqr(group, n0, a->X, ctx))
807 			goto err;
808 		if (!BN_mod_lshift1_quick(n1, n0, group->p))
809 			goto err;
810 		if (!BN_mod_add_quick(n0, n0, n1, group->p))
811 			goto err;
812 		if (!BN_mod_add_quick(n1, n0, group->a, group->p))
813 			goto err;
814 		/* n1 = 3 * X_a^2 + a_curve */
815 	} else if (group->a_is_minus3) {
816 		if (!ec_field_sqr(group, n1, a->Z, ctx))
817 			goto err;
818 		if (!BN_mod_add_quick(n0, a->X, n1, group->p))
819 			goto err;
820 		if (!BN_mod_sub_quick(n2, a->X, n1, group->p))
821 			goto err;
822 		if (!ec_field_mul(group, n1, n0, n2, ctx))
823 			goto err;
824 		if (!BN_mod_lshift1_quick(n0, n1, group->p))
825 			goto err;
826 		if (!BN_mod_add_quick(n1, n0, n1, group->p))
827 			goto err;
828 		/*
829 		 * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) = 3 * X_a^2 - 3 *
830 		 * Z_a^4
831 		 */
832 	} else {
833 		if (!ec_field_sqr(group, n0, a->X, ctx))
834 			goto err;
835 		if (!BN_mod_lshift1_quick(n1, n0, group->p))
836 			goto err;
837 		if (!BN_mod_add_quick(n0, n0, n1, group->p))
838 			goto err;
839 		if (!ec_field_sqr(group, n1, a->Z, ctx))
840 			goto err;
841 		if (!ec_field_sqr(group, n1, n1, ctx))
842 			goto err;
843 		if (!ec_field_mul(group, n1, n1, group->a, ctx))
844 			goto err;
845 		if (!BN_mod_add_quick(n1, n1, n0, group->p))
846 			goto err;
847 		/* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
848 	}
849 
850 	/* Z_r */
851 	if (a->Z_is_one) {
852 		if (!bn_copy(n0, a->Y))
853 			goto err;
854 	} else {
855 		if (!ec_field_mul(group, n0, a->Y, a->Z, ctx))
856 			goto err;
857 	}
858 	if (!BN_mod_lshift1_quick(r->Z, n0, group->p))
859 		goto err;
860 	r->Z_is_one = 0;
861 	/* Z_r = 2 * Y_a * Z_a */
862 
863 	/* n2 */
864 	if (!ec_field_sqr(group, n3, a->Y, ctx))
865 		goto err;
866 	if (!ec_field_mul(group, n2, a->X, n3, ctx))
867 		goto err;
868 	if (!BN_mod_lshift_quick(n2, n2, 2, group->p))
869 		goto err;
870 	/* n2 = 4 * X_a * Y_a^2 */
871 
872 	/* X_r */
873 	if (!BN_mod_lshift1_quick(n0, n2, group->p))
874 		goto err;
875 	if (!ec_field_sqr(group, r->X, n1, ctx))
876 		goto err;
877 	if (!BN_mod_sub_quick(r->X, r->X, n0, group->p))
878 		goto err;
879 	/* X_r = n1^2 - 2 * n2 */
880 
881 	/* n3 */
882 	if (!ec_field_sqr(group, n0, n3, ctx))
883 		goto err;
884 	if (!BN_mod_lshift_quick(n3, n0, 3, group->p))
885 		goto err;
886 	/* n3 = 8 * Y_a^4 */
887 
888 	/* Y_r */
889 	if (!BN_mod_sub_quick(n0, n2, r->X, group->p))
890 		goto err;
891 	if (!ec_field_mul(group, n0, n1, n0, ctx))
892 		goto err;
893 	if (!BN_mod_sub_quick(r->Y, n0, n3, group->p))
894 		goto err;
895 	/* Y_r = n1 * (n2 - X_r) - n3 */
896 
897 	ret = 1;
898 
899  err:
900 	BN_CTX_end(ctx);
901 
902 	return ret;
903 }
904 
905 static int
906 ec_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
907 {
908 	if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
909 		/* point is its own inverse */
910 		return 1;
911 
912 	return BN_usub(point->Y, group->p, point->Y);
913 }
914 
915 /*
916  * Apply randomization of EC point Jacobian projective coordinates:
917  *
918  *	(X, Y, Z) = (lambda^2 * X, lambda^3 * Y, lambda * Z)
919  *
920  * where lambda is in the interval [1, p).
921  */
922 static int
923 ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
924 {
925 	BIGNUM *lambda = NULL;
926 	BIGNUM *tmp = NULL;
927 	int ret = 0;
928 
929 	BN_CTX_start(ctx);
930 	if ((lambda = BN_CTX_get(ctx)) == NULL)
931 		goto err;
932 	if ((tmp = BN_CTX_get(ctx)) == NULL)
933 		goto err;
934 
935 	/* Generate lambda in [1, p). */
936 	if (!bn_rand_interval(lambda, 1, group->p))
937 		goto err;
938 
939 	if (group->meth->field_encode != NULL &&
940 	    !group->meth->field_encode(group, lambda, lambda, ctx))
941 		goto err;
942 
943 	/* Z = lambda * Z */
944 	if (!ec_field_mul(group, p->Z, lambda, p->Z, ctx))
945 		goto err;
946 
947 	/* tmp = lambda^2 */
948 	if (!ec_field_sqr(group, tmp, lambda, ctx))
949 		goto err;
950 
951 	/* X = lambda^2 * X */
952 	if (!ec_field_mul(group, p->X, tmp, p->X, ctx))
953 		goto err;
954 
955 	/* tmp = lambda^3 */
956 	if (!ec_field_mul(group, tmp, tmp, lambda, ctx))
957 		goto err;
958 
959 	/* Y = lambda^3 * Y */
960 	if (!ec_field_mul(group, p->Y, tmp, p->Y, ctx))
961 		goto err;
962 
963 	/* Disable optimized arithmetics after replacing Z by lambda * Z. */
964 	p->Z_is_one = 0;
965 
966 	ret = 1;
967 
968  err:
969 	BN_CTX_end(ctx);
970 	return ret;
971 }
972 
973 #define EC_POINT_BN_set_flags(P, flags) do {				\
974 	BN_set_flags((P)->X, (flags));					\
975 	BN_set_flags((P)->Y, (flags));					\
976 	BN_set_flags((P)->Z, (flags));					\
977 } while(0)
978 
979 #define EC_POINT_CSWAP(c, a, b, w, t) do {				\
980 	if (!BN_swap_ct(c, (a)->X, (b)->X, w)	||			\
981 	    !BN_swap_ct(c, (a)->Y, (b)->Y, w)	||			\
982 	    !BN_swap_ct(c, (a)->Z, (b)->Z, w))				\
983 		goto err;						\
984 	t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c);			\
985 	(a)->Z_is_one ^= (t);						\
986 	(b)->Z_is_one ^= (t);						\
987 } while(0)
988 
989 /*
990  * This function computes (in constant time) a point multiplication over the
991  * EC group.
992  *
993  * At a high level, it is Montgomery ladder with conditional swaps.
994  *
995  * It performs either a fixed point multiplication
996  *          (scalar * generator)
997  * when point is NULL, or a variable point multiplication
998  *          (scalar * point)
999  * when point is not NULL.
1000  *
1001  * scalar should be in the range [0,n) otherwise all constant time bets are off.
1002  *
1003  * NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
1004  * which of course are not constant time themselves.
1005  *
1006  * The product is stored in r.
1007  *
1008  * Returns 1 on success, 0 otherwise.
1009  */
1010 static int
1011 ec_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1012     const EC_POINT *point, BN_CTX *ctx)
1013 {
1014 	int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
1015 	EC_POINT *s = NULL;
1016 	BIGNUM *k = NULL;
1017 	BIGNUM *lambda = NULL;
1018 	BIGNUM *cardinality = NULL;
1019 	int ret = 0;
1020 
1021 	BN_CTX_start(ctx);
1022 
1023 	if ((s = EC_POINT_dup(point, group)) == NULL)
1024 		goto err;
1025 
1026 	EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
1027 
1028 	if ((cardinality = BN_CTX_get(ctx)) == NULL)
1029 		goto err;
1030 	if ((lambda = BN_CTX_get(ctx)) == NULL)
1031 		goto err;
1032 	if ((k = BN_CTX_get(ctx)) == NULL)
1033 		goto err;
1034 	if (!BN_mul(cardinality, group->order, group->cofactor, ctx))
1035 		goto err;
1036 
1037 	/*
1038 	 * Group cardinalities are often on a word boundary.
1039 	 * So when we pad the scalar, some timing diff might
1040 	 * pop if it needs to be expanded due to carries.
1041 	 * So expand ahead of time.
1042 	 */
1043 	cardinality_bits = BN_num_bits(cardinality);
1044 	group_top = cardinality->top;
1045 	if (!bn_wexpand(k, group_top + 2) ||
1046 	    !bn_wexpand(lambda, group_top + 2))
1047 		goto err;
1048 
1049 	if (!bn_copy(k, scalar))
1050 		goto err;
1051 
1052 	BN_set_flags(k, BN_FLG_CONSTTIME);
1053 
1054 	if (BN_num_bits(k) > cardinality_bits || BN_is_negative(k)) {
1055 		/*
1056 		 * This is an unusual input, and we don't guarantee
1057 		 * constant-timeness
1058 		 */
1059 		if (!BN_nnmod(k, k, cardinality, ctx))
1060 			goto err;
1061 	}
1062 
1063 	if (!BN_add(lambda, k, cardinality))
1064 		goto err;
1065 	BN_set_flags(lambda, BN_FLG_CONSTTIME);
1066 	if (!BN_add(k, lambda, cardinality))
1067 		goto err;
1068 	/*
1069 	 * lambda := scalar + cardinality
1070 	 * k := scalar + 2*cardinality
1071 	 */
1072 	kbit = BN_is_bit_set(lambda, cardinality_bits);
1073 	if (!BN_swap_ct(kbit, k, lambda, group_top + 2))
1074 		goto err;
1075 
1076 	group_top = group->p->top;
1077 	if (!bn_wexpand(s->X, group_top) ||
1078 	    !bn_wexpand(s->Y, group_top) ||
1079 	    !bn_wexpand(s->Z, group_top) ||
1080 	    !bn_wexpand(r->X, group_top) ||
1081 	    !bn_wexpand(r->Y, group_top) ||
1082 	    !bn_wexpand(r->Z, group_top))
1083 		goto err;
1084 
1085 	/*
1086 	 * Apply coordinate blinding for EC_POINT if the underlying EC_METHOD
1087 	 * implements it.
1088 	 */
1089 	if (!ec_blind_coordinates(group, s, ctx))
1090 		goto err;
1091 
1092 	/* top bit is a 1, in a fixed pos */
1093 	if (!EC_POINT_copy(r, s))
1094 		goto err;
1095 
1096 	EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
1097 
1098 	if (!EC_POINT_dbl(group, s, s, ctx))
1099 		goto err;
1100 
1101 	pbit = 0;
1102 
1103 	/*
1104 	 * The ladder step, with branches, is
1105 	 *
1106 	 * k[i] == 0: S = add(R, S), R = dbl(R)
1107 	 * k[i] == 1: R = add(S, R), S = dbl(S)
1108 	 *
1109 	 * Swapping R, S conditionally on k[i] leaves you with state
1110 	 *
1111 	 * k[i] == 0: T, U = R, S
1112 	 * k[i] == 1: T, U = S, R
1113 	 *
1114 	 * Then perform the ECC ops.
1115 	 *
1116 	 * U = add(T, U)
1117 	 * T = dbl(T)
1118 	 *
1119 	 * Which leaves you with state
1120 	 *
1121 	 * k[i] == 0: U = add(R, S), T = dbl(R)
1122 	 * k[i] == 1: U = add(S, R), T = dbl(S)
1123 	 *
1124 	 * Swapping T, U conditionally on k[i] leaves you with state
1125 	 *
1126 	 * k[i] == 0: R, S = T, U
1127 	 * k[i] == 1: R, S = U, T
1128 	 *
1129 	 * Which leaves you with state
1130 	 *
1131 	 * k[i] == 0: S = add(R, S), R = dbl(R)
1132 	 * k[i] == 1: R = add(S, R), S = dbl(S)
1133 	 *
1134 	 * So we get the same logic, but instead of a branch it's a
1135 	 * conditional swap, followed by ECC ops, then another conditional swap.
1136 	 *
1137 	 * Optimization: The end of iteration i and start of i-1 looks like
1138 	 *
1139 	 * ...
1140 	 * CSWAP(k[i], R, S)
1141 	 * ECC
1142 	 * CSWAP(k[i], R, S)
1143 	 * (next iteration)
1144 	 * CSWAP(k[i-1], R, S)
1145 	 * ECC
1146 	 * CSWAP(k[i-1], R, S)
1147 	 * ...
1148 	 *
1149 	 * So instead of two contiguous swaps, you can merge the condition
1150 	 * bits and do a single swap.
1151 	 *
1152 	 * k[i]   k[i-1]    Outcome
1153 	 * 0      0         No Swap
1154 	 * 0      1         Swap
1155 	 * 1      0         Swap
1156 	 * 1      1         No Swap
1157 	 *
1158 	 * This is XOR. pbit tracks the previous bit of k.
1159 	 */
1160 
1161 	for (i = cardinality_bits - 1; i >= 0; i--) {
1162 		kbit = BN_is_bit_set(k, i) ^ pbit;
1163 		EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
1164 		if (!EC_POINT_add(group, s, r, s, ctx))
1165 			goto err;
1166 		if (!EC_POINT_dbl(group, r, r, ctx))
1167 			goto err;
1168 		/*
1169 		 * pbit logic merges this cswap with that of the
1170 		 * next iteration
1171 		 */
1172 		pbit ^= kbit;
1173 	}
1174 	/* one final cswap to move the right value into r */
1175 	EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
1176 
1177 	ret = 1;
1178 
1179  err:
1180 	EC_POINT_free(s);
1181 	BN_CTX_end(ctx);
1182 
1183 	return ret;
1184 }
1185 
1186 #undef EC_POINT_BN_set_flags
1187 #undef EC_POINT_CSWAP
1188 
1189 static int
1190 ec_mul_single_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1191     const EC_POINT *point, BN_CTX *ctx)
1192 {
1193 	return ec_mul_ct(group, r, scalar, point, ctx);
1194 }
1195 
1196 static int
1197 ec_mul_double_nonct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1198     const BIGNUM *p_scalar, const EC_POINT *point, BN_CTX *ctx)
1199 {
1200 	return ec_wnaf_mul(group, r, g_scalar, point, p_scalar, ctx);
1201 }
1202 
1203 static int
1204 ec_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1205     const BIGNUM *b, BN_CTX *ctx)
1206 {
1207 	return BN_mod_mul(r, a, b, group->p, ctx);
1208 }
1209 
1210 static int
1211 ec_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
1212 {
1213 	return BN_mod_sqr(r, a, group->p, ctx);
1214 }
1215 
1216 static int
1217 ec_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
1218     const BIGNUM *b, BN_CTX *ctx)
1219 {
1220 	BN_MONT_CTX *mont = NULL;
1221 	int ret = 0;
1222 
1223 	BN_MONT_CTX_free(group->mont_ctx);
1224 	group->mont_ctx = NULL;
1225 
1226 	if ((mont = BN_MONT_CTX_new()) == NULL)
1227 		goto err;
1228 	if (!BN_MONT_CTX_set(mont, p, ctx)) {
1229 		ECerror(ERR_R_BN_LIB);
1230 		goto err;
1231 	}
1232 	group->mont_ctx = mont;
1233 	mont = NULL;
1234 
1235 	if (!ec_group_set_curve(group, p, a, b, ctx)) {
1236 		BN_MONT_CTX_free(group->mont_ctx);
1237 		group->mont_ctx = NULL;
1238 		goto err;
1239 	}
1240 
1241 	ret = 1;
1242 
1243  err:
1244 	BN_MONT_CTX_free(mont);
1245 
1246 	return ret;
1247 }
1248 
1249 static int
1250 ec_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1251     const BIGNUM *b, BN_CTX *ctx)
1252 {
1253 	if (group->mont_ctx == NULL) {
1254 		ECerror(EC_R_NOT_INITIALIZED);
1255 		return 0;
1256 	}
1257 	return BN_mod_mul_montgomery(r, a, b, group->mont_ctx, ctx);
1258 }
1259 
1260 static int
1261 ec_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1262     BN_CTX *ctx)
1263 {
1264 	if (group->mont_ctx == NULL) {
1265 		ECerror(EC_R_NOT_INITIALIZED);
1266 		return 0;
1267 	}
1268 	return BN_mod_mul_montgomery(r, a, a, group->mont_ctx, ctx);
1269 }
1270 
1271 static int
1272 ec_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1273     BN_CTX *ctx)
1274 {
1275 	if (group->mont_ctx == NULL) {
1276 		ECerror(EC_R_NOT_INITIALIZED);
1277 		return 0;
1278 	}
1279 	return BN_to_montgomery(r, a, group->mont_ctx, ctx);
1280 }
1281 
1282 static int
1283 ec_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1284     BN_CTX *ctx)
1285 {
1286 	if (group->mont_ctx == NULL) {
1287 		ECerror(EC_R_NOT_INITIALIZED);
1288 		return 0;
1289 	}
1290 	return BN_from_montgomery(r, a, group->mont_ctx, ctx);
1291 }
1292 
1293 static const EC_METHOD ec_GFp_simple_method = {
1294 	.group_set_curve = ec_group_set_curve,
1295 	.group_get_curve = ec_group_get_curve,
1296 	.point_is_on_curve = ec_point_is_on_curve,
1297 	.point_cmp = ec_point_cmp,
1298 	.point_set_affine_coordinates = ec_point_set_affine_coordinates,
1299 	.point_get_affine_coordinates = ec_point_get_affine_coordinates,
1300 	.points_make_affine = ec_points_make_affine,
1301 	.add = ec_add,
1302 	.dbl = ec_dbl,
1303 	.invert = ec_invert,
1304 	.mul_single_ct = ec_mul_single_ct,
1305 	.mul_double_nonct = ec_mul_double_nonct,
1306 	.field_mul = ec_simple_field_mul,
1307 	.field_sqr = ec_simple_field_sqr,
1308 };
1309 
1310 const EC_METHOD *
1311 EC_GFp_simple_method(void)
1312 {
1313 	return &ec_GFp_simple_method;
1314 }
1315 LCRYPTO_ALIAS(EC_GFp_simple_method);
1316 
1317 static const EC_METHOD ec_GFp_mont_method = {
1318 	.group_set_curve = ec_mont_group_set_curve,
1319 	.group_get_curve = ec_group_get_curve,
1320 	.point_is_on_curve = ec_point_is_on_curve,
1321 	.point_cmp = ec_point_cmp,
1322 	.point_set_affine_coordinates = ec_point_set_affine_coordinates,
1323 	.point_get_affine_coordinates = ec_point_get_affine_coordinates,
1324 	.points_make_affine = ec_points_make_affine,
1325 	.add = ec_add,
1326 	.dbl = ec_dbl,
1327 	.invert = ec_invert,
1328 	.mul_single_ct = ec_mul_single_ct,
1329 	.mul_double_nonct = ec_mul_double_nonct,
1330 	.field_mul = ec_mont_field_mul,
1331 	.field_sqr = ec_mont_field_sqr,
1332 	.field_encode = ec_mont_field_encode,
1333 	.field_decode = ec_mont_field_decode,
1334 };
1335 
1336 const EC_METHOD *
1337 EC_GFp_mont_method(void)
1338 {
1339 	return &ec_GFp_mont_method;
1340 }
1341 LCRYPTO_ALIAS(EC_GFp_mont_method);
1342