• 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 #ifndef BN_BINCAL_NOASM_H
16 #define BN_BINCAL_NOASM_H
17 
18 #include "hitls_build.h"
19 #ifdef HITLS_CRYPTO_BN
20 
21 #include <stdint.h>
22 #include "bn_basic.h"
23 
24 #ifdef __cplusplus
25 extern "c" {
26 #endif
27 
28 /* nh|nl / d = q...r */
29 #define DIV_ND(q, r, nh, nl, d)                                 \
30     do {                                                        \
31         BN_UINT macroTmpD1, macroTmpD0, macroTmpQ1, macroTmpQ0, macroTmpR1, macroTmpR0, macroTmpM;        \
32                                                                 \
33         macroTmpD1 = BN_UINT_HI(d);                                   \
34         macroTmpD0 = BN_UINT_LO(d);                                   \
35                                                                 \
36         macroTmpQ1 = (nh) / macroTmpD1;                                     \
37         macroTmpR1 = (nh) - macroTmpQ1 * macroTmpD1;                              \
38         macroTmpM = macroTmpQ1 * macroTmpD0;                                      \
39         macroTmpR1 = (macroTmpR1 << (BN_UINT_BITS >> 1)) | BN_UINT_HI(nl);  \
40         if (macroTmpR1 < macroTmpM) {                                       \
41             macroTmpQ1--, macroTmpR1 += (d);                                \
42             if (macroTmpR1 >= (d)) {                                  \
43                 if (macroTmpR1 < macroTmpM) {                               \
44                     macroTmpQ1--;                                     \
45                     macroTmpR1 += (d);                                \
46                 }                                               \
47             }                                                   \
48         }                                                       \
49         macroTmpR1 -= macroTmpM;                                            \
50                                                                 \
51         macroTmpQ0 = macroTmpR1 / macroTmpD1;                                     \
52         macroTmpR0 = macroTmpR1 - macroTmpQ0 * macroTmpD1;                              \
53         macroTmpM = macroTmpQ0 * macroTmpD0;                                      \
54         macroTmpR0 = (macroTmpR0 << (BN_UINT_BITS >> 1)) | BN_UINT_LO(nl);  \
55         if (macroTmpR0 < macroTmpM) {                                       \
56             macroTmpQ0--, macroTmpR0 += (d);                                \
57             if (macroTmpR0 >= (d)) {                                  \
58                 if (macroTmpR0 < macroTmpM) {                               \
59                     macroTmpQ0--;                                     \
60                     macroTmpR0 += (d);                                \
61                 }                                               \
62             }                                                   \
63         }                                                       \
64         macroTmpR0 -= macroTmpM;                                            \
65                                                                 \
66         (q) = (macroTmpQ1 << (BN_UINT_BITS >> 1)) | macroTmpQ0;             \
67         (r) = macroTmpR0;                                             \
68     } while (0)
69 
70 #define MUL_AB(wh, wl, u, v)                                \
71     do {                                                    \
72         BN_UINT macroTmpUl = BN_UINT_LO(u);                       \
73         BN_UINT macroTmpUh = BN_UINT_HI(u);                       \
74         BN_UINT macroTmpVl = BN_UINT_LO(v);                       \
75         BN_UINT macroTmpVh = BN_UINT_HI(v);                       \
76                                                             \
77         BN_UINT macroTmpX0 = macroTmpUl * macroTmpVl;            \
78         BN_UINT macroTmpX1 = macroTmpUl * macroTmpVh;            \
79         BN_UINT macroTmpX2 = macroTmpUh * macroTmpVl;            \
80         BN_UINT macroTmpX3 = macroTmpUh * macroTmpVh;            \
81                                                               \
82         macroTmpX1 += BN_UINT_HI(macroTmpX0);                             \
83         macroTmpX1 += macroTmpX2;                                         \
84         if (macroTmpX1 < macroTmpX2) { macroTmpX3 += BN_UINT_HC; }              \
85                                                               \
86         (wh) = macroTmpX3 + BN_UINT_HI(macroTmpX1);                       \
87         (wl) = (macroTmpX1 << (BN_UINT_BITS >> 1)) | BN_UINT_LO(macroTmpX0); \
88     } while (0)
89 
90 #define SQR_A(wh, wl, u)                       \
91     do {                                       \
92         BN_UINT macroTmpUl = BN_UINT_LO(u);          \
93         BN_UINT macroTmpUh = BN_UINT_HI(u);          \
94                                                \
95         BN_UINT macroTmpX0 = macroTmpUl * macroTmpUl;            \
96         BN_UINT macroTmpX1 = macroTmpUl * macroTmpUh;            \
97         BN_UINT macroTmpX2 = macroTmpUh * macroTmpUh;            \
98                                                \
99         BN_UINT macroTmpT = macroTmpX1 << 1;               \
100         macroTmpT += BN_UINT_HI(macroTmpX0);                                \
101         if (macroTmpT < macroTmpX1) { macroTmpX2 += BN_UINT_HC; }                 \
102                                                                 \
103         (wh) = macroTmpX2 + BN_UINT_HI(macroTmpT);                          \
104         (wl) = (macroTmpT << (BN_UINT_BITS >> 1)) | BN_UINT_LO(macroTmpX0); \
105     } while (0)
106 
107 /* r = a + b + c, input 'carry' means carry. Note that a and carry cannot be the same variable. */
108 #define ADD_ABC(carry, r, a, b, c)      \
109     do {                                \
110         BN_UINT macroTmpS = (b) + (c);        \
111         carry = (macroTmpS < (c)) ? 1 : 0;    \
112         (r) = macroTmpS + (a);                \
113         carry += ((r) < macroTmpS) ? 1 : 0;   \
114     } while (0)
115 
116 // (hi, lo) = a * b
117 // r += lo + carry
118 // carry = hi + c
119 #define MULADC_AB(r, a, b, carry)              \
120     do {                                       \
121         BN_UINT hi, lo;                        \
122         MUL_AB(hi, lo, a, b);                  \
123         ADD_ABC(carry, r, r, lo, carry);       \
124         carry += hi;                           \
125     } while (0)
126 
127 /* h|m|l = h|m|l + u * v. Ensure that the value of h is not too large to avoid carry. */
128 #define MULADD_AB(h, m, l, u, v)                            \
129     do {                                                    \
130         BN_UINT macroTmpUl = BN_UINT_LO(u);                       \
131         BN_UINT macroTmpUh = BN_UINT_HI(u);                       \
132         BN_UINT macroTmpVl = BN_UINT_LO(v);                       \
133         BN_UINT macroTmpVh = BN_UINT_HI(v);                       \
134                                                             \
135         BN_UINT macroTmpX3 = macroTmpUh * macroTmpVh;            \
136         BN_UINT macroTmpX2 = macroTmpUh * macroTmpVl;            \
137         BN_UINT macroTmpX1 = macroTmpUl * macroTmpVh;            \
138         BN_UINT macroTmpX0 = macroTmpUl * macroTmpVl;            \
139         macroTmpX1 += BN_UINT_HI(macroTmpX0);              \
140         macroTmpX0 = (u) * (v); \
141         macroTmpX1 += macroTmpX2;                          \
142         macroTmpX3 = macroTmpX3 + BN_UINT_HI(macroTmpX1); \
143             \
144         (l) += macroTmpX0; \
145         \
146         if (macroTmpX1 < macroTmpX2) { macroTmpX3 += BN_UINT_HC; }    \
147         macroTmpX3 += ((l) < macroTmpX0); \
148         (m) += macroTmpX3; \
149         (h) += ((m) < macroTmpX3);  \
150     } while (0)
151 
152 /* h|m|l = h|m|l + 2 * u * v. Ensure that the value of h is not too large to avoid carry. */
153 #define MULADD_AB2(h, m, l, u, v)                            \
154     do {                                     \
155         MULADD_AB((h), (m), (l), (u), (v));   \
156         MULADD_AB((h), (m), (l), (u), (v));   \
157     } while (0)
158 
159 /* h|m|l = h|m|l + v * v. Ensure that the value of h is not too large to avoid carry. */
160 #define SQRADD_A(h, m, l, v)  \
161 do { \
162     BN_UINT macroTmpVl = BN_UINT_LO(v);                       \
163     BN_UINT macroTmpVh = BN_UINT_HI(v);                       \
164                                                         \
165     BN_UINT macroTmpX3 = macroTmpVh * macroTmpVh;            \
166     BN_UINT macroTmpX2 = macroTmpVh * macroTmpVl;            \
167     BN_UINT macroTmpX1 = macroTmpX2;            \
168     BN_UINT macroTmpX0 = macroTmpVl * macroTmpVl;            \
169     macroTmpX1 += BN_UINT_HI(macroTmpX0);              \
170     macroTmpX0 = (v) * (v); \
171     macroTmpX1 += macroTmpX2;                          \
172     macroTmpX3 = macroTmpX3 + BN_UINT_HI(macroTmpX1); \
173         \
174     (l) += macroTmpX0; \
175     \
176     if (macroTmpX1 < macroTmpX2) { macroTmpX3 += BN_UINT_HC; }              \
177     if ((l) < macroTmpX0) { macroTmpX3 += 1; } \
178     (m) += macroTmpX3; \
179     if ((m) < macroTmpX3) { (h)++; } \
180 } while (0)
181 
182 
183 #ifdef __cplusplus
184 }
185 #endif
186 
187 #endif /* HITLS_CRYPTO_BN */
188 
189 #endif