• 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 /* 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