github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/utilities/common/math/big.go (about) 1 package math 2 3 import ( 4 "fmt" 5 "math/big" 6 ) 7 8 var ( 9 tt255 = BigPow(2, 255) 10 tt256 = BigPow(2, 256) 11 tt256m1 = new(big.Int).Sub(tt256, big.NewInt(1)) 12 MaxBig256 = new(big.Int).Set(tt256m1) 13 tt63 = BigPow(2, 63) 14 MaxBig63 = new(big.Int).Sub(tt63, big.NewInt(1)) 15 ) 16 17 const ( 18 wordBits = 32 << (uint64(^big.Word(0)) >> 63) 19 20 wordBytes = wordBits / 8 21 ) 22 23 type HexOrDecimal256 big.Int 24 25 func (i *HexOrDecimal256) UnmarshalText(input []byte) error { 26 bigint, ok := ParseBig256(string(input)) 27 if !ok { 28 return fmt.Errorf("invalid hex or decimal integer %q", input) 29 } 30 *i = HexOrDecimal256(*bigint) 31 return nil 32 } 33 34 func (i *HexOrDecimal256) MarshalText() ([]byte, error) { 35 if i == nil { 36 return []byte("0x0"), nil 37 } 38 return []byte(fmt.Sprintf("%#x", (*big.Int)(i))), nil 39 } 40 41 func ParseBig256(s string) (*big.Int, bool) { 42 if s == "" { 43 return new(big.Int), true 44 } 45 var bigint *big.Int 46 var ok bool 47 if len(s) >= 2 && (s[:2] == "0x" || s[:2] == "0X") { 48 bigint, ok = new(big.Int).SetString(s[2:], 16) 49 } else { 50 bigint, ok = new(big.Int).SetString(s, 10) 51 } 52 if ok && bigint.BitLen() > 256 { 53 bigint, ok = nil, false 54 } 55 return bigint, ok 56 } 57 58 func MustParseBig256(s string) *big.Int { 59 v, ok := ParseBig256(s) 60 if !ok { 61 panic("invalid 256 bit integer: " + s) 62 } 63 return v 64 } 65 66 func BigPow(a, b int64) *big.Int { 67 r := big.NewInt(a) 68 return r.Exp(r, big.NewInt(b), nil) 69 } 70 71 func BigMax(x, y *big.Int) *big.Int { 72 if x.Cmp(y) < 0 { 73 return y 74 } 75 return x 76 } 77 78 func BigMin(x, y *big.Int) *big.Int { 79 if x.Cmp(y) > 0 { 80 return y 81 } 82 return x 83 } 84 85 func FirstBitSet(v *big.Int) int { 86 for i := 0; i < v.BitLen(); i++ { 87 if v.Bit(i) > 0 { 88 return i 89 } 90 } 91 return v.BitLen() 92 } 93 94 func PaddedBigBytes(bigint *big.Int, n int) []byte { 95 if bigint.BitLen()/8 >= n { 96 return bigint.Bytes() 97 } 98 ret := make([]byte, n) 99 ReadBits(bigint, ret) 100 return ret 101 } 102 103 func bigEndianByteAt(bigint *big.Int, n int) byte { 104 words := bigint.Bits() 105 106 i := n / wordBytes 107 if i >= len(words) { 108 return byte(0) 109 } 110 word := words[i] 111 112 shift := 8 * uint(n%wordBytes) 113 114 return byte(word >> shift) 115 } 116 117 func Byte(bigint *big.Int, padlength, n int) byte { 118 if n >= padlength { 119 return byte(0) 120 } 121 return bigEndianByteAt(bigint, padlength-1-n) 122 } 123 124 func ReadBits(bigint *big.Int, buf []byte) { 125 i := len(buf) 126 for _, d := range bigint.Bits() { 127 for j := 0; j < wordBytes && i > 0; j++ { 128 i-- 129 buf[i] = byte(d) 130 d >>= 8 131 } 132 } 133 } 134 135 func U256(x *big.Int) *big.Int { 136 return x.And(x, tt256m1) 137 } 138 139 func S256(x *big.Int) *big.Int { 140 if x.Cmp(tt255) < 0 { 141 return x 142 } else { 143 return new(big.Int).Sub(x, tt256) 144 } 145 } 146 147 func Exp(base, exponent *big.Int) *big.Int { 148 result := big.NewInt(1) 149 150 for _, word := range exponent.Bits() { 151 for i := 0; i < wordBits; i++ { 152 if word&1 == 1 { 153 U256(result.Mul(result, base)) 154 } 155 U256(base.Mul(base, base)) 156 word >>= 1 157 } 158 } 159 return result 160 }