OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
ecp_smpl.c
Go to the documentation of this file.
1 /* crypto/ec/ecp_smpl.c */
2 /* Includes code written by Lenka Fibikova <[email protected]>
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
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  * ([email protected]). This product includes software written by Tim
56  * Hudson ([email protected]).
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 #include <openssl/symhacks.h>
67 
68 #ifdef OPENSSL_FIPS
69 #include <openssl/fips.h>
70 #endif
71 
72 #include "ec_lcl.h"
73 
75  {
76 #ifdef OPENSSL_FIPS
77  return fips_ec_gfp_simple_method();
78 #else
79  static const EC_METHOD ret = {
99  0,0,0,
108  0 /* mul */,
109  0 /* precompute_mult */,
110  0 /* have_precompute_mult */,
113  0 /* field_div */,
114  0 /* field_encode */,
115  0 /* field_decode */,
116  0 /* field_set_to_one */ };
117 
118  return &ret;
119 #endif
120  }
121 
122 
123 /* Most method functions in this file are designed to work with
124  * non-trivial representations of field elements if necessary
125  * (see ecp_mont.c): while standard modular addition and subtraction
126  * are used, the field_mul and field_sqr methods will be used for
127  * multiplication, and field_encode and field_decode (if defined)
128  * will be used for converting between representations.
129 
130  * Functions ec_GFp_simple_points_make_affine() and
131  * ec_GFp_simple_point_get_affine_coordinates() specifically assume
132  * that if a non-trivial representation is used, it is a Montgomery
133  * representation (i.e. 'encoding' means multiplying by some factor R).
134  */
135 
136 
138  {
139  BN_init(&group->field);
140  BN_init(&group->a);
141  BN_init(&group->b);
142  group->a_is_minus3 = 0;
143  return 1;
144  }
145 
146 
148  {
149  BN_free(&group->field);
150  BN_free(&group->a);
151  BN_free(&group->b);
152  }
153 
154 
156  {
157  BN_clear_free(&group->field);
158  BN_clear_free(&group->a);
159  BN_clear_free(&group->b);
160  }
161 
162 
164  {
165  if (!BN_copy(&dest->field, &src->field)) return 0;
166  if (!BN_copy(&dest->a, &src->a)) return 0;
167  if (!BN_copy(&dest->b, &src->b)) return 0;
168 
169  dest->a_is_minus3 = src->a_is_minus3;
170 
171  return 1;
172  }
173 
174 
176  const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
177  {
178  int ret = 0;
179  BN_CTX *new_ctx = NULL;
180  BIGNUM *tmp_a;
181 
182  /* p must be a prime > 3 */
183  if (BN_num_bits(p) <= 2 || !BN_is_odd(p))
184  {
186  return 0;
187  }
188 
189  if (ctx == NULL)
190  {
191  ctx = new_ctx = BN_CTX_new();
192  if (ctx == NULL)
193  return 0;
194  }
195 
196  BN_CTX_start(ctx);
197  tmp_a = BN_CTX_get(ctx);
198  if (tmp_a == NULL) goto err;
199 
200  /* group->field */
201  if (!BN_copy(&group->field, p)) goto err;
202  BN_set_negative(&group->field, 0);
203 
204  /* group->a */
205  if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
206  if (group->meth->field_encode)
207  { if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) goto err; }
208  else
209  if (!BN_copy(&group->a, tmp_a)) goto err;
210 
211  /* group->b */
212  if (!BN_nnmod(&group->b, b, p, ctx)) goto err;
213  if (group->meth->field_encode)
214  if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) goto err;
215 
216  /* group->a_is_minus3 */
217  if (!BN_add_word(tmp_a, 3)) goto err;
218  group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
219 
220  ret = 1;
221 
222  err:
223  BN_CTX_end(ctx);
224  if (new_ctx != NULL)
225  BN_CTX_free(new_ctx);
226  return ret;
227  }
228 
229 
231  {
232  int ret = 0;
233  BN_CTX *new_ctx = NULL;
234 
235  if (p != NULL)
236  {
237  if (!BN_copy(p, &group->field)) return 0;
238  }
239 
240  if (a != NULL || b != NULL)
241  {
242  if (group->meth->field_decode)
243  {
244  if (ctx == NULL)
245  {
246  ctx = new_ctx = BN_CTX_new();
247  if (ctx == NULL)
248  return 0;
249  }
250  if (a != NULL)
251  {
252  if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
253  }
254  if (b != NULL)
255  {
256  if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
257  }
258  }
259  else
260  {
261  if (a != NULL)
262  {
263  if (!BN_copy(a, &group->a)) goto err;
264  }
265  if (b != NULL)
266  {
267  if (!BN_copy(b, &group->b)) goto err;
268  }
269  }
270  }
271 
272  ret = 1;
273 
274  err:
275  if (new_ctx)
276  BN_CTX_free(new_ctx);
277  return ret;
278  }
279 
280 
282  {
283  return BN_num_bits(&group->field);
284  }
285 
286 
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  {
296  ctx = new_ctx = BN_CTX_new();
297  if (ctx == NULL)
298  {
300  goto err;
301  }
302  }
303  BN_CTX_start(ctx);
304  a = BN_CTX_get(ctx);
305  b = BN_CTX_get(ctx);
306  tmp_1 = BN_CTX_get(ctx);
307  tmp_2 = BN_CTX_get(ctx);
308  order = BN_CTX_get(ctx);
309  if (order == NULL) goto err;
310 
311  if (group->meth->field_decode)
312  {
313  if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
314  if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
315  }
316  else
317  {
318  if (!BN_copy(a, &group->a)) goto err;
319  if (!BN_copy(b, &group->b)) goto err;
320  }
321 
322  /* check the discriminant:
323  * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
324  * 0 =< a, b < p */
325  if (BN_is_zero(a))
326  {
327  if (BN_is_zero(b)) goto err;
328  }
329  else if (!BN_is_zero(b))
330  {
331  if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
332  if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
333  if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
334  /* tmp_1 = 4*a^3 */
335 
336  if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err;
337  if (!BN_mul_word(tmp_2, 27)) goto err;
338  /* tmp_2 = 27*b^2 */
339 
340  if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
341  if (BN_is_zero(a)) goto err;
342  }
343  ret = 1;
344 
345 err:
346  if (ctx != NULL)
347  BN_CTX_end(ctx);
348  if (new_ctx != NULL)
349  BN_CTX_free(new_ctx);
350  return ret;
351  }
352 
353 
355  {
356  BN_init(&point->X);
357  BN_init(&point->Y);
358  BN_init(&point->Z);
359  point->Z_is_one = 0;
360 
361  return 1;
362  }
363 
364 
366  {
367  BN_free(&point->X);
368  BN_free(&point->Y);
369  BN_free(&point->Z);
370  }
371 
372 
374  {
375  BN_clear_free(&point->X);
376  BN_clear_free(&point->Y);
377  BN_clear_free(&point->Z);
378  point->Z_is_one = 0;
379  }
380 
381 
383  {
384  if (!BN_copy(&dest->X, &src->X)) return 0;
385  if (!BN_copy(&dest->Y, &src->Y)) return 0;
386  if (!BN_copy(&dest->Z, &src->Z)) return 0;
387  dest->Z_is_one = src->Z_is_one;
388 
389  return 1;
390  }
391 
392 
394  {
395  point->Z_is_one = 0;
396  BN_zero(&point->Z);
397  return 1;
398  }
399 
400 
402  const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
403  {
404  BN_CTX *new_ctx = NULL;
405  int ret = 0;
406 
407  if (ctx == NULL)
408  {
409  ctx = new_ctx = BN_CTX_new();
410  if (ctx == NULL)
411  return 0;
412  }
413 
414  if (x != NULL)
415  {
416  if (!BN_nnmod(&point->X, x, &group->field, ctx)) goto err;
417  if (group->meth->field_encode)
418  {
419  if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) goto err;
420  }
421  }
422 
423  if (y != NULL)
424  {
425  if (!BN_nnmod(&point->Y, y, &group->field, ctx)) goto err;
426  if (group->meth->field_encode)
427  {
428  if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) goto err;
429  }
430  }
431 
432  if (z != NULL)
433  {
434  int Z_is_one;
435 
436  if (!BN_nnmod(&point->Z, z, &group->field, ctx)) goto err;
437  Z_is_one = BN_is_one(&point->Z);
438  if (group->meth->field_encode)
439  {
440  if (Z_is_one && (group->meth->field_set_to_one != 0))
441  {
442  if (!group->meth->field_set_to_one(group, &point->Z, ctx)) goto err;
443  }
444  else
445  {
446  if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) goto err;
447  }
448  }
449  point->Z_is_one = Z_is_one;
450  }
451 
452  ret = 1;
453 
454  err:
455  if (new_ctx != NULL)
456  BN_CTX_free(new_ctx);
457  return ret;
458  }
459 
460 
462  BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
463  {
464  BN_CTX *new_ctx = NULL;
465  int ret = 0;
466 
467  if (group->meth->field_decode != 0)
468  {
469  if (ctx == NULL)
470  {
471  ctx = new_ctx = BN_CTX_new();
472  if (ctx == NULL)
473  return 0;
474  }
475 
476  if (x != NULL)
477  {
478  if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
479  }
480  if (y != NULL)
481  {
482  if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
483  }
484  if (z != NULL)
485  {
486  if (!group->meth->field_decode(group, z, &point->Z, ctx)) goto err;
487  }
488  }
489  else
490  {
491  if (x != NULL)
492  {
493  if (!BN_copy(x, &point->X)) goto err;
494  }
495  if (y != NULL)
496  {
497  if (!BN_copy(y, &point->Y)) goto err;
498  }
499  if (z != NULL)
500  {
501  if (!BN_copy(z, &point->Z)) goto err;
502  }
503  }
504 
505  ret = 1;
506 
507  err:
508  if (new_ctx != NULL)
509  BN_CTX_free(new_ctx);
510  return ret;
511  }
512 
513 
515  const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
516  {
517  if (x == NULL || y == NULL)
518  {
519  /* unlike for projective coordinates, we do not tolerate this */
521  return 0;
522  }
523 
524  return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
525  }
526 
527 
529  BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
530  {
531  BN_CTX *new_ctx = NULL;
532  BIGNUM *Z, *Z_1, *Z_2, *Z_3;
533  const BIGNUM *Z_;
534  int ret = 0;
535 
536  if (EC_POINT_is_at_infinity(group, point))
537  {
539  return 0;
540  }
541 
542  if (ctx == NULL)
543  {
544  ctx = new_ctx = BN_CTX_new();
545  if (ctx == NULL)
546  return 0;
547  }
548 
549  BN_CTX_start(ctx);
550  Z = BN_CTX_get(ctx);
551  Z_1 = BN_CTX_get(ctx);
552  Z_2 = BN_CTX_get(ctx);
553  Z_3 = BN_CTX_get(ctx);
554  if (Z_3 == NULL) goto err;
555 
556  /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
557 
558  if (group->meth->field_decode)
559  {
560  if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err;
561  Z_ = Z;
562  }
563  else
564  {
565  Z_ = &point->Z;
566  }
567 
568  if (BN_is_one(Z_))
569  {
570  if (group->meth->field_decode)
571  {
572  if (x != NULL)
573  {
574  if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
575  }
576  if (y != NULL)
577  {
578  if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
579  }
580  }
581  else
582  {
583  if (x != NULL)
584  {
585  if (!BN_copy(x, &point->X)) goto err;
586  }
587  if (y != NULL)
588  {
589  if (!BN_copy(y, &point->Y)) goto err;
590  }
591  }
592  }
593  else
594  {
595  if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx))
596  {
598  goto err;
599  }
600 
601  if (group->meth->field_encode == 0)
602  {
603  /* field_sqr works on standard representation */
604  if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) goto err;
605  }
606  else
607  {
608  if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err;
609  }
610 
611  if (x != NULL)
612  {
613  /* in the Montgomery case, field_mul will cancel out Montgomery factor in X: */
614  if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) goto err;
615  }
616 
617  if (y != NULL)
618  {
619  if (group->meth->field_encode == 0)
620  {
621  /* field_mul works on standard representation */
622  if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err;
623  }
624  else
625  {
626  if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err;
627  }
628 
629  /* in the Montgomery case, field_mul will cancel out Montgomery factor in Y: */
630  if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) goto err;
631  }
632  }
633 
634  ret = 1;
635 
636  err:
637  BN_CTX_end(ctx);
638  if (new_ctx != NULL)
639  BN_CTX_free(new_ctx);
640  return ret;
641  }
642 
643 int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
644  {
645  int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
646  int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
647  const BIGNUM *p;
648  BN_CTX *new_ctx = NULL;
649  BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
650  int ret = 0;
651 
652  if (a == b)
653  return EC_POINT_dbl(group, r, a, ctx);
654  if (EC_POINT_is_at_infinity(group, a))
655  return EC_POINT_copy(r, b);
656  if (EC_POINT_is_at_infinity(group, b))
657  return EC_POINT_copy(r, a);
658 
659  field_mul = group->meth->field_mul;
660  field_sqr = group->meth->field_sqr;
661  p = &group->field;
662 
663  if (ctx == NULL)
664  {
665  ctx = new_ctx = BN_CTX_new();
666  if (ctx == NULL)
667  return 0;
668  }
669 
670  BN_CTX_start(ctx);
671  n0 = BN_CTX_get(ctx);
672  n1 = BN_CTX_get(ctx);
673  n2 = BN_CTX_get(ctx);
674  n3 = BN_CTX_get(ctx);
675  n4 = BN_CTX_get(ctx);
676  n5 = BN_CTX_get(ctx);
677  n6 = BN_CTX_get(ctx);
678  if (n6 == NULL) goto end;
679 
680  /* Note that in this function we must not read components of 'a' or 'b'
681  * once we have written the corresponding components of 'r'.
682  * ('r' might be one of 'a' or 'b'.)
683  */
684 
685  /* n1, n2 */
686  if (b->Z_is_one)
687  {
688  if (!BN_copy(n1, &a->X)) goto end;
689  if (!BN_copy(n2, &a->Y)) goto end;
690  /* n1 = X_a */
691  /* n2 = Y_a */
692  }
693  else
694  {
695  if (!field_sqr(group, n0, &b->Z, ctx)) goto end;
696  if (!field_mul(group, n1, &a->X, n0, ctx)) goto end;
697  /* n1 = X_a * Z_b^2 */
698 
699  if (!field_mul(group, n0, n0, &b->Z, ctx)) goto end;
700  if (!field_mul(group, n2, &a->Y, n0, ctx)) goto end;
701  /* n2 = Y_a * Z_b^3 */
702  }
703 
704  /* n3, n4 */
705  if (a->Z_is_one)
706  {
707  if (!BN_copy(n3, &b->X)) goto end;
708  if (!BN_copy(n4, &b->Y)) goto end;
709  /* n3 = X_b */
710  /* n4 = Y_b */
711  }
712  else
713  {
714  if (!field_sqr(group, n0, &a->Z, ctx)) goto end;
715  if (!field_mul(group, n3, &b->X, n0, ctx)) goto end;
716  /* n3 = X_b * Z_a^2 */
717 
718  if (!field_mul(group, n0, n0, &a->Z, ctx)) goto end;
719  if (!field_mul(group, n4, &b->Y, n0, ctx)) goto end;
720  /* n4 = Y_b * Z_a^3 */
721  }
722 
723  /* n5, n6 */
724  if (!BN_mod_sub_quick(n5, n1, n3, p)) goto end;
725  if (!BN_mod_sub_quick(n6, n2, n4, p)) goto end;
726  /* n5 = n1 - n3 */
727  /* n6 = n2 - n4 */
728 
729  if (BN_is_zero(n5))
730  {
731  if (BN_is_zero(n6))
732  {
733  /* a is the same point as b */
734  BN_CTX_end(ctx);
735  ret = EC_POINT_dbl(group, r, a, ctx);
736  ctx = NULL;
737  goto end;
738  }
739  else
740  {
741  /* a is the inverse of b */
742  BN_zero(&r->Z);
743  r->Z_is_one = 0;
744  ret = 1;
745  goto end;
746  }
747  }
748 
749  /* 'n7', 'n8' */
750  if (!BN_mod_add_quick(n1, n1, n3, p)) goto end;
751  if (!BN_mod_add_quick(n2, n2, n4, p)) goto end;
752  /* 'n7' = n1 + n3 */
753  /* 'n8' = n2 + n4 */
754 
755  /* Z_r */
756  if (a->Z_is_one && b->Z_is_one)
757  {
758  if (!BN_copy(&r->Z, n5)) goto end;
759  }
760  else
761  {
762  if (a->Z_is_one)
763  { if (!BN_copy(n0, &b->Z)) goto end; }
764  else if (b->Z_is_one)
765  { if (!BN_copy(n0, &a->Z)) goto end; }
766  else
767  { if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) goto end; }
768  if (!field_mul(group, &r->Z, n0, n5, ctx)) goto end;
769  }
770  r->Z_is_one = 0;
771  /* Z_r = Z_a * Z_b * n5 */
772 
773  /* X_r */
774  if (!field_sqr(group, n0, n6, ctx)) goto end;
775  if (!field_sqr(group, n4, n5, ctx)) goto end;
776  if (!field_mul(group, n3, n1, n4, ctx)) goto end;
777  if (!BN_mod_sub_quick(&r->X, n0, n3, p)) goto end;
778  /* X_r = n6^2 - n5^2 * 'n7' */
779 
780  /* 'n9' */
781  if (!BN_mod_lshift1_quick(n0, &r->X, p)) goto end;
782  if (!BN_mod_sub_quick(n0, n3, n0, p)) goto end;
783  /* n9 = n5^2 * 'n7' - 2 * X_r */
784 
785  /* Y_r */
786  if (!field_mul(group, n0, n0, n6, ctx)) goto end;
787  if (!field_mul(group, n5, n4, n5, ctx)) goto end; /* now n5 is n5^3 */
788  if (!field_mul(group, n1, n2, n5, ctx)) goto end;
789  if (!BN_mod_sub_quick(n0, n0, n1, p)) goto end;
790  if (BN_is_odd(n0))
791  if (!BN_add(n0, n0, p)) goto end;
792  /* now 0 <= n0 < 2*p, and n0 is even */
793  if (!BN_rshift1(&r->Y, n0)) goto end;
794  /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
795 
796  ret = 1;
797 
798  end:
799  if (ctx) /* otherwise we already called BN_CTX_end */
800  BN_CTX_end(ctx);
801  if (new_ctx != NULL)
802  BN_CTX_free(new_ctx);
803  return ret;
804  }
805 
806 
807 int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
808  {
809  int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
810  int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
811  const BIGNUM *p;
812  BN_CTX *new_ctx = NULL;
813  BIGNUM *n0, *n1, *n2, *n3;
814  int ret = 0;
815 
816  if (EC_POINT_is_at_infinity(group, a))
817  {
818  BN_zero(&r->Z);
819  r->Z_is_one = 0;
820  return 1;
821  }
822 
823  field_mul = group->meth->field_mul;
824  field_sqr = group->meth->field_sqr;
825  p = &group->field;
826 
827  if (ctx == NULL)
828  {
829  ctx = new_ctx = BN_CTX_new();
830  if (ctx == NULL)
831  return 0;
832  }
833 
834  BN_CTX_start(ctx);
835  n0 = BN_CTX_get(ctx);
836  n1 = BN_CTX_get(ctx);
837  n2 = BN_CTX_get(ctx);
838  n3 = BN_CTX_get(ctx);
839  if (n3 == NULL) goto err;
840 
841  /* Note that in this function we must not read components of 'a'
842  * once we have written the corresponding components of 'r'.
843  * ('r' might the same as 'a'.)
844  */
845 
846  /* n1 */
847  if (a->Z_is_one)
848  {
849  if (!field_sqr(group, n0, &a->X, ctx)) goto err;
850  if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
851  if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
852  if (!BN_mod_add_quick(n1, n0, &group->a, p)) goto err;
853  /* n1 = 3 * X_a^2 + a_curve */
854  }
855  else if (group->a_is_minus3)
856  {
857  if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
858  if (!BN_mod_add_quick(n0, &a->X, n1, p)) goto err;
859  if (!BN_mod_sub_quick(n2, &a->X, n1, p)) goto err;
860  if (!field_mul(group, n1, n0, n2, ctx)) goto err;
861  if (!BN_mod_lshift1_quick(n0, n1, p)) goto err;
862  if (!BN_mod_add_quick(n1, n0, n1, p)) goto err;
863  /* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
864  * = 3 * X_a^2 - 3 * Z_a^4 */
865  }
866  else
867  {
868  if (!field_sqr(group, n0, &a->X, ctx)) goto err;
869  if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
870  if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
871  if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
872  if (!field_sqr(group, n1, n1, ctx)) goto err;
873  if (!field_mul(group, n1, n1, &group->a, ctx)) goto err;
874  if (!BN_mod_add_quick(n1, n1, n0, p)) goto err;
875  /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
876  }
877 
878  /* Z_r */
879  if (a->Z_is_one)
880  {
881  if (!BN_copy(n0, &a->Y)) goto err;
882  }
883  else
884  {
885  if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) goto err;
886  }
887  if (!BN_mod_lshift1_quick(&r->Z, n0, p)) goto err;
888  r->Z_is_one = 0;
889  /* Z_r = 2 * Y_a * Z_a */
890 
891  /* n2 */
892  if (!field_sqr(group, n3, &a->Y, ctx)) goto err;
893  if (!field_mul(group, n2, &a->X, n3, ctx)) goto err;
894  if (!BN_mod_lshift_quick(n2, n2, 2, p)) goto err;
895  /* n2 = 4 * X_a * Y_a^2 */
896 
897  /* X_r */
898  if (!BN_mod_lshift1_quick(n0, n2, p)) goto err;
899  if (!field_sqr(group, &r->X, n1, ctx)) goto err;
900  if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) goto err;
901  /* X_r = n1^2 - 2 * n2 */
902 
903  /* n3 */
904  if (!field_sqr(group, n0, n3, ctx)) goto err;
905  if (!BN_mod_lshift_quick(n3, n0, 3, p)) goto err;
906  /* n3 = 8 * Y_a^4 */
907 
908  /* Y_r */
909  if (!BN_mod_sub_quick(n0, n2, &r->X, p)) goto err;
910  if (!field_mul(group, n0, n1, n0, ctx)) goto err;
911  if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) goto err;
912  /* Y_r = n1 * (n2 - X_r) - n3 */
913 
914  ret = 1;
915 
916  err:
917  BN_CTX_end(ctx);
918  if (new_ctx != NULL)
919  BN_CTX_free(new_ctx);
920  return ret;
921  }
922 
923 
924 int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
925  {
926  if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
927  /* point is its own inverse */
928  return 1;
929 
930  return BN_usub(&point->Y, &group->field, &point->Y);
931  }
932 
933 
934 int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
935  {
936  return BN_is_zero(&point->Z);
937  }
938 
939 
940 int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
941  {
942  int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
943  int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
944  const BIGNUM *p;
945  BN_CTX *new_ctx = NULL;
946  BIGNUM *rh, *tmp, *Z4, *Z6;
947  int ret = -1;
948 
949  if (EC_POINT_is_at_infinity(group, point))
950  return 1;
951 
952  field_mul = group->meth->field_mul;
953  field_sqr = group->meth->field_sqr;
954  p = &group->field;
955 
956  if (ctx == NULL)
957  {
958  ctx = new_ctx = BN_CTX_new();
959  if (ctx == NULL)
960  return -1;
961  }
962 
963  BN_CTX_start(ctx);
964  rh = BN_CTX_get(ctx);
965  tmp = BN_CTX_get(ctx);
966  Z4 = BN_CTX_get(ctx);
967  Z6 = BN_CTX_get(ctx);
968  if (Z6 == NULL) goto err;
969 
970  /* We have a curve defined by a Weierstrass equation
971  * y^2 = x^3 + a*x + b.
972  * The point to consider is given in Jacobian projective coordinates
973  * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
974  * Substituting this and multiplying by Z^6 transforms the above equation into
975  * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
976  * To test this, we add up the right-hand side in 'rh'.
977  */
978 
979  /* rh := X^2 */
980  if (!field_sqr(group, rh, &point->X, ctx)) goto err;
981 
982  if (!point->Z_is_one)
983  {
984  if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;
985  if (!field_sqr(group, Z4, tmp, ctx)) goto err;
986  if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;
987 
988  /* rh := (rh + a*Z^4)*X */
989  if (group->a_is_minus3)
990  {
991  if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;
992  if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;
993  if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;
994  if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
995  }
996  else
997  {
998  if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;
999  if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
1000  if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1001  }
1002 
1003  /* rh := rh + b*Z^6 */
1004  if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;
1005  if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
1006  }
1007  else
1008  {
1009  /* point->Z_is_one */
1010 
1011  /* rh := (rh + a)*X */
1012  if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;
1013  if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1014  /* rh := rh + b */
1015  if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
1016  }
1017 
1018  /* 'lh' := Y^2 */
1019  if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;
1020 
1021  ret = (0 == BN_ucmp(tmp, rh));
1022 
1023  err:
1024  BN_CTX_end(ctx);
1025  if (new_ctx != NULL)
1026  BN_CTX_free(new_ctx);
1027  return ret;
1028  }
1029 
1030 
1031 int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
1032  {
1033  /* return values:
1034  * -1 error
1035  * 0 equal (in affine coordinates)
1036  * 1 not equal
1037  */
1038 
1039  int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
1040  int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1041  BN_CTX *new_ctx = NULL;
1042  BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
1043  const BIGNUM *tmp1_, *tmp2_;
1044  int ret = -1;
1045 
1046  if (EC_POINT_is_at_infinity(group, a))
1047  {
1048  return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
1049  }
1050 
1051  if (EC_POINT_is_at_infinity(group, b))
1052  return 1;
1053 
1054  if (a->Z_is_one && b->Z_is_one)
1055  {
1056  return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
1057  }
1058 
1059  field_mul = group->meth->field_mul;
1060  field_sqr = group->meth->field_sqr;
1061 
1062  if (ctx == NULL)
1063  {
1064  ctx = new_ctx = BN_CTX_new();
1065  if (ctx == NULL)
1066  return -1;
1067  }
1068 
1069  BN_CTX_start(ctx);
1070  tmp1 = BN_CTX_get(ctx);
1071  tmp2 = BN_CTX_get(ctx);
1072  Za23 = BN_CTX_get(ctx);
1073  Zb23 = BN_CTX_get(ctx);
1074  if (Zb23 == NULL) goto end;
1075 
1076  /* We have to decide whether
1077  * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
1078  * or equivalently, whether
1079  * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
1080  */
1081 
1082  if (!b->Z_is_one)
1083  {
1084  if (!field_sqr(group, Zb23, &b->Z, ctx)) goto end;
1085  if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) goto end;
1086  tmp1_ = tmp1;
1087  }
1088  else
1089  tmp1_ = &a->X;
1090  if (!a->Z_is_one)
1091  {
1092  if (!field_sqr(group, Za23, &a->Z, ctx)) goto end;
1093  if (!field_mul(group, tmp2, &b->X, Za23, ctx)) goto end;
1094  tmp2_ = tmp2;
1095  }
1096  else
1097  tmp2_ = &b->X;
1098 
1099  /* compare X_a*Z_b^2 with X_b*Z_a^2 */
1100  if (BN_cmp(tmp1_, tmp2_) != 0)
1101  {
1102  ret = 1; /* points differ */
1103  goto end;
1104  }
1105 
1106 
1107  if (!b->Z_is_one)
1108  {
1109  if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) goto end;
1110  if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) goto end;
1111  /* tmp1_ = tmp1 */
1112  }
1113  else
1114  tmp1_ = &a->Y;
1115  if (!a->Z_is_one)
1116  {
1117  if (!field_mul(group, Za23, Za23, &a->Z, ctx)) goto end;
1118  if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) goto end;
1119  /* tmp2_ = tmp2 */
1120  }
1121  else
1122  tmp2_ = &b->Y;
1123 
1124  /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
1125  if (BN_cmp(tmp1_, tmp2_) != 0)
1126  {
1127  ret = 1; /* points differ */
1128  goto end;
1129  }
1130 
1131  /* points are equal */
1132  ret = 0;
1133 
1134  end:
1135  BN_CTX_end(ctx);
1136  if (new_ctx != NULL)
1137  BN_CTX_free(new_ctx);
1138  return ret;
1139  }
1140 
1141 
1142 int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1143  {
1144  BN_CTX *new_ctx = NULL;
1145  BIGNUM *x, *y;
1146  int ret = 0;
1147 
1148  if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
1149  return 1;
1150 
1151  if (ctx == NULL)
1152  {
1153  ctx = new_ctx = BN_CTX_new();
1154  if (ctx == NULL)
1155  return 0;
1156  }
1157 
1158  BN_CTX_start(ctx);
1159  x = BN_CTX_get(ctx);
1160  y = BN_CTX_get(ctx);
1161  if (y == NULL) goto err;
1162 
1163  if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
1164  if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
1165  if (!point->Z_is_one)
1166  {
1168  goto err;
1169  }
1170 
1171  ret = 1;
1172 
1173  err:
1174  BN_CTX_end(ctx);
1175  if (new_ctx != NULL)
1176  BN_CTX_free(new_ctx);
1177  return ret;
1178  }
1179 
1180 
1181 int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
1182  {
1183  BN_CTX *new_ctx = NULL;
1184  BIGNUM *tmp0, *tmp1;
1185  size_t pow2 = 0;
1186  BIGNUM **heap = NULL;
1187  size_t i;
1188  int ret = 0;
1189 
1190  if (num == 0)
1191  return 1;
1192 
1193  if (ctx == NULL)
1194  {
1195  ctx = new_ctx = BN_CTX_new();
1196  if (ctx == NULL)
1197  return 0;
1198  }
1199 
1200  BN_CTX_start(ctx);
1201  tmp0 = BN_CTX_get(ctx);
1202  tmp1 = BN_CTX_get(ctx);
1203  if (tmp0 == NULL || tmp1 == NULL) goto err;
1204 
1205  /* Before converting the individual points, compute inverses of all Z values.
1206  * Modular inversion is rather slow, but luckily we can do with a single
1207  * explicit inversion, plus about 3 multiplications per input value.
1208  */
1209 
1210  pow2 = 1;
1211  while (num > pow2)
1212  pow2 <<= 1;
1213  /* Now pow2 is the smallest power of 2 satifsying pow2 >= num.
1214  * We need twice that. */
1215  pow2 <<= 1;
1216 
1217  heap = OPENSSL_malloc(pow2 * sizeof heap[0]);
1218  if (heap == NULL) goto err;
1219 
1220  /* The array is used as a binary tree, exactly as in heapsort:
1221  *
1222  * heap[1]
1223  * heap[2] heap[3]
1224  * heap[4] heap[5] heap[6] heap[7]
1225  * heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15]
1226  *
1227  * We put the Z's in the last line;
1228  * then we set each other node to the product of its two child-nodes (where
1229  * empty or 0 entries are treated as ones);
1230  * then we invert heap[1];
1231  * then we invert each other node by replacing it by the product of its
1232  * parent (after inversion) and its sibling (before inversion).
1233  */
1234  heap[0] = NULL;
1235  for (i = pow2/2 - 1; i > 0; i--)
1236  heap[i] = NULL;
1237  for (i = 0; i < num; i++)
1238  heap[pow2/2 + i] = &points[i]->Z;
1239  for (i = pow2/2 + num; i < pow2; i++)
1240  heap[i] = NULL;
1241 
1242  /* set each node to the product of its children */
1243  for (i = pow2/2 - 1; i > 0; i--)
1244  {
1245  heap[i] = BN_new();
1246  if (heap[i] == NULL) goto err;
1247 
1248  if (heap[2*i] != NULL)
1249  {
1250  if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1]))
1251  {
1252  if (!BN_copy(heap[i], heap[2*i])) goto err;
1253  }
1254  else
1255  {
1256  if (BN_is_zero(heap[2*i]))
1257  {
1258  if (!BN_copy(heap[i], heap[2*i + 1])) goto err;
1259  }
1260  else
1261  {
1262  if (!group->meth->field_mul(group, heap[i],
1263  heap[2*i], heap[2*i + 1], ctx)) goto err;
1264  }
1265  }
1266  }
1267  }
1268 
1269  /* invert heap[1] */
1270  if (!BN_is_zero(heap[1]))
1271  {
1272  if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx))
1273  {
1275  goto err;
1276  }
1277  }
1278  if (group->meth->field_encode != 0)
1279  {
1280  /* in the Montgomery case, we just turned R*H (representing H)
1281  * into 1/(R*H), but we need R*(1/H) (representing 1/H);
1282  * i.e. we have need to multiply by the Montgomery factor twice */
1283  if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
1284  if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
1285  }
1286 
1287  /* set other heap[i]'s to their inverses */
1288  for (i = 2; i < pow2/2 + num; i += 2)
1289  {
1290  /* i is even */
1291  if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1]))
1292  {
1293  if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err;
1294  if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err;
1295  if (!BN_copy(heap[i], tmp0)) goto err;
1296  if (!BN_copy(heap[i + 1], tmp1)) goto err;
1297  }
1298  else
1299  {
1300  if (!BN_copy(heap[i], heap[i/2])) goto err;
1301  }
1302  }
1303 
1304  /* we have replaced all non-zero Z's by their inverses, now fix up all the points */
1305  for (i = 0; i < num; i++)
1306  {
1307  EC_POINT *p = points[i];
1308 
1309  if (!BN_is_zero(&p->Z))
1310  {
1311  /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
1312 
1313  if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err;
1314  if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err;
1315 
1316  if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err;
1317  if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err;
1318 
1319  if (group->meth->field_set_to_one != 0)
1320  {
1321  if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err;
1322  }
1323  else
1324  {
1325  if (!BN_one(&p->Z)) goto err;
1326  }
1327  p->Z_is_one = 1;
1328  }
1329  }
1330 
1331  ret = 1;
1332 
1333  err:
1334  BN_CTX_end(ctx);
1335  if (new_ctx != NULL)
1336  BN_CTX_free(new_ctx);
1337  if (heap != NULL)
1338  {
1339  /* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */
1340  for (i = pow2/2 - 1; i > 0; i--)
1341  {
1342  if (heap[i] != NULL)
1343  BN_clear_free(heap[i]);
1344  }
1345  OPENSSL_free(heap);
1346  }
1347  return ret;
1348  }
1349 
1350 
1351 int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
1352  {
1353  return BN_mod_mul(r, a, b, &group->field, ctx);
1354  }
1355 
1356 
1357 int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
1358  {
1359  return BN_mod_sqr(r, a, &group->field, ctx);
1360  }