xref: /dragonfly/crypto/libressl/crypto/ec/ecp_smpl.c (revision de0e0e4d)
1 /* $OpenBSD: ecp_smpl.c,v 1.34 2022/01/20 11:02:44 inoguchi 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 <openssl/err.h>
66 
67 #include "bn_lcl.h"
68 #include "ec_lcl.h"
69 
70 const EC_METHOD *
EC_GFp_simple_method(void)71 EC_GFp_simple_method(void)
72 {
73 	static const EC_METHOD ret = {
74 		.flags = EC_FLAGS_DEFAULT_OCT,
75 		.field_type = NID_X9_62_prime_field,
76 		.group_init = ec_GFp_simple_group_init,
77 		.group_finish = ec_GFp_simple_group_finish,
78 		.group_clear_finish = ec_GFp_simple_group_clear_finish,
79 		.group_copy = ec_GFp_simple_group_copy,
80 		.group_set_curve = ec_GFp_simple_group_set_curve,
81 		.group_get_curve = ec_GFp_simple_group_get_curve,
82 		.group_get_degree = ec_GFp_simple_group_get_degree,
83 		.group_order_bits = ec_group_simple_order_bits,
84 		.group_check_discriminant =
85 		    ec_GFp_simple_group_check_discriminant,
86 		.point_init = ec_GFp_simple_point_init,
87 		.point_finish = ec_GFp_simple_point_finish,
88 		.point_clear_finish = ec_GFp_simple_point_clear_finish,
89 		.point_copy = ec_GFp_simple_point_copy,
90 		.point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
91 		.point_set_Jprojective_coordinates =
92 		    ec_GFp_simple_set_Jprojective_coordinates,
93 		.point_get_Jprojective_coordinates =
94 		    ec_GFp_simple_get_Jprojective_coordinates,
95 		.point_set_affine_coordinates =
96 		    ec_GFp_simple_point_set_affine_coordinates,
97 		.point_get_affine_coordinates =
98 		    ec_GFp_simple_point_get_affine_coordinates,
99 		.add = ec_GFp_simple_add,
100 		.dbl = ec_GFp_simple_dbl,
101 		.invert = ec_GFp_simple_invert,
102 		.is_at_infinity = ec_GFp_simple_is_at_infinity,
103 		.is_on_curve = ec_GFp_simple_is_on_curve,
104 		.point_cmp = ec_GFp_simple_cmp,
105 		.make_affine = ec_GFp_simple_make_affine,
106 		.points_make_affine = ec_GFp_simple_points_make_affine,
107 		.mul_generator_ct = ec_GFp_simple_mul_generator_ct,
108 		.mul_single_ct = ec_GFp_simple_mul_single_ct,
109 		.mul_double_nonct = ec_GFp_simple_mul_double_nonct,
110 		.field_mul = ec_GFp_simple_field_mul,
111 		.field_sqr = ec_GFp_simple_field_sqr,
112 		.blind_coordinates = ec_GFp_simple_blind_coordinates,
113 	};
114 
115 	return &ret;
116 }
117 
118 
119 /* Most method functions in this file are designed to work with
120  * non-trivial representations of field elements if necessary
121  * (see ecp_mont.c): while standard modular addition and subtraction
122  * are used, the field_mul and field_sqr methods will be used for
123  * multiplication, and field_encode and field_decode (if defined)
124  * will be used for converting between representations.
125 
126  * Functions ec_GFp_simple_points_make_affine() and
127  * ec_GFp_simple_point_get_affine_coordinates() specifically assume
128  * that if a non-trivial representation is used, it is a Montgomery
129  * representation (i.e. 'encoding' means multiplying by some factor R).
130  */
131 
132 
133 int
ec_GFp_simple_group_init(EC_GROUP * group)134 ec_GFp_simple_group_init(EC_GROUP * group)
135 {
136 	BN_init(&group->field);
137 	BN_init(&group->a);
138 	BN_init(&group->b);
139 	group->a_is_minus3 = 0;
140 	return 1;
141 }
142 
143 
144 void
ec_GFp_simple_group_finish(EC_GROUP * group)145 ec_GFp_simple_group_finish(EC_GROUP * group)
146 {
147 	BN_free(&group->field);
148 	BN_free(&group->a);
149 	BN_free(&group->b);
150 }
151 
152 
153 void
ec_GFp_simple_group_clear_finish(EC_GROUP * group)154 ec_GFp_simple_group_clear_finish(EC_GROUP * group)
155 {
156 	BN_clear_free(&group->field);
157 	BN_clear_free(&group->a);
158 	BN_clear_free(&group->b);
159 }
160 
161 
162 int
ec_GFp_simple_group_copy(EC_GROUP * dest,const EC_GROUP * src)163 ec_GFp_simple_group_copy(EC_GROUP * dest, const EC_GROUP * src)
164 {
165 	if (!BN_copy(&dest->field, &src->field))
166 		return 0;
167 	if (!BN_copy(&dest->a, &src->a))
168 		return 0;
169 	if (!BN_copy(&dest->b, &src->b))
170 		return 0;
171 
172 	dest->a_is_minus3 = src->a_is_minus3;
173 
174 	return 1;
175 }
176 
177 
178 int
ec_GFp_simple_group_set_curve(EC_GROUP * group,const BIGNUM * p,const BIGNUM * a,const BIGNUM * b,BN_CTX * ctx)179 ec_GFp_simple_group_set_curve(EC_GROUP * group,
180     const BIGNUM * p, const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
181 {
182 	int ret = 0;
183 	BN_CTX *new_ctx = NULL;
184 	BIGNUM *tmp_a;
185 
186 	/* p must be a prime > 3 */
187 	if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
188 		ECerror(EC_R_INVALID_FIELD);
189 		return 0;
190 	}
191 	if (ctx == NULL) {
192 		ctx = new_ctx = BN_CTX_new();
193 		if (ctx == NULL)
194 			return 0;
195 	}
196 	BN_CTX_start(ctx);
197 	if ((tmp_a = BN_CTX_get(ctx)) == NULL)
198 		goto err;
199 
200 	/* group->field */
201 	if (!BN_copy(&group->field, p))
202 		goto err;
203 	BN_set_negative(&group->field, 0);
204 
205 	/* group->a */
206 	if (!BN_nnmod(tmp_a, a, p, ctx))
207 		goto err;
208 	if (group->meth->field_encode) {
209 		if (!group->meth->field_encode(group, &group->a, tmp_a, ctx))
210 			goto err;
211 	} else if (!BN_copy(&group->a, tmp_a))
212 		goto err;
213 
214 	/* group->b */
215 	if (!BN_nnmod(&group->b, b, p, ctx))
216 		goto err;
217 	if (group->meth->field_encode)
218 		if (!group->meth->field_encode(group, &group->b, &group->b, ctx))
219 			goto err;
220 
221 	/* group->a_is_minus3 */
222 	if (!BN_add_word(tmp_a, 3))
223 		goto err;
224 	group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
225 
226 	ret = 1;
227 
228  err:
229 	BN_CTX_end(ctx);
230 	BN_CTX_free(new_ctx);
231 	return ret;
232 }
233 
234 
235 int
ec_GFp_simple_group_get_curve(const EC_GROUP * group,BIGNUM * p,BIGNUM * a,BIGNUM * b,BN_CTX * ctx)236 ec_GFp_simple_group_get_curve(const EC_GROUP * group, BIGNUM * p, BIGNUM * a, BIGNUM * b, BN_CTX * ctx)
237 {
238 	int ret = 0;
239 	BN_CTX *new_ctx = NULL;
240 
241 	if (p != NULL) {
242 		if (!BN_copy(p, &group->field))
243 			return 0;
244 	}
245 	if (a != NULL || b != NULL) {
246 		if (group->meth->field_decode) {
247 			if (ctx == NULL) {
248 				ctx = new_ctx = BN_CTX_new();
249 				if (ctx == NULL)
250 					return 0;
251 			}
252 			if (a != NULL) {
253 				if (!group->meth->field_decode(group, a, &group->a, ctx))
254 					goto err;
255 			}
256 			if (b != NULL) {
257 				if (!group->meth->field_decode(group, b, &group->b, ctx))
258 					goto err;
259 			}
260 		} else {
261 			if (a != NULL) {
262 				if (!BN_copy(a, &group->a))
263 					goto err;
264 			}
265 			if (b != NULL) {
266 				if (!BN_copy(b, &group->b))
267 					goto err;
268 			}
269 		}
270 	}
271 	ret = 1;
272 
273  err:
274 	BN_CTX_free(new_ctx);
275 	return ret;
276 }
277 
278 
279 int
ec_GFp_simple_group_get_degree(const EC_GROUP * group)280 ec_GFp_simple_group_get_degree(const EC_GROUP * group)
281 {
282 	return BN_num_bits(&group->field);
283 }
284 
285 
286 int
ec_GFp_simple_group_check_discriminant(const EC_GROUP * group,BN_CTX * ctx)287 ec_GFp_simple_group_check_discriminant(const EC_GROUP * group, BN_CTX * ctx)
288 {
289 	int ret = 0;
290 	BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
291 	const BIGNUM *p = &group->field;
292 	BN_CTX *new_ctx = NULL;
293 
294 	if (ctx == NULL) {
295 		ctx = new_ctx = BN_CTX_new();
296 		if (ctx == NULL) {
297 			ECerror(ERR_R_MALLOC_FAILURE);
298 			goto err;
299 		}
300 	}
301 	BN_CTX_start(ctx);
302 	if ((a = BN_CTX_get(ctx)) == NULL)
303 		goto err;
304 	if ((b = BN_CTX_get(ctx)) == NULL)
305 		goto err;
306 	if ((tmp_1 = BN_CTX_get(ctx)) == NULL)
307 		goto err;
308 	if ((tmp_2 = BN_CTX_get(ctx)) == NULL)
309 		goto err;
310 	if ((order = BN_CTX_get(ctx)) == NULL)
311 		goto err;
312 
313 	if (group->meth->field_decode) {
314 		if (!group->meth->field_decode(group, a, &group->a, ctx))
315 			goto err;
316 		if (!group->meth->field_decode(group, b, &group->b, ctx))
317 			goto err;
318 	} else {
319 		if (!BN_copy(a, &group->a))
320 			goto err;
321 		if (!BN_copy(b, &group->b))
322 			goto err;
323 	}
324 
325 	/*
326 	 * check the discriminant: y^2 = x^3 + a*x + b is an elliptic curve
327 	 * <=> 4*a^3 + 27*b^2 != 0 (mod p) 0 =< a, b < p
328 	 */
329 	if (BN_is_zero(a)) {
330 		if (BN_is_zero(b))
331 			goto err;
332 	} else if (!BN_is_zero(b)) {
333 		if (!BN_mod_sqr(tmp_1, a, p, ctx))
334 			goto err;
335 		if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
336 			goto err;
337 		if (!BN_lshift(tmp_1, tmp_2, 2))
338 			goto err;
339 		/* tmp_1 = 4*a^3 */
340 
341 		if (!BN_mod_sqr(tmp_2, b, p, ctx))
342 			goto err;
343 		if (!BN_mul_word(tmp_2, 27))
344 			goto err;
345 		/* tmp_2 = 27*b^2 */
346 
347 		if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
348 			goto err;
349 		if (BN_is_zero(a))
350 			goto err;
351 	}
352 	ret = 1;
353 
354  err:
355 	if (ctx != NULL)
356 		BN_CTX_end(ctx);
357 	BN_CTX_free(new_ctx);
358 	return ret;
359 }
360 
361 
362 int
ec_GFp_simple_point_init(EC_POINT * point)363 ec_GFp_simple_point_init(EC_POINT * point)
364 {
365 	BN_init(&point->X);
366 	BN_init(&point->Y);
367 	BN_init(&point->Z);
368 	point->Z_is_one = 0;
369 
370 	return 1;
371 }
372 
373 
374 void
ec_GFp_simple_point_finish(EC_POINT * point)375 ec_GFp_simple_point_finish(EC_POINT * point)
376 {
377 	BN_free(&point->X);
378 	BN_free(&point->Y);
379 	BN_free(&point->Z);
380 }
381 
382 
383 void
ec_GFp_simple_point_clear_finish(EC_POINT * point)384 ec_GFp_simple_point_clear_finish(EC_POINT * point)
385 {
386 	BN_clear_free(&point->X);
387 	BN_clear_free(&point->Y);
388 	BN_clear_free(&point->Z);
389 	point->Z_is_one = 0;
390 }
391 
392 
393 int
ec_GFp_simple_point_copy(EC_POINT * dest,const EC_POINT * src)394 ec_GFp_simple_point_copy(EC_POINT * dest, const EC_POINT * src)
395 {
396 	if (!BN_copy(&dest->X, &src->X))
397 		return 0;
398 	if (!BN_copy(&dest->Y, &src->Y))
399 		return 0;
400 	if (!BN_copy(&dest->Z, &src->Z))
401 		return 0;
402 	dest->Z_is_one = src->Z_is_one;
403 
404 	return 1;
405 }
406 
407 
408 int
ec_GFp_simple_point_set_to_infinity(const EC_GROUP * group,EC_POINT * point)409 ec_GFp_simple_point_set_to_infinity(const EC_GROUP * group, EC_POINT * point)
410 {
411 	point->Z_is_one = 0;
412 	BN_zero(&point->Z);
413 	return 1;
414 }
415 
416 
417 int
ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP * group,EC_POINT * point,const BIGNUM * x,const BIGNUM * y,const BIGNUM * z,BN_CTX * ctx)418 ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group,
419     EC_POINT *point, const BIGNUM *x, const BIGNUM *y, const BIGNUM *z,
420     BN_CTX *ctx)
421 {
422 	BN_CTX *new_ctx = NULL;
423 	int ret = 0;
424 
425 	if (ctx == NULL) {
426 		ctx = new_ctx = BN_CTX_new();
427 		if (ctx == NULL)
428 			return 0;
429 	}
430 	if (x != NULL) {
431 		if (!BN_nnmod(&point->X, x, &group->field, ctx))
432 			goto err;
433 		if (group->meth->field_encode) {
434 			if (!group->meth->field_encode(group, &point->X, &point->X, ctx))
435 				goto err;
436 		}
437 	}
438 	if (y != NULL) {
439 		if (!BN_nnmod(&point->Y, y, &group->field, ctx))
440 			goto err;
441 		if (group->meth->field_encode) {
442 			if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx))
443 				goto err;
444 		}
445 	}
446 	if (z != NULL) {
447 		int Z_is_one;
448 
449 		if (!BN_nnmod(&point->Z, z, &group->field, ctx))
450 			goto err;
451 		Z_is_one = BN_is_one(&point->Z);
452 		if (group->meth->field_encode) {
453 			if (Z_is_one && (group->meth->field_set_to_one != 0)) {
454 				if (!group->meth->field_set_to_one(group, &point->Z, ctx))
455 					goto err;
456 			} else {
457 				if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx))
458 					goto err;
459 			}
460 		}
461 		point->Z_is_one = Z_is_one;
462 	}
463 	ret = 1;
464 
465  err:
466 	BN_CTX_free(new_ctx);
467 	return ret;
468 }
469 
470 int
ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP * group,const EC_POINT * point,BIGNUM * x,BIGNUM * y,BIGNUM * z,BN_CTX * ctx)471 ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP *group,
472     const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
473 {
474 	BN_CTX *new_ctx = NULL;
475 	int ret = 0;
476 
477 	if (group->meth->field_decode != 0) {
478 		if (ctx == NULL) {
479 			ctx = new_ctx = BN_CTX_new();
480 			if (ctx == NULL)
481 				return 0;
482 		}
483 		if (x != NULL) {
484 			if (!group->meth->field_decode(group, x, &point->X, ctx))
485 				goto err;
486 		}
487 		if (y != NULL) {
488 			if (!group->meth->field_decode(group, y, &point->Y, ctx))
489 				goto err;
490 		}
491 		if (z != NULL) {
492 			if (!group->meth->field_decode(group, z, &point->Z, ctx))
493 				goto err;
494 		}
495 	} else {
496 		if (x != NULL) {
497 			if (!BN_copy(x, &point->X))
498 				goto err;
499 		}
500 		if (y != NULL) {
501 			if (!BN_copy(y, &point->Y))
502 				goto err;
503 		}
504 		if (z != NULL) {
505 			if (!BN_copy(z, &point->Z))
506 				goto err;
507 		}
508 	}
509 
510 	ret = 1;
511 
512  err:
513 	BN_CTX_free(new_ctx);
514 	return ret;
515 }
516 
517 int
ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP * group,EC_POINT * point,const BIGNUM * x,const BIGNUM * y,BN_CTX * ctx)518 ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP * group, EC_POINT * point,
519     const BIGNUM * x, const BIGNUM * y, BN_CTX * ctx)
520 {
521 	if (x == NULL || y == NULL) {
522 		/* unlike for projective coordinates, we do not tolerate this */
523 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
524 		return 0;
525 	}
526 	return EC_POINT_set_Jprojective_coordinates(group, point, x, y,
527 	    BN_value_one(), ctx);
528 }
529 
530 int
ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP * group,const EC_POINT * point,BIGNUM * x,BIGNUM * y,BN_CTX * ctx)531 ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP * group, const EC_POINT * point,
532     BIGNUM * x, BIGNUM * y, BN_CTX * ctx)
533 {
534 	BN_CTX *new_ctx = NULL;
535 	BIGNUM *Z, *Z_1, *Z_2, *Z_3;
536 	const BIGNUM *Z_;
537 	int ret = 0;
538 
539 	if (EC_POINT_is_at_infinity(group, point) > 0) {
540 		ECerror(EC_R_POINT_AT_INFINITY);
541 		return 0;
542 	}
543 	if (ctx == NULL) {
544 		ctx = new_ctx = BN_CTX_new();
545 		if (ctx == NULL)
546 			return 0;
547 	}
548 	BN_CTX_start(ctx);
549 	if ((Z = BN_CTX_get(ctx)) == NULL)
550 		goto err;
551 	if ((Z_1 = BN_CTX_get(ctx)) == NULL)
552 		goto err;
553 	if ((Z_2 = BN_CTX_get(ctx)) == NULL)
554 		goto err;
555 	if ((Z_3 = BN_CTX_get(ctx)) == NULL)
556 		goto err;
557 
558 	/* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */
559 
560 	if (group->meth->field_decode) {
561 		if (!group->meth->field_decode(group, Z, &point->Z, ctx))
562 			goto err;
563 		Z_ = Z;
564 	} else {
565 		Z_ = &point->Z;
566 	}
567 
568 	if (BN_is_one(Z_)) {
569 		if (group->meth->field_decode) {
570 			if (x != NULL) {
571 				if (!group->meth->field_decode(group, x, &point->X, ctx))
572 					goto err;
573 			}
574 			if (y != NULL) {
575 				if (!group->meth->field_decode(group, y, &point->Y, ctx))
576 					goto err;
577 			}
578 		} else {
579 			if (x != NULL) {
580 				if (!BN_copy(x, &point->X))
581 					goto err;
582 			}
583 			if (y != NULL) {
584 				if (!BN_copy(y, &point->Y))
585 					goto err;
586 			}
587 		}
588 	} else {
589 		if (BN_mod_inverse_ct(Z_1, Z_, &group->field, ctx) == NULL) {
590 			ECerror(ERR_R_BN_LIB);
591 			goto err;
592 		}
593 		if (group->meth->field_encode == 0) {
594 			/* field_sqr works on standard representation */
595 			if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
596 				goto err;
597 		} else {
598 			if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx))
599 				goto err;
600 		}
601 
602 		if (x != NULL) {
603 			/*
604 			 * in the Montgomery case, field_mul will cancel out
605 			 * Montgomery factor in X:
606 			 */
607 			if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx))
608 				goto err;
609 		}
610 		if (y != NULL) {
611 			if (group->meth->field_encode == 0) {
612 				/* field_mul works on standard representation */
613 				if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
614 					goto err;
615 			} else {
616 				if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx))
617 					goto err;
618 			}
619 
620 			/*
621 			 * in the Montgomery case, field_mul will cancel out
622 			 * Montgomery factor in Y:
623 			 */
624 			if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx))
625 				goto err;
626 		}
627 	}
628 
629 	ret = 1;
630 
631  err:
632 	BN_CTX_end(ctx);
633 	BN_CTX_free(new_ctx);
634 	return ret;
635 }
636 
637 int
ec_GFp_simple_add(const EC_GROUP * group,EC_POINT * r,const EC_POINT * a,const EC_POINT * b,BN_CTX * ctx)638 ec_GFp_simple_add(const EC_GROUP * group, EC_POINT * r, const EC_POINT * a, const EC_POINT * b, BN_CTX * ctx)
639 {
640 	int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
641 	int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
642 	const BIGNUM *p;
643 	BN_CTX *new_ctx = NULL;
644 	BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
645 	int ret = 0;
646 
647 	if (a == b)
648 		return EC_POINT_dbl(group, r, a, ctx);
649 	if (EC_POINT_is_at_infinity(group, a) > 0)
650 		return EC_POINT_copy(r, b);
651 	if (EC_POINT_is_at_infinity(group, b) > 0)
652 		return EC_POINT_copy(r, a);
653 
654 	field_mul = group->meth->field_mul;
655 	field_sqr = group->meth->field_sqr;
656 	p = &group->field;
657 
658 	if (ctx == NULL) {
659 		ctx = new_ctx = BN_CTX_new();
660 		if (ctx == NULL)
661 			return 0;
662 	}
663 	BN_CTX_start(ctx);
664 	if ((n0 = BN_CTX_get(ctx)) == NULL)
665 		goto end;
666 	if ((n1 = BN_CTX_get(ctx)) == NULL)
667 		goto end;
668 	if ((n2 = BN_CTX_get(ctx)) == NULL)
669 		goto end;
670 	if ((n3 = BN_CTX_get(ctx)) == NULL)
671 		goto end;
672 	if ((n4 = BN_CTX_get(ctx)) == NULL)
673 		goto end;
674 	if ((n5 = BN_CTX_get(ctx)) == NULL)
675 		goto end;
676 	if ((n6 = BN_CTX_get(ctx)) == NULL)
677 		goto end;
678 
679 	/*
680 	 * Note that in this function we must not read components of 'a' or
681 	 * 'b' once we have written the corresponding components of 'r'. ('r'
682 	 * might be one of 'a' or 'b'.)
683 	 */
684 
685 	/* n1, n2 */
686 	if (b->Z_is_one) {
687 		if (!BN_copy(n1, &a->X))
688 			goto end;
689 		if (!BN_copy(n2, &a->Y))
690 			goto end;
691 		/* n1 = X_a */
692 		/* n2 = Y_a */
693 	} else {
694 		if (!field_sqr(group, n0, &b->Z, ctx))
695 			goto end;
696 		if (!field_mul(group, n1, &a->X, n0, ctx))
697 			goto end;
698 		/* n1 = X_a * Z_b^2 */
699 
700 		if (!field_mul(group, n0, n0, &b->Z, ctx))
701 			goto end;
702 		if (!field_mul(group, n2, &a->Y, n0, ctx))
703 			goto end;
704 		/* n2 = Y_a * Z_b^3 */
705 	}
706 
707 	/* n3, n4 */
708 	if (a->Z_is_one) {
709 		if (!BN_copy(n3, &b->X))
710 			goto end;
711 		if (!BN_copy(n4, &b->Y))
712 			goto end;
713 		/* n3 = X_b */
714 		/* n4 = Y_b */
715 	} else {
716 		if (!field_sqr(group, n0, &a->Z, ctx))
717 			goto end;
718 		if (!field_mul(group, n3, &b->X, n0, ctx))
719 			goto end;
720 		/* n3 = X_b * Z_a^2 */
721 
722 		if (!field_mul(group, n0, n0, &a->Z, ctx))
723 			goto end;
724 		if (!field_mul(group, n4, &b->Y, n0, ctx))
725 			goto end;
726 		/* n4 = Y_b * Z_a^3 */
727 	}
728 
729 	/* n5, n6 */
730 	if (!BN_mod_sub_quick(n5, n1, n3, p))
731 		goto end;
732 	if (!BN_mod_sub_quick(n6, n2, n4, p))
733 		goto end;
734 	/* n5 = n1 - n3 */
735 	/* n6 = n2 - n4 */
736 
737 	if (BN_is_zero(n5)) {
738 		if (BN_is_zero(n6)) {
739 			/* a is the same point as b */
740 			BN_CTX_end(ctx);
741 			ret = EC_POINT_dbl(group, r, a, ctx);
742 			ctx = NULL;
743 			goto end;
744 		} else {
745 			/* a is the inverse of b */
746 			BN_zero(&r->Z);
747 			r->Z_is_one = 0;
748 			ret = 1;
749 			goto end;
750 		}
751 	}
752 	/* 'n7', 'n8' */
753 	if (!BN_mod_add_quick(n1, n1, n3, p))
754 		goto end;
755 	if (!BN_mod_add_quick(n2, n2, n4, p))
756 		goto end;
757 	/* 'n7' = n1 + n3 */
758 	/* 'n8' = n2 + n4 */
759 
760 	/* Z_r */
761 	if (a->Z_is_one && b->Z_is_one) {
762 		if (!BN_copy(&r->Z, n5))
763 			goto end;
764 	} else {
765 		if (a->Z_is_one) {
766 			if (!BN_copy(n0, &b->Z))
767 				goto end;
768 		} else if (b->Z_is_one) {
769 			if (!BN_copy(n0, &a->Z))
770 				goto end;
771 		} else {
772 			if (!field_mul(group, n0, &a->Z, &b->Z, ctx))
773 				goto end;
774 		}
775 		if (!field_mul(group, &r->Z, n0, n5, ctx))
776 			goto end;
777 	}
778 	r->Z_is_one = 0;
779 	/* Z_r = Z_a * Z_b * n5 */
780 
781 	/* X_r */
782 	if (!field_sqr(group, n0, n6, ctx))
783 		goto end;
784 	if (!field_sqr(group, n4, n5, ctx))
785 		goto end;
786 	if (!field_mul(group, n3, n1, n4, ctx))
787 		goto end;
788 	if (!BN_mod_sub_quick(&r->X, n0, n3, p))
789 		goto end;
790 	/* X_r = n6^2 - n5^2 * 'n7' */
791 
792 	/* 'n9' */
793 	if (!BN_mod_lshift1_quick(n0, &r->X, p))
794 		goto end;
795 	if (!BN_mod_sub_quick(n0, n3, n0, p))
796 		goto end;
797 	/* n9 = n5^2 * 'n7' - 2 * X_r */
798 
799 	/* Y_r */
800 	if (!field_mul(group, n0, n0, n6, ctx))
801 		goto end;
802 	if (!field_mul(group, n5, n4, n5, ctx))
803 		goto end;	/* now n5 is n5^3 */
804 	if (!field_mul(group, n1, n2, n5, ctx))
805 		goto end;
806 	if (!BN_mod_sub_quick(n0, n0, n1, p))
807 		goto end;
808 	if (BN_is_odd(n0))
809 		if (!BN_add(n0, n0, p))
810 			goto end;
811 	/* now  0 <= n0 < 2*p,  and n0 is even */
812 	if (!BN_rshift1(&r->Y, n0))
813 		goto end;
814 	/* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
815 
816 	ret = 1;
817 
818  end:
819 	if (ctx)		/* otherwise we already called BN_CTX_end */
820 		BN_CTX_end(ctx);
821 	BN_CTX_free(new_ctx);
822 	return ret;
823 }
824 
825 
826 int
ec_GFp_simple_dbl(const EC_GROUP * group,EC_POINT * r,const EC_POINT * a,BN_CTX * ctx)827 ec_GFp_simple_dbl(const EC_GROUP * group, EC_POINT * r, const EC_POINT * a, BN_CTX * ctx)
828 {
829 	int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
830 	int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
831 	const BIGNUM *p;
832 	BN_CTX *new_ctx = NULL;
833 	BIGNUM *n0, *n1, *n2, *n3;
834 	int ret = 0;
835 
836 	if (EC_POINT_is_at_infinity(group, a) > 0) {
837 		BN_zero(&r->Z);
838 		r->Z_is_one = 0;
839 		return 1;
840 	}
841 	field_mul = group->meth->field_mul;
842 	field_sqr = group->meth->field_sqr;
843 	p = &group->field;
844 
845 	if (ctx == NULL) {
846 		ctx = new_ctx = BN_CTX_new();
847 		if (ctx == NULL)
848 			return 0;
849 	}
850 	BN_CTX_start(ctx);
851 	if ((n0 = BN_CTX_get(ctx)) == NULL)
852 		goto err;
853 	if ((n1 = BN_CTX_get(ctx)) == NULL)
854 		goto err;
855 	if ((n2 = BN_CTX_get(ctx)) == NULL)
856 		goto err;
857 	if ((n3 = BN_CTX_get(ctx)) == NULL)
858 		goto err;
859 
860 	/*
861 	 * Note that in this function we must not read components of 'a' once
862 	 * we have written the corresponding components of 'r'. ('r' might
863 	 * the same as 'a'.)
864 	 */
865 
866 	/* n1 */
867 	if (a->Z_is_one) {
868 		if (!field_sqr(group, n0, &a->X, ctx))
869 			goto err;
870 		if (!BN_mod_lshift1_quick(n1, n0, p))
871 			goto err;
872 		if (!BN_mod_add_quick(n0, n0, n1, p))
873 			goto err;
874 		if (!BN_mod_add_quick(n1, n0, &group->a, p))
875 			goto err;
876 		/* n1 = 3 * X_a^2 + a_curve */
877 	} else if (group->a_is_minus3) {
878 		if (!field_sqr(group, n1, &a->Z, ctx))
879 			goto err;
880 		if (!BN_mod_add_quick(n0, &a->X, n1, p))
881 			goto err;
882 		if (!BN_mod_sub_quick(n2, &a->X, n1, p))
883 			goto err;
884 		if (!field_mul(group, n1, n0, n2, ctx))
885 			goto err;
886 		if (!BN_mod_lshift1_quick(n0, n1, p))
887 			goto err;
888 		if (!BN_mod_add_quick(n1, n0, n1, p))
889 			goto err;
890 		/*
891 		 * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) = 3 * X_a^2 - 3 *
892 		 * Z_a^4
893 		 */
894 	} else {
895 		if (!field_sqr(group, n0, &a->X, ctx))
896 			goto err;
897 		if (!BN_mod_lshift1_quick(n1, n0, p))
898 			goto err;
899 		if (!BN_mod_add_quick(n0, n0, n1, p))
900 			goto err;
901 		if (!field_sqr(group, n1, &a->Z, ctx))
902 			goto err;
903 		if (!field_sqr(group, n1, n1, ctx))
904 			goto err;
905 		if (!field_mul(group, n1, n1, &group->a, ctx))
906 			goto err;
907 		if (!BN_mod_add_quick(n1, n1, n0, p))
908 			goto err;
909 		/* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
910 	}
911 
912 	/* Z_r */
913 	if (a->Z_is_one) {
914 		if (!BN_copy(n0, &a->Y))
915 			goto err;
916 	} else {
917 		if (!field_mul(group, n0, &a->Y, &a->Z, ctx))
918 			goto err;
919 	}
920 	if (!BN_mod_lshift1_quick(&r->Z, n0, p))
921 		goto err;
922 	r->Z_is_one = 0;
923 	/* Z_r = 2 * Y_a * Z_a */
924 
925 	/* n2 */
926 	if (!field_sqr(group, n3, &a->Y, ctx))
927 		goto err;
928 	if (!field_mul(group, n2, &a->X, n3, ctx))
929 		goto err;
930 	if (!BN_mod_lshift_quick(n2, n2, 2, p))
931 		goto err;
932 	/* n2 = 4 * X_a * Y_a^2 */
933 
934 	/* X_r */
935 	if (!BN_mod_lshift1_quick(n0, n2, p))
936 		goto err;
937 	if (!field_sqr(group, &r->X, n1, ctx))
938 		goto err;
939 	if (!BN_mod_sub_quick(&r->X, &r->X, n0, p))
940 		goto err;
941 	/* X_r = n1^2 - 2 * n2 */
942 
943 	/* n3 */
944 	if (!field_sqr(group, n0, n3, ctx))
945 		goto err;
946 	if (!BN_mod_lshift_quick(n3, n0, 3, p))
947 		goto err;
948 	/* n3 = 8 * Y_a^4 */
949 
950 	/* Y_r */
951 	if (!BN_mod_sub_quick(n0, n2, &r->X, p))
952 		goto err;
953 	if (!field_mul(group, n0, n1, n0, ctx))
954 		goto err;
955 	if (!BN_mod_sub_quick(&r->Y, n0, n3, p))
956 		goto err;
957 	/* Y_r = n1 * (n2 - X_r) - n3 */
958 
959 	ret = 1;
960 
961  err:
962 	BN_CTX_end(ctx);
963 	BN_CTX_free(new_ctx);
964 	return ret;
965 }
966 
967 
968 int
ec_GFp_simple_invert(const EC_GROUP * group,EC_POINT * point,BN_CTX * ctx)969 ec_GFp_simple_invert(const EC_GROUP * group, EC_POINT * point, BN_CTX * ctx)
970 {
971 	if (EC_POINT_is_at_infinity(group, point) > 0 || BN_is_zero(&point->Y))
972 		/* point is its own inverse */
973 		return 1;
974 
975 	return BN_usub(&point->Y, &group->field, &point->Y);
976 }
977 
978 
979 int
ec_GFp_simple_is_at_infinity(const EC_GROUP * group,const EC_POINT * point)980 ec_GFp_simple_is_at_infinity(const EC_GROUP * group, const EC_POINT * point)
981 {
982 	return BN_is_zero(&point->Z);
983 }
984 
985 
986 int
ec_GFp_simple_is_on_curve(const EC_GROUP * group,const EC_POINT * point,BN_CTX * ctx)987 ec_GFp_simple_is_on_curve(const EC_GROUP * group, const EC_POINT * point, BN_CTX * ctx)
988 {
989 	int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
990 	int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
991 	const BIGNUM *p;
992 	BN_CTX *new_ctx = NULL;
993 	BIGNUM *rh, *tmp, *Z4, *Z6;
994 	int ret = -1;
995 
996 	if (EC_POINT_is_at_infinity(group, point) > 0)
997 		return 1;
998 
999 	field_mul = group->meth->field_mul;
1000 	field_sqr = group->meth->field_sqr;
1001 	p = &group->field;
1002 
1003 	if (ctx == NULL) {
1004 		ctx = new_ctx = BN_CTX_new();
1005 		if (ctx == NULL)
1006 			return -1;
1007 	}
1008 	BN_CTX_start(ctx);
1009 	if ((rh = BN_CTX_get(ctx)) == NULL)
1010 		goto err;
1011 	if ((tmp = BN_CTX_get(ctx)) == NULL)
1012 		goto err;
1013 	if ((Z4 = BN_CTX_get(ctx)) == NULL)
1014 		goto err;
1015 	if ((Z6 = BN_CTX_get(ctx)) == NULL)
1016 		goto err;
1017 
1018 	/*
1019 	 * We have a curve defined by a Weierstrass equation y^2 = x^3 + a*x
1020 	 * + b. The point to consider is given in Jacobian projective
1021 	 * coordinates where  (X, Y, Z)  represents  (x, y) = (X/Z^2, Y/Z^3).
1022 	 * Substituting this and multiplying by  Z^6  transforms the above
1023 	 * equation into Y^2 = X^3 + a*X*Z^4 + b*Z^6. To test this, we add up
1024 	 * the right-hand side in 'rh'.
1025 	 */
1026 
1027 	/* rh := X^2 */
1028 	if (!field_sqr(group, rh, &point->X, ctx))
1029 		goto err;
1030 
1031 	if (!point->Z_is_one) {
1032 		if (!field_sqr(group, tmp, &point->Z, ctx))
1033 			goto err;
1034 		if (!field_sqr(group, Z4, tmp, ctx))
1035 			goto err;
1036 		if (!field_mul(group, Z6, Z4, tmp, ctx))
1037 			goto err;
1038 
1039 		/* rh := (rh + a*Z^4)*X */
1040 		if (group->a_is_minus3) {
1041 			if (!BN_mod_lshift1_quick(tmp, Z4, p))
1042 				goto err;
1043 			if (!BN_mod_add_quick(tmp, tmp, Z4, p))
1044 				goto err;
1045 			if (!BN_mod_sub_quick(rh, rh, tmp, p))
1046 				goto err;
1047 			if (!field_mul(group, rh, rh, &point->X, ctx))
1048 				goto err;
1049 		} else {
1050 			if (!field_mul(group, tmp, Z4, &group->a, ctx))
1051 				goto err;
1052 			if (!BN_mod_add_quick(rh, rh, tmp, p))
1053 				goto err;
1054 			if (!field_mul(group, rh, rh, &point->X, ctx))
1055 				goto err;
1056 		}
1057 
1058 		/* rh := rh + b*Z^6 */
1059 		if (!field_mul(group, tmp, &group->b, Z6, ctx))
1060 			goto err;
1061 		if (!BN_mod_add_quick(rh, rh, tmp, p))
1062 			goto err;
1063 	} else {
1064 		/* point->Z_is_one */
1065 
1066 		/* rh := (rh + a)*X */
1067 		if (!BN_mod_add_quick(rh, rh, &group->a, p))
1068 			goto err;
1069 		if (!field_mul(group, rh, rh, &point->X, ctx))
1070 			goto err;
1071 		/* rh := rh + b */
1072 		if (!BN_mod_add_quick(rh, rh, &group->b, p))
1073 			goto err;
1074 	}
1075 
1076 	/* 'lh' := Y^2 */
1077 	if (!field_sqr(group, tmp, &point->Y, ctx))
1078 		goto err;
1079 
1080 	ret = (0 == BN_ucmp(tmp, rh));
1081 
1082  err:
1083 	BN_CTX_end(ctx);
1084 	BN_CTX_free(new_ctx);
1085 	return ret;
1086 }
1087 
1088 
1089 int
ec_GFp_simple_cmp(const EC_GROUP * group,const EC_POINT * a,const EC_POINT * b,BN_CTX * ctx)1090 ec_GFp_simple_cmp(const EC_GROUP * group, const EC_POINT * a, const EC_POINT * b, BN_CTX * ctx)
1091 {
1092 	/*
1093 	 * return values: -1   error 0   equal (in affine coordinates) 1
1094 	 * not equal
1095 	 */
1096 
1097 	int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
1098 	int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1099 	BN_CTX *new_ctx = NULL;
1100 	BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
1101 	const BIGNUM *tmp1_, *tmp2_;
1102 	int ret = -1;
1103 
1104 	if (EC_POINT_is_at_infinity(group, a) > 0) {
1105 		return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1;
1106 	}
1107 	if (EC_POINT_is_at_infinity(group, b) > 0)
1108 		return 1;
1109 
1110 	if (a->Z_is_one && b->Z_is_one) {
1111 		return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
1112 	}
1113 	field_mul = group->meth->field_mul;
1114 	field_sqr = group->meth->field_sqr;
1115 
1116 	if (ctx == NULL) {
1117 		ctx = new_ctx = BN_CTX_new();
1118 		if (ctx == NULL)
1119 			return -1;
1120 	}
1121 	BN_CTX_start(ctx);
1122 	if ((tmp1 = BN_CTX_get(ctx)) == NULL)
1123 		goto end;
1124 	if ((tmp2 = BN_CTX_get(ctx)) == NULL)
1125 		goto end;
1126 	if ((Za23 = BN_CTX_get(ctx)) == NULL)
1127 		goto end;
1128 	if ((Zb23 = BN_CTX_get(ctx)) == NULL)
1129 		goto end;
1130 
1131 	/*
1132 	 * We have to decide whether (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2,
1133 	 * Y_b/Z_b^3), or equivalently, whether (X_a*Z_b^2, Y_a*Z_b^3) =
1134 	 * (X_b*Z_a^2, Y_b*Z_a^3).
1135 	 */
1136 
1137 	if (!b->Z_is_one) {
1138 		if (!field_sqr(group, Zb23, &b->Z, ctx))
1139 			goto end;
1140 		if (!field_mul(group, tmp1, &a->X, Zb23, ctx))
1141 			goto end;
1142 		tmp1_ = tmp1;
1143 	} else
1144 		tmp1_ = &a->X;
1145 	if (!a->Z_is_one) {
1146 		if (!field_sqr(group, Za23, &a->Z, ctx))
1147 			goto end;
1148 		if (!field_mul(group, tmp2, &b->X, Za23, ctx))
1149 			goto end;
1150 		tmp2_ = tmp2;
1151 	} else
1152 		tmp2_ = &b->X;
1153 
1154 	/* compare  X_a*Z_b^2  with  X_b*Z_a^2 */
1155 	if (BN_cmp(tmp1_, tmp2_) != 0) {
1156 		ret = 1;	/* points differ */
1157 		goto end;
1158 	}
1159 	if (!b->Z_is_one) {
1160 		if (!field_mul(group, Zb23, Zb23, &b->Z, ctx))
1161 			goto end;
1162 		if (!field_mul(group, tmp1, &a->Y, Zb23, ctx))
1163 			goto end;
1164 		/* tmp1_ = tmp1 */
1165 	} else
1166 		tmp1_ = &a->Y;
1167 	if (!a->Z_is_one) {
1168 		if (!field_mul(group, Za23, Za23, &a->Z, ctx))
1169 			goto end;
1170 		if (!field_mul(group, tmp2, &b->Y, Za23, ctx))
1171 			goto end;
1172 		/* tmp2_ = tmp2 */
1173 	} else
1174 		tmp2_ = &b->Y;
1175 
1176 	/* compare  Y_a*Z_b^3  with  Y_b*Z_a^3 */
1177 	if (BN_cmp(tmp1_, tmp2_) != 0) {
1178 		ret = 1;	/* points differ */
1179 		goto end;
1180 	}
1181 	/* points are equal */
1182 	ret = 0;
1183 
1184  end:
1185 	BN_CTX_end(ctx);
1186 	BN_CTX_free(new_ctx);
1187 	return ret;
1188 }
1189 
1190 
1191 int
ec_GFp_simple_make_affine(const EC_GROUP * group,EC_POINT * point,BN_CTX * ctx)1192 ec_GFp_simple_make_affine(const EC_GROUP * group, EC_POINT * point, BN_CTX * ctx)
1193 {
1194 	BN_CTX *new_ctx = NULL;
1195 	BIGNUM *x, *y;
1196 	int ret = 0;
1197 
1198 	if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0)
1199 		return 1;
1200 
1201 	if (ctx == NULL) {
1202 		ctx = new_ctx = BN_CTX_new();
1203 		if (ctx == NULL)
1204 			return 0;
1205 	}
1206 	BN_CTX_start(ctx);
1207 	if ((x = BN_CTX_get(ctx)) == NULL)
1208 		goto err;
1209 	if ((y = BN_CTX_get(ctx)) == NULL)
1210 		goto err;
1211 
1212 	if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
1213 		goto err;
1214 	if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
1215 		goto err;
1216 	if (!point->Z_is_one) {
1217 		ECerror(ERR_R_INTERNAL_ERROR);
1218 		goto err;
1219 	}
1220 	ret = 1;
1221 
1222  err:
1223 	BN_CTX_end(ctx);
1224 	BN_CTX_free(new_ctx);
1225 	return ret;
1226 }
1227 
1228 
1229 int
ec_GFp_simple_points_make_affine(const EC_GROUP * group,size_t num,EC_POINT * points[],BN_CTX * ctx)1230 ec_GFp_simple_points_make_affine(const EC_GROUP * group, size_t num, EC_POINT * points[], BN_CTX * ctx)
1231 {
1232 	BN_CTX *new_ctx = NULL;
1233 	BIGNUM *tmp0, *tmp1;
1234 	size_t pow2 = 0;
1235 	BIGNUM **heap = NULL;
1236 	size_t i;
1237 	int ret = 0;
1238 
1239 	if (num == 0)
1240 		return 1;
1241 
1242 	if (ctx == NULL) {
1243 		ctx = new_ctx = BN_CTX_new();
1244 		if (ctx == NULL)
1245 			return 0;
1246 	}
1247 	BN_CTX_start(ctx);
1248 	if ((tmp0 = BN_CTX_get(ctx)) == NULL)
1249 		goto err;
1250 	if ((tmp1 = BN_CTX_get(ctx)) == NULL)
1251 		goto err;
1252 
1253 	/*
1254 	 * Before converting the individual points, compute inverses of all Z
1255 	 * values. Modular inversion is rather slow, but luckily we can do
1256 	 * with a single explicit inversion, plus about 3 multiplications per
1257 	 * input value.
1258 	 */
1259 
1260 	pow2 = 1;
1261 	while (num > pow2)
1262 		pow2 <<= 1;
1263 	/*
1264 	 * Now pow2 is the smallest power of 2 satifsying pow2 >= num. We
1265 	 * need twice that.
1266 	 */
1267 	pow2 <<= 1;
1268 
1269 	heap = reallocarray(NULL, pow2, sizeof heap[0]);
1270 	if (heap == NULL)
1271 		goto err;
1272 
1273 	/*
1274 	 * The array is used as a binary tree, exactly as in heapsort:
1275 	 *
1276 	 * heap[1] heap[2]                     heap[3] heap[4]       heap[5]
1277 	 * heap[6]       heap[7] heap[8]heap[9] heap[10]heap[11]
1278 	 * heap[12]heap[13] heap[14] heap[15]
1279 	 *
1280 	 * We put the Z's in the last line; then we set each other node to the
1281 	 * product of its two child-nodes (where empty or 0 entries are
1282 	 * treated as ones); then we invert heap[1]; then we invert each
1283 	 * other node by replacing it by the product of its parent (after
1284 	 * inversion) and its sibling (before inversion).
1285 	 */
1286 	heap[0] = NULL;
1287 	for (i = pow2 / 2 - 1; i > 0; i--)
1288 		heap[i] = NULL;
1289 	for (i = 0; i < num; i++)
1290 		heap[pow2 / 2 + i] = &points[i]->Z;
1291 	for (i = pow2 / 2 + num; i < pow2; i++)
1292 		heap[i] = NULL;
1293 
1294 	/* set each node to the product of its children */
1295 	for (i = pow2 / 2 - 1; i > 0; i--) {
1296 		heap[i] = BN_new();
1297 		if (heap[i] == NULL)
1298 			goto err;
1299 
1300 		if (heap[2 * i] != NULL) {
1301 			if ((heap[2 * i + 1] == NULL) || BN_is_zero(heap[2 * i + 1])) {
1302 				if (!BN_copy(heap[i], heap[2 * i]))
1303 					goto err;
1304 			} else {
1305 				if (BN_is_zero(heap[2 * i])) {
1306 					if (!BN_copy(heap[i], heap[2 * i + 1]))
1307 						goto err;
1308 				} else {
1309 					if (!group->meth->field_mul(group, heap[i],
1310 						heap[2 * i], heap[2 * i + 1], ctx))
1311 						goto err;
1312 				}
1313 			}
1314 		}
1315 	}
1316 
1317 	/* invert heap[1] */
1318 	if (!BN_is_zero(heap[1])) {
1319 		if (BN_mod_inverse_ct(heap[1], heap[1], &group->field, ctx) == NULL) {
1320 			ECerror(ERR_R_BN_LIB);
1321 			goto err;
1322 		}
1323 	}
1324 	if (group->meth->field_encode != 0) {
1325 		/*
1326 		 * in the Montgomery case, we just turned  R*H  (representing
1327 		 * H) into  1/(R*H),  but we need  R*(1/H)  (representing
1328 		 * 1/H); i.e. we have need to multiply by the Montgomery
1329 		 * factor twice
1330 		 */
1331 		if (!group->meth->field_encode(group, heap[1], heap[1], ctx))
1332 			goto err;
1333 		if (!group->meth->field_encode(group, heap[1], heap[1], ctx))
1334 			goto err;
1335 	}
1336 	/* set other heap[i]'s to their inverses */
1337 	for (i = 2; i < pow2 / 2 + num; i += 2) {
1338 		/* i is even */
1339 		if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1])) {
1340 			if (!group->meth->field_mul(group, tmp0, heap[i / 2], heap[i + 1], ctx))
1341 				goto err;
1342 			if (!group->meth->field_mul(group, tmp1, heap[i / 2], heap[i], ctx))
1343 				goto err;
1344 			if (!BN_copy(heap[i], tmp0))
1345 				goto err;
1346 			if (!BN_copy(heap[i + 1], tmp1))
1347 				goto err;
1348 		} else {
1349 			if (!BN_copy(heap[i], heap[i / 2]))
1350 				goto err;
1351 		}
1352 	}
1353 
1354 	/*
1355 	 * we have replaced all non-zero Z's by their inverses, now fix up
1356 	 * all the points
1357 	 */
1358 	for (i = 0; i < num; i++) {
1359 		EC_POINT *p = points[i];
1360 
1361 		if (!BN_is_zero(&p->Z)) {
1362 			/* turn  (X, Y, 1/Z)  into  (X/Z^2, Y/Z^3, 1) */
1363 
1364 			if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx))
1365 				goto err;
1366 			if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx))
1367 				goto err;
1368 
1369 			if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx))
1370 				goto err;
1371 			if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx))
1372 				goto err;
1373 
1374 			if (group->meth->field_set_to_one != 0) {
1375 				if (!group->meth->field_set_to_one(group, &p->Z, ctx))
1376 					goto err;
1377 			} else {
1378 				if (!BN_one(&p->Z))
1379 					goto err;
1380 			}
1381 			p->Z_is_one = 1;
1382 		}
1383 	}
1384 
1385 	ret = 1;
1386 
1387  err:
1388 	BN_CTX_end(ctx);
1389 	BN_CTX_free(new_ctx);
1390 	if (heap != NULL) {
1391 		/*
1392 		 * heap[pow2/2] .. heap[pow2-1] have not been allocated
1393 		 * locally!
1394 		 */
1395 		for (i = pow2 / 2 - 1; i > 0; i--) {
1396 			BN_clear_free(heap[i]);
1397 		}
1398 		free(heap);
1399 	}
1400 	return ret;
1401 }
1402 
1403 
1404 int
ec_GFp_simple_field_mul(const EC_GROUP * group,BIGNUM * r,const BIGNUM * a,const BIGNUM * b,BN_CTX * ctx)1405 ec_GFp_simple_field_mul(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
1406 {
1407 	return BN_mod_mul(r, a, b, &group->field, ctx);
1408 }
1409 
1410 int
ec_GFp_simple_field_sqr(const EC_GROUP * group,BIGNUM * r,const BIGNUM * a,BN_CTX * ctx)1411 ec_GFp_simple_field_sqr(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, BN_CTX * ctx)
1412 {
1413 	return BN_mod_sqr(r, a, &group->field, ctx);
1414 }
1415 
1416 /*
1417  * Apply randomization of EC point projective coordinates:
1418  *
1419  * 	(X, Y, Z) = (lambda^2 * X, lambda^3 * Y, lambda * Z)
1420  *
1421  * where lambda is in the interval [1, group->field).
1422  */
1423 int
ec_GFp_simple_blind_coordinates(const EC_GROUP * group,EC_POINT * p,BN_CTX * ctx)1424 ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
1425 {
1426 	BIGNUM *lambda = NULL;
1427 	BIGNUM *tmp = NULL;
1428 	int ret = 0;
1429 
1430 	BN_CTX_start(ctx);
1431 	if ((lambda = BN_CTX_get(ctx)) == NULL)
1432 		goto err;
1433 	if ((tmp = BN_CTX_get(ctx)) == NULL)
1434 		goto err;
1435 
1436 	/* Generate lambda in [1, group->field - 1] */
1437 	if (!bn_rand_interval(lambda, BN_value_one(), &group->field))
1438 		goto err;
1439 
1440 	if (group->meth->field_encode != NULL &&
1441 	    !group->meth->field_encode(group, lambda, lambda, ctx))
1442 		goto err;
1443 
1444 	/* Z = lambda * Z */
1445 	if (!group->meth->field_mul(group, &p->Z, lambda, &p->Z, ctx))
1446 		goto err;
1447 
1448 	/* tmp = lambda^2 */
1449 	if (!group->meth->field_sqr(group, tmp, lambda, ctx))
1450 		goto err;
1451 
1452 	/* X = lambda^2 * X */
1453 	if (!group->meth->field_mul(group, &p->X, tmp, &p->X, ctx))
1454 		goto err;
1455 
1456 	/* tmp = lambda^3 */
1457 	if (!group->meth->field_mul(group, tmp, tmp, lambda, ctx))
1458 		goto err;
1459 
1460 	/* Y = lambda^3 * Y */
1461 	if (!group->meth->field_mul(group, &p->Y, tmp, &p->Y, ctx))
1462 		goto err;
1463 
1464 	/* Disable optimized arithmetics after replacing Z by lambda * Z. */
1465 	p->Z_is_one = 0;
1466 
1467 	ret = 1;
1468 
1469  err:
1470 	BN_CTX_end(ctx);
1471 	return ret;
1472 }
1473 
1474 
1475 #define EC_POINT_BN_set_flags(P, flags) do {				\
1476 	BN_set_flags(&(P)->X, (flags));         			\
1477 	BN_set_flags(&(P)->Y, (flags));         			\
1478 	BN_set_flags(&(P)->Z, (flags));         			\
1479 } while(0)
1480 
1481 #define EC_POINT_CSWAP(c, a, b, w, t) do {      			\
1482 	if (!BN_swap_ct(c, &(a)->X, &(b)->X, w)	||			\
1483 	    !BN_swap_ct(c, &(a)->Y, &(b)->Y, w)	|| 			\
1484 	    !BN_swap_ct(c, &(a)->Z, &(b)->Z, w))			\
1485 		goto err;						\
1486 	t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c);			\
1487 	(a)->Z_is_one ^= (t);						\
1488 	(b)->Z_is_one ^= (t);						\
1489 } while(0)
1490 
1491 /*
1492  * This function computes (in constant time) a point multiplication over the
1493  * EC group.
1494  *
1495  * At a high level, it is Montgomery ladder with conditional swaps.
1496  *
1497  * It performs either a fixed point multiplication
1498  *          (scalar * generator)
1499  * when point is NULL, or a variable point multiplication
1500  *          (scalar * point)
1501  * when point is not NULL.
1502  *
1503  * scalar should be in the range [0,n) otherwise all constant time bets are off.
1504  *
1505  * NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
1506  * which of course are not constant time themselves.
1507  *
1508  * The product is stored in r.
1509  *
1510  * Returns 1 on success, 0 otherwise.
1511  */
1512 static int
ec_GFp_simple_mul_ct(const EC_GROUP * group,EC_POINT * r,const BIGNUM * scalar,const EC_POINT * point,BN_CTX * ctx)1513 ec_GFp_simple_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1514     const EC_POINT *point, BN_CTX *ctx)
1515 {
1516 	int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
1517 	EC_POINT *s = NULL;
1518 	BIGNUM *k = NULL;
1519 	BIGNUM *lambda = NULL;
1520 	BIGNUM *cardinality = NULL;
1521 	BN_CTX *new_ctx = NULL;
1522 	int ret = 0;
1523 
1524 	if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL)
1525 		return 0;
1526 
1527 	BN_CTX_start(ctx);
1528 
1529 	if ((s = EC_POINT_new(group)) == NULL)
1530 		goto err;
1531 
1532 	if (point == NULL) {
1533 		if (!EC_POINT_copy(s, group->generator))
1534 			goto err;
1535 	} else {
1536 		if (!EC_POINT_copy(s, point))
1537 			goto err;
1538 	}
1539 
1540 	EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
1541 
1542 	if ((cardinality = BN_CTX_get(ctx)) == NULL)
1543 		goto err;
1544 	if ((lambda = BN_CTX_get(ctx)) == NULL)
1545 		goto err;
1546 	if ((k = BN_CTX_get(ctx)) == NULL)
1547 		goto err;
1548 	if (!BN_mul(cardinality, &group->order, &group->cofactor, ctx))
1549 		goto err;
1550 
1551 	/*
1552 	 * Group cardinalities are often on a word boundary.
1553 	 * So when we pad the scalar, some timing diff might
1554 	 * pop if it needs to be expanded due to carries.
1555 	 * So expand ahead of time.
1556 	 */
1557 	cardinality_bits = BN_num_bits(cardinality);
1558 	group_top = cardinality->top;
1559 	if ((bn_wexpand(k, group_top + 2) == NULL) ||
1560 	    (bn_wexpand(lambda, group_top + 2) == NULL))
1561 		goto err;
1562 
1563 	if (!BN_copy(k, scalar))
1564 		goto err;
1565 
1566 	BN_set_flags(k, BN_FLG_CONSTTIME);
1567 
1568 	if (BN_num_bits(k) > cardinality_bits || BN_is_negative(k)) {
1569 		/*
1570 		 * This is an unusual input, and we don't guarantee
1571 		 * constant-timeness
1572 		 */
1573 		if (!BN_nnmod(k, k, cardinality, ctx))
1574 			goto err;
1575 	}
1576 
1577 	if (!BN_add(lambda, k, cardinality))
1578 		goto err;
1579 	BN_set_flags(lambda, BN_FLG_CONSTTIME);
1580 	if (!BN_add(k, lambda, cardinality))
1581 		goto err;
1582 	/*
1583 	 * lambda := scalar + cardinality
1584 	 * k := scalar + 2*cardinality
1585 	 */
1586 	kbit = BN_is_bit_set(lambda, cardinality_bits);
1587 	if (!BN_swap_ct(kbit, k, lambda, group_top + 2))
1588 		goto err;
1589 
1590 	group_top = group->field.top;
1591 	if ((bn_wexpand(&s->X, group_top) == NULL) ||
1592 	    (bn_wexpand(&s->Y, group_top) == NULL) ||
1593 	    (bn_wexpand(&s->Z, group_top) == NULL) ||
1594 	    (bn_wexpand(&r->X, group_top) == NULL) ||
1595 	    (bn_wexpand(&r->Y, group_top) == NULL) ||
1596 	    (bn_wexpand(&r->Z, group_top) == NULL))
1597 		goto err;
1598 
1599 	/*
1600 	 * Apply coordinate blinding for EC_POINT if the underlying EC_METHOD
1601 	 * implements it.
1602 	 */
1603 	if (!ec_point_blind_coordinates(group, s, ctx))
1604 		goto err;
1605 
1606 	/* top bit is a 1, in a fixed pos */
1607 	if (!EC_POINT_copy(r, s))
1608 		goto err;
1609 
1610 	EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
1611 
1612 	if (!EC_POINT_dbl(group, s, s, ctx))
1613 		goto err;
1614 
1615 	pbit = 0;
1616 
1617 	/*
1618 	 * The ladder step, with branches, is
1619 	 *
1620 	 * k[i] == 0: S = add(R, S), R = dbl(R)
1621 	 * k[i] == 1: R = add(S, R), S = dbl(S)
1622 	 *
1623 	 * Swapping R, S conditionally on k[i] leaves you with state
1624 	 *
1625 	 * k[i] == 0: T, U = R, S
1626 	 * k[i] == 1: T, U = S, R
1627 	 *
1628 	 * Then perform the ECC ops.
1629 	 *
1630 	 * U = add(T, U)
1631 	 * T = dbl(T)
1632 	 *
1633 	 * Which leaves you with state
1634 	 *
1635 	 * k[i] == 0: U = add(R, S), T = dbl(R)
1636 	 * k[i] == 1: U = add(S, R), T = dbl(S)
1637 	 *
1638 	 * Swapping T, U conditionally on k[i] leaves you with state
1639 	 *
1640 	 * k[i] == 0: R, S = T, U
1641 	 * k[i] == 1: R, S = U, T
1642 	 *
1643 	 * Which leaves you with state
1644 	 *
1645 	 * k[i] == 0: S = add(R, S), R = dbl(R)
1646 	 * k[i] == 1: R = add(S, R), S = dbl(S)
1647 	 *
1648 	 * So we get the same logic, but instead of a branch it's a
1649 	 * conditional swap, followed by ECC ops, then another conditional swap.
1650 	 *
1651 	 * Optimization: The end of iteration i and start of i-1 looks like
1652 	 *
1653 	 * ...
1654 	 * CSWAP(k[i], R, S)
1655 	 * ECC
1656 	 * CSWAP(k[i], R, S)
1657 	 * (next iteration)
1658 	 * CSWAP(k[i-1], R, S)
1659 	 * ECC
1660 	 * CSWAP(k[i-1], R, S)
1661 	 * ...
1662 	 *
1663 	 * So instead of two contiguous swaps, you can merge the condition
1664 	 * bits and do a single swap.
1665 	 *
1666 	 * k[i]   k[i-1]    Outcome
1667 	 * 0      0         No Swap
1668 	 * 0      1         Swap
1669 	 * 1      0         Swap
1670 	 * 1      1         No Swap
1671 	 *
1672 	 * This is XOR. pbit tracks the previous bit of k.
1673 	 */
1674 
1675 	for (i = cardinality_bits - 1; i >= 0; i--) {
1676 		kbit = BN_is_bit_set(k, i) ^ pbit;
1677 		EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
1678 		if (!EC_POINT_add(group, s, r, s, ctx))
1679 			goto err;
1680 		if (!EC_POINT_dbl(group, r, r, ctx))
1681 			goto err;
1682 		/*
1683 		 * pbit logic merges this cswap with that of the
1684 		 * next iteration
1685 		 */
1686 		pbit ^= kbit;
1687 	}
1688 	/* one final cswap to move the right value into r */
1689 	EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
1690 
1691 	ret = 1;
1692 
1693  err:
1694 	EC_POINT_free(s);
1695 	if (ctx != NULL)
1696 		BN_CTX_end(ctx);
1697 	BN_CTX_free(new_ctx);
1698 
1699 	return ret;
1700 }
1701 
1702 #undef EC_POINT_BN_set_flags
1703 #undef EC_POINT_CSWAP
1704 
1705 int
ec_GFp_simple_mul_generator_ct(const EC_GROUP * group,EC_POINT * r,const BIGNUM * scalar,BN_CTX * ctx)1706 ec_GFp_simple_mul_generator_ct(const EC_GROUP *group, EC_POINT *r,
1707     const BIGNUM *scalar, BN_CTX *ctx)
1708 {
1709 	return ec_GFp_simple_mul_ct(group, r, scalar, NULL, ctx);
1710 }
1711 
1712 int
ec_GFp_simple_mul_single_ct(const EC_GROUP * group,EC_POINT * r,const BIGNUM * scalar,const EC_POINT * point,BN_CTX * ctx)1713 ec_GFp_simple_mul_single_ct(const EC_GROUP *group, EC_POINT *r,
1714     const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx)
1715 {
1716 	return ec_GFp_simple_mul_ct(group, r, scalar, point, ctx);
1717 }
1718 
1719 int
ec_GFp_simple_mul_double_nonct(const EC_GROUP * group,EC_POINT * r,const BIGNUM * g_scalar,const BIGNUM * p_scalar,const EC_POINT * point,BN_CTX * ctx)1720 ec_GFp_simple_mul_double_nonct(const EC_GROUP *group, EC_POINT *r,
1721     const BIGNUM *g_scalar, const BIGNUM *p_scalar, const EC_POINT *point,
1722     BN_CTX *ctx)
1723 {
1724 	return ec_wNAF_mul(group, r, g_scalar, 1, &point, &p_scalar, ctx);
1725 }
1726