• 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 = n;
33     asm volatile (
34                   ".p2align 4                          \n"
35                   "       mov     %0, %%rcx            \n"
36                   "       and     $3, %%rcx            \n" // will clear CF
37                   "       shr     $2, %0               \n"
38                   "       clc                          \n"
39                   "       jz      aone                 \n" // n / 4 > = 0 , goto step 4
40                   "4:     movq    0(%2), %%r8          \n"
41                   "       movq    8(%2), %%r9          \n"
42                   "       movq    16(%2), %%r10        \n"
43                   "       movq    24(%2), %%r11        \n"
44                   "       adcq    0(%3), %%r8          \n"
45                   "       adcq    8(%3), %%r9          \n"
46                   "       adcq    16(%3), %%r10        \n"
47                   "       adcq    24(%3), %%r11        \n"
48                   "       movq    %%r8, 0(%1)          \n"
49                   "       movq    %%r9, 8(%1)          \n"
50                   "       movq    %%r10, 16(%1)        \n"
51                   "       movq    %%r11, 24(%1)        \n"
52                   "       lea     32(%1), %1           \n"
53                   "       lea     32(%2), %2           \n"
54                   "       lea     32(%3), %3           \n"
55                   "       dec     %0                   \n"
56                   "       jnz     4b                   \n"
57                   "aone:  jrcxz   eadd                 \n" // n % 4 == 0, goto end
58                   "1:     movq    (%2,%0,8),  %%r8     \n"
59                   "       adcq    (%3,%0,8),  %%r8     \n"
60                   "       movq    %%r8, (%1,%0,8)      \n"
61                   "       inc     %0                   \n"
62                   "       dec     %%rcx                \n"
63                   "       jnz     1b                   \n"
64                   "eadd:  sbbq    %0, %0               \n"
65                   :"+&r" (ret)
66                   :"r"(r), "r"(a), "r"(b)
67                   :"r8", "r9", "r10", "r11", "rcx", "cc", "memory");
68 
69     return ret & 1;
70 }
71 
72 // r = a - b, len = n, return carry
BinSub(BN_UINT * r,const BN_UINT * a,const BN_UINT * b,uint32_t n)73 BN_UINT BinSub(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n)
74 {
75     if (n == 0) {
76         return 0;
77     }
78 
79     BN_UINT res = n;
80     asm volatile (
81                   ".p2align 4                          \n"
82                   "       mov     %0, %%rcx            \n"
83                   "       and     $3, %%rcx            \n"
84                   "       shr     $2, %0               \n"
85                   "       clc                          \n"
86                   "       jz      sone                 \n" // n / 4 > = 0 , goto step 4
87                   "4:     movq    0(%2), %%r8          \n"
88                   "       movq    8(%2), %%r9          \n"
89                   "       movq    16(%2), %%r10        \n"
90                   "       movq    24(%2), %%r11        \n"
91                   "       sbbq    0(%3), %%r8          \n"
92                   "       sbbq    8(%3), %%r9          \n"
93                   "       sbbq    16(%3), %%r10        \n"
94                   "       sbbq    24(%3), %%r11        \n"
95                   "       movq    %%r8, 0(%1)          \n"
96                   "       movq    %%r9, 8(%1)          \n"
97                   "       movq    %%r10, 16(%1)        \n"
98                   "       movq    %%r11, 24(%1)        \n"
99                   "       lea     32(%1), %1           \n"
100                   "       lea     32(%2), %2           \n"
101                   "       lea     32(%3), %3           \n"
102                   "       dec     %0                   \n"
103                   "       jnz     4b                   \n"
104                   "sone:  jrcxz   esub                 \n" // n % 4 == 0, goto end
105                   "1:     movq    (%2,%0,8),  %%r8     \n"
106                   "       sbbq    (%3,%0,8),  %%r8     \n"
107                   "       movq    %%r8, (%1,%0,8)      \n"
108                   "       inc     %0                   \n"
109                   "       dec     %%rcx                \n"
110                   "       jnz     1b                   \n"
111                   "esub:  sbbq    %0, %0               \n"
112                   :"+&r" (res)
113                   :"r"(r), "r"(a), "r"(b)
114                   :"r8", "r9", "r10", "r11", "rcx", "cc", "memory");
115 
116     return res & 1;
117 }
118 
119 // r = r - a * m, return the carry;
BinSubMul(BN_UINT * r,const BN_UINT * a,BN_UINT aSize,BN_UINT m)120 BN_UINT BinSubMul(BN_UINT *r, const BN_UINT *a, BN_UINT aSize, BN_UINT m)
121 {
122     BN_UINT borrow = 0;
123     BN_UINT i = 0;
124     asm volatile (
125                   ".p2align 4                          \n"
126                   "endy:  movq    %5, %%rax            \n" // rax = m
127                   "       mulq    (%4,%1,8)            \n" // rax -> al, rdx -> ah
128                   "       addq    %0,  %%rax           \n" // rax = al + borrow
129                   "       adcq    $0,  %%rdx           \n" // if has carry, rdx++
130                   "       subq    %%rax,  (%3,%1,8)    \n" // r[i] = r[i] - (al + borrow)
131                   "       adcq    $0,  %%rdx           \n" // if has carry, borrow++
132                   "       movq    %%rdx,  %0           \n"
133                   "       inc     %1                   \n"
134                   "       dec     %2                   \n"
135                   "       jnz     endy                 \n"
136                 :"+&r" (borrow), "+r"(i), "+r"(aSize)
137                 :"r"(r), "r"(a), "r"(m)
138                 :"rax", "rdx", "cc", "memory");
139     return borrow;
140 }
141 
142 /* Obtains the number of 0s in the first x most significant bits of data. */
GetZeroBitsUint(BN_UINT x)143 uint32_t GetZeroBitsUint(BN_UINT x)
144 {
145     BN_UINT iter;
146     BN_UINT tmp = x;
147     uint32_t bits = BN_UNIT_BITS;
148     uint32_t base = BN_UNIT_BITS >> 1;
149     do {
150         iter = tmp >> base;
151         if (iter != 0) {
152             tmp = iter;
153             bits -= base;
154         }
155         base = base >> 1;
156     } while (base != 0);
157 
158     return bits - tmp;
159 }
160 
161 #endif /* HITLS_CRYPTO_BN */
162