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