API参考
载入中...
搜索中...
未找到
bn_bincal_noasm.h
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
25extern "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) \
161do { \
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// Modular operation, satisfy d < (1 << BN_UINT_HALF_BITS) r = nh | nl % d
183#define MOD_HALF(r, nh, nl, d) \
184 do { \
185 BN_UINT macroTmpD = (d); \
186 (r) = (nh) % macroTmpD; \
187 (r) = ((r) << BN_UINT_HALF_BITS) | BN_UINT_HI((nl)); \
188 (r) = (r) % macroTmpD; \
189 (r) = ((r) << BN_UINT_HALF_BITS) | BN_UINT_LO((nl)); \
190 (r) = (r) % macroTmpD; \
191 } while (0)
192
193#ifdef __cplusplus
194}
195#endif
196
197#endif /* HITLS_CRYPTO_BN */
198
199#endif