Home | History | Annotate | Download | only in ec
      1 /* Originally written by Bodo Moeller for the OpenSSL project.
      2  * ====================================================================
      3  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  *
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in
     14  *    the documentation and/or other materials provided with the
     15  *    distribution.
     16  *
     17  * 3. All advertising materials mentioning features or use of this
     18  *    software must display the following acknowledgment:
     19  *    "This product includes software developed by the OpenSSL Project
     20  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
     21  *
     22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     23  *    endorse or promote products derived from this software without
     24  *    prior written permission. For written permission, please contact
     25  *    openssl-core (at) openssl.org.
     26  *
     27  * 5. Products derived from this software may not be called "OpenSSL"
     28  *    nor may "OpenSSL" appear in their names without prior written
     29  *    permission of the OpenSSL Project.
     30  *
     31  * 6. Redistributions of any form whatsoever must retain the following
     32  *    acknowledgment:
     33  *    "This product includes software developed by the OpenSSL Project
     34  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
     35  *
     36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     47  * OF THE POSSIBILITY OF SUCH DAMAGE.
     48  * ====================================================================
     49  *
     50  * This product includes cryptographic software written by Eric Young
     51  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     52  * Hudson (tjh (at) cryptsoft.com).
     53  *
     54  */
     55 /* ====================================================================
     56  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
     57  *
     58  * Portions of the attached software ("Contribution") are developed by
     59  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
     60  *
     61  * The Contribution is licensed pursuant to the OpenSSL open source
     62  * license provided above.
     63  *
     64  * The elliptic curve binary polynomial software is originally written by
     65  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
     66  * Laboratories. */
     67 
     68 #include <openssl/ec.h>
     69 
     70 #include <assert.h>
     71 #include <string.h>
     72 
     73 #include <openssl/bn.h>
     74 #include <openssl/err.h>
     75 #include <openssl/mem.h>
     76 #include <openssl/nid.h>
     77 
     78 #include "internal.h"
     79 #include "../../internal.h"
     80 #include "../bn/internal.h"
     81 #include "../delocate.h"
     82 
     83 
     84 static void ec_point_free(EC_POINT *point, int free_group);
     85 
     86 static const uint8_t kP224Params[6 * 28] = {
     87     // p
     88     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     89     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     90     0x00, 0x00, 0x00, 0x01,
     91     // a
     92     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     93     0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     94     0xFF, 0xFF, 0xFF, 0xFE,
     95     // b
     96     0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
     97     0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
     98     0x23, 0x55, 0xFF, 0xB4,
     99     // x
    100     0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
    101     0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
    102     0x11, 0x5C, 0x1D, 0x21,
    103     // y
    104     0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
    105     0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
    106     0x85, 0x00, 0x7e, 0x34,
    107     // order
    108     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    109     0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
    110     0x5C, 0x5C, 0x2A, 0x3D,
    111 };
    112 
    113 static const uint8_t kP256Params[6 * 32] = {
    114     // p
    115     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
    116     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    117     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    118     // a
    119     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
    120     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    121     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
    122     // b
    123     0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
    124     0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
    125     0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
    126     // x
    127     0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
    128     0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
    129     0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
    130     // y
    131     0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
    132     0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
    133     0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
    134     // order
    135     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    136     0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
    137     0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51,
    138 };
    139 
    140 static const uint8_t kP384Params[6 * 48] = {
    141     // p
    142     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    143     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    144     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
    145     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    146     // a
    147     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    148     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    149     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
    150     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
    151     // b
    152     0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
    153     0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
    154     0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
    155     0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
    156     // x
    157     0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
    158     0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
    159     0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
    160     0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
    161     // y
    162     0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
    163     0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
    164     0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
    165     0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
    166     // order
    167     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    168     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    169     0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
    170     0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73,
    171 };
    172 
    173 static const uint8_t kP521Params[6 * 66] = {
    174     // p
    175     0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    176     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    177     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    178     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    179     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    180     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    181     // a
    182     0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    183     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    184     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    185     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    186     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    187     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
    188     // b
    189     0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
    190     0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
    191     0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
    192     0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
    193     0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
    194     0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
    195     // x
    196     0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
    197     0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
    198     0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
    199     0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
    200     0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
    201     0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
    202     // y
    203     0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
    204     0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
    205     0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
    206     0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
    207     0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
    208     0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
    209     // order
    210     0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    211     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    212     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
    213     0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
    214     0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
    215     0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09,
    216 };
    217 
    218 DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) {
    219   // 1.3.132.0.35
    220   static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23};
    221   out->curves[0].nid = NID_secp521r1;
    222   out->curves[0].oid = kOIDP521;
    223   out->curves[0].oid_len = sizeof(kOIDP521);
    224   out->curves[0].comment = "NIST P-521";
    225   out->curves[0].param_len = 66;
    226   out->curves[0].params = kP521Params;
    227   out->curves[0].method = EC_GFp_mont_method();
    228 
    229   // 1.3.132.0.34
    230   static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22};
    231   out->curves[1].nid = NID_secp384r1;
    232   out->curves[1].oid = kOIDP384;
    233   out->curves[1].oid_len = sizeof(kOIDP384);
    234   out->curves[1].comment = "NIST P-384";
    235   out->curves[1].param_len = 48;
    236   out->curves[1].params = kP384Params;
    237   out->curves[1].method = EC_GFp_mont_method();
    238 
    239   // 1.2.840.10045.3.1.7
    240   static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce,
    241                                      0x3d, 0x03, 0x01, 0x07};
    242   out->curves[2].nid = NID_X9_62_prime256v1;
    243   out->curves[2].oid = kOIDP256;
    244   out->curves[2].oid_len = sizeof(kOIDP256);
    245   out->curves[2].comment = "NIST P-256";
    246   out->curves[2].param_len = 32;
    247   out->curves[2].params = kP256Params;
    248   out->curves[2].method =
    249 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
    250     !defined(OPENSSL_SMALL)
    251       EC_GFp_nistz256_method();
    252 #else
    253       EC_GFp_nistp256_method();
    254 #endif
    255 
    256   // 1.3.132.0.33
    257   static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21};
    258   out->curves[3].nid = NID_secp224r1;
    259   out->curves[3].oid = kOIDP224;
    260   out->curves[3].oid_len = sizeof(kOIDP224);
    261   out->curves[3].comment = "NIST P-224";
    262   out->curves[3].param_len = 28;
    263   out->curves[3].params = kP224Params;
    264   out->curves[3].method =
    265 #if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
    266       EC_GFp_nistp224_method();
    267 #else
    268       EC_GFp_mont_method();
    269 #endif
    270 }
    271 
    272 EC_GROUP *ec_group_new(const EC_METHOD *meth) {
    273   EC_GROUP *ret;
    274 
    275   if (meth == NULL) {
    276     OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
    277     return NULL;
    278   }
    279 
    280   if (meth->group_init == 0) {
    281     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    282     return NULL;
    283   }
    284 
    285   ret = OPENSSL_malloc(sizeof(EC_GROUP));
    286   if (ret == NULL) {
    287     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    288     return NULL;
    289   }
    290   OPENSSL_memset(ret, 0, sizeof(EC_GROUP));
    291 
    292   ret->references = 1;
    293   ret->meth = meth;
    294   BN_init(&ret->order);
    295 
    296   if (!meth->group_init(ret)) {
    297     OPENSSL_free(ret);
    298     return NULL;
    299   }
    300 
    301   return ret;
    302 }
    303 
    304 static void ec_group_set0_generator(EC_GROUP *group, EC_POINT *generator) {
    305   assert(group->generator == NULL);
    306   assert(group == generator->group);
    307 
    308   // Avoid a reference cycle. |group->generator| does not maintain an owning
    309   // pointer to |group|.
    310   group->generator = generator;
    311   int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references);
    312 
    313   assert(!is_zero);
    314   (void)is_zero;
    315 }
    316 
    317 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
    318                                  const BIGNUM *b, BN_CTX *ctx) {
    319   if (BN_num_bytes(p) > EC_MAX_BYTES) {
    320     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
    321     return NULL;
    322   }
    323 
    324   EC_GROUP *ret = ec_group_new(EC_GFp_mont_method());
    325   if (ret == NULL) {
    326     return NULL;
    327   }
    328 
    329   if (ret->meth->group_set_curve == NULL) {
    330     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    331     EC_GROUP_free(ret);
    332     return NULL;
    333   }
    334   if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
    335     EC_GROUP_free(ret);
    336     return NULL;
    337   }
    338   return ret;
    339 }
    340 
    341 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
    342                            const BIGNUM *order, const BIGNUM *cofactor) {
    343   if (group->curve_name != NID_undef || group->generator != NULL ||
    344       generator->group != group) {
    345     // |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
    346     // |EC_GROUP_new_curve_GFp| and may only used once on each group.
    347     // |generator| must have been created from |EC_GROUP_new_curve_GFp|, not a
    348     // copy, so that |generator->group->generator| is set correctly.
    349     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    350     return 0;
    351   }
    352 
    353   if (BN_num_bytes(order) > EC_MAX_BYTES) {
    354     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
    355     return 0;
    356   }
    357 
    358   // Require a cofactor of one for custom curves, which implies prime order.
    359   if (!BN_is_one(cofactor)) {
    360     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR);
    361     return 0;
    362   }
    363 
    364   // Require that p < 2order. This simplifies some ECDSA operations.
    365   //
    366   // Note any curve which did not satisfy this must have been invalid or use a
    367   // tiny prime (less than 17). See the proof in |field_element_to_scalar| in
    368   // the ECDSA implementation.
    369   int ret = 0;
    370   EC_POINT *copy = NULL;
    371   BIGNUM *tmp = BN_new();
    372   if (tmp == NULL ||
    373       !BN_lshift1(tmp, order)) {
    374     goto err;
    375   }
    376   if (BN_cmp(tmp, &group->field) <= 0) {
    377     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
    378     goto err;
    379   }
    380 
    381   copy = EC_POINT_new(group);
    382   if (copy == NULL ||
    383       !EC_POINT_copy(copy, generator) ||
    384       !BN_copy(&group->order, order)) {
    385     goto err;
    386   }
    387   // Store the order in minimal form, so it can be used with |BN_ULONG| arrays.
    388   bn_set_minimal_width(&group->order);
    389 
    390   BN_MONT_CTX_free(group->order_mont);
    391   group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL);
    392   if (group->order_mont == NULL) {
    393     goto err;
    394   }
    395 
    396   group->field_greater_than_order = BN_cmp(&group->field, &group->order) > 0;
    397   if (group->field_greater_than_order) {
    398     if (!BN_sub(tmp, &group->field, &group->order) ||
    399         !bn_copy_words(group->field_minus_order.words, group->field.width,
    400                        tmp)) {
    401       goto err;
    402     }
    403   }
    404 
    405   ec_group_set0_generator(group, copy);
    406   copy = NULL;
    407   ret = 1;
    408 
    409 err:
    410   EC_POINT_free(copy);
    411   BN_free(tmp);
    412   return ret;
    413 }
    414 
    415 static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
    416   EC_GROUP *group = NULL;
    417   EC_POINT *P = NULL;
    418   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
    419   int ok = 0;
    420 
    421   BN_CTX *ctx = BN_CTX_new();
    422   if (ctx == NULL) {
    423     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    424     goto err;
    425   }
    426 
    427   const unsigned param_len = curve->param_len;
    428   const uint8_t *params = curve->params;
    429 
    430   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
    431       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
    432       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
    433     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    434     goto err;
    435   }
    436 
    437   group = ec_group_new(curve->method);
    438   if (group == NULL ||
    439       !group->meth->group_set_curve(group, p, a, b, ctx)) {
    440     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    441     goto err;
    442   }
    443 
    444   if ((P = EC_POINT_new(group)) == NULL) {
    445     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    446     goto err;
    447   }
    448 
    449   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
    450       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
    451     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    452     goto err;
    453   }
    454 
    455   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
    456     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    457     goto err;
    458   }
    459   if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) {
    460     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    461     goto err;
    462   }
    463 
    464   group->field_greater_than_order = BN_cmp(&group->field, &group->order) > 0;
    465   if (group->field_greater_than_order) {
    466     if (!BN_sub(p, &group->field, &group->order) ||
    467         !bn_copy_words(group->field_minus_order.words, group->field.width, p)) {
    468       goto err;
    469     }
    470   }
    471 
    472   group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, ctx);
    473   if (group->order_mont == NULL) {
    474     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    475     goto err;
    476   }
    477 
    478   ec_group_set0_generator(group, P);
    479   P = NULL;
    480   ok = 1;
    481 
    482 err:
    483   if (!ok) {
    484     EC_GROUP_free(group);
    485     group = NULL;
    486   }
    487   EC_POINT_free(P);
    488   BN_CTX_free(ctx);
    489   BN_free(p);
    490   BN_free(a);
    491   BN_free(b);
    492   BN_free(x);
    493   BN_free(y);
    494   return group;
    495 }
    496 
    497 // Built-in groups are allocated lazily and static once allocated.
    498 // TODO(davidben): Make these actually static. https://crbug.com/boringssl/20.
    499 struct built_in_groups_st {
    500   EC_GROUP *groups[OPENSSL_NUM_BUILT_IN_CURVES];
    501 };
    502 DEFINE_BSS_GET(struct built_in_groups_st, built_in_groups)
    503 DEFINE_STATIC_MUTEX(built_in_groups_lock)
    504 
    505 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
    506   struct built_in_groups_st *groups = built_in_groups_bss_get();
    507   EC_GROUP **group_ptr = NULL;
    508   const struct built_in_curves *const curves = OPENSSL_built_in_curves();
    509   const struct built_in_curve *curve = NULL;
    510   for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
    511     if (curves->curves[i].nid == nid) {
    512       curve = &curves->curves[i];
    513       group_ptr = &groups->groups[i];
    514       break;
    515     }
    516   }
    517 
    518   if (curve == NULL) {
    519     OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
    520     return NULL;
    521   }
    522 
    523   CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get());
    524   EC_GROUP *ret = *group_ptr;
    525   CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get());
    526   if (ret != NULL) {
    527     return ret;
    528   }
    529 
    530   ret = ec_group_new_from_data(curve);
    531   if (ret == NULL) {
    532     return NULL;
    533   }
    534 
    535   EC_GROUP *to_free = NULL;
    536   CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get());
    537   if (*group_ptr == NULL) {
    538     *group_ptr = ret;
    539     // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup|
    540     // into no-ops. At this point, |ret| is considered static.
    541     ret->curve_name = nid;
    542   } else {
    543     to_free = ret;
    544     ret = *group_ptr;
    545   }
    546   CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get());
    547 
    548   EC_GROUP_free(to_free);
    549   return ret;
    550 }
    551 
    552 void EC_GROUP_free(EC_GROUP *group) {
    553   if (group == NULL ||
    554       // Built-in curves are static.
    555       group->curve_name != NID_undef ||
    556       !CRYPTO_refcount_dec_and_test_zero(&group->references)) {
    557     return;
    558   }
    559 
    560   if (group->meth->group_finish != NULL) {
    561     group->meth->group_finish(group);
    562   }
    563 
    564   ec_point_free(group->generator, 0 /* don't free group */);
    565   BN_free(&group->order);
    566   BN_MONT_CTX_free(group->order_mont);
    567 
    568   OPENSSL_free(group);
    569 }
    570 
    571 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
    572   if (a == NULL ||
    573       // Built-in curves are static.
    574       a->curve_name != NID_undef) {
    575     return (EC_GROUP *)a;
    576   }
    577 
    578   // Groups are logically immutable (but for |EC_GROUP_set_generator| which must
    579   // be called early on), so we simply take a reference.
    580   EC_GROUP *group = (EC_GROUP *)a;
    581   CRYPTO_refcount_inc(&group->references);
    582   return group;
    583 }
    584 
    585 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
    586   // Note this function returns 0 if equal and non-zero otherwise.
    587   if (a == b) {
    588     return 0;
    589   }
    590   if (a->curve_name != b->curve_name) {
    591     return 1;
    592   }
    593   if (a->curve_name != NID_undef) {
    594     // Built-in curves may be compared by curve name alone.
    595     return 0;
    596   }
    597 
    598   // |a| and |b| are both custom curves. We compare the entire curve
    599   // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes,
    600   // custom curve construction is sadly done in two parts) but otherwise not the
    601   // same object, we consider them always unequal.
    602   return a->meth != b->meth ||
    603          a->generator == NULL ||
    604          b->generator == NULL ||
    605          BN_cmp(&a->order, &b->order) != 0 ||
    606          BN_cmp(&a->field, &b->field) != 0 ||
    607          !ec_felem_equal(a, &a->a, &b->a) ||
    608          !ec_felem_equal(a, &a->b, &b->b) ||
    609          ec_GFp_simple_cmp(a, &a->generator->raw, &b->generator->raw) != 0;
    610 }
    611 
    612 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
    613   return group->generator;
    614 }
    615 
    616 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
    617   assert(!BN_is_zero(&group->order));
    618   return &group->order;
    619 }
    620 
    621 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
    622   if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
    623     return 0;
    624   }
    625   return 1;
    626 }
    627 
    628 int EC_GROUP_order_bits(const EC_GROUP *group) {
    629   return BN_num_bits(&group->order);
    630 }
    631 
    632 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
    633                           BN_CTX *ctx) {
    634   // All |EC_GROUP|s have cofactor 1.
    635   return BN_set_word(cofactor, 1);
    636 }
    637 
    638 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
    639                            BIGNUM *out_b, BN_CTX *ctx) {
    640   return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b);
    641 }
    642 
    643 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
    644 
    645 unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
    646   return BN_num_bits(&group->field);
    647 }
    648 
    649 const char *EC_curve_nid2nist(int nid) {
    650   switch (nid) {
    651     case NID_secp224r1:
    652       return "P-224";
    653     case NID_X9_62_prime256v1:
    654       return "P-256";
    655     case NID_secp384r1:
    656       return "P-384";
    657     case NID_secp521r1:
    658       return "P-521";
    659   }
    660   return NULL;
    661 }
    662 
    663 int EC_curve_nist2nid(const char *name) {
    664   if (strcmp(name, "P-224") == 0) {
    665     return NID_secp224r1;
    666   }
    667   if (strcmp(name, "P-256") == 0) {
    668     return NID_X9_62_prime256v1;
    669   }
    670   if (strcmp(name, "P-384") == 0) {
    671     return NID_secp384r1;
    672   }
    673   if (strcmp(name, "P-521") == 0) {
    674     return NID_secp521r1;
    675   }
    676   return NID_undef;
    677 }
    678 
    679 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
    680   if (group == NULL) {
    681     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    682     return NULL;
    683   }
    684 
    685   EC_POINT *ret = OPENSSL_malloc(sizeof *ret);
    686   if (ret == NULL) {
    687     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    688     return NULL;
    689   }
    690 
    691   ret->group = EC_GROUP_dup(group);
    692   ec_GFp_simple_point_init(&ret->raw);
    693   return ret;
    694 }
    695 
    696 static void ec_point_free(EC_POINT *point, int free_group) {
    697   if (!point) {
    698     return;
    699   }
    700   if (free_group) {
    701     EC_GROUP_free(point->group);
    702   }
    703   OPENSSL_free(point);
    704 }
    705 
    706 void EC_POINT_free(EC_POINT *point) {
    707   ec_point_free(point, 1 /* free group */);
    708 }
    709 
    710 void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); }
    711 
    712 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
    713   if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) {
    714     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    715     return 0;
    716   }
    717   if (dest == src) {
    718     return 1;
    719   }
    720   ec_GFp_simple_point_copy(&dest->raw, &src->raw);
    721   return 1;
    722 }
    723 
    724 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
    725   if (a == NULL) {
    726     return NULL;
    727   }
    728 
    729   EC_POINT *ret = EC_POINT_new(group);
    730   if (ret == NULL ||
    731       !EC_POINT_copy(ret, a)) {
    732     EC_POINT_free(ret);
    733     return NULL;
    734   }
    735 
    736   return ret;
    737 }
    738 
    739 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
    740   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    741     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    742     return 0;
    743   }
    744   ec_GFp_simple_point_set_to_infinity(group, &point->raw);
    745   return 1;
    746 }
    747 
    748 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
    749   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    750     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    751     return 0;
    752   }
    753   return ec_GFp_simple_is_at_infinity(group, &point->raw);
    754 }
    755 
    756 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
    757                          BN_CTX *ctx) {
    758   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    759     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    760     return 0;
    761   }
    762   return ec_GFp_simple_is_on_curve(group, &point->raw);
    763 }
    764 
    765 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
    766                  BN_CTX *ctx) {
    767   if (EC_GROUP_cmp(group, a->group, NULL) != 0 ||
    768       EC_GROUP_cmp(group, b->group, NULL) != 0) {
    769     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    770     return -1;
    771   }
    772   return ec_GFp_simple_cmp(group, &a->raw, &b->raw);
    773 }
    774 
    775 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
    776                                         const EC_POINT *point, BIGNUM *x,
    777                                         BIGNUM *y, BN_CTX *ctx) {
    778   if (group->meth->point_get_affine_coordinates == 0) {
    779     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    780     return 0;
    781   }
    782   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    783     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    784     return 0;
    785   }
    786   EC_FELEM x_felem, y_felem;
    787   if (!group->meth->point_get_affine_coordinates(group, &point->raw,
    788                                                  x == NULL ? NULL : &x_felem,
    789                                                  y == NULL ? NULL : &y_felem) ||
    790       (x != NULL && !bn_set_words(x, x_felem.words, group->field.width)) ||
    791       (y != NULL && !bn_set_words(y, y_felem.words, group->field.width))) {
    792     return 0;
    793   }
    794   return 1;
    795 }
    796 
    797 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
    798                                         const BIGNUM *x, const BIGNUM *y,
    799                                         BN_CTX *ctx) {
    800   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    801     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    802     return 0;
    803   }
    804   if (!ec_GFp_simple_point_set_affine_coordinates(group, &point->raw, x, y)) {
    805     return 0;
    806   }
    807 
    808   if (!EC_POINT_is_on_curve(group, point, ctx)) {
    809     // In the event of an error, defend against the caller not checking the
    810     // return value by setting a known safe value: the base point.
    811     const EC_POINT *generator = EC_GROUP_get0_generator(group);
    812     // The generator can be missing if the caller is in the process of
    813     // constructing an arbitrary group. In this, we give up and hope they're
    814     // checking the return value.
    815     if (generator) {
    816       ec_GFp_simple_point_copy(&point->raw, &generator->raw);
    817     }
    818     OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
    819     return 0;
    820   }
    821 
    822   return 1;
    823 }
    824 
    825 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
    826                  const EC_POINT *b, BN_CTX *ctx) {
    827   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
    828       EC_GROUP_cmp(group, a->group, NULL) != 0 ||
    829       EC_GROUP_cmp(group, b->group, NULL) != 0) {
    830     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    831     return 0;
    832   }
    833   group->meth->add(group, &r->raw, &a->raw, &b->raw);
    834   return 1;
    835 }
    836 
    837 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
    838                  BN_CTX *ctx) {
    839   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
    840       EC_GROUP_cmp(group, a->group, NULL) != 0) {
    841     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    842     return 0;
    843   }
    844   group->meth->dbl(group, &r->raw, &a->raw);
    845   return 1;
    846 }
    847 
    848 
    849 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
    850   if (EC_GROUP_cmp(group, a->group, NULL) != 0) {
    851     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    852     return 0;
    853   }
    854   ec_GFp_simple_invert(group, &a->raw);
    855   return 1;
    856 }
    857 
    858 static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
    859                                       const BIGNUM *in, BN_CTX *ctx) {
    860   if (ec_bignum_to_scalar(group, out, in)) {
    861     return 1;
    862   }
    863 
    864   ERR_clear_error();
    865 
    866   // This is an unusual input, so we do not guarantee constant-time processing.
    867   const BIGNUM *order = &group->order;
    868   BN_CTX_start(ctx);
    869   BIGNUM *tmp = BN_CTX_get(ctx);
    870   int ok = tmp != NULL &&
    871            BN_nnmod(tmp, in, order, ctx) &&
    872            ec_bignum_to_scalar(group, out, tmp);
    873   BN_CTX_end(ctx);
    874   return ok;
    875 }
    876 
    877 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
    878                  const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
    879   // Previously, this function set |r| to the point at infinity if there was
    880   // nothing to multiply. But, nobody should be calling this function with
    881   // nothing to multiply in the first place.
    882   if ((g_scalar == NULL && p_scalar == NULL) ||
    883       (p == NULL) != (p_scalar == NULL))  {
    884     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    885     return 0;
    886   }
    887 
    888   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
    889       (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
    890     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    891     return 0;
    892   }
    893 
    894   int ret = 0;
    895   EC_SCALAR g_scalar_storage, p_scalar_storage;
    896   EC_SCALAR *g_scalar_arg = NULL, *p_scalar_arg = NULL;
    897   BN_CTX *new_ctx = NULL;
    898   if (ctx == NULL) {
    899     new_ctx = BN_CTX_new();
    900     if (new_ctx == NULL) {
    901       goto err;
    902     }
    903     ctx = new_ctx;
    904   }
    905 
    906   if (g_scalar != NULL) {
    907     if (!arbitrary_bignum_to_scalar(group, &g_scalar_storage, g_scalar, ctx)) {
    908       goto err;
    909     }
    910     g_scalar_arg = &g_scalar_storage;
    911   }
    912 
    913   if (p_scalar != NULL) {
    914     if (!arbitrary_bignum_to_scalar(group, &p_scalar_storage, p_scalar, ctx)) {
    915       goto err;
    916     }
    917     p_scalar_arg = &p_scalar_storage;
    918   }
    919 
    920   ret = ec_point_mul_scalar(group, &r->raw, g_scalar_arg,
    921                             p == NULL ? NULL : &p->raw, p_scalar_arg);
    922 
    923 err:
    924   BN_CTX_free(new_ctx);
    925   OPENSSL_cleanse(&g_scalar_storage, sizeof(g_scalar_storage));
    926   OPENSSL_cleanse(&p_scalar_storage, sizeof(p_scalar_storage));
    927   return ret;
    928 }
    929 
    930 int ec_point_mul_scalar_public(const EC_GROUP *group, EC_RAW_POINT *r,
    931                                const EC_SCALAR *g_scalar, const EC_RAW_POINT *p,
    932                                const EC_SCALAR *p_scalar) {
    933   if ((g_scalar == NULL && p_scalar == NULL) ||
    934       (p == NULL) != (p_scalar == NULL)) {
    935     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    936     return 0;
    937   }
    938 
    939   group->meth->mul_public(group, r, g_scalar, p, p_scalar);
    940   return 1;
    941 }
    942 
    943 int ec_point_mul_scalar(const EC_GROUP *group, EC_RAW_POINT *r,
    944                         const EC_SCALAR *g_scalar, const EC_RAW_POINT *p,
    945                         const EC_SCALAR *p_scalar) {
    946   if ((g_scalar == NULL && p_scalar == NULL) ||
    947       (p == NULL) != (p_scalar == NULL)) {
    948     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    949     return 0;
    950   }
    951 
    952   group->meth->mul(group, r, g_scalar, p, p_scalar);
    953   return 1;
    954 }
    955 
    956 int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p,
    957                         const EC_SCALAR *r) {
    958   return group->meth->cmp_x_coordinate(group, p, r);
    959 }
    960 
    961 int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out,
    962                                   const EC_RAW_POINT *p) {
    963   EC_FELEM x;
    964   // For simplicity, in case of width mismatches between |group->field| and
    965   // |group->order|, zero any untouched words in |x|.
    966   OPENSSL_memset(&x, 0, sizeof(x));
    967   if (!group->meth->point_get_affine_coordinates(group, p, &x, NULL)) {
    968     return 0;
    969   }
    970 
    971   // We must have p < 2order, assuming p is not tiny (p >= 17). Thus rather we
    972   // can reduce by performing at most one subtraction.
    973   //
    974   // Proof: We only work with prime order curves, so the number of points on
    975   // the curve is the order. Thus Hasse's theorem gives:
    976   //
    977   //     |order - (p + 1)| <= 2sqrt(p)
    978   //         p + 1 - order <= 2sqrt(p)
    979   //     p + 1 - 2sqrt(p) <= order
    980   //       p + 1 - 2(p/4)  < order       (p/4 > sqrt(p) for p >= 17)
    981   //         p/2 < p/2 + 1  < order
    982   //                     p  < 2order
    983   //
    984   // Additionally, one can manually check this property for built-in curves. It
    985   // is enforced for legacy custom curves in |EC_GROUP_set_generator|.
    986 
    987   // The above does not guarantee |group->field| is not one word larger than
    988   // |group->order|, so read one extra carry word.
    989   BN_ULONG carry =
    990       group->order.width < EC_MAX_WORDS ? x.words[group->order.width] : 0;
    991   bn_reduce_once(out->words, x.words, carry, group->order.d,
    992                  group->order.width);
    993   return 1;
    994 }
    995 
    996 int ec_point_get_affine_coordinate_bytes(const EC_GROUP *group, uint8_t *out_x,
    997                                          uint8_t *out_y, size_t *out_len,
    998                                          size_t max_out,
    999                                          const EC_RAW_POINT *p) {
   1000   size_t len = BN_num_bytes(&group->field);
   1001   assert(len <= EC_MAX_BYTES);
   1002   if (max_out < len) {
   1003     OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
   1004     return 0;
   1005   }
   1006 
   1007   EC_FELEM x, y;
   1008   if (!group->meth->point_get_affine_coordinates(
   1009           group, p, out_x == NULL ? NULL : &x, out_y == NULL ? NULL : &y)) {
   1010     return 0;
   1011   }
   1012 
   1013   if (out_x != NULL) {
   1014     for (size_t i = 0; i < len; i++) {
   1015       out_x[i] = x.bytes[len - i - 1];
   1016     }
   1017   }
   1018   if (out_y != NULL) {
   1019     for (size_t i = 0; i < len; i++) {
   1020       out_y[i] = y.bytes[len - i - 1];
   1021     }
   1022   }
   1023   *out_len = len;
   1024   return 1;
   1025 }
   1026 
   1027 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
   1028 
   1029 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
   1030   // This function exists purely to give callers a way to call
   1031   // |EC_METHOD_get_field_type|. cryptography.io crashes if |EC_GROUP_method_of|
   1032   // returns NULL, so return some other garbage pointer.
   1033   return (const EC_METHOD *)0x12340000;
   1034 }
   1035 
   1036 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
   1037   return NID_X9_62_prime_field;
   1038 }
   1039 
   1040 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
   1041                                         point_conversion_form_t form) {
   1042   if (form != POINT_CONVERSION_UNCOMPRESSED) {
   1043     abort();
   1044   }
   1045 }
   1046 
   1047 size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
   1048                              size_t max_num_curves) {
   1049   const struct built_in_curves *const curves = OPENSSL_built_in_curves();
   1050 
   1051   for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES;
   1052        i++) {
   1053     out_curves[i].comment = curves->curves[i].comment;
   1054     out_curves[i].nid = curves->curves[i].nid;
   1055   }
   1056 
   1057   return OPENSSL_NUM_BUILT_IN_CURVES;
   1058 }
   1059