github.com/annchain/OG@v0.0.9/common/math/bigint.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package math 15 16 import ( 17 "encoding/json" 18 "fmt" 19 "math/big" 20 ) 21 22 // DO NOT USE MSGP FOR AUTO-GENERATING HERE. 23 // THE bigint_gen.go has been modified intentionally to adapt big.Int 24 25 // FORBID: go:generate msgp 26 // FORBID: msgp:tuple BigInt 27 28 // A BigInt represents an unsigned multi-precision integer. 29 // The BigInt should always be unsigned since the sign of the number is not serialized. 30 type BigInt struct { 31 Value *big.Int 32 } 33 34 // NewBigInt allocates and returns a new BigInt set to x. 35 func NewBigInt(x int64) *BigInt { 36 return &BigInt{big.NewInt(x)} 37 } 38 39 // NewBigInt allocates and returns a new BigInt set to x. 40 func NewBigIntFromString(x string, base int) (*BigInt, bool) { 41 v, success := big.NewInt(0).SetString(x, base) 42 return &BigInt{v}, success 43 } 44 45 // NewBigInt allocates and returns a new BigInt set to x. 46 func NewBigIntFromBigInt(x *big.Int) *BigInt { 47 return &BigInt{big.NewInt(0).SetBytes(x.Bytes())} 48 } 49 50 // GetBytes returns the absolute value of x as a big-endian byte slice. 51 func (bi *BigInt) GetBytes() []byte { 52 return bi.Value.Bytes() 53 } 54 55 // String returns the value of x as a formatted decimal string. 56 func (bi *BigInt) String() string { 57 return bi.Value.String() 58 } 59 60 // GetInt64 returns the int64 representation of x. If x cannot be represented in 61 // an int64, the result is undefined. 62 func (bi *BigInt) GetInt64() int64 { 63 return bi.Value.Int64() 64 } 65 66 // SetInt64 sets the big int to x. 67 func (bi *BigInt) SetInt64(x int64) { 68 bi.Value.SetInt64(x) 69 } 70 71 // GetSigBytes returns the bytes of bigint. This bytes are for signatures only. 72 func (bi *BigInt) GetSigBytes() []byte { 73 if bi.GetInt64() == 0 { 74 return []byte{0} 75 } 76 return bi.GetBytes() 77 } 78 79 // Sign returns: 80 // 81 // -1 if x < 0 82 // 0 if x == 0 83 // +1 if x > 0 84 // 85 func (bi *BigInt) Sign() int { 86 return bi.Value.Sign() 87 } 88 89 // Set sets bi to x and returns bi. 90 func (bi *BigInt) Set(x *BigInt) *BigInt { 91 bi.Value.Set(x.Value) 92 return bi 93 } 94 95 // Add sets bi to the sum (bi + increment) and returns bi. 96 func (bi *BigInt) Add(increment *BigInt) *BigInt { 97 return NewBigIntFromBigInt(new(big.Int).Add(bi.Value, increment.Value)) 98 } 99 100 // Sub sets bi to the difference (bi - decrement) and returns bi. 101 func (bi *BigInt) Sub(decrement *BigInt) *BigInt { 102 return NewBigIntFromBigInt(new(big.Int).Sub(bi.Value, decrement.Value)) 103 } 104 105 // SetString sets the big int to x. 106 // 107 // The string prefix determines the actual conversion base. A prefix of "0x" or 108 // "0X" selects base 16; the "0" prefix selects base 8, and a "0b" or "0B" prefix 109 // selects base 2. Otherwise the selected base is 10. 110 func (bi *BigInt) SetString(x string, base int) { 111 if bi.Value == nil { 112 bi.Value = big.NewInt(0) 113 } 114 bi.Value.SetString(x, base) 115 } 116 117 // GetString returns the value of x as a formatted string in some number base. 118 func (bi *BigInt) GetString(base int) string { 119 return bi.Value.Text(base) 120 } 121 122 func (bi *BigInt) MarshalJSON() ([]byte, error) { 123 res := fmt.Sprintf("%d", bi.Value) 124 //fmt.Println("Marshaling into ", res) 125 return json.Marshal(res) 126 } 127 128 func (bi *BigInt) UnmarshalJSON(b []byte) error { 129 var val string 130 err := json.Unmarshal(b, &val) 131 if err != nil { 132 panic(err) 133 } 134 135 bi.SetString(val, 10) 136 return nil 137 } 138 139 var ( 140 // number of bits in a big.Word 141 wordBits = 32 << (uint64(^big.Word(0)) >> 63) 142 // number of bytes in a big.Word 143 wordBytes = wordBits / 8 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 // ParseBig256 parses s as a 256 bit integer in decimal or hexadecimal syntax. 171 // Leading zeros are accepted. The empty string parses as zero. 172 func ParseBig256(s string) (*big.Int, bool) { 173 if s == "" { 174 return new(big.Int), true 175 } 176 var bigint *big.Int 177 var ok bool 178 if len(s) >= 2 && (s[:2] == "0x" || s[:2] == "0X") { 179 bigint, ok = new(big.Int).SetString(s[2:], 16) 180 } else { 181 bigint, ok = new(big.Int).SetString(s, 10) 182 } 183 if ok && bigint.BitLen() > 256 { 184 bigint, ok = nil, false 185 } 186 return bigint, ok 187 } 188 189 // MustParseBig256 parses s as a 256 bit big integer and panics if the string is invalid. 190 func MustParseBig256(s string) *big.Int { 191 v, ok := ParseBig256(s) 192 if !ok { 193 panic("invalid 256 bit integer: " + s) 194 } 195 return v 196 }