LCOV - code coverage report
Current view: top level - ec - ecp_smpl.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 453 553 81.9 %
Date: 2014-08-02 Functions: 23 28 82.1 %
Branches: 322 636 50.6 %

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

Generated by: LCOV version 1.9