1 /* 2 * This file is part of the openHiTLS project. 3 * 4 * openHiTLS is licensed under the Mulan PSL v2. 5 * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 * You may obtain a copy of Mulan PSL v2 at: 7 * 8 * http://license.coscl.org.cn/MulanPSL2 9 * 10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13 * See the Mulan PSL v2 for more details. 14 */ 15 16 #ifndef ECC_LOCAL_H 17 #define ECC_LOCAL_H 18 19 #include "hitls_build.h" 20 #ifdef HITLS_CRYPTO_ECC 21 22 #include "crypt_ecc.h" 23 #include "crypt_bn.h" 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 #define ECC_MAX_BIT_LEN 521 30 31 #define PRE_COMPUTE_WINDOW 5 // Default Window Size 32 #define PRE_COMPUTE_MAX_TABLELEN (1 << 5) // Maximum specifications of the pre-calculation table 33 34 /** 35 * Elliptic Curve Implementation Method 36 */ 37 typedef struct { 38 // Calculate r = k1 * G + k2 * pt 39 int32_t (*pointMulAdd)(ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt); 40 // Calculate r = k * pt. If pt is null, calculate r = k * G. This is the ConstTime processing function. 41 int32_t (*pointMul)(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); 42 // Calculate r = k * pt. If pt is null, calculate r = k * G 43 int32_t (*pointMulFast)(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); 44 // point addition r = a + b, a all can be the jacobi coordinate, b must be an affine point 45 int32_t (*pointAddAffine)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); 46 // point addition r = a + b, a, b all can be the jacobi coordinate. 47 int32_t (*pointAdd)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); 48 // point double r = a + a, a can be the jacobi coordinate. 49 int32_t (*pointDouble)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); 50 // point Multi-double Calculate r = (2^m)*a, a can be the jacobi coordinate. 51 int32_t (*pointMultDouble)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m); 52 // Module inverse 53 int32_t (*modInv)(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *p, BN_Optimizer *opt); 54 // Convert points to affine coordinates based on the given module inverse information. 55 int32_t (*point2AffineWithInv)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const BN_BigNum *inv); 56 // Convert the point information to affine coordinates. 57 int32_t (*point2Affine)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); 58 // Calculate r = (a*b) % mod 59 int32_t (*bnModNistEccMul)(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, 60 void *mod, BN_Optimizer *opt); 61 // Calculate r = (a^2) % mod 62 int32_t (*bnModNistEccSqr)(BN_BigNum *r, const BN_BigNum *a, void *mod, BN_Optimizer *opt); 63 // Inverse mode order. 64 int32_t (*modOrdInv)(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a); 65 // convert date to Montgomery form 66 int32_t (*bnMontEnc)(BN_BigNum *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime); 67 // convert Montgomery form to common form 68 void (*bnMontDec)(BN_BigNum *r, BN_Mont *mont); 69 } ECC_Method; 70 71 /** 72 * Elliptic Curve Point Information 73 */ 74 struct EccPointInfo { 75 BN_BigNum *x; 76 BN_BigNum *y; 77 BN_BigNum *z; 78 CRYPT_PKEY_ParaId id; 79 }; 80 81 /** 82 * Elliptic curve parameter information 83 */ 84 struct EccPara { 85 BN_BigNum *p; 86 BN_BigNum *a; 87 BN_BigNum *b; 88 BN_BigNum *n; 89 BN_BigNum *h; 90 BN_BigNum *x; 91 BN_BigNum *y; 92 // Currently, the 5-bit window is used. Only odd multiple points are calculated. 93 // The total number of pre-calculated data is (2 ^ 5)/2, that is 16 points. 94 ECC_Point *tableG[16]; 95 const ECC_Method *method; 96 CRYPT_PKEY_ParaId id; 97 BN_Mont *montP; 98 void *libCtx; 99 }; 100 101 /** 102 * @ingroup ecc 103 * @brief Check whether the checkpoint is at infinity. 104 * 105 * @param para [IN] Curve parameters 106 * @param pt [IN] Point information 107 * 108 * @retval CRYPT_SUCCESS succeeded, indicating that the point is not at infinity. 109 * @retval For details about other errors, see crypt_errno.h 110 */ 111 int32_t ECP_PointAtInfinity(const ECC_Para *para, const ECC_Point *pt); 112 113 /** 114 * @ingroup ecc 115 * @brief Check whether the point is on the curve. 116 * The determined point must be on the Cartesian coordinate, which is used to check the validity of the point input. 117 * 118 * @param para [IN] Curve parameters 119 * @param pt [IN] Point information 120 * 121 * @retval CRYPT_SUCCESS succeeded. 122 * @retval For details about other errors, see crypt_errno.h 123 */ 124 int32_t ECP_PointOnCurve(const ECC_Para *para, const ECC_Point *pt); 125 126 /** 127 * @ingroup ecc 128 * @brief Add salt to the pt point and add random z information. 129 * 130 * @param para [IN] Curve parameters 131 * @param pt [IN/OUT] Point information 132 * 133 * @retval CRYPT_SUCCESS succeeded. 134 * @retval For details about other errors, see crypt_errno.h 135 */ 136 int32_t ECP_PointBlind(const ECC_Para *para, ECC_Point *pt); 137 138 /** 139 * @ingroup ecc 140 * @brief Convert the point information pt to the affine coordinate system and synchronize the data to r. 141 * 142 * @param para [IN] Curve parameters 143 * @param r [OUT] Output point information 144 * @param pt [IN] Input point information 145 * 146 * @retval CRYPT_SUCCESS succeeded. 147 * @retval For details about other errors, see crypt_errno.h 148 */ 149 int32_t ECP_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt); 150 151 /** 152 * @ingroup ecc 153 * @brief Converts all point information on pt to affine coordinate system, 154 * which is used for the coordinate system conversion of the pre-computation table. 155 * 156 * @attention pt[0] cannot be an infinite point. 157 * 158 * @param para [IN] Curve parameters 159 * @param pt [IN/OUT] Point information 160 * @param ptNums [IN] Number of pts 161 * 162 * @retval CRYPT_SUCCESS succeeded. 163 * @retval For details about other errors, see crypt_errno.h 164 */ 165 int32_t ECP_Points2Affine(const ECC_Para *para, ECC_Point *pt[], uint32_t ptNums); 166 167 /** 168 * @ingroup ecc 169 * @brief Calculated r = -a 170 * 171 * @attention point a must be a point in the Cartesian coordinate system 172 * 173 * @param para [IN] Curve parameters 174 * @param r [OUT] Output point information 175 * @param pt [IN] Input point information 176 * 177 * @retval CRYPT_SUCCESS succeeded. 178 * @retval For details about other errors, see crypt_errno.h 179 */ 180 int32_t ECP_PointInvertAtAffine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); 181 182 /** 183 * @ingroup ecc 184 * @brief Convert the point information pt to the affine coordinate system and refresh the data to r. 185 * The inverse information of z is provided by the user. 186 * 187 * @attention The validity of inv is guaranteed by the user. 188 * 189 * @param para [IN] Curve parameters 190 * @param r [OUT] Output point information 191 * @param pt [IN] Input point information 192 * @param inv [IN] inverse information of z 193 * 194 * @retval CRYPT_SUCCESS succeeded. 195 * @retval For details about other errors, see crypt_errno.h 196 */ 197 int32_t ECP_Point2AffineWithInv( 198 const ECC_Para *para, ECC_Point *r, const ECC_Point *pt, const BN_BigNum *inv); 199 200 /** 201 * @ingroup ecc 202 * @brief Calculate r = k1 * G + k2 * pt 203 * 204 * @param para [IN] Curve parameters 205 * @param r [OUT] Output point information 206 * @param k1 [IN] Scalar 1 207 * @param k2 [IN] Scalar 2 208 * @param pt [IN] Point data 209 * 210 * @retval CRYPT_SUCCESS succeeded. 211 * @retval For details about other errors, see crypt_errno.h 212 */ 213 int32_t ECP_PointMulAdd( 214 ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt); 215 216 /** 217 * @ingroup ecc 218 * @brief Check whether a is consistent with b. 219 * 220 * @param para [IN] Curve parameter information 221 * @param a [IN] Input point information 222 * @param b [IN] Input point information 223 * 224 * @retval CRYPT_SUCCESS The two points are the same. 225 * @retval CRYPT_ECC_POINT_NOT_EQUAL The two points are different. 226 * @retval For details about other errors, see crypt_errno.h 227 */ 228 int32_t ECP_PointCmp(const ECC_Para *para, const ECC_Point *a, const ECC_Point *b); 229 230 /** 231 * @ingroup ecc 232 * @brief Calculate r = k * pt. When pt is NULL, calculate r = k * G 233 * The pre-computation table under para will be updated. 234 * 235 * @param para [IN] Curve parameter information 236 * @param r [OUT] Output point information 237 * @param k [IN] Scalar 238 * @param pt [IN] Point data, which can be set to NULL 239 * 240 * @retval CRYPT_SUCCESS set successfully 241 * @retval For details about other errors, see crypt_errno.h 242 */ 243 int32_t ECP_PointMul(ECC_Para *para, ECC_Point *r, 244 const BN_BigNum *k, const ECC_Point *pt); 245 246 /** 247 * @ingroup ecc 248 * @brief Calculate r = k * pt. When pt is NULL, calculate r = k * G 249 * The pre-computation table under para will be updated. 250 * Non-consttime calculation 251 * 252 * @param para [IN] Curve parameter information 253 * @param r [OUT] Output point information 254 * @param k [IN] Scalar 255 * @param pt [IN] Point data, which can be set to NULL 256 * 257 * @retval CRYPT_SUCCESS set successfully 258 * @retval For details about other errors, see crypt_errno.h 259 */ 260 int32_t ECP_PointMulFast(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); 261 262 /** 263 * @ingroup ecc 264 * @brief Obtaining a prime number curve (p + 1)/2 265 * 266 * @param p [IN] Input module 267 * 268 * @retval non-NULL succeeded. 269 * @retval NULL failed 270 */ 271 BN_BigNum *ECP_HalfPGet(const BN_BigNum *p); 272 273 /** 274 * @ingroup ecc 275 * @brief Search implementation method by curve ID 276 * 277 * @param id [IN] Curve enumeration 278 * 279 * @retval non-NULL succeeded. 280 * @retval NULL failed 281 */ 282 const ECC_Method *ECC_FindMethod(CRYPT_PKEY_ParaId id); 283 284 /** 285 * @ingroup ecc 286 * @brief nist Calculation of multiplication(double) of points of prime curve: r = a + a 287 * 288 * @param para [IN] Curve parameters 289 * @param r [OUT] Output point information 290 * @param a [IN] Input point information 291 * 292 * @retval CRYPT_SUCCESS succeeded. 293 * @retval For details about other errors, see crypt_errno.h 294 */ 295 int32_t ECP_NistPointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); 296 297 /** 298 * @ingroup ecc 299 * @brief nist Calculation of multi-double of points of prime curve: r = (2^m)*a 300 * 301 * @param para [IN] Curve parameters 302 * @param r [OUT] Output point information 303 * @param a [IN] Input point information 304 * @param m [IN] Exponential information of point multiplication scalar 305 * 306 * @retval CRYPT_SUCCESS succeeded. 307 * @retval For details about other errors, see crypt_errno.h 308 */ 309 int32_t ECP_NistPointMultDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m); 310 311 /** 312 * @ingroup ecc 313 * @brief nist Calculation of multiplication(double) of points of prime curve: r = a + b 314 * 315 * @param para [IN] Curve parameters 316 * @param r [OUT] Output point information 317 * @param a [IN] Input point information, a can be the jacobi coordinate. 318 * @param b [IN] Input point information, b must be the affine coordinate. 319 * 320 * @retval CRYPT_SUCCESS succeeded. 321 * @retval For details about other errors, see crypt_errno.h 322 */ 323 int32_t ECP_NistPointAddAffine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); 324 325 /** 326 * @ingroup ecc 327 * @brief nist Calculation of multiplication(double) of points of prime curve: r = a + b 328 * 329 * @param para [IN] Curve parameters 330 * @param r [OUT] Output point information 331 * @param a [IN] Input point information, a can be the jacobi coordinate. 332 * @param b [IN] Input point information, b can be the jacobi coordinate. 333 * 334 * @retval CRYPT_SUCCESS succeeded. 335 * @retval For details about other errors, see crypt_errno.h 336 */ 337 int32_t ECP_NistPointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); 338 339 /** 340 * @ingroup ecc 341 * @brief Convert the point to the affine coordinate and encode the point information as a data stream. 342 * 343 * @param para [IN] Curve parameter information 344 * @param pt [IN/OUT] Point data 345 * @param data [OUT] data stream 346 * @param dataLen [IN/OUT] The input is the buff length of data and the output is the valid length of data. 347 * @param format [IN] Encoding format 348 * 349 * @retval CRYPT_SUCCESS succeeded. 350 * @retval For details about other errors, see crypt_errno.h 351 */ 352 int32_t ECP_EncodePoint(const ECC_Para *para, ECC_Point *pt, uint8_t *data, uint32_t *dataLen, 353 CRYPT_PKEY_PointFormat format); 354 355 /** 356 * @ingroup ecc 357 * @brief Encode the data stream into point information. 358 * 359 * @param para [IN] Curve parameter information 360 * @param pt [OUT] Point data 361 * @param data [IN] data stream 362 * @param dataLen [IN] data stream length 363 * 364 * @retval CRYPT_SUCCESS succeeded. 365 * @retval For details about other errors, see crypt_errno.h 366 */ 367 int32_t ECP_DecodePoint(const ECC_Para *para, ECC_Point *pt, const uint8_t *data, uint32_t dataLen); 368 369 /** 370 * @brief Calculate r = 1/a mod para->n 371 * 372 * @param para [IN] Curve parameter information 373 * @param r [OUT] Output modulus inverse value 374 * @param a [IN] BigNum that needs to be inverted. 375 * 376 * @retval CRYPT_SUCCESS set successfully 377 * @retval For details about other errors, see crypt_errno.h 378 */ 379 int32_t ECP_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a); 380 381 #ifdef HITLS_CRYPTO_CURVE_MONT 382 383 /** 384 * The nist curve is based on Montgomery's calculation of double points. 385 * r = a + a 386 */ 387 int32_t ECP_NistPointDoubleMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); 388 389 /** 390 * The nist curve is based on Montgomery's calculation of multi-double points. 391 * r = m * (a + a) 392 */ 393 int32_t ECP_NistPointMultDoubleMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m); 394 395 /** 396 * The nist curve is based on Montgomery's calculation of add points. 397 * r = a + b, b must be an affine point. 398 */ 399 int32_t ECP_NistPointAddAffineMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); 400 401 /** 402 * The nist curve is based on Montgomery's calculation of add points. 403 * r = a + b 404 */ 405 int32_t ECP_NistPointAddMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); 406 407 /** 408 * The nist curve is based on Montgomery's calculation of turn an point to an affine point. 409 * r = a -> affine a 410 */ 411 int32_t ECP_Point2AffineMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt); 412 413 /** 414 * The nist curve is based on Montgomery's calculation of turn an point to an affine point. 415 * r = a -> affine a 416 */ 417 int32_t ECP_PrimePointDoubleMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); 418 419 /** 420 * The prime curve is based on Montgomery's calculation of multi-double points. 421 * r = m * (a + a) 422 */ 423 int32_t ECP_PrimePointMultDoubleMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m); 424 425 /** 426 * The prime curve is based on Montgomery's calculation of add points. 427 * r = a + b, b must be an affine point. 428 */ 429 int32_t ECP_PrimePointAddAffineMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); 430 431 /** 432 * The prime curve is based on Montgomery's calculation of add points. 433 * r = a + b 434 */ 435 int32_t ECP_PrimePointAddMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); 436 437 /** 438 * The prime curve is based on Montgomery's calculation of k * pt. 439 * The implementation is based on the Montgomery ladder. 440 */ 441 int32_t ECP_PointMulMont(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); 442 443 #endif // HITLS_CRYPTO_CURVE_MONT 444 445 #ifdef __cplusplus 446 } 447 #endif 448 449 #endif // HITLS_CRYPTO_ECC 450 451 #endif // ECC_LOCAL_H 452