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