16#ifndef CURVE25519_LOCAL_H
17#define CURVE25519_LOCAL_H
19#include "hitls_build.h"
20#ifdef HITLS_CRYPTO_CURVE25519
22#include "crypt_curve25519.h"
23#include "sal_atomic.h"
29#define CURVE25519_NOKEY 0
30#define CURVE25519_PRVKEY 0x1
31#define CURVE25519_PUBKEY 0x10
33#define UINT8_32_21BITS_BLOCKNUM 12
34#define UINT8_64_21BITS_BLOCKNUM 24
36struct CryptCurve25519Ctx {
38 const EAL_MdMethod *hashMethod;
39 uint8_t pubKey[CRYPT_CURVE25519_KEYLEN];
40 uint8_t prvKey[CRYPT_CURVE25519_KEYLEN];
41 BSL_SAL_RefCount references;
45typedef int32_t Fp25[10];
84typedef struct GeEPre {
92#define MASK_HIGH64(x) (0xFFFFFFFFFFFFFFFFLL << (64 - (x)))
94#define MASK_LOW32(x) (0xFFFFFFFF >> (32 - (x)))
96#define MASK_HIGH32(x) (0xFFFFFFFF << (32 - (x)))
99#define MASK_64_LOW21 0x1fffffLL
101#define CURVE25519_MASK_HIGH_38 0xfffffffffc000000LL
102#define CURVE25519_MASK_HIGH_39 0xfffffffffe000000LL
105#define PROCESS_CARRY(h0_, h1_, signMask_, over_, bits) \
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_); \
114#define PROCESS_CARRY_UNSIGN(h0_, h1_, signMask_, over_, bits) \
116 (signMask_) = MASK_HIGH64((bits)) & (-((h0_) >> 63)); \
117 (over_) = ((h0_) >> (bits)) | (signMask_); \
119 (h0_) -= (over_) * (1 << (bits)); \
124#define CURVE25519_MULTI_BY_L0(src, pos) \
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; \
136#define CURVE25519_MULTI_BY_19(dst, src, t1_, t2_, t16_) \
138 (t1_) = (uint64_t)(src); \
139 (t2_) = (t1_) << 1; \
140 (t16_) = (t1_) << 4; \
141 (dst) += (int64_t)((t1_) + (t2_) + (t16_)); \
145#define CURVE25519_FP_SET(dst, value) \
147 (dst)[0] = (value); \
159#define CURVE25519_FP51_SET(dst, value) \
161 (dst)[0] = (value); \
169#define CURVE25519_FP_COPY(dst, src) \
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]; \
183#define CURVE25519_FP51_COPY(dst, src) \
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]; \
193#define CURVE25519_FP_NEGATE(dst, src) \
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]; \
208#define CURVE25519_FP_OP(dst, src1, src2, op) \
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]; \
223#define CURVE25519_FP51_ADD(dst, src1, src2) \
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]; \
232#define CURVE25519_FP51_SUB(dst, src1, src2) \
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]; \
241#define CURVE25519_GE_COPY(dst, src) \
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); \
250#define CURVE25519_FP_ADD(dst, src1, src2) CURVE25519_FP_OP(dst, src1, src2, +)
252#define CURVE25519_FP_SUB(dst, src1, src2) CURVE25519_FP_OP(dst, src1, src2, -)
255#define CURVE25519_FP_MUL_BIT(dst, bit) \
258 for (ii = 0; ii < 10; ii++) { \
259 (dst)[ii] = (dst)[ii] * (bit); \
264#define CURVE25519_FP_MUL_SCALAR(dst, src, scalar) \
267 for (ii = 0; ii < 10; ii++) { \
268 (dst)[ii] = (uint64_t)((src)[ii] * (scalar)); \
272#define CURVE25519_BYTES3_LOAD_PADDING(dst, bits, src) \
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)); \
280#define CURVE25519_BYTES3_LOAD(dst, src) \
282 *(dst) = ((uint64_t)*((src) + 0)) << 0; \
283 *(dst) |= ((uint64_t)*((src) + 1)) << 8; \
284 *(dst) |= ((uint64_t)*((src) + 2)) << 16; \
287#define CURVE25519_BYTES4_LOAD(dst, src) \
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; \
295#define CURVE25519_BYTES6_LOAD(dst, src) \
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; \
305#define CURVE25519_BYTES7_LOAD(dst, src) \
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; \
316#define CURVE25519_BYTES3_PADDING_UNLOAD(dst, bits1, bits2, src) \
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)))); \
327#define CURVE25519_BYTES3_UNLOAD(dst, bits, src) \
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))); \
337#define CURVE25519_BYTES4_PADDING_UNLOAD(dst, bits, src) \
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))); \
353#define CURVE25519_DECODE_LITTLE_ENDIAN(dst, src) \
356 for (ii = 0; ii < 32; ii++) { \
357 (dst)[ii] = (src)[ii]; \
364#define CURVE25519_FP_CSWAP(s, a, b) \
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); \
375#define CURVE25519_FP51_CSWAP(s, a, b) \
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; \
386void TableLookup(GePre *preCompute, int32_t pos, int8_t e);
388void ConditionalMove(GePre *preCompute,
const GePre *tableElement, uint32_t indicator);
390void ScalarMultiBase(GeE *out,
const uint8_t in[CRYPT_CURVE25519_KEYLEN]);
392#ifdef HITLS_CRYPTO_ED25519
393void PointEncoding(
const GeE *point, uint8_t *output, uint32_t outputLen);
395int32_t PointDecoding(GeE *point,
const uint8_t in[CRYPT_CURVE25519_KEYLEN]);
397void 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]);
400void ModuloL(uint8_t s[CRYPT_CURVE25519_SIGNLEN]);
402void KAMulPlusMulBase(GeE *out,
const uint8_t hash[CRYPT_CURVE25519_KEYLEN],
403 const GeE *p,
const uint8_t s[CRYPT_CURVE25519_KEYLEN]);
406#ifdef HITLS_CRYPTO_X25519
407void ScalarMultiPoint(uint8_t out[32],
const uint8_t scalar[32],
const uint8_t point[32]);
410void FpInvert(Fp25 out,
const Fp25 a);
412void FpMul(Fp25 out,
const Fp25 f,
const Fp25 g);
414void FpSquareDoubleCore(Fp25 out,
const Fp25 in,
bool doDouble);
416void PolynomialToData(uint8_t out[32],
const Fp25 polynomial);
418void DataToPolynomial(Fp25 out,
const uint8_t data[32]);
420#ifdef HITLS_CRYPTO_X25519
421void CRYPT_X25519_PublicFromPrivate(
const uint8_t privateKey[CRYPT_CURVE25519_KEYLEN],
422 uint8_t publicKey[CRYPT_CURVE25519_KEYLEN]);