forked from bnb-chain/tss-lib
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathint.go
152 lines (125 loc) · 3 KB
/
int.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright © 2019 Binance
//
// This file is part of Binance. The full Binance copyright notice, including
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.
package common
import (
"math/big"
)
// modInt is a *big.Int that performs all of its arithmetic with modular reduction.
type modInt big.Int
var (
zero = big.NewInt(0)
one = big.NewInt(1)
two = big.NewInt(2)
)
func Eq(x, y *big.Int) bool {
return x.Cmp(y) == 0
}
func Gt(x, y *big.Int) bool {
return x.Cmp(y) == 1
}
func Lt(x, y *big.Int) bool {
return x.Cmp(y) == -1
}
func Coprime(x, y *big.Int) bool {
z := new(big.Int).GCD(nil, nil, x, y)
return Eq(z, big.NewInt(1))
}
// return x + yz
func AddMul(x, y, z *big.Int) *big.Int {
res := new(big.Int)
res.Mul(y, z)
res.Add(res, x)
return res
}
func ModInt(mod *big.Int) *modInt {
return (*modInt)(mod)
}
func (mi *modInt) Neg(x *big.Int) *big.Int {
i := new(big.Int)
i.Neg(x)
return i.Mod(i, mi.i())
}
func (mi *modInt) Add(x, y *big.Int) *big.Int {
i := new(big.Int)
i.Add(x, y)
return i.Mod(i, mi.i())
}
func (mi *modInt) Sub(x, y *big.Int) *big.Int {
i := new(big.Int)
i.Sub(x, y)
return i.Mod(i, mi.i())
}
func (mi *modInt) Div(x, y *big.Int) *big.Int {
i := new(big.Int)
i.Div(x, y)
return i.Mod(i, mi.i())
}
func (mi *modInt) Mul(x, y *big.Int) *big.Int {
i := new(big.Int)
i.Mul(x, y)
return i.Mod(i, mi.i())
}
func (mi *modInt) Exp(x, y *big.Int) *big.Int {
return new(big.Int).Exp(x, y, mi.i())
}
// return x * y^z % mi
func (mi *modInt) MulExp(x, y, z *big.Int) *big.Int {
return mi.Mul(x, mi.Exp(y, z))
}
// return x^y * z^w % mi
func (mi *modInt) ExpMulExp(x, y, z, w *big.Int) *big.Int {
return mi.Mul(mi.Exp(x, y), mi.Exp(z, w))
}
func (mi *modInt) ModInverse(g *big.Int) *big.Int {
return new(big.Int).ModInverse(g, mi.i())
}
func (mi *modInt) i() *big.Int {
return (*big.Int)(mi)
}
// Marshal the given bigint into bytes.
// with the sign stored in the first byte and the absolute value in the rest.
// `nil` or 0 is stored as the byte 0x00.
// The sign byte is 0x00 for positive and 0x01 for negative.
func MarshalSigned(i *big.Int) []byte {
if i == nil || Eq(i, big.NewInt(0)) {
return []byte{0}
}
// 0 = positive, 1 = negative
sign := make([]byte, 1)
if i.Sign() == 1 {
sign[0] = 0
} else {
sign[0] = 1
}
bs := i.Bytes()
return append(sign, bs...)
}
// Unmarshal a signed bigint from the given bytes.
// Slices of length 1 are interpreted as 0;
// in longer slices the first byte determines the sign
// (0x00 is positive, anything else is negative)
// and the remaining bytes contain the value of the bigint.
func UnmarshalSigned(b []byte) *big.Int {
if len(b) <= 1 {
return big.NewInt(0)
}
sign := b[0]
rest := b[1:]
i := new(big.Int).SetBytes(rest)
if sign != 0 {
i.Neg(i)
}
return i
}
// Returns true when at least one of the arguments is nil
func AnyIsNil(is ...*big.Int) bool {
for _, i := range is {
if i == nil {
return true
}
}
return false
}