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