• 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 BN_BINCAL_H
17 #define BN_BINCAL_H
18 
19 #include "hitls_build.h"
20 #ifdef HITLS_CRYPTO_BN
21 
22 #include <stdint.h>
23 #include "bn_basic.h"
24 
25 #if defined(HITLS_CRYPTO_BN_X8664)
26     #include "bn_bincal_x8664.h"
27 #elif defined(HITLS_CRYPTO_BN_ARMV8)
28     #include "bn_bincal_armv8.h"
29 #else
30     #include "bn_bincal_noasm.h"
31 #endif
32 
33 #ifdef __cplusplus
34 extern "c" {
35 #endif
36 
37 /* r = a + b, input 'carry' means carry */
38 #define ADD_AB(carry, r, a, b)       \
39     do {                             \
40         BN_UINT macroTmpT = (a) + (b);     \
41         (carry) = macroTmpT < (a) ? 1 : 0; \
42         (r) = macroTmpT;                   \
43     } while (0)
44 
45 /* r = a - b, input 'borrow' means borrow digit */
46 #define SUB_AB(borrow, r, a, b)         \
47     do {                                \
48         BN_UINT macroTmpT = (a) - (b);        \
49         (borrow) = ((a) < (b)) ? 1 : 0; \
50         (r) = macroTmpT;                      \
51     } while (0)
52 
53 /* r = a - b - c, input 'borrow' means borrow digit */
54 #define SUB_ABC(borrow, r, a, b, c)         \
55     do {                                    \
56         BN_UINT macroTmpS = (a) - (b);            \
57         BN_UINT macroTmpB = ((a) < (b)) ? 1 : 0;  \
58         macroTmpB += (macroTmpS < (c)) ? 1 : 0;         \
59         (r) = macroTmpS - (c);                    \
60         borrow = macroTmpB;                       \
61     } while (0)
62 
63 #define BN_UINT_HALF_BITS (BN_UINT_BITS >> 1)
64 
65 /* carry value of the upper part */
66 #define BN_UINT_HC ((BN_UINT)1 << BN_UINT_HALF_BITS)
67 
68 /* Takes the low bit and assigns it to the high bit. */
69 #define BN_UINT_LO_TO_HI(t) ((t) << BN_UINT_HALF_BITS)
70 
71 /* Takes the high bit and assigns it to the high bit. */
72 #define BN_UINT_HI_TO_HI(t) ((t) & ((BN_UINT)0 - BN_UINT_HC))
73 
74 /* Takes the low bit and assigns it to the low bit. */
75 #define BN_UINT_LO(t) ((t) & (BN_UINT_HC - 1))
76 
77 /* Takes the high bit and assigns it to the low bit. */
78 #define BN_UINT_HI(t) ((t) >> BN_UINT_HALF_BITS)
79 
80 /* copy bytes, ensure that dstLen >= srcLen */
81 #define BN_COPY_BYTES(dst, dstlen, src, srclen)                             \
82     do {                                                                    \
83         uint32_t macroTmpI;                                                       \
84         for (macroTmpI = 0; macroTmpI < (srclen); macroTmpI++) { (dst)[macroTmpI] = (src)[macroTmpI]; }   \
85         for (; macroTmpI < (dstlen); macroTmpI++) { (dst)[macroTmpI] = 0; }                   \
86     } while (0)
87 
88 // Modular operation, satisfy d < (1 << BN_UINT_HALF_BITS) r = nh | nl % d
89 #define MOD_HALF(r, nh, nl, d)                                  \
90     do {                                                        \
91         BN_UINT macroTmpD = (d);                                      \
92         (r) = (nh) % macroTmpD;                                       \
93         (r) = ((r) << BN_UINT_HALF_BITS) | BN_UINT_HI((nl));  \
94         (r) = (r) % macroTmpD;                                        \
95         (r) = ((r) << BN_UINT_HALF_BITS) | BN_UINT_LO((nl));  \
96         (r) = (r) % macroTmpD;                                        \
97     } while (0)
98 
99 /* r = a * b + r + c, where c is refreshed as the new carry value */
100 #define MULADD_ABC(c, r, a, b)                  \
101 do {                                            \
102     BN_UINT macroTmpAl = BN_UINT_LO(a);               \
103     BN_UINT macroTmpAh = BN_UINT_HI(a);               \
104     BN_UINT macroTmpBl = BN_UINT_LO(b);               \
105     BN_UINT macroTmpBh = BN_UINT_HI(b);               \
106     BN_UINT macroTmpX3 = macroTmpAh * macroTmpBh;                 \
107     BN_UINT macroTmpX2 = macroTmpAh * macroTmpBl;                 \
108     BN_UINT macroTmpX1 = macroTmpAl * macroTmpBh;                 \
109     BN_UINT macroTmpX0 = macroTmpAl * macroTmpBl;                 \
110     (r) += (c);                                 \
111     (c) = ((r) < (c)) ? 1 : 0;                  \
112     macroTmpX1 += macroTmpX2;                               \
113     (c) += (macroTmpX1 < macroTmpX2) ? BN_UINT_HC : 0;      \
114     macroTmpX2 = macroTmpX0;                                \
115     macroTmpX0 += macroTmpX1 << BN_UINT_HALF_BITS;        \
116     (c) += (macroTmpX0 < macroTmpX2) ? 1 : 0;               \
117     (c) += BN_UINT_HI(macroTmpX1);                    \
118     (c) += macroTmpX3;                                \
119     (r) += macroTmpX0;                                \
120     (c) += ((r) < macroTmpX0) ? 1 : 0;                \
121 } while (0)
122 
123 /* r = a + b + c, input 'carry' means carry. Note that a and carry cannot be the same variable. */
124 #define ADD_ABC(carry, r, a, b, c)      \
125     do {                                \
126         BN_UINT macroTmpS = (b) + (c);        \
127         carry = (macroTmpS < (c)) ? 1 : 0;    \
128         (r) = macroTmpS + (a);                \
129         carry += ((r) < macroTmpS) ? 1 : 0;   \
130     } while (0)
131 
132 BN_UINT BinAdd(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n);
133 
134 BN_UINT BinSub(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n);
135 
136 BN_UINT BinInc(BN_UINT *r, const BN_UINT *a, uint32_t size, BN_UINT w);
137 
138 BN_UINT BinDec(BN_UINT *r, const BN_UINT *a, uint32_t n, BN_UINT w);
139 
140 uint32_t BinRshift(BN_UINT *r, const BN_UINT *a, uint32_t n, uint32_t bits);
141 
142 BN_UINT BinSubMul(BN_UINT *r, const BN_UINT *a, BN_UINT aSize, BN_UINT m);
143 
144 uint32_t BinLshift(BN_UINT *r, const BN_UINT *a, uint32_t n, uint32_t bits);
145 
146 BN_UINT BinMulAcc(BN_UINT *r, const BN_UINT *a, uint32_t aSize, BN_UINT b);
147 
148 uint32_t BinMul(BN_UINT *r, uint32_t rRoom, const BN_UINT *a, uint32_t aSize, const BN_UINT *b, uint32_t bSize);
149 
150 uint32_t BinSqr(BN_UINT *r, uint32_t rRoom, const BN_UINT *a, uint32_t aSize);
151 
152 uint32_t GetZeroBitsUint(BN_UINT x);
153 
154 uint32_t BinFixSize(const BN_UINT *data, uint32_t size);
155 
156 int32_t BinCmp(const BN_UINT *a, uint32_t aSize, const BN_UINT *b, uint32_t bSize);
157 
158 uint32_t BinBits(const BN_UINT *data, uint32_t size);
159 
160 uint32_t BinDiv(BN_UINT *q, uint32_t *qSize, BN_UINT *x, uint32_t xSize, BN_UINT *y, uint32_t ySize);
161 
162 #ifdef HITLS_CRYPTO_BN_COMBA
163 uint32_t SpaceSize(uint32_t size);
164 
165 // Perform a multiplication calculation of 4 blocks of data, r = a^2,
166 // where the length of r is 8, and the length of a is 4.
167 void MulComba4(BN_UINT *r, const BN_UINT *a, const BN_UINT *b);
168 
169 // Calculate the square of 4 blocks of data, r = a^2, where the length of r is 8, and the length of a is 4.
170 void SqrComba4(BN_UINT *r, const BN_UINT *a);
171 
172 // Perform a multiplication calculation of 6 blocks of data, r = a*b,
173 // where the length of r is 12, the length of a and b is 6.
174 void MulComba6(BN_UINT *r, const BN_UINT *a, const BN_UINT *b);
175 
176 // Calculate the square of 6 blocks of data, r = a^2, where the length of r is 12, and the length of a is 6.
177 void SqrComba6(BN_UINT *r, const BN_UINT *a);
178 
179 void MulConquer(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t size, BN_UINT *space, bool consttime);
180 
181 void SqrConquer(BN_UINT *r, const BN_UINT *a, uint32_t size, BN_UINT *space, bool consttime);
182 #endif
183 
184 int32_t MontSqrBinCore(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime);
185 
186 int32_t MontMulBinCore(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, BN_Mont *mont,
187     BN_Optimizer *opt, bool consttime);
188 
189 int32_t MontEncBinCore(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime);
190 
191 void ReduceCore(BN_UINT *r, BN_UINT *x, const BN_UINT *m, uint32_t mSize, BN_UINT m0);
192 
193 #ifdef __cplusplus
194 }
195 #endif
196 
197 #endif /* HITLS_CRYPTO_BN */
198 
199 #endif