• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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