github.com/ethereum/go-ethereum@v1.16.1/common/math/big.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package math provides integer math utilities. 18 package math 19 20 import ( 21 "fmt" 22 "math/big" 23 ) 24 25 // Various big integer limit values. 26 var ( 27 tt256 = BigPow(2, 256) 28 tt256m1 = new(big.Int).Sub(tt256, big.NewInt(1)) 29 MaxBig256 = new(big.Int).Set(tt256m1) 30 ) 31 32 const ( 33 // number of bits in a big.Word 34 wordBits = 32 << (uint64(^big.Word(0)) >> 63) 35 // number of bytes in a big.Word 36 wordBytes = wordBits / 8 37 ) 38 39 // HexOrDecimal256 marshals big.Int as hex or decimal. 40 type HexOrDecimal256 big.Int 41 42 // NewHexOrDecimal256 creates a new HexOrDecimal256 43 func NewHexOrDecimal256(x int64) *HexOrDecimal256 { 44 b := big.NewInt(x) 45 h := HexOrDecimal256(*b) 46 return &h 47 } 48 49 // UnmarshalJSON implements json.Unmarshaler. 50 // 51 // It is similar to UnmarshalText, but allows parsing real decimals too, not just 52 // quoted decimal strings. 53 func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error { 54 if len(input) > 1 && input[0] == '"' { 55 input = input[1 : len(input)-1] 56 } 57 return i.UnmarshalText(input) 58 } 59 60 // UnmarshalText implements encoding.TextUnmarshaler. 61 func (i *HexOrDecimal256) UnmarshalText(input []byte) error { 62 bigint, ok := ParseBig256(string(input)) 63 if !ok { 64 return fmt.Errorf("invalid hex or decimal integer %q", input) 65 } 66 *i = HexOrDecimal256(*bigint) 67 return nil 68 } 69 70 // MarshalText implements encoding.TextMarshaler. 71 func (i *HexOrDecimal256) MarshalText() ([]byte, error) { 72 if i == nil { 73 return []byte("0x0"), nil 74 } 75 return fmt.Appendf(nil, "%#x", (*big.Int)(i)), nil 76 } 77 78 // Decimal256 unmarshals big.Int as a decimal string. When unmarshalling, 79 // it however accepts either "0x"-prefixed (hex encoded) or non-prefixed (decimal) 80 type Decimal256 big.Int 81 82 // NewDecimal256 creates a new Decimal256 83 func NewDecimal256(x int64) *Decimal256 { 84 b := big.NewInt(x) 85 d := Decimal256(*b) 86 return &d 87 } 88 89 // UnmarshalText implements encoding.TextUnmarshaler. 90 func (i *Decimal256) UnmarshalText(input []byte) error { 91 bigint, ok := ParseBig256(string(input)) 92 if !ok { 93 return fmt.Errorf("invalid hex or decimal integer %q", input) 94 } 95 *i = Decimal256(*bigint) 96 return nil 97 } 98 99 // MarshalText implements encoding.TextMarshaler. 100 func (i *Decimal256) MarshalText() ([]byte, error) { 101 return []byte(i.String()), nil 102 } 103 104 // String implements Stringer. 105 func (i *Decimal256) String() string { 106 if i == nil { 107 return "0" 108 } 109 return fmt.Sprintf("%#d", (*big.Int)(i)) 110 } 111 112 // ParseBig256 parses s as a 256 bit integer in decimal or hexadecimal syntax. 113 // Leading zeros are accepted. The empty string parses as zero. 114 func ParseBig256(s string) (*big.Int, bool) { 115 if s == "" { 116 return new(big.Int), true 117 } 118 var bigint *big.Int 119 var ok bool 120 if len(s) >= 2 && (s[:2] == "0x" || s[:2] == "0X") { 121 bigint, ok = new(big.Int).SetString(s[2:], 16) 122 } else { 123 bigint, ok = new(big.Int).SetString(s, 10) 124 } 125 if ok && bigint.BitLen() > 256 { 126 bigint, ok = nil, false 127 } 128 return bigint, ok 129 } 130 131 // MustParseBig256 parses s as a 256 bit big integer and panics if the string is invalid. 132 func MustParseBig256(s string) *big.Int { 133 v, ok := ParseBig256(s) 134 if !ok { 135 panic("invalid 256 bit integer: " + s) 136 } 137 return v 138 } 139 140 // BigPow returns a ** b as a big integer. 141 func BigPow(a, b int64) *big.Int { 142 r := big.NewInt(a) 143 return r.Exp(r, big.NewInt(b), nil) 144 } 145 146 // PaddedBigBytes encodes a big integer as a big-endian byte slice. The length 147 // of the slice is at least n bytes. 148 func PaddedBigBytes(bigint *big.Int, n int) []byte { 149 if bigint.BitLen()/8 >= n { 150 return bigint.Bytes() 151 } 152 ret := make([]byte, n) 153 ReadBits(bigint, ret) 154 return ret 155 } 156 157 // ReadBits encodes the absolute value of bigint as big-endian bytes. Callers must ensure 158 // that buf has enough space. If buf is too short the result will be incomplete. 159 func ReadBits(bigint *big.Int, buf []byte) { 160 i := len(buf) 161 for _, d := range bigint.Bits() { 162 for j := 0; j < wordBytes && i > 0; j++ { 163 i-- 164 buf[i] = byte(d) 165 d >>= 8 166 } 167 } 168 } 169 170 // U256 encodes x as a 256 bit two's complement number. This operation is destructive. 171 func U256(x *big.Int) *big.Int { 172 return x.And(x, tt256m1) 173 } 174 175 // U256Bytes converts a big Int into a 256bit EVM number. 176 // This operation is destructive. 177 func U256Bytes(n *big.Int) []byte { 178 return PaddedBigBytes(U256(n), 32) 179 }