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_SCALAR_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     // Additionally, |generator| must been created from
    348     // |EC_GROUP_new_curve_GFp|, not a copy, so that
    349     // |generator->group->generator| is set correctly.
    350     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    351     return 0;
    352   }
    353 
    354   if (BN_num_bytes(order) > EC_MAX_SCALAR_BYTES) {
    355     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
    356     return 0;
    357   }
    358 
    359   // Require a cofactor of one for custom curves, which implies prime order.
    360   if (!BN_is_one(cofactor)) {
    361     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR);
    362     return 0;
    363   }
    364 
    365   // Require that p < 2order. This simplifies some ECDSA operations.
    366   //
    367   // Note any curve which did not satisfy this must have been invalid or use a
    368   // tiny prime (less than 17). See the proof in |field_element_to_scalar| in
    369   // the ECDSA implementation.
    370   BIGNUM *tmp = BN_new();
    371   if (tmp == NULL ||
    372       !BN_lshift1(tmp, order)) {
    373     BN_free(tmp);
    374     return 0;
    375   }
    376   int ok = BN_cmp(tmp, &group->field) > 0;
    377   BN_free(tmp);
    378   if (!ok) {
    379     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
    380     return 0;
    381   }
    382 
    383   EC_POINT *copy = EC_POINT_new(group);
    384   if (copy == NULL ||
    385       !EC_POINT_copy(copy, generator) ||
    386       !BN_copy(&group->order, order)) {
    387     EC_POINT_free(copy);
    388     return 0;
    389   }
    390 
    391   BN_MONT_CTX_free(group->order_mont);
    392   group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL);
    393   if (group->order_mont == NULL) {
    394     return 0;
    395   }
    396 
    397   ec_group_set0_generator(group, copy);
    398   return 1;
    399 }
    400 
    401 static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
    402   EC_GROUP *group = NULL;
    403   EC_POINT *P = NULL;
    404   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
    405   int ok = 0;
    406 
    407   BN_CTX *ctx = BN_CTX_new();
    408   if (ctx == NULL) {
    409     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    410     goto err;
    411   }
    412 
    413   const unsigned param_len = curve->param_len;
    414   const uint8_t *params = curve->params;
    415 
    416   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
    417       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
    418       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
    419     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    420     goto err;
    421   }
    422 
    423   group = ec_group_new(curve->method);
    424   if (group == NULL ||
    425       !group->meth->group_set_curve(group, p, a, b, ctx)) {
    426     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    427     goto err;
    428   }
    429 
    430   if ((P = EC_POINT_new(group)) == NULL) {
    431     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    432     goto err;
    433   }
    434 
    435   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
    436       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
    437     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    438     goto err;
    439   }
    440 
    441   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
    442     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    443     goto err;
    444   }
    445   if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) {
    446     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    447     goto err;
    448   }
    449 
    450   group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, ctx);
    451   if (group->order_mont == NULL) {
    452     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    453     goto err;
    454   }
    455 
    456   ec_group_set0_generator(group, P);
    457   P = NULL;
    458   ok = 1;
    459 
    460 err:
    461   if (!ok) {
    462     EC_GROUP_free(group);
    463     group = NULL;
    464   }
    465   EC_POINT_free(P);
    466   BN_CTX_free(ctx);
    467   BN_free(p);
    468   BN_free(a);
    469   BN_free(b);
    470   BN_free(x);
    471   BN_free(y);
    472   return group;
    473 }
    474 
    475 // Built-in groups are allocated lazily and static once allocated.
    476 // TODO(davidben): Make these actually static. https://crbug.com/boringssl/20.
    477 struct built_in_groups_st {
    478   EC_GROUP *groups[OPENSSL_NUM_BUILT_IN_CURVES];
    479 };
    480 DEFINE_BSS_GET(struct built_in_groups_st, built_in_groups);
    481 DEFINE_STATIC_MUTEX(built_in_groups_lock);
    482 
    483 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
    484   struct built_in_groups_st *groups = built_in_groups_bss_get();
    485   EC_GROUP **group_ptr = NULL;
    486   const struct built_in_curves *const curves = OPENSSL_built_in_curves();
    487   const struct built_in_curve *curve = NULL;
    488   for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
    489     if (curves->curves[i].nid == nid) {
    490       curve = &curves->curves[i];
    491       group_ptr = &groups->groups[i];
    492       break;
    493     }
    494   }
    495 
    496   if (curve == NULL) {
    497     OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
    498     return NULL;
    499   }
    500 
    501   CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get());
    502   EC_GROUP *ret = *group_ptr;
    503   CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get());
    504   if (ret != NULL) {
    505     return ret;
    506   }
    507 
    508   ret = ec_group_new_from_data(curve);
    509   if (ret == NULL) {
    510     return NULL;
    511   }
    512 
    513   EC_GROUP *to_free = NULL;
    514   CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get());
    515   if (*group_ptr == NULL) {
    516     *group_ptr = ret;
    517     // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup|
    518     // into no-ops. At this point, |ret| is considered static.
    519     ret->curve_name = nid;
    520   } else {
    521     to_free = ret;
    522     ret = *group_ptr;
    523   }
    524   CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get());
    525 
    526   EC_GROUP_free(to_free);
    527   return ret;
    528 }
    529 
    530 void EC_GROUP_free(EC_GROUP *group) {
    531   if (group == NULL ||
    532       // Built-in curves are static.
    533       group->curve_name != NID_undef ||
    534       !CRYPTO_refcount_dec_and_test_zero(&group->references)) {
    535     return;
    536   }
    537 
    538   if (group->meth->group_finish != NULL) {
    539     group->meth->group_finish(group);
    540   }
    541 
    542   ec_point_free(group->generator, 0 /* don't free group */);
    543   BN_free(&group->order);
    544   BN_MONT_CTX_free(group->order_mont);
    545 
    546   OPENSSL_free(group);
    547 }
    548 
    549 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
    550   if (a == NULL ||
    551       // Built-in curves are static.
    552       a->curve_name != NID_undef) {
    553     return (EC_GROUP *)a;
    554   }
    555 
    556   // Groups are logically immutable (but for |EC_GROUP_set_generator| which must
    557   // be called early on), so we simply take a reference.
    558   EC_GROUP *group = (EC_GROUP *)a;
    559   CRYPTO_refcount_inc(&group->references);
    560   return group;
    561 }
    562 
    563 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
    564   // Note this function returns 0 if equal and non-zero otherwise.
    565   if (a == b) {
    566     return 0;
    567   }
    568   if (a->curve_name != b->curve_name) {
    569     return 1;
    570   }
    571   if (a->curve_name != NID_undef) {
    572     // Built-in curves may be compared by curve name alone.
    573     return 0;
    574   }
    575 
    576   // |a| and |b| are both custom curves. We compare the entire curve
    577   // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes,
    578   // custom curve construction is sadly done in two parts) but otherwise not the
    579   // same object, we consider them always unequal.
    580   return a->generator == NULL ||
    581          b->generator == NULL ||
    582          BN_cmp(&a->order, &b->order) != 0 ||
    583          BN_cmp(&a->field, &b->field) != 0 ||
    584          BN_cmp(&a->a, &b->a) != 0 ||
    585          BN_cmp(&a->b, &b->b) != 0 ||
    586          ec_GFp_simple_cmp(a, a->generator, b->generator, NULL) != 0;
    587 }
    588 
    589 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
    590   return group->generator;
    591 }
    592 
    593 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
    594   assert(!BN_is_zero(&group->order));
    595   return &group->order;
    596 }
    597 
    598 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
    599   if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
    600     return 0;
    601   }
    602   return 1;
    603 }
    604 
    605 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
    606                           BN_CTX *ctx) {
    607   // All |EC_GROUP|s have cofactor 1.
    608   return BN_set_word(cofactor, 1);
    609 }
    610 
    611 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
    612                            BIGNUM *out_b, BN_CTX *ctx) {
    613   return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
    614 }
    615 
    616 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
    617 
    618 unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
    619   return ec_GFp_simple_group_get_degree(group);
    620 }
    621 
    622 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
    623   EC_POINT *ret;
    624 
    625   if (group == NULL) {
    626     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    627     return NULL;
    628   }
    629 
    630   ret = OPENSSL_malloc(sizeof *ret);
    631   if (ret == NULL) {
    632     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    633     return NULL;
    634   }
    635 
    636   ret->group = EC_GROUP_dup(group);
    637   if (ret->group == NULL ||
    638       !ec_GFp_simple_point_init(ret)) {
    639     OPENSSL_free(ret);
    640     return NULL;
    641   }
    642 
    643   return ret;
    644 }
    645 
    646 static void ec_point_free(EC_POINT *point, int free_group) {
    647   if (!point) {
    648     return;
    649   }
    650   ec_GFp_simple_point_finish(point);
    651   if (free_group) {
    652     EC_GROUP_free(point->group);
    653   }
    654   OPENSSL_free(point);
    655 }
    656 
    657 void EC_POINT_free(EC_POINT *point) {
    658   ec_point_free(point, 1 /* free group */);
    659 }
    660 
    661 void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); }
    662 
    663 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
    664   if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) {
    665     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    666     return 0;
    667   }
    668   if (dest == src) {
    669     return 1;
    670   }
    671   return ec_GFp_simple_point_copy(dest, src);
    672 }
    673 
    674 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
    675   if (a == NULL) {
    676     return NULL;
    677   }
    678 
    679   EC_POINT *ret = EC_POINT_new(group);
    680   if (ret == NULL ||
    681       !EC_POINT_copy(ret, a)) {
    682     EC_POINT_free(ret);
    683     return NULL;
    684   }
    685 
    686   return ret;
    687 }
    688 
    689 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
    690   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    691     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    692     return 0;
    693   }
    694   return ec_GFp_simple_point_set_to_infinity(group, point);
    695 }
    696 
    697 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
    698   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    699     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    700     return 0;
    701   }
    702   return ec_GFp_simple_is_at_infinity(group, point);
    703 }
    704 
    705 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
    706                          BN_CTX *ctx) {
    707   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    708     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    709     return 0;
    710   }
    711   return ec_GFp_simple_is_on_curve(group, point, ctx);
    712 }
    713 
    714 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
    715                  BN_CTX *ctx) {
    716   if (EC_GROUP_cmp(group, a->group, NULL) != 0 ||
    717       EC_GROUP_cmp(group, b->group, NULL) != 0) {
    718     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    719     return -1;
    720   }
    721   return ec_GFp_simple_cmp(group, a, b, ctx);
    722 }
    723 
    724 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
    725   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    726     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    727     return 0;
    728   }
    729   return ec_GFp_simple_make_affine(group, point, ctx);
    730 }
    731 
    732 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
    733                           BN_CTX *ctx) {
    734   for (size_t i = 0; i < num; i++) {
    735     if (EC_GROUP_cmp(group, points[i]->group, NULL) != 0) {
    736       OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    737       return 0;
    738     }
    739   }
    740   return ec_GFp_simple_points_make_affine(group, num, points, ctx);
    741 }
    742 
    743 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
    744                                         const EC_POINT *point, BIGNUM *x,
    745                                         BIGNUM *y, BN_CTX *ctx) {
    746   if (group->meth->point_get_affine_coordinates == 0) {
    747     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    748     return 0;
    749   }
    750   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    751     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    752     return 0;
    753   }
    754   return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
    755 }
    756 
    757 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
    758                                         const BIGNUM *x, const BIGNUM *y,
    759                                         BN_CTX *ctx) {
    760   if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
    761     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    762     return 0;
    763   }
    764   if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
    765     return 0;
    766   }
    767 
    768   if (!EC_POINT_is_on_curve(group, point, ctx)) {
    769     // In the event of an error, defend against the caller not checking the
    770     // return value by setting a known safe value: the base point.
    771     const EC_POINT *generator = EC_GROUP_get0_generator(group);
    772     // The generator can be missing if the caller is in the process of
    773     // constructing an arbitrary group. In this, we give up and hope they're
    774     // checking the return value.
    775     if (generator) {
    776       EC_POINT_copy(point, generator);
    777     }
    778     OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
    779     return 0;
    780   }
    781 
    782   return 1;
    783 }
    784 
    785 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
    786                  const EC_POINT *b, BN_CTX *ctx) {
    787   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
    788       EC_GROUP_cmp(group, a->group, NULL) != 0 ||
    789       EC_GROUP_cmp(group, b->group, NULL) != 0) {
    790     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    791     return 0;
    792   }
    793   return ec_GFp_simple_add(group, r, a, b, ctx);
    794 }
    795 
    796 
    797 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
    798                  BN_CTX *ctx) {
    799   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
    800       EC_GROUP_cmp(group, a->group, NULL) != 0) {
    801     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    802     return 0;
    803   }
    804   return ec_GFp_simple_dbl(group, r, a, ctx);
    805 }
    806 
    807 
    808 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
    809   if (EC_GROUP_cmp(group, a->group, NULL) != 0) {
    810     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    811     return 0;
    812   }
    813   return ec_GFp_simple_invert(group, a, ctx);
    814 }
    815 
    816 static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
    817                                       const BIGNUM *in, BN_CTX *ctx) {
    818   if (ec_bignum_to_scalar(group, out, in)) {
    819     return 1;
    820   }
    821 
    822   ERR_clear_error();
    823 
    824   // This is an unusual input, so we do not guarantee constant-time
    825   // processing, even ignoring |bn_correct_top|.
    826   const BIGNUM *order = &group->order;
    827   BN_CTX_start(ctx);
    828   BIGNUM *tmp = BN_CTX_get(ctx);
    829   int ok = tmp != NULL &&
    830            BN_nnmod(tmp, in, order, ctx) &&
    831            ec_bignum_to_scalar_unchecked(group, out, tmp);
    832   BN_CTX_end(ctx);
    833   return ok;
    834 }
    835 
    836 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
    837                  const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
    838   // Previously, this function set |r| to the point at infinity if there was
    839   // nothing to multiply. But, nobody should be calling this function with
    840   // nothing to multiply in the first place.
    841   if ((g_scalar == NULL && p_scalar == NULL) ||
    842       (p == NULL) != (p_scalar == NULL))  {
    843     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    844     return 0;
    845   }
    846 
    847   int ret = 0;
    848   EC_SCALAR g_scalar_storage, p_scalar_storage;
    849   EC_SCALAR *g_scalar_arg = NULL, *p_scalar_arg = NULL;
    850   BN_CTX *new_ctx = NULL;
    851   if (ctx == NULL) {
    852     new_ctx = BN_CTX_new();
    853     if (new_ctx == NULL) {
    854       goto err;
    855     }
    856     ctx = new_ctx;
    857   }
    858 
    859   if (g_scalar != NULL) {
    860     if (!arbitrary_bignum_to_scalar(group, &g_scalar_storage, g_scalar, ctx)) {
    861       goto err;
    862     }
    863     g_scalar_arg = &g_scalar_storage;
    864   }
    865 
    866   if (p_scalar != NULL) {
    867     if (!arbitrary_bignum_to_scalar(group, &p_scalar_storage, p_scalar, ctx)) {
    868       goto err;
    869     }
    870     p_scalar_arg = &p_scalar_storage;
    871   }
    872 
    873   ret = ec_point_mul_scalar(group, r, g_scalar_arg, p, p_scalar_arg, ctx);
    874 
    875 err:
    876   BN_CTX_free(new_ctx);
    877   OPENSSL_cleanse(&g_scalar_storage, sizeof(g_scalar_storage));
    878   OPENSSL_cleanse(&p_scalar_storage, sizeof(p_scalar_storage));
    879   return ret;
    880 }
    881 
    882 int ec_point_mul_scalar_public(const EC_GROUP *group, EC_POINT *r,
    883                                const EC_SCALAR *g_scalar, const EC_POINT *p,
    884                                const EC_SCALAR *p_scalar, BN_CTX *ctx) {
    885   if ((g_scalar == NULL && p_scalar == NULL) ||
    886       (p == NULL) != (p_scalar == NULL))  {
    887     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    888     return 0;
    889   }
    890 
    891   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
    892       (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
    893     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    894     return 0;
    895   }
    896 
    897   return group->meth->mul_public(group, r, g_scalar, p, p_scalar, ctx);
    898 }
    899 
    900 int ec_point_mul_scalar(const EC_GROUP *group, EC_POINT *r,
    901                         const EC_SCALAR *g_scalar, const EC_POINT *p,
    902                         const EC_SCALAR *p_scalar, BN_CTX *ctx) {
    903   if ((g_scalar == NULL && p_scalar == NULL) ||
    904       (p == NULL) != (p_scalar == NULL))  {
    905     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    906     return 0;
    907   }
    908 
    909   if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
    910       (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
    911     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    912     return 0;
    913   }
    914 
    915   return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
    916 }
    917 
    918 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
    919 
    920 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
    921   return NULL;
    922 }
    923 
    924 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
    925   return NID_X9_62_prime_field;
    926 }
    927 
    928 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
    929                                         point_conversion_form_t form) {
    930   if (form != POINT_CONVERSION_UNCOMPRESSED) {
    931     abort();
    932   }
    933 }
    934 
    935 size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
    936                              size_t max_num_curves) {
    937   const struct built_in_curves *const curves = OPENSSL_built_in_curves();
    938 
    939   for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES;
    940        i++) {
    941     out_curves[i].comment = curves->curves[i].comment;
    942     out_curves[i].nid = curves->curves[i].nid;
    943   }
    944 
    945   return OPENSSL_NUM_BUILT_IN_CURVES;
    946 }
    947 
    948 int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
    949                         const BIGNUM *in) {
    950   if (!ec_bignum_to_scalar_unchecked(group, out, in)) {
    951     return 0;
    952   }
    953   if (!bn_less_than_words(out->words, group->order.d, group->order.top)) {
    954     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
    955     return 0;
    956   }
    957   return 1;
    958 }
    959 
    960 int ec_bignum_to_scalar_unchecked(const EC_GROUP *group, EC_SCALAR *out,
    961                                   const BIGNUM *in) {
    962   if (!bn_copy_words(out->words, group->order.top, in)) {
    963     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
    964     return 0;
    965   }
    966   return 1;
    967 }
    968 
    969 int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out,
    970                              const uint8_t additional_data[32]) {
    971   return bn_rand_range_words(out->words, 1, group->order.d, group->order.top,
    972                              additional_data);
    973 }
    974