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 CURVE25519_LOCAL_H 17 #define CURVE25519_LOCAL_H 18 19 #include "hitls_build.h" 20 #ifdef HITLS_CRYPTO_CURVE25519 21 22 #include "crypt_curve25519.h" 23 #include "sal_atomic.h" 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 #define CURVE25519_NOKEY 0 30 #define CURVE25519_PRVKEY 0x1 31 #define CURVE25519_PUBKEY 0x10 32 33 #define UINT8_32_21BITS_BLOCKNUM 12 34 #define UINT8_64_21BITS_BLOCKNUM 24 35 36 struct CryptCurve25519Ctx { 37 uint8_t keyType; /* specify the key type */ 38 const EAL_MdMethod *hashMethod; 39 uint8_t pubKey[CRYPT_CURVE25519_KEYLEN]; 40 uint8_t prvKey[CRYPT_CURVE25519_KEYLEN]; 41 BSL_SAL_RefCount references; 42 void *libCtx; 43 }; 44 45 typedef int32_t Fp25[10]; 46 47 typedef struct Fp51 { 48 uint64_t data[5]; 49 } Fp51; 50 51 typedef struct H19 { 52 int64_t data[19]; 53 } H19; 54 55 // group element in Projective Coordinate, x = X / Z, y = Y / Z 56 typedef struct GeP { 57 Fp25 x; 58 Fp25 y; 59 Fp25 z; 60 } GeP; 61 62 // group element in Extended Coordinate, x = X / Z, y = Y / Z, T = XY / Z which leads to XY = ZT 63 typedef struct GeE { 64 Fp25 x; 65 Fp25 y; 66 Fp25 t; 67 Fp25 z; 68 } GeE; 69 70 // group element in Completed Coordinate, x = X / Z, y = Y / T 71 typedef struct GeC { 72 Fp25 x; 73 Fp25 y; 74 Fp25 t; 75 Fp25 z; 76 } GeC; 77 78 typedef struct GePre { 79 Fp25 yplusx; 80 Fp25 yminusx; 81 Fp25 xy2d; 82 } GePre; 83 84 typedef struct GeEPre { 85 Fp25 yplusx; 86 Fp25 yminusx; 87 Fp25 t2z; 88 Fp25 z; 89 } GeEPre; 90 91 /* Get High x bits for 64bits block */ 92 #define MASK_HIGH64(x) (0xFFFFFFFFFFFFFFFFLL << (64 - (x))) 93 /* Get low x bits for 32bits block */ 94 #define MASK_LOW32(x) (0xFFFFFFFF >> (32 - (x))) 95 /* Get high x bits for 32bits block */ 96 #define MASK_HIGH32(x) (0xFFFFFFFF << (32 - (x))) 97 98 /* low 21 bits for 64bits block */ 99 #define MASK_64_LOW21 0x1fffffLL 100 101 #define CURVE25519_MASK_HIGH_38 0xfffffffffc000000LL 102 #define CURVE25519_MASK_HIGH_39 0xfffffffffe000000LL 103 104 /* process carry from h0_ to h1_, h0_ boundary restrictions is bits */ 105 #define PROCESS_CARRY(h0_, h1_, signMask_, over_, bits) \ 106 do { \ 107 (over_) = (h0_) + (1 << (bits)); \ 108 (signMask_) = MASK_HIGH64((bits) + 1) & (-((over_) >> 63)); \ 109 (h1_) += ((over_) >> ((bits) + 1)) | (signMask_); \ 110 (h0_) -= MASK_HIGH64(64 - ((bits) + 1)) & (over_); \ 111 } while (0) 112 113 /* process carry from h0_ to h1_ ignoring sign, h0_ boundary restrictions is bits */ 114 #define PROCESS_CARRY_UNSIGN(h0_, h1_, signMask_, over_, bits) \ 115 do { \ 116 (signMask_) = MASK_HIGH64((bits)) & (-((h0_) >> 63)); \ 117 (over_) = ((h0_) >> (bits)) | (signMask_); \ 118 (h1_) += (over_); \ 119 (h0_) -= (over_) * (1 << (bits)); \ 120 } while (0) 121 122 /* l = 2^252 + 27742317777372353535851937790883648493, let l0 = 27742317777372353535851937790883648493 */ 123 /* -l0 = 666643 * 2^0 + 470296 * 2^21 + 654183 * 2^(2*21) - 997805 * 2^(3*21) + 136657 * 2^(4*21) - 683901 * 2^(5*21) */ 124 #define CURVE25519_MULTI_BY_L0(src, pos) \ 125 do { \ 126 (src)[0 + (pos)] += (src)[12 + (pos)] * 666643; \ 127 (src)[1 + (pos)] += (src)[12 + (pos)] * 470296; \ 128 (src)[2 + (pos)] += (src)[12 + (pos)] * 654183; \ 129 (src)[3 + (pos)] -= (src)[12 + (pos)] * 997805; \ 130 (src)[4 + (pos)] += (src)[12 + (pos)] * 136657; \ 131 (src)[5 + (pos)] -= (src)[12 + (pos)] * 683901; \ 132 (src)[12 + (pos)] = 0; \ 133 } while (0) 134 135 /* Compute multiplications by 19 */ 136 #define CURVE25519_MULTI_BY_19(dst, src, t1_, t2_, t16_) \ 137 do { \ 138 (t1_) = (uint64_t)(src); \ 139 (t2_) = (t1_) << 1; \ 140 (t16_) = (t1_) << 4; \ 141 (dst) += (int64_t)((t1_) + (t2_) + (t16_)); \ 142 } while (0) 143 144 /* Set this parameter to value, */ 145 #define CURVE25519_FP_SET(dst, value) \ 146 do { \ 147 (dst)[0] = (value); \ 148 (dst)[1] = 0; \ 149 (dst)[2] = 0; \ 150 (dst)[3] = 0; \ 151 (dst)[4] = 0; \ 152 (dst)[5] = 0; \ 153 (dst)[6] = 0; \ 154 (dst)[7] = 0; \ 155 (dst)[8] = 0; \ 156 (dst)[9] = 0; \ 157 } while (0) 158 159 #define CURVE25519_FP51_SET(dst, value) \ 160 do { \ 161 (dst)[0] = (value); \ 162 (dst)[1] = 0; \ 163 (dst)[2] = 0; \ 164 (dst)[3] = 0; \ 165 (dst)[4] = 0; \ 166 } while (0) 167 168 /* Copy */ 169 #define CURVE25519_FP_COPY(dst, src) \ 170 do { \ 171 (dst)[0] = (src)[0]; \ 172 (dst)[1] = (src)[1]; \ 173 (dst)[2] = (src)[2]; \ 174 (dst)[3] = (src)[3]; \ 175 (dst)[4] = (src)[4]; \ 176 (dst)[5] = (src)[5]; \ 177 (dst)[6] = (src)[6]; \ 178 (dst)[7] = (src)[7]; \ 179 (dst)[8] = (src)[8]; \ 180 (dst)[9] = (src)[9]; \ 181 } while (0) 182 183 #define CURVE25519_FP51_COPY(dst, src) \ 184 do { \ 185 (dst)[0] = (src)[0]; \ 186 (dst)[1] = (src)[1]; \ 187 (dst)[2] = (src)[2]; \ 188 (dst)[3] = (src)[3]; \ 189 (dst)[4] = (src)[4]; \ 190 } while (0) 191 192 /* Negate */ 193 #define CURVE25519_FP_NEGATE(dst, src) \ 194 do { \ 195 (dst)[0] = -(src)[0]; \ 196 (dst)[1] = -(src)[1]; \ 197 (dst)[2] = -(src)[2]; \ 198 (dst)[3] = -(src)[3]; \ 199 (dst)[4] = -(src)[4]; \ 200 (dst)[5] = -(src)[5]; \ 201 (dst)[6] = -(src)[6]; \ 202 (dst)[7] = -(src)[7]; \ 203 (dst)[8] = -(src)[8]; \ 204 (dst)[9] = -(src)[9]; \ 205 } while (0) 206 207 /* Basic operation */ 208 #define CURVE25519_FP_OP(dst, src1, src2, op) \ 209 do { \ 210 (dst)[0] = (src1)[0] op (src2)[0]; \ 211 (dst)[1] = (src1)[1] op (src2)[1]; \ 212 (dst)[2] = (src1)[2] op (src2)[2]; \ 213 (dst)[3] = (src1)[3] op (src2)[3]; \ 214 (dst)[4] = (src1)[4] op (src2)[4]; \ 215 (dst)[5] = (src1)[5] op (src2)[5]; \ 216 (dst)[6] = (src1)[6] op (src2)[6]; \ 217 (dst)[7] = (src1)[7] op (src2)[7]; \ 218 (dst)[8] = (src1)[8] op (src2)[8]; \ 219 (dst)[9] = (src1)[9] op (src2)[9]; \ 220 } while (0) 221 222 /* Basic operation */ 223 #define CURVE25519_FP51_ADD(dst, src1, src2) \ 224 do { \ 225 (dst)[0] = (src1)[0] + (src2)[0]; \ 226 (dst)[1] = (src1)[1] + (src2)[1]; \ 227 (dst)[2] = (src1)[2] + (src2)[2]; \ 228 (dst)[3] = (src1)[3] + (src2)[3]; \ 229 (dst)[4] = (src1)[4] + (src2)[4]; \ 230 } while (0) 231 232 #define CURVE25519_FP51_SUB(dst, src1, src2) \ 233 do { \ 234 (dst)[0] = ((src1)[0] + 0xfffffffffffda) - (src2)[0]; \ 235 (dst)[1] = ((src1)[1] + 0xffffffffffffe) - (src2)[1]; \ 236 (dst)[2] = ((src1)[2] + 0xffffffffffffe) - (src2)[2]; \ 237 (dst)[3] = ((src1)[3] + 0xffffffffffffe) - (src2)[3]; \ 238 (dst)[4] = ((src1)[4] + 0xffffffffffffe) - (src2)[4]; \ 239 } while (0) 240 241 #define CURVE25519_GE_COPY(dst, src) \ 242 do { \ 243 CURVE25519_FP_COPY((dst).x, (src).x); \ 244 CURVE25519_FP_COPY((dst).y, (src).y); \ 245 CURVE25519_FP_COPY((dst).z, (src).z); \ 246 CURVE25519_FP_COPY((dst).t, (src).t); \ 247 } while (0) 248 249 /* Add */ 250 #define CURVE25519_FP_ADD(dst, src1, src2) CURVE25519_FP_OP(dst, src1, src2, +) 251 /* Subtract */ 252 #define CURVE25519_FP_SUB(dst, src1, src2) CURVE25519_FP_OP(dst, src1, src2, -) 253 254 /* dst = dst * bit, bit = 0 or 1 */ 255 #define CURVE25519_FP_MUL_BIT(dst, bit) \ 256 do { \ 257 int ii; \ 258 for (ii = 0; ii < 10; ii++) { \ 259 (dst)[ii] = (dst)[ii] * (bit); \ 260 } \ 261 } while (0) 262 263 /* dst[i] = src[i] * scalar */ 264 #define CURVE25519_FP_MUL_SCALAR(dst, src, scalar) \ 265 do { \ 266 uint32_t ii; \ 267 for (ii = 0; ii < 10; ii++) { \ 268 (dst)[ii] = (uint64_t)((src)[ii] * (scalar)); \ 269 } \ 270 } while (0) 271 272 #define CURVE25519_BYTES3_LOAD_PADDING(dst, bits, src) \ 273 do { \ 274 uint64_t valMacro = ((uint64_t)*((src) + 0)) << 0; \ 275 valMacro |= ((uint64_t)*((src) + 1)) << 8; \ 276 valMacro |= ((uint64_t)*((src) + 2)) << 16; \ 277 *(dst) = (uint64_t)(valMacro<< (bits)); \ 278 } while (0) 279 280 #define CURVE25519_BYTES3_LOAD(dst, src) \ 281 do { \ 282 *(dst) = ((uint64_t)*((src) + 0)) << 0; \ 283 *(dst) |= ((uint64_t)*((src) + 1)) << 8; \ 284 *(dst) |= ((uint64_t)*((src) + 2)) << 16; \ 285 } while (0) 286 287 #define CURVE25519_BYTES4_LOAD(dst, src) \ 288 do { \ 289 *(dst) = ((uint64_t)*((src) + 0)) << 0; \ 290 *(dst) |= ((uint64_t)*((src) + 1)) << 8; \ 291 *(dst) |= ((uint64_t)*((src) + 2)) << 16; \ 292 *(dst) |= ((uint64_t)*((src) + 3)) << 24; \ 293 } while (0) 294 295 #define CURVE25519_BYTES6_LOAD(dst, src) \ 296 do { \ 297 *(dst) = (uint64_t)*(src); \ 298 *(dst) |= ((uint64_t)*((src) + 1)) << 8; \ 299 *(dst) |= ((uint64_t)*((src) + 2)) << 16; \ 300 *(dst) |= ((uint64_t)*((src) + 3)) << 24; \ 301 *(dst) |= ((uint64_t)*((src) + 4)) << 32; \ 302 *(dst) |= ((uint64_t)*((src) + 5)) << 40; \ 303 } while (0) 304 305 #define CURVE25519_BYTES7_LOAD(dst, src) \ 306 do { \ 307 *(dst) = (uint64_t)*(src); \ 308 *(dst) |= ((uint64_t)*((src) + 1)) << 8; \ 309 *(dst) |= ((uint64_t)*((src) + 2)) << 16; \ 310 *(dst) |= ((uint64_t)*((src) + 3)) << 24; \ 311 *(dst) |= ((uint64_t)*((src) + 4)) << 32; \ 312 *(dst) |= ((uint64_t)*((src) + 5)) << 40; \ 313 *(dst) |= ((uint64_t)*((src) + 6)) << 48; \ 314 } while (0) 315 316 #define CURVE25519_BYTES3_PADDING_UNLOAD(dst, bits1, bits2, src) \ 317 do { \ 318 const uint32_t posMacro = 8 - (bits1); \ 319 uint32_t valMacro = (uint32_t)(*(src)); \ 320 uint32_t signMaskMacro= -(valMacro >> 31); \ 321 uint32_t expand =( (uint32_t)(*((src) + 1))) << (bits2); \ 322 *((dst) + 0) = (uint8_t)(valMacro >> (0 + posMacro) | (signMaskMacro>> (0 + posMacro))); \ 323 *((dst) + 1) = (uint8_t)(valMacro >> (8 + posMacro) | (signMaskMacro>> (8 + posMacro))); \ 324 *((dst) + 2) = (uint8_t)(expand | ((valMacro >> (16 + posMacro)) | (signMaskMacro>> (16 + posMacro)))); \ 325 } while (0) 326 327 #define CURVE25519_BYTES3_UNLOAD(dst, bits, src) \ 328 do { \ 329 const uint32_t posMacro = 8 - (bits); \ 330 uint32_t valMacro = (uint32_t)(*(src)); \ 331 uint32_t signMaskMacro= -(valMacro >> 31); \ 332 *((dst) + 0) = (uint8_t)((valMacro >> (0 + posMacro)) | (signMaskMacro>> (0 + posMacro))); \ 333 *((dst) + 1) = (uint8_t)((valMacro >> (8 + posMacro)) | (signMaskMacro>> (8 + posMacro))); \ 334 *((dst) + 2) = (uint8_t)((valMacro >> (16 + posMacro)) | (signMaskMacro>> (16 + posMacro))); \ 335 } while (0) 336 337 #define CURVE25519_BYTES4_PADDING_UNLOAD(dst, bits, src) \ 338 do { \ 339 uint32_t valMacro = (uint32_t)(*(src)); \ 340 uint32_t signMaskMacro= -(valMacro >> 31); \ 341 uint32_t expand = ((uint32_t)(*((src) + 1))) << (bits); \ 342 *((dst) + 0) = (uint8_t)((valMacro >> 0) | (signMaskMacro>> 0)); \ 343 *((dst) + 1) = (uint8_t)((valMacro >> 8) | (signMaskMacro>> 8)); \ 344 *((dst) + 2) = (uint8_t)((valMacro >> 16) | (signMaskMacro>> 16)); \ 345 *((dst) + 3) = (uint8_t)(expand | ((valMacro >> 24) | (signMaskMacro>> 24))); \ 346 } while (0) 347 348 /** 349 * Reference RFC 7748 section 5: For X25519, in order to decode 32 random bytes as an integer scalar, 350 * set the three least significant bits of the first byte and the most significant bit of the last to zero, 351 * set the second most significant bit of the last byte to 1 and, finally, decode as little-endian. 352 */ 353 #define CURVE25519_DECODE_LITTLE_ENDIAN(dst, src) \ 354 do { \ 355 uint32_t ii; \ 356 for (ii = 0; ii < 32; ii++) { \ 357 (dst)[ii] = (src)[ii]; \ 358 } \ 359 (dst)[0] &= 248; \ 360 (dst)[31] &= 127; \ 361 (dst)[31] |= 64; \ 362 } while (0) 363 364 #define CURVE25519_FP_CSWAP(s, a, b) \ 365 do { \ 366 uint32_t tt; \ 367 const uint32_t tsMacro = 0 - (s); \ 368 for (uint32_t ii = 0; ii < 10; ii++) { \ 369 tt = tsMacro & (((uint32_t)(a)[ii]) ^ ((uint32_t)(b)[ii])); \ 370 (a)[ii] = (int32_t)((uint32_t)(a)[ii] ^ tt); \ 371 (b)[ii] = (int32_t)((uint32_t)(b)[ii] ^ tt); \ 372 } \ 373 } while (0) 374 375 #define CURVE25519_FP51_CSWAP(s, a, b) \ 376 do { \ 377 uint64_t tt; \ 378 const uint64_t tsMacro = 0 - (uint64_t)(s); \ 379 for (uint32_t ii = 0; ii < 5; ii++) { \ 380 tt = tsMacro & ((a)[ii] ^ (b)[ii]); \ 381 (a)[ii] = (a)[ii] ^ tt; \ 382 (b)[ii] = (b)[ii] ^ tt; \ 383 } \ 384 } while (0) 385 386 void TableLookup(GePre *preCompute, int32_t pos, int8_t e); 387 388 void ConditionalMove(GePre *preCompute, const GePre *tableElement, uint32_t indicator); 389 390 void ScalarMultiBase(GeE *out, const uint8_t in[CRYPT_CURVE25519_KEYLEN]); 391 392 #ifdef HITLS_CRYPTO_ED25519 393 void PointEncoding(const GeE *point, uint8_t *output, uint32_t outputLen); 394 395 int32_t PointDecoding(GeE *point, const uint8_t in[CRYPT_CURVE25519_KEYLEN]); 396 397 void ScalarMulAdd(uint8_t s[CRYPT_CURVE25519_KEYLEN], const uint8_t a[CRYPT_CURVE25519_KEYLEN], 398 const uint8_t b[CRYPT_CURVE25519_KEYLEN], const uint8_t c[CRYPT_CURVE25519_KEYLEN]); 399 400 void ModuloL(uint8_t s[CRYPT_CURVE25519_SIGNLEN]); 401 402 void KAMulPlusMulBase(GeE *out, const uint8_t hash[CRYPT_CURVE25519_KEYLEN], 403 const GeE *p, const uint8_t s[CRYPT_CURVE25519_KEYLEN]); 404 #endif 405 406 #ifdef HITLS_CRYPTO_X25519 407 void ScalarMultiPoint(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]); 408 #endif 409 410 void FpInvert(Fp25 out, const Fp25 a); 411 412 void FpMul(Fp25 out, const Fp25 f, const Fp25 g); 413 414 void FpSquareDoubleCore(Fp25 out, const Fp25 in, bool doDouble); 415 416 void PolynomialToData(uint8_t out[32], const Fp25 polynomial); 417 418 void DataToPolynomial(Fp25 out, const uint8_t data[32]); 419 420 #ifdef HITLS_CRYPTO_X25519 421 void CRYPT_X25519_PublicFromPrivate(const uint8_t privateKey[CRYPT_CURVE25519_KEYLEN], 422 uint8_t publicKey[CRYPT_CURVE25519_KEYLEN]); 423 #endif 424 425 #ifdef __cplusplus 426 } 427 #endif 428 429 #endif // HITLS_CRYPTO_CURVE25519 430 431 #endif // CURVE25519_LOCAL_H 432