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_ARMV8_H 16 #define BN_BINCAL_ARMV8_H 17 18 #include "hitls_build.h" 19 #ifdef HITLS_CRYPTO_BN 20 21 #include "bn_basic.h" 22 23 #ifdef __cplusplus 24 extern "c" { 25 #endif 26 27 // wh | wl = u * v 28 #define MUL_AB(wh, wl, u, v) \ 29 { \ 30 __asm("mul %1, %2, %3 \n\t" \ 31 "umulh %0, %2, %3 \n\t" \ 32 : "=&r"(wh), "=&r"(wl) \ 33 : "r"(u), "r"(v) \ 34 : "cc"); \ 35 } 36 // wh | wl = u ^ 2 37 #define SQR_A(wh, wl, u) \ 38 { \ 39 __asm("mul %1, %2, %2 \n\t" \ 40 "umulh %0, %2, %2 \n\t" \ 41 : "=&r"(wh), "=&r"(wl) \ 42 : "r"(u) \ 43 : "cc"); \ 44 } 45 46 /* nh|nl / d = q...r */ 47 #define DIV_ND(q, r, nh, nl, d) \ 48 do { \ 49 BN_UINT macroTmpD1, macroTmpD0, macroTmpQ1, macroTmpQ0, macroTmpR1, macroTmpR0, macroTmpM; \ 50 \ 51 macroTmpD1 = BN_UINT_HI(d); \ 52 macroTmpD0 = BN_UINT_LO(d); \ 53 \ 54 macroTmpQ1 = (nh) / macroTmpD1; \ 55 macroTmpR1 = (nh) - macroTmpQ1 * macroTmpD1; \ 56 macroTmpM = macroTmpQ1 * macroTmpD0; \ 57 macroTmpR1 = (macroTmpR1 << (BN_UINT_BITS >> 1)) | BN_UINT_HI(nl); \ 58 if (macroTmpR1 < macroTmpM) { \ 59 macroTmpQ1--, macroTmpR1 += (d); \ 60 if (macroTmpR1 >= (d)) { \ 61 if (macroTmpR1 < macroTmpM) { \ 62 macroTmpQ1--; \ 63 macroTmpR1 += (d); \ 64 } \ 65 } \ 66 } \ 67 macroTmpR1 -= macroTmpM; \ 68 \ 69 macroTmpQ0 = macroTmpR1 / macroTmpD1; \ 70 macroTmpR0 = macroTmpR1 - macroTmpQ0 * macroTmpD1; \ 71 macroTmpM = macroTmpQ0 * macroTmpD0; \ 72 macroTmpR0 = (macroTmpR0 << (BN_UINT_BITS >> 1)) | BN_UINT_LO(nl); \ 73 if (macroTmpR0 < macroTmpM) { \ 74 macroTmpQ0--, macroTmpR0 += (d); \ 75 if (macroTmpR0 >= (d)) { \ 76 if (macroTmpR0 < macroTmpM) { \ 77 macroTmpQ0--; \ 78 macroTmpR0 += (d); \ 79 } \ 80 } \ 81 } \ 82 macroTmpR0 -= macroTmpM; \ 83 \ 84 (q) = (macroTmpQ1 << (BN_UINT_BITS >> 1)) | macroTmpQ0; \ 85 (r) = macroTmpR0; \ 86 } while (0) 87 88 // (hi, lo) = a * b 89 // r += lo + carry 90 // carry = hi + c 91 #define MULADC_AB(r, a, b, carry) \ 92 do { \ 93 BN_UINT hi, lo; \ 94 __asm("mul %0, %2, %3 \n\t" \ 95 "umulh %1, %2, %3 \n\t" \ 96 : "=&r"(lo), "=&r"(hi) \ 97 : "r"(a), "r"(b) \ 98 : "cc"); \ 99 __asm("adds %1, %1, %3 \n\t" \ 100 "adc %2, %2, xzr \n\t " \ 101 "adds %0, %0, %1 \n\t" \ 102 "adc %2, %2, xzr \n\t " \ 103 "mov %1, %2 \n\t" \ 104 : "+&r"(r), "+&r"(carry), "+&r"(hi) \ 105 : "r"(lo) \ 106 : "cc"); \ 107 } while (0) 108 109 /* h|m|l = h|m|l + u * v. Ensure that the value of h is not too large to avoid carry. */ 110 #define MULADD_AB(h, m, l, u, v) \ 111 do { \ 112 BN_UINT hi, lo; \ 113 __asm("mul %0, %2, %3 \n\t" \ 114 "umulh %1, %2, %3 \n\t" \ 115 : "=&r"(lo), "=&r"(hi) \ 116 : "r"(u), "r"(v) \ 117 : "cc"); \ 118 __asm("adds %0, %0, %3 \n\t " \ 119 "adcs %1, %1, %4 \n\t " \ 120 "adc %2, %2, xzr \n\t " \ 121 : "+&r"(l), "+&r"(m), "+&r"(h) \ 122 : "r"(lo), "r"(hi) \ 123 : "cc"); \ 124 } while (0) 125 126 /* h|m|l = h|m|l + 2 * u * v. Ensure that the value of h is not too large to avoid carry. */ 127 #define MULADD_AB2(h, m, l, u, v) \ 128 do { \ 129 BN_UINT hi, lo; \ 130 __asm("mul %0, %2, %3 \n\t" \ 131 "umulh %1, %2, %3 \n\t" \ 132 : "=&r"(lo), "=&r"(hi) \ 133 : "r"(u), "r"(v) \ 134 : "cc"); \ 135 __asm("adds %0, %0, %3 \n\t " \ 136 "adcs %1, %1, %4 \n\t " \ 137 "adc %2, %2, xzr \n\t " \ 138 "adds %0, %0, %3 \n\t " \ 139 "adcs %1, %1, %4 \n\t " \ 140 "adc %2, %2, xzr \n\t " \ 141 : "+&r"(l), "+&r"(m), "+&r"(h) \ 142 : "r"(lo), "r"(hi) \ 143 : "cc"); \ 144 } while (0) 145 146 /* h|m|l = h|m|l + u * u. Ensure that the value of h is not too large to avoid carry. */ 147 #define SQRADD_A(h, m, l, u) MULADD_AB(h, m, l, u, u) 148 149 #ifdef __cplusplus 150 } 151 #endif 152 153 #endif /* HITLS_CRYPTO_BN */ 154 155 #endif