1*4882a593Smuzhiyun /** 2*4882a593Smuzhiyun * \file ecp.h 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * \brief Elliptic curves over GF(p) 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7*4882a593Smuzhiyun * SPDX-License-Identifier: Apache-2.0 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * Licensed under the Apache License, Version 2.0 (the "License"); you may 10*4882a593Smuzhiyun * not use this file except in compliance with the License. 11*4882a593Smuzhiyun * You may obtain a copy of the License at 12*4882a593Smuzhiyun * 13*4882a593Smuzhiyun * http://www.apache.org/licenses/LICENSE-2.0 14*4882a593Smuzhiyun * 15*4882a593Smuzhiyun * Unless required by applicable law or agreed to in writing, software 16*4882a593Smuzhiyun * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17*4882a593Smuzhiyun * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18*4882a593Smuzhiyun * See the License for the specific language governing permissions and 19*4882a593Smuzhiyun * limitations under the License. 20*4882a593Smuzhiyun * 21*4882a593Smuzhiyun * This file is part of mbed TLS (https://tls.mbed.org) 22*4882a593Smuzhiyun */ 23*4882a593Smuzhiyun #ifndef MBEDTLS_ECP_H 24*4882a593Smuzhiyun #define MBEDTLS_ECP_H 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #include "bignum.h" 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun #define MBEDTLS_ECP_DP_SECP192R1_ENABLED 29*4882a593Smuzhiyun #define MBEDTLS_ECP_DP_SECP224R1_ENABLED 30*4882a593Smuzhiyun #define MBEDTLS_ECP_DP_SECP256R1_ENABLED 31*4882a593Smuzhiyun #define MBEDTLS_ECP_DP_SECP384R1_ENABLED 32*4882a593Smuzhiyun #define MBEDTLS_ECP_DP_SECP521R1_ENABLED 33*4882a593Smuzhiyun #define MBEDTLS_ECP_DP_SECP192K1_ENABLED 34*4882a593Smuzhiyun #define MBEDTLS_ECP_DP_SECP224K1_ENABLED 35*4882a593Smuzhiyun #define MBEDTLS_ECP_DP_SECP256K1_ENABLED 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun /* 38*4882a593Smuzhiyun * ECP error codes 39*4882a593Smuzhiyun */ 40*4882a593Smuzhiyun #define MBEDTLS_ERR_ECP_BAD_INPUT_DATA -0x4F80 /**< Bad input parameters to function. */ 41*4882a593Smuzhiyun #define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 /**< The buffer is too small to write to. */ 42*4882a593Smuzhiyun #define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 /**< Requested curve not available. */ 43*4882a593Smuzhiyun #define MBEDTLS_ERR_ECP_VERIFY_FAILED -0x4E00 /**< The signature is not valid. */ 44*4882a593Smuzhiyun #define MBEDTLS_ERR_ECP_ALLOC_FAILED -0x4D80 /**< Memory allocation failed. */ 45*4882a593Smuzhiyun #define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as (ephemeral) key, failed. */ 46*4882a593Smuzhiyun #define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */ 47*4882a593Smuzhiyun #define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< Signature is valid but shorter than the user-supplied length. */ 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun #ifdef __cplusplus 50*4882a593Smuzhiyun extern "C" { 51*4882a593Smuzhiyun #endif 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun typedef struct ECDSA_KEY { 54*4882a593Smuzhiyun unsigned char d[132]; 55*4882a593Smuzhiyun unsigned char x[132]; 56*4882a593Smuzhiyun unsigned char y[132]; 57*4882a593Smuzhiyun unsigned int d_len; 58*4882a593Smuzhiyun unsigned int x_len; 59*4882a593Smuzhiyun unsigned int y_len; 60*4882a593Smuzhiyun unsigned int curve; 61*4882a593Smuzhiyun unsigned int key_len; /* bit */ 62*4882a593Smuzhiyun } mbed_ecc_key_t; 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /** 65*4882a593Smuzhiyun * Domain parameters (curve, subgroup and generator) identifiers. 66*4882a593Smuzhiyun * 67*4882a593Smuzhiyun * Only curves over prime fields are supported. 68*4882a593Smuzhiyun * 69*4882a593Smuzhiyun * \warning This library does not support validation of arbitrary domain 70*4882a593Smuzhiyun * parameters. Therefore, only well-known domain parameters from trusted 71*4882a593Smuzhiyun * sources should be used. See mbedtls_ecp_group_load(). 72*4882a593Smuzhiyun */ 73*4882a593Smuzhiyun typedef enum 74*4882a593Smuzhiyun { 75*4882a593Smuzhiyun MBEDTLS_ECP_DP_NONE = 0, 76*4882a593Smuzhiyun MBEDTLS_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */ 77*4882a593Smuzhiyun MBEDTLS_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */ 78*4882a593Smuzhiyun MBEDTLS_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */ 79*4882a593Smuzhiyun MBEDTLS_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */ 80*4882a593Smuzhiyun MBEDTLS_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */ 81*4882a593Smuzhiyun MBEDTLS_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */ 82*4882a593Smuzhiyun MBEDTLS_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */ 83*4882a593Smuzhiyun MBEDTLS_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */ 84*4882a593Smuzhiyun MBEDTLS_ECP_DP_CURVE25519, /*!< Curve25519 */ 85*4882a593Smuzhiyun MBEDTLS_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */ 86*4882a593Smuzhiyun MBEDTLS_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */ 87*4882a593Smuzhiyun MBEDTLS_ECP_DP_SECP256K1 /*!< 256-bits "Koblitz" curve */ 88*4882a593Smuzhiyun } mbedtls_ecp_group_id; 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun /** 91*4882a593Smuzhiyun * Number of supported curves (plus one for NONE). 92*4882a593Smuzhiyun * 93*4882a593Smuzhiyun * (Montgomery curves excluded for now.) 94*4882a593Smuzhiyun */ 95*4882a593Smuzhiyun #define MBEDTLS_ECP_DP_MAX 12 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun /** 98*4882a593Smuzhiyun * Curve information for use by other modules 99*4882a593Smuzhiyun */ 100*4882a593Smuzhiyun typedef struct 101*4882a593Smuzhiyun { 102*4882a593Smuzhiyun mbedtls_ecp_group_id grp_id; /*!< Internal identifier */ 103*4882a593Smuzhiyun uint16_t tls_id; /*!< TLS NamedCurve identifier */ 104*4882a593Smuzhiyun uint16_t bit_size; /*!< Curve size in bits */ 105*4882a593Smuzhiyun const char *name; /*!< Human-friendly name */ 106*4882a593Smuzhiyun } mbedtls_ecp_curve_info; 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun /** 109*4882a593Smuzhiyun * \brief ECP point structure (jacobian coordinates) 110*4882a593Smuzhiyun * 111*4882a593Smuzhiyun * \note All functions expect and return points satisfying 112*4882a593Smuzhiyun * the following condition: Z == 0 or Z == 1. (Other 113*4882a593Smuzhiyun * values of Z are used by internal functions only.) 114*4882a593Smuzhiyun * The point is zero, or "at infinity", if Z == 0. 115*4882a593Smuzhiyun * Otherwise, X and Y are its standard (affine) coordinates. 116*4882a593Smuzhiyun */ 117*4882a593Smuzhiyun typedef struct 118*4882a593Smuzhiyun { 119*4882a593Smuzhiyun mbedtls_mpi X; /*!< the point's X coordinate */ 120*4882a593Smuzhiyun mbedtls_mpi Y; /*!< the point's Y coordinate */ 121*4882a593Smuzhiyun mbedtls_mpi Z; /*!< the point's Z coordinate */ 122*4882a593Smuzhiyun } 123*4882a593Smuzhiyun mbedtls_ecp_point; 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun /** 126*4882a593Smuzhiyun * \brief ECP group structure 127*4882a593Smuzhiyun * 128*4882a593Smuzhiyun * We consider two types of curves equations: 129*4882a593Smuzhiyun * 1. Short Weierstrass y^2 = x^3 + A x + B mod P (SEC1 + RFC 4492) 130*4882a593Smuzhiyun * 2. Montgomery, y^2 = x^3 + A x^2 + x mod P (Curve25519 + draft) 131*4882a593Smuzhiyun * In both cases, a generator G for a prime-order subgroup is fixed. In the 132*4882a593Smuzhiyun * short weierstrass, this subgroup is actually the whole curve, and its 133*4882a593Smuzhiyun * cardinal is denoted by N. 134*4882a593Smuzhiyun * 135*4882a593Smuzhiyun * In the case of Short Weierstrass curves, our code requires that N is an odd 136*4882a593Smuzhiyun * prime. (Use odd in mbedtls_ecp_mul() and prime in mbedtls_ecdsa_sign() for blinding.) 137*4882a593Smuzhiyun * 138*4882a593Smuzhiyun * In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is 139*4882a593Smuzhiyun * the quantity actually used in the formulas. Also, nbits is not the size of N 140*4882a593Smuzhiyun * but the required size for private keys. 141*4882a593Smuzhiyun * 142*4882a593Smuzhiyun * If modp is NULL, reduction modulo P is done using a generic algorithm. 143*4882a593Smuzhiyun * Otherwise, it must point to a function that takes an mbedtls_mpi in the range 144*4882a593Smuzhiyun * 0..2^(2*pbits)-1 and transforms it in-place in an integer of little more 145*4882a593Smuzhiyun * than pbits, so that the integer may be efficiently brought in the 0..P-1 146*4882a593Smuzhiyun * range by a few additions or substractions. It must return 0 on success and 147*4882a593Smuzhiyun * non-zero on failure. 148*4882a593Smuzhiyun */ 149*4882a593Smuzhiyun typedef struct 150*4882a593Smuzhiyun { 151*4882a593Smuzhiyun mbedtls_ecp_group_id id; /*!< internal group identifier */ 152*4882a593Smuzhiyun mbedtls_mpi P; /*!< prime modulus of the base field */ 153*4882a593Smuzhiyun mbedtls_mpi A; /*!< 1. A in the equation, or 2. (A + 2) / 4 */ 154*4882a593Smuzhiyun mbedtls_mpi B; /*!< 1. B in the equation, or 2. unused */ 155*4882a593Smuzhiyun mbedtls_ecp_point G; /*!< generator of the (sub)group used */ 156*4882a593Smuzhiyun mbedtls_mpi N; /*!< 1. the order of G, or 2. unused */ 157*4882a593Smuzhiyun size_t pbits; /*!< number of bits in P */ 158*4882a593Smuzhiyun size_t nbits; /*!< number of bits in 1. P, or 2. private keys */ 159*4882a593Smuzhiyun unsigned int h; /*!< internal: 1 if the constants are static */ 160*4882a593Smuzhiyun int (*modp)(mbedtls_mpi *); /*!< function for fast reduction mod P */ 161*4882a593Smuzhiyun int (*t_pre)(mbedtls_ecp_point *, void *); /*!< unused */ 162*4882a593Smuzhiyun int (*t_post)(mbedtls_ecp_point *, void *); /*!< unused */ 163*4882a593Smuzhiyun void *t_data; /*!< unused */ 164*4882a593Smuzhiyun mbedtls_ecp_point *T; /*!< pre-computed points for ecp_mul_comb() */ 165*4882a593Smuzhiyun size_t T_size; /*!< number for pre-computed points */ 166*4882a593Smuzhiyun } 167*4882a593Smuzhiyun mbedtls_ecp_group; 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun /** 170*4882a593Smuzhiyun * \brief ECP key pair structure 171*4882a593Smuzhiyun * 172*4882a593Smuzhiyun * A generic key pair that could be used for ECDSA, fixed ECDH, etc. 173*4882a593Smuzhiyun * 174*4882a593Smuzhiyun * \note Members purposefully in the same order as struc mbedtls_ecdsa_context. 175*4882a593Smuzhiyun */ 176*4882a593Smuzhiyun typedef struct 177*4882a593Smuzhiyun { 178*4882a593Smuzhiyun mbedtls_ecp_group grp; /*!< Elliptic curve and base point */ 179*4882a593Smuzhiyun mbedtls_mpi d; /*!< our secret value */ 180*4882a593Smuzhiyun mbedtls_ecp_point Q; /*!< our public value */ 181*4882a593Smuzhiyun } 182*4882a593Smuzhiyun mbedtls_ecp_keypair; 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun /** 185*4882a593Smuzhiyun * \name SECTION: Module settings 186*4882a593Smuzhiyun * 187*4882a593Smuzhiyun * The configuration options you can set for this module are in this section. 188*4882a593Smuzhiyun * Either change them in config.h or define them on the compiler command line. 189*4882a593Smuzhiyun * \{ 190*4882a593Smuzhiyun */ 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun #if !defined(MBEDTLS_ECP_MAX_BITS) 193*4882a593Smuzhiyun /** 194*4882a593Smuzhiyun * Maximum size of the groups (that is, of N and P) 195*4882a593Smuzhiyun */ 196*4882a593Smuzhiyun #define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ 197*4882a593Smuzhiyun #endif 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun #define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 ) 200*4882a593Smuzhiyun #define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 ) 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun #if !defined(MBEDTLS_ECP_WINDOW_SIZE) 203*4882a593Smuzhiyun /* 204*4882a593Smuzhiyun * Maximum "window" size used for point multiplication. 205*4882a593Smuzhiyun * Default: 6. 206*4882a593Smuzhiyun * Minimum value: 2. Maximum value: 7. 207*4882a593Smuzhiyun * 208*4882a593Smuzhiyun * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) 209*4882a593Smuzhiyun * points used for point multiplication. This value is directly tied to EC 210*4882a593Smuzhiyun * peak memory usage, so decreasing it by one should roughly cut memory usage 211*4882a593Smuzhiyun * by two (if large curves are in use). 212*4882a593Smuzhiyun * 213*4882a593Smuzhiyun * Reduction in size may reduce speed, but larger curves are impacted first. 214*4882a593Smuzhiyun * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): 215*4882a593Smuzhiyun * w-size: 6 5 4 3 2 216*4882a593Smuzhiyun * 521 145 141 135 120 97 217*4882a593Smuzhiyun * 384 214 209 198 177 146 218*4882a593Smuzhiyun * 256 320 320 303 262 226 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun * 224 475 475 453 398 342 221*4882a593Smuzhiyun * 192 640 640 633 587 476 222*4882a593Smuzhiyun */ 223*4882a593Smuzhiyun #define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ 224*4882a593Smuzhiyun #endif /* MBEDTLS_ECP_WINDOW_SIZE */ 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun #if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) 227*4882a593Smuzhiyun /* 228*4882a593Smuzhiyun * Trade memory for speed on fixed-point multiplication. 229*4882a593Smuzhiyun * 230*4882a593Smuzhiyun * This speeds up repeated multiplication of the generator (that is, the 231*4882a593Smuzhiyun * multiplication in ECDSA signatures, and half of the multiplications in 232*4882a593Smuzhiyun * ECDSA verification and ECDHE) by a factor roughly 3 to 4. 233*4882a593Smuzhiyun * 234*4882a593Smuzhiyun * The cost is increasing EC peak memory usage by a factor roughly 2. 235*4882a593Smuzhiyun * 236*4882a593Smuzhiyun * Change this value to 0 to reduce peak memory usage. 237*4882a593Smuzhiyun */ 238*4882a593Smuzhiyun #define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ 239*4882a593Smuzhiyun #endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun /* \} name SECTION: Module settings */ 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun /* 244*4882a593Smuzhiyun * Point formats, from RFC 4492's enum ECPointFormat 245*4882a593Smuzhiyun */ 246*4882a593Smuzhiyun #define MBEDTLS_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format */ 247*4882a593Smuzhiyun #define MBEDTLS_ECP_PF_COMPRESSED 1 /**< Compressed point format */ 248*4882a593Smuzhiyun 249*4882a593Smuzhiyun /* 250*4882a593Smuzhiyun * Some other constants from RFC 4492 251*4882a593Smuzhiyun */ 252*4882a593Smuzhiyun #define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< ECCurveType's named_curve */ 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun /** 255*4882a593Smuzhiyun * \brief Get the list of supported curves in order of preferrence 256*4882a593Smuzhiyun * (full information) 257*4882a593Smuzhiyun * 258*4882a593Smuzhiyun * \return A statically allocated array, the last entry is 0. 259*4882a593Smuzhiyun */ 260*4882a593Smuzhiyun const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ); 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun /** 263*4882a593Smuzhiyun * \brief Get the list of supported curves in order of preferrence 264*4882a593Smuzhiyun * (grp_id only) 265*4882a593Smuzhiyun * 266*4882a593Smuzhiyun * \return A statically allocated array, 267*4882a593Smuzhiyun * terminated with MBEDTLS_ECP_DP_NONE. 268*4882a593Smuzhiyun */ 269*4882a593Smuzhiyun const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void ); 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun /** 272*4882a593Smuzhiyun * \brief Get curve information from an internal group identifier 273*4882a593Smuzhiyun * 274*4882a593Smuzhiyun * \param grp_id A MBEDTLS_ECP_DP_XXX value 275*4882a593Smuzhiyun * 276*4882a593Smuzhiyun * \return The associated curve information or NULL 277*4882a593Smuzhiyun */ 278*4882a593Smuzhiyun const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id ); 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun /** 281*4882a593Smuzhiyun * \brief Get curve information from a TLS NamedCurve value 282*4882a593Smuzhiyun * 283*4882a593Smuzhiyun * \param tls_id A MBEDTLS_ECP_DP_XXX value 284*4882a593Smuzhiyun * 285*4882a593Smuzhiyun * \return The associated curve information or NULL 286*4882a593Smuzhiyun */ 287*4882a593Smuzhiyun const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id ); 288*4882a593Smuzhiyun 289*4882a593Smuzhiyun /** 290*4882a593Smuzhiyun * \brief Get curve information from a human-readable name 291*4882a593Smuzhiyun * 292*4882a593Smuzhiyun * \param name The name 293*4882a593Smuzhiyun * 294*4882a593Smuzhiyun * \return The associated curve information or NULL 295*4882a593Smuzhiyun */ 296*4882a593Smuzhiyun const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name ); 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun /** 299*4882a593Smuzhiyun * \brief Initialize a point (as zero) 300*4882a593Smuzhiyun */ 301*4882a593Smuzhiyun void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ); 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun /** 304*4882a593Smuzhiyun * \brief Initialize a group (to something meaningless) 305*4882a593Smuzhiyun */ 306*4882a593Smuzhiyun void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ); 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun /** 309*4882a593Smuzhiyun * \brief Initialize a key pair (as an invalid one) 310*4882a593Smuzhiyun */ 311*4882a593Smuzhiyun void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ); 312*4882a593Smuzhiyun 313*4882a593Smuzhiyun /** 314*4882a593Smuzhiyun * \brief Free the components of a point 315*4882a593Smuzhiyun */ 316*4882a593Smuzhiyun void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ); 317*4882a593Smuzhiyun 318*4882a593Smuzhiyun /** 319*4882a593Smuzhiyun * \brief Free the components of an ECP group 320*4882a593Smuzhiyun */ 321*4882a593Smuzhiyun void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ); 322*4882a593Smuzhiyun 323*4882a593Smuzhiyun /** 324*4882a593Smuzhiyun * \brief Free the components of a key pair 325*4882a593Smuzhiyun */ 326*4882a593Smuzhiyun void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ); 327*4882a593Smuzhiyun 328*4882a593Smuzhiyun /** 329*4882a593Smuzhiyun * \brief Copy the contents of point Q into P 330*4882a593Smuzhiyun * 331*4882a593Smuzhiyun * \param P Destination point 332*4882a593Smuzhiyun * \param Q Source point 333*4882a593Smuzhiyun * 334*4882a593Smuzhiyun * \return 0 if successful, 335*4882a593Smuzhiyun * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 336*4882a593Smuzhiyun */ 337*4882a593Smuzhiyun int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); 338*4882a593Smuzhiyun 339*4882a593Smuzhiyun /** 340*4882a593Smuzhiyun * \brief Copy the contents of a group object 341*4882a593Smuzhiyun * 342*4882a593Smuzhiyun * \param dst Destination group 343*4882a593Smuzhiyun * \param src Source group 344*4882a593Smuzhiyun * 345*4882a593Smuzhiyun * \return 0 if successful, 346*4882a593Smuzhiyun * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 347*4882a593Smuzhiyun */ 348*4882a593Smuzhiyun int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ); 349*4882a593Smuzhiyun 350*4882a593Smuzhiyun /** 351*4882a593Smuzhiyun * \brief Set a point to zero 352*4882a593Smuzhiyun * 353*4882a593Smuzhiyun * \param pt Destination point 354*4882a593Smuzhiyun * 355*4882a593Smuzhiyun * \return 0 if successful, 356*4882a593Smuzhiyun * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 357*4882a593Smuzhiyun */ 358*4882a593Smuzhiyun int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ); 359*4882a593Smuzhiyun 360*4882a593Smuzhiyun /** 361*4882a593Smuzhiyun * \brief Tell if a point is zero 362*4882a593Smuzhiyun * 363*4882a593Smuzhiyun * \param pt Point to test 364*4882a593Smuzhiyun * 365*4882a593Smuzhiyun * \return 1 if point is zero, 0 otherwise 366*4882a593Smuzhiyun */ 367*4882a593Smuzhiyun int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ); 368*4882a593Smuzhiyun 369*4882a593Smuzhiyun /** 370*4882a593Smuzhiyun * \brief Compare two points 371*4882a593Smuzhiyun * 372*4882a593Smuzhiyun * \note This assumes the points are normalized. Otherwise, 373*4882a593Smuzhiyun * they may compare as "not equal" even if they are. 374*4882a593Smuzhiyun * 375*4882a593Smuzhiyun * \param P First point to compare 376*4882a593Smuzhiyun * \param Q Second point to compare 377*4882a593Smuzhiyun * 378*4882a593Smuzhiyun * \return 0 if the points are equal, 379*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise 380*4882a593Smuzhiyun */ 381*4882a593Smuzhiyun int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, 382*4882a593Smuzhiyun const mbedtls_ecp_point *Q ); 383*4882a593Smuzhiyun 384*4882a593Smuzhiyun /** 385*4882a593Smuzhiyun * \brief Import a non-zero point from two ASCII strings 386*4882a593Smuzhiyun * 387*4882a593Smuzhiyun * \param P Destination point 388*4882a593Smuzhiyun * \param radix Input numeric base 389*4882a593Smuzhiyun * \param x First affine coordinate as a null-terminated string 390*4882a593Smuzhiyun * \param y Second affine coordinate as a null-terminated string 391*4882a593Smuzhiyun * 392*4882a593Smuzhiyun * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code 393*4882a593Smuzhiyun */ 394*4882a593Smuzhiyun int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, 395*4882a593Smuzhiyun const char *x, const char *y ); 396*4882a593Smuzhiyun 397*4882a593Smuzhiyun /** 398*4882a593Smuzhiyun * \brief Export a point into unsigned binary data 399*4882a593Smuzhiyun * 400*4882a593Smuzhiyun * \param grp Group to which the point should belong 401*4882a593Smuzhiyun * \param P Point to export 402*4882a593Smuzhiyun * \param format Point format, should be a MBEDTLS_ECP_PF_XXX macro 403*4882a593Smuzhiyun * \param olen Length of the actual output 404*4882a593Smuzhiyun * \param buf Output buffer 405*4882a593Smuzhiyun * \param buflen Length of the output buffer 406*4882a593Smuzhiyun * 407*4882a593Smuzhiyun * \return 0 if successful, 408*4882a593Smuzhiyun * or MBEDTLS_ERR_ECP_BAD_INPUT_DATA 409*4882a593Smuzhiyun * or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL 410*4882a593Smuzhiyun */ 411*4882a593Smuzhiyun int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P, 412*4882a593Smuzhiyun int format, size_t *olen, 413*4882a593Smuzhiyun unsigned char *buf, size_t buflen ); 414*4882a593Smuzhiyun 415*4882a593Smuzhiyun /** 416*4882a593Smuzhiyun * \brief Import a point from unsigned binary data 417*4882a593Smuzhiyun * 418*4882a593Smuzhiyun * \param grp Group to which the point should belong 419*4882a593Smuzhiyun * \param P Point to import 420*4882a593Smuzhiyun * \param buf Input buffer 421*4882a593Smuzhiyun * \param ilen Actual length of input 422*4882a593Smuzhiyun * 423*4882a593Smuzhiyun * \return 0 if successful, 424*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid, 425*4882a593Smuzhiyun * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 426*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format 427*4882a593Smuzhiyun * is not implemented. 428*4882a593Smuzhiyun * 429*4882a593Smuzhiyun * \note This function does NOT check that the point actually 430*4882a593Smuzhiyun * belongs to the given group, see mbedtls_ecp_check_pubkey() for 431*4882a593Smuzhiyun * that. 432*4882a593Smuzhiyun */ 433*4882a593Smuzhiyun int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, 434*4882a593Smuzhiyun const unsigned char *buf, size_t ilen ); 435*4882a593Smuzhiyun 436*4882a593Smuzhiyun /** 437*4882a593Smuzhiyun * \brief Import a point from a TLS ECPoint record 438*4882a593Smuzhiyun * 439*4882a593Smuzhiyun * \param grp ECP group used 440*4882a593Smuzhiyun * \param pt Destination point 441*4882a593Smuzhiyun * \param buf $(Start of input buffer) 442*4882a593Smuzhiyun * \param len Buffer length 443*4882a593Smuzhiyun * 444*4882a593Smuzhiyun * \note buf is updated to point right after the ECPoint on exit 445*4882a593Smuzhiyun * 446*4882a593Smuzhiyun * \return 0 if successful, 447*4882a593Smuzhiyun * MBEDTLS_ERR_MPI_XXX if initialization failed 448*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid 449*4882a593Smuzhiyun */ 450*4882a593Smuzhiyun int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, 451*4882a593Smuzhiyun const unsigned char **buf, size_t len ); 452*4882a593Smuzhiyun 453*4882a593Smuzhiyun /** 454*4882a593Smuzhiyun * \brief Export a point as a TLS ECPoint record 455*4882a593Smuzhiyun * 456*4882a593Smuzhiyun * \param grp ECP group used 457*4882a593Smuzhiyun * \param pt Point to export 458*4882a593Smuzhiyun * \param format Export format 459*4882a593Smuzhiyun * \param olen length of data written 460*4882a593Smuzhiyun * \param buf Buffer to write to 461*4882a593Smuzhiyun * \param blen Buffer length 462*4882a593Smuzhiyun * 463*4882a593Smuzhiyun * \return 0 if successful, 464*4882a593Smuzhiyun * or MBEDTLS_ERR_ECP_BAD_INPUT_DATA 465*4882a593Smuzhiyun * or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL 466*4882a593Smuzhiyun */ 467*4882a593Smuzhiyun int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, 468*4882a593Smuzhiyun int format, size_t *olen, 469*4882a593Smuzhiyun unsigned char *buf, size_t blen ); 470*4882a593Smuzhiyun 471*4882a593Smuzhiyun /** 472*4882a593Smuzhiyun * \brief Set a group using well-known domain parameters 473*4882a593Smuzhiyun * 474*4882a593Smuzhiyun * \param grp Destination group 475*4882a593Smuzhiyun * \param index Index in the list of well-known domain parameters 476*4882a593Smuzhiyun * 477*4882a593Smuzhiyun * \return 0 if successful, 478*4882a593Smuzhiyun * MBEDTLS_ERR_MPI_XXX if initialization failed 479*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups 480*4882a593Smuzhiyun * 481*4882a593Smuzhiyun * \note Index should be a value of RFC 4492's enum NamedCurve, 482*4882a593Smuzhiyun * usually in the form of a MBEDTLS_ECP_DP_XXX macro. 483*4882a593Smuzhiyun */ 484*4882a593Smuzhiyun int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id index ); 485*4882a593Smuzhiyun 486*4882a593Smuzhiyun /** 487*4882a593Smuzhiyun * \brief Set a group from a TLS ECParameters record 488*4882a593Smuzhiyun * 489*4882a593Smuzhiyun * \param grp Destination group 490*4882a593Smuzhiyun * \param buf &(Start of input buffer) 491*4882a593Smuzhiyun * \param len Buffer length 492*4882a593Smuzhiyun * 493*4882a593Smuzhiyun * \note buf is updated to point right after ECParameters on exit 494*4882a593Smuzhiyun * 495*4882a593Smuzhiyun * \return 0 if successful, 496*4882a593Smuzhiyun * MBEDTLS_ERR_MPI_XXX if initialization failed 497*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid 498*4882a593Smuzhiyun */ 499*4882a593Smuzhiyun int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len ); 500*4882a593Smuzhiyun 501*4882a593Smuzhiyun /** 502*4882a593Smuzhiyun * \brief Write the TLS ECParameters record for a group 503*4882a593Smuzhiyun * 504*4882a593Smuzhiyun * \param grp ECP group used 505*4882a593Smuzhiyun * \param olen Number of bytes actually written 506*4882a593Smuzhiyun * \param buf Buffer to write to 507*4882a593Smuzhiyun * \param blen Buffer length 508*4882a593Smuzhiyun * 509*4882a593Smuzhiyun * \return 0 if successful, 510*4882a593Smuzhiyun * or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL 511*4882a593Smuzhiyun */ 512*4882a593Smuzhiyun int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, 513*4882a593Smuzhiyun unsigned char *buf, size_t blen ); 514*4882a593Smuzhiyun 515*4882a593Smuzhiyun /** 516*4882a593Smuzhiyun * \brief Multiplication by an integer: R = m * P 517*4882a593Smuzhiyun * (Not thread-safe to use same group in multiple threads) 518*4882a593Smuzhiyun * 519*4882a593Smuzhiyun * \note In order to prevent timing attacks, this function 520*4882a593Smuzhiyun * executes the exact same sequence of (base field) 521*4882a593Smuzhiyun * operations for any valid m. It avoids any if-branch or 522*4882a593Smuzhiyun * array index depending on the value of m. 523*4882a593Smuzhiyun * 524*4882a593Smuzhiyun * \note If f_rng is not NULL, it is used to randomize intermediate 525*4882a593Smuzhiyun * results in order to prevent potential timing attacks 526*4882a593Smuzhiyun * targeting these results. It is recommended to always 527*4882a593Smuzhiyun * provide a non-NULL f_rng (the overhead is negligible). 528*4882a593Smuzhiyun * 529*4882a593Smuzhiyun * \param grp ECP group 530*4882a593Smuzhiyun * \param R Destination point 531*4882a593Smuzhiyun * \param m Integer by which to multiply 532*4882a593Smuzhiyun * \param P Point to multiply 533*4882a593Smuzhiyun * \param f_rng RNG function (see notes) 534*4882a593Smuzhiyun * \param p_rng RNG parameter 535*4882a593Smuzhiyun * 536*4882a593Smuzhiyun * \return 0 if successful, 537*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_INVALID_KEY if m is not a valid privkey 538*4882a593Smuzhiyun * or P is not a valid pubkey, 539*4882a593Smuzhiyun * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 540*4882a593Smuzhiyun */ 541*4882a593Smuzhiyun int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, 542*4882a593Smuzhiyun const mbedtls_mpi *m, const mbedtls_ecp_point *P, 543*4882a593Smuzhiyun int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); 544*4882a593Smuzhiyun 545*4882a593Smuzhiyun /** 546*4882a593Smuzhiyun * \brief Multiplication and addition of two points by integers: 547*4882a593Smuzhiyun * R = m * P + n * Q 548*4882a593Smuzhiyun * (Not thread-safe to use same group in multiple threads) 549*4882a593Smuzhiyun * 550*4882a593Smuzhiyun * \note In contrast to mbedtls_ecp_mul(), this function does not guarantee 551*4882a593Smuzhiyun * a constant execution flow and timing. 552*4882a593Smuzhiyun * 553*4882a593Smuzhiyun * \param grp ECP group 554*4882a593Smuzhiyun * \param R Destination point 555*4882a593Smuzhiyun * \param m Integer by which to multiply P 556*4882a593Smuzhiyun * \param P Point to multiply by m 557*4882a593Smuzhiyun * \param n Integer by which to multiply Q 558*4882a593Smuzhiyun * \param Q Point to be multiplied by n 559*4882a593Smuzhiyun * 560*4882a593Smuzhiyun * \return 0 if successful, 561*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_INVALID_KEY if m or n is not a valid privkey 562*4882a593Smuzhiyun * or P or Q is not a valid pubkey, 563*4882a593Smuzhiyun * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 564*4882a593Smuzhiyun */ 565*4882a593Smuzhiyun int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, 566*4882a593Smuzhiyun const mbedtls_mpi *m, const mbedtls_ecp_point *P, 567*4882a593Smuzhiyun const mbedtls_mpi *n, const mbedtls_ecp_point *Q ); 568*4882a593Smuzhiyun 569*4882a593Smuzhiyun /** 570*4882a593Smuzhiyun * \brief Check that a point is a valid public key on this curve 571*4882a593Smuzhiyun * 572*4882a593Smuzhiyun * \param grp Curve/group the point should belong to 573*4882a593Smuzhiyun * \param pt Point to check 574*4882a593Smuzhiyun * 575*4882a593Smuzhiyun * \return 0 if point is a valid public key, 576*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_INVALID_KEY otherwise. 577*4882a593Smuzhiyun * 578*4882a593Smuzhiyun * \note This function only checks the point is non-zero, has valid 579*4882a593Smuzhiyun * coordinates and lies on the curve, but not that it is 580*4882a593Smuzhiyun * indeed a multiple of G. This is additional check is more 581*4882a593Smuzhiyun * expensive, isn't required by standards, and shouldn't be 582*4882a593Smuzhiyun * necessary if the group used has a small cofactor. In 583*4882a593Smuzhiyun * particular, it is useless for the NIST groups which all 584*4882a593Smuzhiyun * have a cofactor of 1. 585*4882a593Smuzhiyun * 586*4882a593Smuzhiyun * \note Uses bare components rather than an mbedtls_ecp_keypair structure 587*4882a593Smuzhiyun * in order to ease use with other structures such as 588*4882a593Smuzhiyun * mbedtls_ecdh_context of mbedtls_ecdsa_context. 589*4882a593Smuzhiyun */ 590*4882a593Smuzhiyun int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ); 591*4882a593Smuzhiyun 592*4882a593Smuzhiyun /** 593*4882a593Smuzhiyun * \brief Check that an mbedtls_mpi is a valid private key for this curve 594*4882a593Smuzhiyun * 595*4882a593Smuzhiyun * \param grp Group used 596*4882a593Smuzhiyun * \param d Integer to check 597*4882a593Smuzhiyun * 598*4882a593Smuzhiyun * \return 0 if point is a valid private key, 599*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_INVALID_KEY otherwise. 600*4882a593Smuzhiyun * 601*4882a593Smuzhiyun * \note Uses bare components rather than an mbedtls_ecp_keypair structure 602*4882a593Smuzhiyun * in order to ease use with other structures such as 603*4882a593Smuzhiyun * mbedtls_ecdh_context of mbedtls_ecdsa_context. 604*4882a593Smuzhiyun */ 605*4882a593Smuzhiyun int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d ); 606*4882a593Smuzhiyun 607*4882a593Smuzhiyun /** 608*4882a593Smuzhiyun * \brief Generate a keypair with configurable base point 609*4882a593Smuzhiyun * 610*4882a593Smuzhiyun * \param grp ECP group 611*4882a593Smuzhiyun * \param G Chosen base point 612*4882a593Smuzhiyun * \param d Destination MPI (secret part) 613*4882a593Smuzhiyun * \param Q Destination point (public part) 614*4882a593Smuzhiyun * \param f_rng RNG function 615*4882a593Smuzhiyun * \param p_rng RNG parameter 616*4882a593Smuzhiyun * 617*4882a593Smuzhiyun * \return 0 if successful, 618*4882a593Smuzhiyun * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code 619*4882a593Smuzhiyun * 620*4882a593Smuzhiyun * \note Uses bare components rather than an mbedtls_ecp_keypair structure 621*4882a593Smuzhiyun * in order to ease use with other structures such as 622*4882a593Smuzhiyun * mbedtls_ecdh_context of mbedtls_ecdsa_context. 623*4882a593Smuzhiyun */ 624*4882a593Smuzhiyun int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, 625*4882a593Smuzhiyun const mbedtls_ecp_point *G, 626*4882a593Smuzhiyun mbedtls_mpi *d, mbedtls_ecp_point *Q, 627*4882a593Smuzhiyun int (*f_rng)(void *, unsigned char *, size_t), 628*4882a593Smuzhiyun void *p_rng ); 629*4882a593Smuzhiyun 630*4882a593Smuzhiyun /** 631*4882a593Smuzhiyun * \brief Generate a keypair 632*4882a593Smuzhiyun * 633*4882a593Smuzhiyun * \param grp ECP group 634*4882a593Smuzhiyun * \param d Destination MPI (secret part) 635*4882a593Smuzhiyun * \param Q Destination point (public part) 636*4882a593Smuzhiyun * \param f_rng RNG function 637*4882a593Smuzhiyun * \param p_rng RNG parameter 638*4882a593Smuzhiyun * 639*4882a593Smuzhiyun * \return 0 if successful, 640*4882a593Smuzhiyun * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code 641*4882a593Smuzhiyun * 642*4882a593Smuzhiyun * \note Uses bare components rather than an mbedtls_ecp_keypair structure 643*4882a593Smuzhiyun * in order to ease use with other structures such as 644*4882a593Smuzhiyun * mbedtls_ecdh_context of mbedtls_ecdsa_context. 645*4882a593Smuzhiyun */ 646*4882a593Smuzhiyun int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, 647*4882a593Smuzhiyun int (*f_rng)(void *, unsigned char *, size_t), 648*4882a593Smuzhiyun void *p_rng ); 649*4882a593Smuzhiyun 650*4882a593Smuzhiyun /** 651*4882a593Smuzhiyun * \brief Generate a keypair 652*4882a593Smuzhiyun * 653*4882a593Smuzhiyun * \param grp_id ECP group identifier 654*4882a593Smuzhiyun * \param key Destination keypair 655*4882a593Smuzhiyun * \param f_rng RNG function 656*4882a593Smuzhiyun * \param p_rng RNG parameter 657*4882a593Smuzhiyun * 658*4882a593Smuzhiyun * \return 0 if successful, 659*4882a593Smuzhiyun * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code 660*4882a593Smuzhiyun */ 661*4882a593Smuzhiyun int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, 662*4882a593Smuzhiyun int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); 663*4882a593Smuzhiyun 664*4882a593Smuzhiyun /** 665*4882a593Smuzhiyun * \brief Check a public-private key pair 666*4882a593Smuzhiyun * 667*4882a593Smuzhiyun * \param pub Keypair structure holding a public key 668*4882a593Smuzhiyun * \param prv Keypair structure holding a private (plus public) key 669*4882a593Smuzhiyun * 670*4882a593Smuzhiyun * \return 0 if successful (keys are valid and match), or 671*4882a593Smuzhiyun * MBEDTLS_ERR_ECP_BAD_INPUT_DATA, or 672*4882a593Smuzhiyun * a MBEDTLS_ERR_ECP_XXX or MBEDTLS_ERR_MPI_XXX code. 673*4882a593Smuzhiyun */ 674*4882a593Smuzhiyun int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ); 675*4882a593Smuzhiyun 676*4882a593Smuzhiyun #if defined(MBEDTLS_SELF_TEST) 677*4882a593Smuzhiyun /** 678*4882a593Smuzhiyun * \brief Checkup routine 679*4882a593Smuzhiyun * 680*4882a593Smuzhiyun * \return 0 if successful, or 1 if a test failed 681*4882a593Smuzhiyun */ 682*4882a593Smuzhiyun int mbedtls_ecp_self_test( int verbose ); 683*4882a593Smuzhiyun #endif 684*4882a593Smuzhiyun 685*4882a593Smuzhiyun #ifdef __cplusplus 686*4882a593Smuzhiyun } 687*4882a593Smuzhiyun #endif 688*4882a593Smuzhiyun 689*4882a593Smuzhiyun #endif /* ecp.h */ 690