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