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 /* r = a + b, the length of r, a and b array is n. The return value is the carry. */
BinAdd(BN_UINT * r,const BN_UINT * a,const BN_UINT * b,uint32_t n)22 BN_UINT BinAdd(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n)
23 {
24 BN_UINT carry = 0;
25 uint32_t nn = n;
26 const BN_UINT *aa = a;
27 const BN_UINT *bb = b;
28 BN_UINT *rr = r;
29 #ifndef HITLS_CRYPTO_BN_SMALL_MEM
30 while (nn >= 4) { /* Process 4 groups in batches. */
31 ADD_ABC(carry, rr[0], aa[0], bb[0], carry); /* offset 0 */
32 ADD_ABC(carry, rr[1], aa[1], bb[1], carry); /* offset 1 */
33 ADD_ABC(carry, rr[2], aa[2], bb[2], carry); /* offset 2 */
34 ADD_ABC(carry, rr[3], aa[3], bb[3], carry); /* offset 3 */
35 rr += 4; /* a group of 4 */
36 aa += 4; /* a group of 4 */
37 bb += 4; /* a group of 4 */
38 nn -= 4; /* a group of 4 */
39 }
40 #endif
41 uint32_t i = 0;
42 for (; i < nn; i++) {
43 ADD_ABC(carry, rr[i], aa[i], bb[i], carry);
44 }
45 return carry;
46 }
47 /* r = a - b, the length of r, a and b array is n. The return value is the borrow-digit. */
BinSub(BN_UINT * r,const BN_UINT * a,const BN_UINT * b,uint32_t n)48 BN_UINT BinSub(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n)
49 {
50 BN_UINT borrow = 0;
51 uint32_t nn = n;
52 const BN_UINT *aa = a;
53 const BN_UINT *bb = b;
54 BN_UINT *rr = r;
55 #ifndef HITLS_CRYPTO_BN_SMALL_MEM
56 while (nn >= 4) { /* Process 4 groups in batches. */
57 SUB_ABC(borrow, rr[0], aa[0], bb[0], borrow); /* offset 0 */
58 SUB_ABC(borrow, rr[1], aa[1], bb[1], borrow); /* offset 1 */
59 SUB_ABC(borrow, rr[2], aa[2], bb[2], borrow); /* offset 2 */
60 SUB_ABC(borrow, rr[3], aa[3], bb[3], borrow); /* offset 3 */
61 rr += 4; /* a group of 4 */
62 aa += 4; /* a group of 4 */
63 bb += 4; /* a group of 4 */
64 nn -= 4; /* a group of 4 */
65 }
66 #endif
67 uint32_t i = 0;
68 for (; i < nn; i++) {
69 SUB_ABC(borrow, rr[i], aa[i], bb[i], borrow);
70 }
71 return borrow;
72 }
73
74 /* Obtains the number of 0s in the first x most significant bits of data. */
GetZeroBitsUint(BN_UINT x)75 uint32_t GetZeroBitsUint(BN_UINT x)
76 {
77 BN_UINT iter;
78 BN_UINT tmp = x;
79 uint32_t bits = BN_UNIT_BITS;
80 uint32_t base = BN_UNIT_BITS >> 1;
81 do {
82 iter = tmp >> base;
83 if (iter != 0) {
84 tmp = iter;
85 bits -= base;
86 }
87 base = base >> 1;
88 } while (base != 0);
89
90 return (uint32_t)(bits - tmp);
91 }
92
93 /* Multiply and then subtract. The return value is borrow digit. */
BinSubMul(BN_UINT * r,const BN_UINT * a,BN_UINT aSize,BN_UINT m)94 BN_UINT BinSubMul(BN_UINT *r, const BN_UINT *a, BN_UINT aSize, BN_UINT m)
95 {
96 BN_UINT borrow = 0;
97 uint32_t i;
98 for (i = 0; i < aSize; i++) {
99 BN_UINT ah, al;
100 MUL_AB(ah, al, a[i], m);
101 SUB_ABC(borrow, r[i], r[i], al, borrow);
102 borrow += ah;
103 }
104
105 return borrow;
106 }
107
108 #endif /* HITLS_CRYPTO_BN */
109