• 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_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