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 CRYPT_ECC_H 17 #define CRYPT_ECC_H 18 19 #include "hitls_build.h" 20 #ifdef HITLS_CRYPTO_ECC 21 22 #include "crypt_bn.h" 23 #include "crypt_algid.h" 24 #include "crypt_types.h" 25 #include "bsl_params.h" 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 /** 32 * Elliptic Curve Point Information 33 */ 34 typedef struct EccPointInfo ECC_Point; 35 36 /** 37 * Elliptic Curve Parameter Information 38 */ 39 typedef struct EccPara ECC_Para; 40 41 /** 42 * Point information of elliptic curve scalar after recoding 43 */ 44 typedef struct { 45 int8_t *num; 46 uint32_t *wide; 47 uint32_t size; 48 uint32_t baseBits; // Indicates the offset start address of the first block. 49 uint32_t offset; 50 } ReCodeData; 51 52 /** 53 * @ingroup ecc 54 * @brief Creating curve parameters 55 * 56 * @param id [IN] Curve enumeration 57 * 58 * @retval Not NULL Success 59 * @retval NULL failure 60 */ 61 ECC_Para *ECC_NewPara(CRYPT_PKEY_ParaId id); 62 63 /** 64 * @ingroup ecc 65 * @brief Curve parameter release 66 * 67 * @param para [IN] Curve parameter information. The para is set NULL by the invoker. 68 * 69 * @retval None 70 */ 71 void ECC_FreePara(ECC_Para *para); 72 73 /** 74 * @ingroup ecc 75 * @brief Read the curve parameter ID. 76 * 77 * @param para [IN] Curve parameter information 78 * 79 * @retval Curve ID 80 */ 81 CRYPT_PKEY_ParaId ECC_GetParaId(const ECC_Para *para); 82 83 /** 84 * @ingroup ecc 85 * @brief Obtain the curve parameter ID based on the curve parameter information. 86 * 87 * @param eccpara [IN] Curve parameter information 88 * 89 * @retval Curve ID 90 */ 91 CRYPT_PKEY_ParaId ECC_GetCurveId(const BSL_Param *eccPara); 92 93 /** 94 * @ingroup ecc 95 * @brief Point creation 96 * 97 * @param para [IN] Curve parameter information 98 * 99 * @retval Not NULL Success 100 * @retval NULL failure 101 */ 102 ECC_Point *ECC_NewPoint(const ECC_Para *para); 103 104 /** 105 * @ingroup ecc 106 * @brief Point Release 107 * 108 * @param pt [IN] Point data, pt is set to null by the invoker. 109 * 110 * @retval none 111 */ 112 void ECC_FreePoint(ECC_Point *pt); 113 114 /** 115 * @ingroup ecc 116 * @brief Point copy 117 * 118 * @param dst [OUT] The copied point information 119 * @param src [IN] Input 120 * 121 * @retval Not NULL Success 122 * @retval NULL failure 123 */ 124 int32_t ECC_CopyPoint(ECC_Point *dst, const ECC_Point *src); 125 126 /** 127 * @ingroup ecc 128 * @brief Generate a point data with the same content. 129 * 130 * @param pt [IN] Input point information 131 * 132 * @retval Not NULL Success 133 * @retval NULL failure 134 */ 135 ECC_Point *ECC_DupPoint(const ECC_Point *pt); 136 137 /** 138 * @ingroup ecc 139 * @brief Check if a and b are the same point 140 * 141 * @param para [IN] Curve parameter information 142 * @param a [IN] Point a in Jacobian coordinate 143 * @param b [IN] Point b in Jacobian coordinate 144 * 145 * @retval CRYPT_SUCCESS The two points are the same. 146 * @retval CRYPT_ECC_POINT_NOT_EQUAL The two points are different. 147 * @retval For details about other errors, see crypt_errno.h. 148 */ 149 int32_t ECC_PointCmp(const ECC_Para *para, const ECC_Point *a, const ECC_Point *b); 150 151 /** 152 * @ingroup ecc 153 * @brief Convert the Jacobian coordinate point (x, y, z) to affine coordinate (x/z^2, y/z^3, 1) and get coordinates. 154 * 155 * @param para [IN] Curve parameter information 156 * @param pt [IN/OUT] Point (x, y, z) -> (x/z^2, y/z^3, 1) 157 * @param x [OUT] x/z^2 158 * @param y [OUT] y/z^3 159 * 160 * @retval CRYPT_SUCCESS succeeded. 161 * @retval For details about other errors, see crypt_errno.h. 162 */ 163 int32_t ECC_GetPoint(const ECC_Para *para, ECC_Point *pt, CRYPT_Data *x, CRYPT_Data *y); 164 165 /** 166 * @ingroup ecc 167 * @brief Convert the Jacobian coordinate point (x, y, z) to affine coordinate (x/z^2, y/z^3, 1) and get coordinats. 168 * 169 * @param para [IN] Curve parameter information 170 * @param pt [IN/OUT] Point (x, y, z) -> (x/z^2, y/z^3, 1) 171 * @param x [OUT] x/z^2 172 * @param y [OUT] y/z^3 173 * 174 * @retval CRYPT_SUCCESS succeeded. 175 * @retval For details about other errors, see crypt_errno.h. 176 */ 177 int32_t ECC_GetPoint2Bn(const ECC_Para *para, ECC_Point *pt, BN_BigNum *x, BN_BigNum *y); 178 179 /** 180 * @ingroup ecc 181 * @brief Convert the Jacobian coordinate point (x, y, z) to affine coordinate (x/z^2, y/z^3, 1) and get x/z^2 182 * 183 * @param para [IN] Curve parameter information 184 * @param pt [IN/OUT] Point (x, y, z) -> (x/z^2, y/z^3, 1) 185 * @param x [OUT] x/z^2 186 * 187 * @retval CRYPT_SUCCESS succeeded. 188 * @retval For details about other errors, see crypt_errno.h. 189 */ 190 int32_t ECC_GetPointDataX(const ECC_Para *para, ECC_Point *pt, BN_BigNum *x); 191 192 /** 193 * @ingroup ecc 194 * @brief Calculate r = k * pt. When pt is NULL, calculate r = k * G, where G is the generator 195 * The pre-computation table under the para parameter will be updated. 196 * 197 * @param para [IN] Curve parameter information 198 * @param r [OUT] Scalar multiplication 199 * @param k [IN] Scalar 200 * @param pt [IN] Point data, which can be NULL. 201 * 202 * @retval CRYPT_SUCCESS succeeded. 203 * @retval For details about other errors, see crypt_errno.h. 204 */ 205 int32_t ECC_PointMul(ECC_Para *para, ECC_Point *r, 206 const BN_BigNum *k, const ECC_Point *pt); 207 208 /** 209 * @ingroup ecc 210 * @brief Calculate r = k1 * G + k2 * pt, where G is the generator. 211 * 212 * @param para [IN] Curve parameter information 213 * @param r [OUT] Point k1 * G + k2 * pt 214 * @param k1 [IN] Scalar k1 215 * @param k2 [IN] Scalar k2 216 * @param pt [IN] Point pt 217 * 218 * @retval CRYPT_SUCCESS succeeded. 219 * @retval For details about other errors, see crypt_errno.h. 220 */ 221 int32_t ECC_PointMulAdd(ECC_Para *para, ECC_Point *r, 222 const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt); 223 224 /** 225 * @ingroup ecc 226 * @brief Convert the Jacobian coordinate point (x, y, z) to affine coordinate (x/z^2, y/z^3, 1) and encode point. 227 * 228 * @param para [IN] Curve parameter information 229 * @param pt [IN/OUT] Point (x, y, z) -> (x/z^2, y/z^3, 1) 230 * @param data [OUT] Data stream 231 * @param dataLen [IN/OUT] The input is the buff length of data and the output is the valid length of data. 232 * @param format [IN] Encoding format 233 * 234 * @retval CRYPT_SUCCESS succeeded. 235 * @retval For details about other errors, see crypt_errno.h. 236 */ 237 int32_t ECC_EncodePoint(const ECC_Para *para, ECC_Point *pt, uint8_t *data, uint32_t *dataLen, 238 CRYPT_PKEY_PointFormat format); 239 240 /** 241 * @ingroup ecc 242 * @brief Encode the data stream into point information. 243 * 244 * @param para [IN] Curve parameter information 245 * @param pt [OUT] Point in affine coordinate(z=1) 246 * @param data [IN] Data stream 247 * @param dataLen [IN] Data stream length 248 * 249 * @retval CRYPT_SUCCESS succeeded. 250 * @retval For details about other errors, see crypt_errno.h. 251 */ 252 int32_t ECC_DecodePoint(const ECC_Para *para, ECC_Point *pt, const uint8_t *data, uint32_t dataLen); 253 254 /** 255 * @ingroup ecc 256 * @brief Obtain the parameter value h based on the curve parameter. 257 * 258 * @param para [IN] Curve parameter information 259 * 260 * @retval Not NULL Success 261 * @retval NULL failure 262 */ 263 BN_BigNum *ECC_GetParaH(const ECC_Para *para); 264 265 /** 266 * @ingroup ecc 267 * @brief Obtain the parameter value n based on the curve parameter. 268 * 269 * @param para [IN] Curve parameter information 270 * 271 * @retval Not NULL Success 272 * @retval NULL failure 273 */ 274 BN_BigNum *ECC_GetParaN(const ECC_Para *para); 275 276 /** 277 * @ingroup ecc 278 * @brief Obtain the coefficient a based on curve parameters. 279 * 280 * @param para [IN] Curve parameter information 281 * 282 * @retval Not NULL Success 283 * @retval NULL failure 284 */ 285 BN_BigNum *ECC_GetParaA(const ECC_Para *para); 286 287 /** 288 * @ingroup ecc 289 * @brief Obtain the coefficient b based on curve parameters. 290 * 291 * @param para [IN] Curve parameter information 292 * 293 * @retval Not NULL Success 294 * @retval NULL failure 295 */ 296 BN_BigNum *ECC_GetParaB(const ECC_Para *para); 297 298 /** 299 * @ingroup ecc 300 * @brief Obtain the coordinate x of the base point G based on curve parameters. 301 * 302 * @param para [IN] Curve parameter information 303 * 304 * @retval Not NULL Success 305 * @retval NULL failure 306 */ 307 BN_BigNum *ECC_GetParaX(const ECC_Para *para); 308 309 /** 310 * @ingroup ecc 311 * @brief Obtain the coordinate y of the base point G based on curve parameters. 312 * 313 * @param para [IN] Curve parameter information 314 * 315 * @retval Not NULL Success 316 * @retval NULL failure 317 */ 318 BN_BigNum *ECC_GetParaY(const ECC_Para *para); 319 320 /** 321 * @ingroup ecc 322 * @brief Obtain bit length of parameter p based on the curve parameter. 323 * 324 * @param para [IN] Curve parameter information 325 * 326 * @retval Return the specification unit of the curve parameter is bits. 0 is returned when an error occurs. 327 */ 328 uint32_t ECC_ParaBits(const ECC_Para *para); 329 330 /** 331 * @ingroup ecc 332 * @brief Generate a curve parameter with the same content. 333 * 334 * @param para [IN] Curve parameter information 335 * 336 * @retval Not NULL Success 337 * @retval NULL failure 338 */ 339 ECC_Para *ECC_DupPara(const ECC_Para *para); 340 341 /** 342 * @ingroup ecc 343 * @brief Check whether the point is valid. 344 * 345 * @param pt [IN] Point information 346 * 347 * @retval CRYPT_SUCCESS This point is valid. 348 * @retval CRYPT_ECC_POINT_AT_INFINITY The point is an infinite point (0 point). 349 * @retval For details about other errors, see crypt_errno.h. 350 */ 351 int32_t ECC_PointCheck(const ECC_Point *pt); 352 353 354 /** 355 * @ingroup ecc 356 * @brief Obtain the generator(with z=1) based on curve parameters. 357 * 358 * @param para [IN] Curve parameters 359 * 360 * @retval Not NULL Success 361 * @retval NULL failure 362 */ 363 ECC_Point *ECC_GetGFromPara(const ECC_Para *para); 364 365 /** 366 * @ingroup ecc 367 * @brief Scalar re-encoding to obtain the encoded data whose window is the 'window'. 368 * 369 * @param k [IN] Curve parameters 370 * @param window [IN] Window size 371 * 372 * @retval Not NULL Success 373 * @retval NULL failure 374 */ 375 ReCodeData *ECC_ReCodeK(const BN_BigNum *k, uint32_t window); 376 377 /** 378 * @ingroup ecc 379 * @brief Release the encoded data. 380 * 381 * @param code [IN/OUT] Data to be released. The code is set NULL by the invoker. 382 * 383 * @retval None 384 */ 385 void ECC_ReCodeFree(ReCodeData *code); 386 387 /** 388 * @brief Calculate r = 1/a mod para->n 389 * 390 * @param para [IN] Curve parameter information 391 * @param r [OUT] Output modulus inverse value 392 * @param a [IN] Input BigNum that needs to be inverted. 393 * 394 * @retval CRYPT_SUCCESS set successfully. 395 * @retval For details about other errors, see crypt_errno.h. 396 */ 397 int32_t ECC_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a); 398 399 /** 400 * @ingroup ecc 401 * @brief Calculate addition r = a + b 402 * 403 * @param para [IN] Curve parameter 404 * @param r [OUT] Point r = a + b 405 * @param a [IN] Point a 406 * @param b [IN] Point b 407 * 408 * @retval CRYPT_SUCCESS succeeded. 409 * @retval For other errors, see crypt_errno.h. 410 */ 411 int32_t ECC_PointAddAffine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); 412 413 /** 414 * @ingroup ecc 415 * @brief ecc get security bits 416 * 417 * @param para [IN] ecc Context structure 418 * 419 * @retval security bits 420 */ 421 int32_t ECC_GetSecBits(const ECC_Para *para); 422 423 /** 424 * @ingroup ecc 425 * @brief Randomize z for preventing attack. 426 * Converting a point (x, y, z) -> (x/z0^2, y/z0^3, z*z0) 427 * @param para [IN] Curve parameters 428 * @param pt [IN/OUT] Point information 429 * 430 * @retval CRYPT_SUCCESS succeeded. 431 * @retval For details about other errors, see crypt_errno.h 432 */ 433 int32_t ECC_PointBlind(const ECC_Para *para, ECC_Point *pt); 434 435 /** 436 * @ingroup ecc 437 * @brief convert ecc point to mont form 438 * @param para [IN] Curve parameters 439 * @param pt [IN/OUT] Point information 440 * 441 * @retval CRYPT_SUCCESS succeeded. 442 * @retval For details about other errors, see crypt_errno.h 443 */ 444 int32_t ECC_PointToMont(const ECC_Para *para, ECC_Point *pt, BN_Optimizer *opt); 445 446 /** 447 * @ingroup ecc 448 * @brief recover ecc point from mont form 449 * @param para [IN] Curve parameters 450 * @param pt [IN/OUT] Point information 451 * 452 * @retval CRYPT_SUCCESS succeeded. 453 * @retval For details about other errors, see crypt_errno.h 454 */ 455 void ECC_PointFromMont(const ECC_Para *para, ECC_Point *r); 456 457 /** 458 * @ingroup ecc 459 * @brief convert ecc point to mont form 460 * @param para [IN] Curve parameters 461 * @param pt [IN/OUT] Point information 462 * 463 * @param libCtx [IN] Pointer to the library context 464 * @param para [OUT] Pointer to the elliptic curve parameters 465 */ 466 void ECC_SetLibCtx(void *libCtx, ECC_Para *para); 467 468 #ifdef __cplusplus 469 } 470 #endif 471 472 #endif // HITLS_CRYPTO_ECC 473 474 #endif // CRYPT_ECC_H 475