Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / third_party / boringssl / crypto / fipsmodule / ec / simple.c
1 /* Originally written by Bodo Moeller for the OpenSSL project.
2  * ====================================================================
3  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. All advertising materials mentioning features or use of this
18  *    software must display the following acknowledgment:
19  *    "This product includes software developed by the OpenSSL Project
20  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21  *
22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23  *    endorse or promote products derived from this software without
24  *    prior written permission. For written permission, please contact
25  *    openssl-core@openssl.org.
26  *
27  * 5. Products derived from this software may not be called "OpenSSL"
28  *    nor may "OpenSSL" appear in their names without prior written
29  *    permission of the OpenSSL Project.
30  *
31  * 6. Redistributions of any form whatsoever must retain the following
32  *    acknowledgment:
33  *    "This product includes software developed by the OpenSSL Project
34  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47  * OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This product includes cryptographic software written by Eric Young
51  * (eay@cryptsoft.com).  This product includes software written by Tim
52  * Hudson (tjh@cryptsoft.com).
53  *
54  */
55 /* ====================================================================
56  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
57  *
58  * Portions of the attached software ("Contribution") are developed by
59  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
60  *
61  * The Contribution is licensed pursuant to the OpenSSL open source
62  * license provided above.
63  *
64  * The elliptic curve binary polynomial software is originally written by
65  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
66  * Laboratories. */
67
68 #include <openssl/ec.h>
69
70 #include <string.h>
71
72 #include <openssl/bn.h>
73 #include <openssl/err.h>
74 #include <openssl/mem.h>
75
76 #include "internal.h"
77 #include "../../internal.h"
78
79
80 // Most method functions in this file are designed to work with non-trivial
81 // representations of field elements if necessary (see ecp_mont.c): while
82 // standard modular addition and subtraction are used, the field_mul and
83 // field_sqr methods will be used for multiplication, and field_encode and
84 // field_decode (if defined) will be used for converting between
85 // representations.
86 //
87 // Functions here specifically assume that if a non-trivial representation is
88 // used, it is a Montgomery representation (i.e. 'encoding' means multiplying
89 // by some factor R).
90
91 int ec_GFp_simple_group_init(EC_GROUP *group) {
92   BN_init(&group->field);
93   BN_init(&group->a);
94   BN_init(&group->b);
95   BN_init(&group->one);
96   group->a_is_minus3 = 0;
97   return 1;
98 }
99
100 void ec_GFp_simple_group_finish(EC_GROUP *group) {
101   BN_free(&group->field);
102   BN_free(&group->a);
103   BN_free(&group->b);
104   BN_free(&group->one);
105 }
106
107 int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
108                                   const BIGNUM *a, const BIGNUM *b,
109                                   BN_CTX *ctx) {
110   int ret = 0;
111   BN_CTX *new_ctx = NULL;
112   BIGNUM *tmp_a;
113
114   // p must be a prime > 3
115   if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
116     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
117     return 0;
118   }
119
120   if (ctx == NULL) {
121     ctx = new_ctx = BN_CTX_new();
122     if (ctx == NULL) {
123       return 0;
124     }
125   }
126
127   BN_CTX_start(ctx);
128   tmp_a = BN_CTX_get(ctx);
129   if (tmp_a == NULL) {
130     goto err;
131   }
132
133   // group->field
134   if (!BN_copy(&group->field, p)) {
135     goto err;
136   }
137   BN_set_negative(&group->field, 0);
138   // Store the field in minimal form, so it can be used with |BN_ULONG| arrays.
139   bn_set_minimal_width(&group->field);
140
141   // group->a
142   if (!BN_nnmod(tmp_a, a, &group->field, ctx)) {
143     goto err;
144   }
145   if (group->meth->field_encode) {
146     if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) {
147       goto err;
148     }
149   } else if (!BN_copy(&group->a, tmp_a)) {
150     goto err;
151   }
152
153   // group->b
154   if (!BN_nnmod(&group->b, b, &group->field, ctx)) {
155     goto err;
156   }
157   if (group->meth->field_encode &&
158       !group->meth->field_encode(group, &group->b, &group->b, ctx)) {
159     goto err;
160   }
161
162   // group->a_is_minus3
163   if (!BN_add_word(tmp_a, 3)) {
164     goto err;
165   }
166   group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
167
168   if (group->meth->field_encode != NULL) {
169     if (!group->meth->field_encode(group, &group->one, BN_value_one(), ctx)) {
170       goto err;
171     }
172   } else if (!BN_copy(&group->one, BN_value_one())) {
173     goto err;
174   }
175
176   ret = 1;
177
178 err:
179   BN_CTX_end(ctx);
180   BN_CTX_free(new_ctx);
181   return ret;
182 }
183
184 int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
185                                   BIGNUM *b, BN_CTX *ctx) {
186   int ret = 0;
187   BN_CTX *new_ctx = NULL;
188
189   if (p != NULL && !BN_copy(p, &group->field)) {
190     return 0;
191   }
192
193   if (a != NULL || b != NULL) {
194     if (group->meth->field_decode) {
195       if (ctx == NULL) {
196         ctx = new_ctx = BN_CTX_new();
197         if (ctx == NULL) {
198           return 0;
199         }
200       }
201       if (a != NULL && !group->meth->field_decode(group, a, &group->a, ctx)) {
202         goto err;
203       }
204       if (b != NULL && !group->meth->field_decode(group, b, &group->b, ctx)) {
205         goto err;
206       }
207     } else {
208       if (a != NULL && !BN_copy(a, &group->a)) {
209         goto err;
210       }
211       if (b != NULL && !BN_copy(b, &group->b)) {
212         goto err;
213       }
214     }
215   }
216
217   ret = 1;
218
219 err:
220   BN_CTX_free(new_ctx);
221   return ret;
222 }
223
224 unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *group) {
225   return BN_num_bits(&group->field);
226 }
227
228 int ec_GFp_simple_point_init(EC_POINT *point) {
229   BN_init(&point->X);
230   BN_init(&point->Y);
231   BN_init(&point->Z);
232
233   return 1;
234 }
235
236 void ec_GFp_simple_point_finish(EC_POINT *point) {
237   BN_free(&point->X);
238   BN_free(&point->Y);
239   BN_free(&point->Z);
240 }
241
242 int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) {
243   if (!BN_copy(&dest->X, &src->X) ||
244       !BN_copy(&dest->Y, &src->Y) ||
245       !BN_copy(&dest->Z, &src->Z)) {
246     return 0;
247   }
248
249   return 1;
250 }
251
252 int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
253                                         EC_POINT *point) {
254   BN_zero(&point->Z);
255   return 1;
256 }
257
258 static int set_Jprojective_coordinate_GFp(const EC_GROUP *group, BIGNUM *out,
259                                           const BIGNUM *in, BN_CTX *ctx) {
260   if (in == NULL) {
261     return 1;
262   }
263   if (BN_is_negative(in) ||
264       BN_cmp(in, &group->field) >= 0) {
265     OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
266     return 0;
267   }
268   if (group->meth->field_encode) {
269     return group->meth->field_encode(group, out, in, ctx);
270   }
271   return BN_copy(out, in) != NULL;
272 }
273
274 int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
275                                                EC_POINT *point, const BIGNUM *x,
276                                                const BIGNUM *y, BN_CTX *ctx) {
277   if (x == NULL || y == NULL) {
278     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
279     return 0;
280   }
281
282   BN_CTX *new_ctx = NULL;
283   int ret = 0;
284
285   if (ctx == NULL) {
286     ctx = new_ctx = BN_CTX_new();
287     if (ctx == NULL) {
288       return 0;
289     }
290   }
291
292   if (!set_Jprojective_coordinate_GFp(group, &point->X, x, ctx) ||
293       !set_Jprojective_coordinate_GFp(group, &point->Y, y, ctx) ||
294       !BN_copy(&point->Z, &group->one)) {
295     goto err;
296   }
297
298   ret = 1;
299
300 err:
301   BN_CTX_free(new_ctx);
302   return ret;
303 }
304
305 int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
306                       const EC_POINT *b, BN_CTX *ctx) {
307   int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
308                    BN_CTX *);
309   int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
310   const BIGNUM *p;
311   BN_CTX *new_ctx = NULL;
312   BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
313   int ret = 0;
314
315   if (a == b) {
316     return EC_POINT_dbl(group, r, a, ctx);
317   }
318   if (EC_POINT_is_at_infinity(group, a)) {
319     return EC_POINT_copy(r, b);
320   }
321   if (EC_POINT_is_at_infinity(group, b)) {
322     return EC_POINT_copy(r, a);
323   }
324
325   field_mul = group->meth->field_mul;
326   field_sqr = group->meth->field_sqr;
327   p = &group->field;
328
329   if (ctx == NULL) {
330     ctx = new_ctx = BN_CTX_new();
331     if (ctx == NULL) {
332       return 0;
333     }
334   }
335
336   BN_CTX_start(ctx);
337   n0 = BN_CTX_get(ctx);
338   n1 = BN_CTX_get(ctx);
339   n2 = BN_CTX_get(ctx);
340   n3 = BN_CTX_get(ctx);
341   n4 = BN_CTX_get(ctx);
342   n5 = BN_CTX_get(ctx);
343   n6 = BN_CTX_get(ctx);
344   if (n6 == NULL) {
345     goto end;
346   }
347
348   // Note that in this function we must not read components of 'a' or 'b'
349   // once we have written the corresponding components of 'r'.
350   // ('r' might be one of 'a' or 'b'.)
351
352   // n1, n2
353   int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;
354
355   if (b_Z_is_one) {
356     if (!BN_copy(n1, &a->X) || !BN_copy(n2, &a->Y)) {
357       goto end;
358     }
359     // n1 = X_a
360     // n2 = Y_a
361   } else {
362     if (!field_sqr(group, n0, &b->Z, ctx) ||
363         !field_mul(group, n1, &a->X, n0, ctx)) {
364       goto end;
365     }
366     // n1 = X_a * Z_b^2
367
368     if (!field_mul(group, n0, n0, &b->Z, ctx) ||
369         !field_mul(group, n2, &a->Y, n0, ctx)) {
370       goto end;
371     }
372     // n2 = Y_a * Z_b^3
373   }
374
375   // n3, n4
376   int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
377   if (a_Z_is_one) {
378     if (!BN_copy(n3, &b->X) || !BN_copy(n4, &b->Y)) {
379       goto end;
380     }
381     // n3 = X_b
382     // n4 = Y_b
383   } else {
384     if (!field_sqr(group, n0, &a->Z, ctx) ||
385         !field_mul(group, n3, &b->X, n0, ctx)) {
386       goto end;
387     }
388     // n3 = X_b * Z_a^2
389
390     if (!field_mul(group, n0, n0, &a->Z, ctx) ||
391         !field_mul(group, n4, &b->Y, n0, ctx)) {
392       goto end;
393     }
394     // n4 = Y_b * Z_a^3
395   }
396
397   // n5, n6
398   if (!bn_mod_sub_consttime(n5, n1, n3, p, ctx) ||
399       !bn_mod_sub_consttime(n6, n2, n4, p, ctx)) {
400     goto end;
401   }
402   // n5 = n1 - n3
403   // n6 = n2 - n4
404
405   if (BN_is_zero(n5)) {
406     if (BN_is_zero(n6)) {
407       // a is the same point as b
408       BN_CTX_end(ctx);
409       ret = EC_POINT_dbl(group, r, a, ctx);
410       ctx = NULL;
411       goto end;
412     } else {
413       // a is the inverse of b
414       BN_zero(&r->Z);
415       ret = 1;
416       goto end;
417     }
418   }
419
420   // 'n7', 'n8'
421   if (!bn_mod_add_consttime(n1, n1, n3, p, ctx) ||
422       !bn_mod_add_consttime(n2, n2, n4, p, ctx)) {
423     goto end;
424   }
425   // 'n7' = n1 + n3
426   // 'n8' = n2 + n4
427
428   // Z_r
429   if (a_Z_is_one && b_Z_is_one) {
430     if (!BN_copy(&r->Z, n5)) {
431       goto end;
432     }
433   } else {
434     if (a_Z_is_one) {
435       if (!BN_copy(n0, &b->Z)) {
436         goto end;
437       }
438     } else if (b_Z_is_one) {
439       if (!BN_copy(n0, &a->Z)) {
440         goto end;
441       }
442     } else if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) {
443       goto end;
444     }
445     if (!field_mul(group, &r->Z, n0, n5, ctx)) {
446       goto end;
447     }
448   }
449
450   // Z_r = Z_a * Z_b * n5
451
452   // X_r
453   if (!field_sqr(group, n0, n6, ctx) ||
454       !field_sqr(group, n4, n5, ctx) ||
455       !field_mul(group, n3, n1, n4, ctx) ||
456       !bn_mod_sub_consttime(&r->X, n0, n3, p, ctx)) {
457     goto end;
458   }
459   // X_r = n6^2 - n5^2 * 'n7'
460
461   // 'n9'
462   if (!bn_mod_lshift1_consttime(n0, &r->X, p, ctx) ||
463       !bn_mod_sub_consttime(n0, n3, n0, p, ctx)) {
464     goto end;
465   }
466   // n9 = n5^2 * 'n7' - 2 * X_r
467
468   // Y_r
469   if (!field_mul(group, n0, n0, n6, ctx) ||
470       !field_mul(group, n5, n4, n5, ctx)) {
471     goto end;  // now n5 is n5^3
472   }
473   if (!field_mul(group, n1, n2, n5, ctx) ||
474       !bn_mod_sub_consttime(n0, n0, n1, p, ctx)) {
475     goto end;
476   }
477   if (BN_is_odd(n0) && !BN_add(n0, n0, p)) {
478     goto end;
479   }
480   // now  0 <= n0 < 2*p,  and n0 is even
481   if (!BN_rshift1(&r->Y, n0)) {
482     goto end;
483   }
484   // Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2
485
486   ret = 1;
487
488 end:
489   if (ctx) {
490     // otherwise we already called BN_CTX_end
491     BN_CTX_end(ctx);
492   }
493   BN_CTX_free(new_ctx);
494   return ret;
495 }
496
497 int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
498                       BN_CTX *ctx) {
499   int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
500                    BN_CTX *);
501   int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
502   const BIGNUM *p;
503   BN_CTX *new_ctx = NULL;
504   BIGNUM *n0, *n1, *n2, *n3;
505   int ret = 0;
506
507   if (EC_POINT_is_at_infinity(group, a)) {
508     BN_zero(&r->Z);
509     return 1;
510   }
511
512   field_mul = group->meth->field_mul;
513   field_sqr = group->meth->field_sqr;
514   p = &group->field;
515
516   if (ctx == NULL) {
517     ctx = new_ctx = BN_CTX_new();
518     if (ctx == NULL) {
519       return 0;
520     }
521   }
522
523   BN_CTX_start(ctx);
524   n0 = BN_CTX_get(ctx);
525   n1 = BN_CTX_get(ctx);
526   n2 = BN_CTX_get(ctx);
527   n3 = BN_CTX_get(ctx);
528   if (n3 == NULL) {
529     goto err;
530   }
531
532   // Note that in this function we must not read components of 'a'
533   // once we have written the corresponding components of 'r'.
534   // ('r' might the same as 'a'.)
535
536   // n1
537   if (BN_cmp(&a->Z, &group->one) == 0) {
538     if (!field_sqr(group, n0, &a->X, ctx) ||
539         !bn_mod_lshift1_consttime(n1, n0, p, ctx) ||
540         !bn_mod_add_consttime(n0, n0, n1, p, ctx) ||
541         !bn_mod_add_consttime(n1, n0, &group->a, p, ctx)) {
542       goto err;
543     }
544     // n1 = 3 * X_a^2 + a_curve
545   } else if (group->a_is_minus3) {
546     if (!field_sqr(group, n1, &a->Z, ctx) ||
547         !bn_mod_add_consttime(n0, &a->X, n1, p, ctx) ||
548         !bn_mod_sub_consttime(n2, &a->X, n1, p, ctx) ||
549         !field_mul(group, n1, n0, n2, ctx) ||
550         !bn_mod_lshift1_consttime(n0, n1, p, ctx) ||
551         !bn_mod_add_consttime(n1, n0, n1, p, ctx)) {
552       goto err;
553     }
554     // n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
555     //    = 3 * X_a^2 - 3 * Z_a^4
556   } else {
557     if (!field_sqr(group, n0, &a->X, ctx) ||
558         !bn_mod_lshift1_consttime(n1, n0, p, ctx) ||
559         !bn_mod_add_consttime(n0, n0, n1, p, ctx) ||
560         !field_sqr(group, n1, &a->Z, ctx) ||
561         !field_sqr(group, n1, n1, ctx) ||
562         !field_mul(group, n1, n1, &group->a, ctx) ||
563         !bn_mod_add_consttime(n1, n1, n0, p, ctx)) {
564       goto err;
565     }
566     // n1 = 3 * X_a^2 + a_curve * Z_a^4
567   }
568
569   // Z_r
570   if (BN_cmp(&a->Z, &group->one) == 0) {
571     if (!BN_copy(n0, &a->Y)) {
572       goto err;
573     }
574   } else if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) {
575     goto err;
576   }
577   if (!bn_mod_lshift1_consttime(&r->Z, n0, p, ctx)) {
578     goto err;
579   }
580   // Z_r = 2 * Y_a * Z_a
581
582   // n2
583   if (!field_sqr(group, n3, &a->Y, ctx) ||
584       !field_mul(group, n2, &a->X, n3, ctx) ||
585       !bn_mod_lshift_consttime(n2, n2, 2, p, ctx)) {
586     goto err;
587   }
588   // n2 = 4 * X_a * Y_a^2
589
590   // X_r
591   if (!bn_mod_lshift1_consttime(n0, n2, p, ctx) ||
592       !field_sqr(group, &r->X, n1, ctx) ||
593       !bn_mod_sub_consttime(&r->X, &r->X, n0, p, ctx)) {
594     goto err;
595   }
596   // X_r = n1^2 - 2 * n2
597
598   // n3
599   if (!field_sqr(group, n0, n3, ctx) ||
600       !bn_mod_lshift_consttime(n3, n0, 3, p, ctx)) {
601     goto err;
602   }
603   // n3 = 8 * Y_a^4
604
605   // Y_r
606   if (!bn_mod_sub_consttime(n0, n2, &r->X, p, ctx) ||
607       !field_mul(group, n0, n1, n0, ctx) ||
608       !bn_mod_sub_consttime(&r->Y, n0, n3, p, ctx)) {
609     goto err;
610   }
611   // Y_r = n1 * (n2 - X_r) - n3
612
613   ret = 1;
614
615 err:
616   BN_CTX_end(ctx);
617   BN_CTX_free(new_ctx);
618   return ret;
619 }
620
621 int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
622   if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) {
623     // point is its own inverse
624     return 1;
625   }
626
627   return BN_usub(&point->Y, &group->field, &point->Y);
628 }
629
630 int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
631   return BN_is_zero(&point->Z);
632 }
633
634 int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
635                               BN_CTX *ctx) {
636   int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
637                    BN_CTX *);
638   int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
639   const BIGNUM *p;
640   BN_CTX *new_ctx = NULL;
641   BIGNUM *rh, *tmp, *Z4, *Z6;
642   int ret = 0;
643
644   if (EC_POINT_is_at_infinity(group, point)) {
645     return 1;
646   }
647
648   field_mul = group->meth->field_mul;
649   field_sqr = group->meth->field_sqr;
650   p = &group->field;
651
652   if (ctx == NULL) {
653     ctx = new_ctx = BN_CTX_new();
654     if (ctx == NULL) {
655       return 0;
656     }
657   }
658
659   BN_CTX_start(ctx);
660   rh = BN_CTX_get(ctx);
661   tmp = BN_CTX_get(ctx);
662   Z4 = BN_CTX_get(ctx);
663   Z6 = BN_CTX_get(ctx);
664   if (Z6 == NULL) {
665     goto err;
666   }
667
668   // We have a curve defined by a Weierstrass equation
669   //      y^2 = x^3 + a*x + b.
670   // The point to consider is given in Jacobian projective coordinates
671   // where  (X, Y, Z)  represents  (x, y) = (X/Z^2, Y/Z^3).
672   // Substituting this and multiplying by  Z^6  transforms the above equation
673   // into
674   //      Y^2 = X^3 + a*X*Z^4 + b*Z^6.
675   // To test this, we add up the right-hand side in 'rh'.
676
677   // rh := X^2
678   if (!field_sqr(group, rh, &point->X, ctx)) {
679     goto err;
680   }
681
682   if (BN_cmp(&point->Z, &group->one) != 0) {
683     if (!field_sqr(group, tmp, &point->Z, ctx) ||
684         !field_sqr(group, Z4, tmp, ctx) ||
685         !field_mul(group, Z6, Z4, tmp, ctx)) {
686       goto err;
687     }
688
689     // rh := (rh + a*Z^4)*X
690     if (group->a_is_minus3) {
691       if (!bn_mod_lshift1_consttime(tmp, Z4, p, ctx) ||
692           !bn_mod_add_consttime(tmp, tmp, Z4, p, ctx) ||
693           !bn_mod_sub_consttime(rh, rh, tmp, p, ctx) ||
694           !field_mul(group, rh, rh, &point->X, ctx)) {
695         goto err;
696       }
697     } else {
698       if (!field_mul(group, tmp, Z4, &group->a, ctx) ||
699           !bn_mod_add_consttime(rh, rh, tmp, p, ctx) ||
700           !field_mul(group, rh, rh, &point->X, ctx)) {
701         goto err;
702       }
703     }
704
705     // rh := rh + b*Z^6
706     if (!field_mul(group, tmp, &group->b, Z6, ctx) ||
707         !bn_mod_add_consttime(rh, rh, tmp, p, ctx)) {
708       goto err;
709     }
710   } else {
711     // rh := (rh + a)*X
712     if (!bn_mod_add_consttime(rh, rh, &group->a, p, ctx) ||
713         !field_mul(group, rh, rh, &point->X, ctx)) {
714       goto err;
715     }
716     // rh := rh + b
717     if (!bn_mod_add_consttime(rh, rh, &group->b, p, ctx)) {
718       goto err;
719     }
720   }
721
722   // 'lh' := Y^2
723   if (!field_sqr(group, tmp, &point->Y, ctx)) {
724     goto err;
725   }
726
727   ret = (0 == BN_ucmp(tmp, rh));
728
729 err:
730   BN_CTX_end(ctx);
731   BN_CTX_free(new_ctx);
732   return ret;
733 }
734
735 int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
736                       const EC_POINT *b, BN_CTX *ctx) {
737   // return values:
738   //  -1   error
739   //   0   equal (in affine coordinates)
740   //   1   not equal
741
742   int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
743                    BN_CTX *);
744   int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
745   BN_CTX *new_ctx = NULL;
746   BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
747   const BIGNUM *tmp1_, *tmp2_;
748   int ret = -1;
749
750   if (ec_GFp_simple_is_at_infinity(group, a)) {
751     return ec_GFp_simple_is_at_infinity(group, b) ? 0 : 1;
752   }
753
754   if (ec_GFp_simple_is_at_infinity(group, b)) {
755     return 1;
756   }
757
758   int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
759   int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;
760
761   if (a_Z_is_one && b_Z_is_one) {
762     return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
763   }
764
765   field_mul = group->meth->field_mul;
766   field_sqr = group->meth->field_sqr;
767
768   if (ctx == NULL) {
769     ctx = new_ctx = BN_CTX_new();
770     if (ctx == NULL) {
771       return -1;
772     }
773   }
774
775   BN_CTX_start(ctx);
776   tmp1 = BN_CTX_get(ctx);
777   tmp2 = BN_CTX_get(ctx);
778   Za23 = BN_CTX_get(ctx);
779   Zb23 = BN_CTX_get(ctx);
780   if (Zb23 == NULL) {
781     goto end;
782   }
783
784   // We have to decide whether
785   //     (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
786   // or equivalently, whether
787   //     (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
788
789   if (!b_Z_is_one) {
790     if (!field_sqr(group, Zb23, &b->Z, ctx) ||
791         !field_mul(group, tmp1, &a->X, Zb23, ctx)) {
792       goto end;
793     }
794     tmp1_ = tmp1;
795   } else {
796     tmp1_ = &a->X;
797   }
798   if (!a_Z_is_one) {
799     if (!field_sqr(group, Za23, &a->Z, ctx) ||
800         !field_mul(group, tmp2, &b->X, Za23, ctx)) {
801       goto end;
802     }
803     tmp2_ = tmp2;
804   } else {
805     tmp2_ = &b->X;
806   }
807
808   // compare  X_a*Z_b^2  with  X_b*Z_a^2
809   if (BN_cmp(tmp1_, tmp2_) != 0) {
810     ret = 1;  // points differ
811     goto end;
812   }
813
814
815   if (!b_Z_is_one) {
816     if (!field_mul(group, Zb23, Zb23, &b->Z, ctx) ||
817         !field_mul(group, tmp1, &a->Y, Zb23, ctx)) {
818       goto end;
819     }
820     // tmp1_ = tmp1
821   } else {
822     tmp1_ = &a->Y;
823   }
824   if (!a_Z_is_one) {
825     if (!field_mul(group, Za23, Za23, &a->Z, ctx) ||
826         !field_mul(group, tmp2, &b->Y, Za23, ctx)) {
827       goto end;
828     }
829     // tmp2_ = tmp2
830   } else {
831     tmp2_ = &b->Y;
832   }
833
834   // compare  Y_a*Z_b^3  with  Y_b*Z_a^3
835   if (BN_cmp(tmp1_, tmp2_) != 0) {
836     ret = 1;  // points differ
837     goto end;
838   }
839
840   // points are equal
841   ret = 0;
842
843 end:
844   BN_CTX_end(ctx);
845   BN_CTX_free(new_ctx);
846   return ret;
847 }
848
849 int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
850                               BN_CTX *ctx) {
851   BN_CTX *new_ctx = NULL;
852   BIGNUM *x, *y;
853   int ret = 0;
854
855   if (BN_cmp(&point->Z, &group->one) == 0 ||
856       EC_POINT_is_at_infinity(group, point)) {
857     return 1;
858   }
859
860   if (ctx == NULL) {
861     ctx = new_ctx = BN_CTX_new();
862     if (ctx == NULL) {
863       return 0;
864     }
865   }
866
867   BN_CTX_start(ctx);
868   x = BN_CTX_get(ctx);
869   y = BN_CTX_get(ctx);
870   if (y == NULL) {
871     goto err;
872   }
873
874   if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx) ||
875       !EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
876     goto err;
877   }
878   if (BN_cmp(&point->Z, &group->one) != 0) {
879     OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
880     goto err;
881   }
882
883   ret = 1;
884
885 err:
886   BN_CTX_end(ctx);
887   BN_CTX_free(new_ctx);
888   return ret;
889 }
890
891 int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
892                                      EC_POINT *points[], BN_CTX *ctx) {
893   BN_CTX *new_ctx = NULL;
894   BIGNUM *tmp, *tmp_Z;
895   BIGNUM **prod_Z = NULL;
896   int ret = 0;
897
898   if (num == 0) {
899     return 1;
900   }
901
902   if (ctx == NULL) {
903     ctx = new_ctx = BN_CTX_new();
904     if (ctx == NULL) {
905       return 0;
906     }
907   }
908
909   BN_CTX_start(ctx);
910   tmp = BN_CTX_get(ctx);
911   tmp_Z = BN_CTX_get(ctx);
912   if (tmp == NULL || tmp_Z == NULL) {
913     goto err;
914   }
915
916   prod_Z = OPENSSL_malloc(num * sizeof(prod_Z[0]));
917   if (prod_Z == NULL) {
918     goto err;
919   }
920   OPENSSL_memset(prod_Z, 0, num * sizeof(prod_Z[0]));
921   for (size_t i = 0; i < num; i++) {
922     prod_Z[i] = BN_new();
923     if (prod_Z[i] == NULL) {
924       goto err;
925     }
926   }
927
928   // Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
929   // skipping any zero-valued inputs (pretend that they're 1).
930
931   if (!BN_is_zero(&points[0]->Z)) {
932     if (!BN_copy(prod_Z[0], &points[0]->Z)) {
933       goto err;
934     }
935   } else {
936     if (BN_copy(prod_Z[0], &group->one) == NULL) {
937       goto err;
938     }
939   }
940
941   for (size_t i = 1; i < num; i++) {
942     if (!BN_is_zero(&points[i]->Z)) {
943       if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1],
944                                   &points[i]->Z, ctx)) {
945         goto err;
946       }
947     } else {
948       if (!BN_copy(prod_Z[i], prod_Z[i - 1])) {
949         goto err;
950       }
951     }
952   }
953
954   // Now use a single explicit inversion to replace every non-zero points[i]->Z
955   // by its inverse. We use |BN_mod_inverse_odd| instead of doing a constant-
956   // time inversion using Fermat's Little Theorem because this function is
957   // usually only used for converting multiples of a public key point to
958   // affine, and a public key point isn't secret. If we were to use Fermat's
959   // Little Theorem then the cost of the inversion would usually be so high
960   // that converting the multiples to affine would be counterproductive.
961   int no_inverse;
962   if (!BN_mod_inverse_odd(tmp, &no_inverse, prod_Z[num - 1], &group->field,
963                           ctx)) {
964     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
965     goto err;
966   }
967
968   if (group->meth->field_encode != NULL) {
969     // In the Montgomery case, we just turned R*H (representing H)
970     // into 1/(R*H), but we need R*(1/H) (representing 1/H);
971     // i.e. we need to multiply by the Montgomery factor twice.
972     if (!group->meth->field_encode(group, tmp, tmp, ctx) ||
973         !group->meth->field_encode(group, tmp, tmp, ctx)) {
974       goto err;
975     }
976   }
977
978   for (size_t i = num - 1; i > 0; --i) {
979     // Loop invariant: tmp is the product of the inverses of
980     // points[0]->Z .. points[i]->Z (zero-valued inputs skipped).
981     if (BN_is_zero(&points[i]->Z)) {
982       continue;
983     }
984
985     // Set tmp_Z to the inverse of points[i]->Z (as product
986     // of Z inverses 0 .. i, Z values 0 .. i - 1).
987     if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx) ||
988         // Update tmp to satisfy the loop invariant for i - 1.
989         !group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx) ||
990         // Replace points[i]->Z by its inverse.
991         !BN_copy(&points[i]->Z, tmp_Z)) {
992       goto err;
993     }
994   }
995
996   // Replace points[0]->Z by its inverse.
997   if (!BN_is_zero(&points[0]->Z) && !BN_copy(&points[0]->Z, tmp)) {
998     goto err;
999   }
1000
1001   // Finally, fix up the X and Y coordinates for all points.
1002   for (size_t i = 0; i < num; i++) {
1003     EC_POINT *p = points[i];
1004
1005     if (!BN_is_zero(&p->Z)) {
1006       // turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1).
1007       if (!group->meth->field_sqr(group, tmp, &p->Z, ctx) ||
1008           !group->meth->field_mul(group, &p->X, &p->X, tmp, ctx) ||
1009           !group->meth->field_mul(group, tmp, tmp, &p->Z, ctx) ||
1010           !group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) {
1011         goto err;
1012       }
1013
1014       if (BN_copy(&p->Z, &group->one) == NULL) {
1015         goto err;
1016       }
1017     }
1018   }
1019
1020   ret = 1;
1021
1022 err:
1023   BN_CTX_end(ctx);
1024   BN_CTX_free(new_ctx);
1025   if (prod_Z != NULL) {
1026     for (size_t i = 0; i < num; i++) {
1027       if (prod_Z[i] == NULL) {
1028         break;
1029       }
1030       BN_clear_free(prod_Z[i]);
1031     }
1032     OPENSSL_free(prod_Z);
1033   }
1034
1035   return ret;
1036 }
1037
1038 int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1039                             const BIGNUM *b, BN_CTX *ctx) {
1040   return BN_mod_mul(r, a, b, &group->field, ctx);
1041 }
1042
1043 int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1044                             BN_CTX *ctx) {
1045   return BN_mod_sqr(r, a, &group->field, ctx);
1046 }