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 #include "hitls_build.h"
16 #ifdef HITLS_CRYPTO_BN
17
18 #include <stdint.h>
19 #include "bn_bincal.h"
20
21 #ifndef HITLS_SIXTY_FOUR_BITS
22 #error Bn binical x8664 optimizer must open BN-64.
23 #endif
24
25 // r = a + b, len = n, return carry
BinAdd(BN_UINT * r,const BN_UINT * a,const BN_UINT * b,uint32_t n)26 BN_UINT BinAdd(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n)
27 {
28 if (n == 0) {
29 return 0;
30 }
31
32 BN_UINT ret = 0;
33 BN_UINT times = n >> 2;
34 BN_UINT rem = n & 3;
35 asm volatile(
36 ".align 3 \n"
37 " mov %0, #1 \n"
38 " adcs %0, xzr, %0 \n" // clear C flags
39 " mov %0, #0 \n"
40 " cbz %1, 3f \n"
41 "4: add x4, %3, %0 \n"
42 " add x5, %4, %0 \n"
43 " add x6, %5, %0 \n"
44 " ldp x7, x8, [x5] \n"
45 " ldp x9, x10, [x5,#16] \n"
46 " ldp x11, x12, [x6] \n"
47 " ldp x13, x14, [x6,#16] \n"
48 " adcs x7, x7, x11 \n"
49 " adcs x8, x8, x12 \n"
50 " adcs x9, x9, x13 \n"
51 " adcs x10, x10, x14 \n"
52 " stp x7, x8, [x4] \n"
53 " stp x9, x10, [x4, #16] \n"
54 " sub %1, %1, #0x1 \n"
55 " add %0, %0, #0x20 \n"
56 " cbnz %1, 4b \n"
57 "3: cbz %2, 2f \n" // times <= 0, jump to single cycle
58 "1: ldr x7, [%4, %0] \n"
59 " ldr x8, [%5, %0] \n"
60 " adcs x7, x7, x8 \n"
61 " str x7, [%3, %0] \n"
62 " sub %2, %2, #0x1 \n"
63 " add %0, %0, #0x8 \n"
64 " cbnz %2, 1b \n"
65 "2: mov %0, #0 \n"
66 " adcs %0, xzr, %0 \n"
67 :"+&r" (ret), "+r"(times), "+r"(rem)
68 :"r"(r), "r"(a), "r"(b)
69 :"x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "cc", "memory");
70
71 return ret & 1;
72 }
73
74 // r = a - b, len = n, return carry
BinSub(BN_UINT * r,const BN_UINT * a,const BN_UINT * b,uint32_t n)75 BN_UINT BinSub(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n)
76 {
77 if (n == 0) {
78 return 0;
79 }
80
81 BN_UINT ret = 0;
82 BN_UINT rem = n & 3;
83 BN_UINT times = n >> 2;
84 asm volatile(
85 ".align 3 \n"
86 " mov %0, #1 \n"
87 " sbcs %0, %0, xzr \n" // clear C flags
88 " mov %0, #0 \n"
89 " cbz %1, 2f \n"
90 "4: add x4, %3, %0 \n"
91 " add x5, %4, %0 \n"
92 " add x6, %5, %0 \n"
93 " ldp x7, x8, [x5] \n"
94 " ldp x9, x10, [x5,#16] \n"
95 " ldp x11, x12, [x6] \n"
96 " ldp x13, x14, [x6,#16] \n"
97 " sbcs x7, x7, x11 \n"
98 " sbcs x8, x8, x12 \n"
99 " sbcs x9, x9, x13 \n"
100 " sbcs x10, x10, x14 \n"
101 " stp x7, x8, [x4] \n"
102 " stp x9, x10, [x4, #16] \n"
103 " sub %1, %1, #0x1 \n"
104 " add %0, %0, #0x20 \n"
105 " cbnz %1, 4b \n"
106 "2: cbz %2, 3f \n" // times <= 0, jump to single cycle
107 "1: ldr x7, [%4, %0] \n"
108 " ldr x8, [%5, %0] \n"
109 " sbcs x7, x7, x8 \n"
110 " str x7, [%3, %0] \n"
111 " sub %2, %2, #0x1 \n"
112 " add %0, %0, #0x8 \n"
113 " cbnz %2, 1b \n"
114 "3: mov %0,#0 \n"
115 " sbcs %0,xzr,%0 \n"
116 :"+&r" (ret), "+r"(times), "+r"(rem)
117 :"r"(r), "r"(a), "r"(b)
118 :"x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "cc", "memory");
119
120 return ret & 1;
121 }
122
123 // r = r - a * m, return the carry;
BinSubMul(BN_UINT * r,const BN_UINT * a,BN_UINT aSize,BN_UINT m)124 BN_UINT BinSubMul(BN_UINT *r, const BN_UINT *a, BN_UINT aSize, BN_UINT m)
125 {
126 BN_UINT borrow = 0;
127 BN_UINT i = 0;
128 asm volatile(
129 ".align 3 \n"
130 "2: ldr x4, [%3, %1] \n" // x4 = r[i]
131 " ldr x5, [%4, %1] \n" // x5 = r[i]
132 " mul x7, x5, %5 \n" // x7 = al
133 " umulh x6, x5, %5 \n" // x6 = ah
134 " adds x7, %0, x7 \n" // x7 = borrow + al
135 " adcs %0, x6, xzr \n" // borrow = ah + H(borrow + al)
136 " cmp x7, x4 \n" // if r[i] > borrow + al, dont needs carry
137 " beq 1f \n"
138 " adc %0, %0, xzr \n"
139 "1: sub x4, x4, x7 \n"
140 " str x4, [%3, %1] \n"
141 " sub %2, %2, #0x1 \n"
142 " add %1, %1, #0x8 \n"
143 " cbnz %2, 2b \n"
144 :"+&r" (borrow), "+r"(i), "+r"(aSize)
145 :"r"(r), "r"(a), "r"(m)
146 :"x4", "x5", "x6", "x7", "cc", "memory");
147
148 return borrow;
149 }
150
151 /* Obtains the number of 0s in the first x most significant bits of data. */
GetZeroBitsUint(BN_UINT x)152 uint32_t GetZeroBitsUint(BN_UINT x)
153 {
154 BN_UINT count;
155 asm ("clz %0, %1" : "=r" (count) : "r" (x));
156 return (uint32_t)count;
157 }
158
159 #endif /* HITLS_CRYPTO_BN */
160