uint256.gno
8.64 Kb ยท 292 lines
1// Ported from https://github.com/holiman/uint256
2// This package provides a 256-bit unsigned integer type, Uint256, and associated functions.
3package uint256
4
5import (
6 "errors"
7 "math/bits"
8 "strconv"
9)
10
11const (
12 MaxUint64 = 1<<64 - 1
13 uintSize = 32 << (^uint(0) >> 63)
14)
15
16// Uint is represented as an array of 4 uint64, in little-endian order,
17// so that Uint[3] is the most significant, and Uint[0] is the least significant
18type Uint struct {
19 arr [4]uint64
20}
21
22// NewUint returns a new initialized Uint.
23func NewUint(val uint64) *Uint {
24 z := &Uint{arr: [4]uint64{val, 0, 0, 0}}
25 return z
26}
27
28// Zero returns a new Uint initialized to zero.
29func Zero() *Uint {
30 return NewUint(0)
31}
32
33// One returns a new Uint initialized to one.
34func One() *Uint {
35 return NewUint(1)
36}
37
38// SetAllOne sets all the bits of z to 1
39func (z *Uint) SetAllOne() *Uint {
40 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = MaxUint64, MaxUint64, MaxUint64, MaxUint64
41 return z
42}
43
44// Set sets z to x and returns z.
45func (z *Uint) Set(x *Uint) *Uint {
46 *z = *x
47
48 return z
49}
50
51// SetOne sets z to 1
52func (z *Uint) SetOne() *Uint {
53 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = 0, 0, 0, 1
54 return z
55}
56
57const twoPow256Sub1 = "115792089237316195423570985008687907853269984665640564039457584007913129639935"
58
59// SetFromDecimal sets z from the given string, interpreted as a decimal number.
60// OBS! This method is _not_ strictly identical to the (*big.Uint).SetString(..., 10) method.
61// Notable differences:
62// - This method does not accept underscore input, e.g. "100_000",
63// - This method does not accept negative zero as valid, e.g "-0",
64// - (this method does not accept any negative input as valid))
65func (z *Uint) SetFromDecimal(s string) (err error) {
66 // Remove max one leading +
67 if len(s) > 0 && s[0] == '+' {
68 s = s[1:]
69 }
70 // Remove any number of leading zeroes
71 if len(s) > 0 && s[0] == '0' {
72 var i int
73 var c rune
74 for i, c = range s {
75 if c != '0' {
76 break
77 }
78 }
79 s = s[i:]
80 }
81 if len(s) < len(twoPow256Sub1) {
82 return z.fromDecimal(s)
83 }
84 if len(s) == len(twoPow256Sub1) {
85 if s > twoPow256Sub1 {
86 return ErrBig256Range
87 }
88 return z.fromDecimal(s)
89 }
90 return ErrBig256Range
91}
92
93// FromDecimal is a convenience-constructor to create an Uint from a
94// decimal (base 10) string. Numbers larger than 256 bits are not accepted.
95func FromDecimal(decimal string) (*Uint, error) {
96 var z Uint
97 if err := z.SetFromDecimal(decimal); err != nil {
98 return nil, err
99 }
100 return &z, nil
101}
102
103// MustFromDecimal is a convenience-constructor to create an Uint from a
104// decimal (base 10) string.
105// Returns a new Uint and panics if any error occurred.
106func MustFromDecimal(decimal string) *Uint {
107 var z Uint
108 if err := z.SetFromDecimal(decimal); err != nil {
109 panic(err)
110 }
111 return &z
112}
113
114// multipliers holds the values that are needed for fromDecimal
115var multipliers = [5]*Uint{
116 nil, // represents first round, no multiplication needed
117 {[4]uint64{10000000000000000000, 0, 0, 0}}, // 10 ^ 19
118 {[4]uint64{687399551400673280, 5421010862427522170, 0, 0}}, // 10 ^ 38
119 {[4]uint64{5332261958806667264, 17004971331911604867, 2938735877055718769, 0}}, // 10 ^ 57
120 {[4]uint64{0, 8607968719199866880, 532749306367912313, 1593091911132452277}}, // 10 ^ 76
121}
122
123// fromDecimal is a helper function to only ever be called via SetFromDecimal
124// this function takes a string and chunks it up, calling ParseUint on it up to 5 times
125// these chunks are then multiplied by the proper power of 10, then added together.
126func (z *Uint) fromDecimal(bs string) error {
127 // first clear the input
128 z.Clear()
129 // the maximum value of uint64 is 18446744073709551615, which is 20 characters
130 // one less means that a string of 19 9's is always within the uint64 limit
131 var (
132 num uint64
133 err error
134 remaining = len(bs)
135 )
136 if remaining == 0 {
137 return errors.New("EOF")
138 }
139 // We proceed in steps of 19 characters (nibbles), from least significant to most significant.
140 // This means that the first (up to) 19 characters do not need to be multiplied.
141 // In the second iteration, our slice of 19 characters needs to be multipleied
142 // by a factor of 10^19. Et cetera.
143 for i, mult := range multipliers {
144 if remaining <= 0 {
145 return nil // Done
146 } else if remaining > 19 {
147 num, err = strconv.ParseUint(bs[remaining-19:remaining], 10, 64)
148 } else {
149 // Final round
150 num, err = strconv.ParseUint(bs, 10, 64)
151 }
152 if err != nil {
153 return err
154 }
155 // add that number to our running total
156 if i == 0 {
157 z.SetUint64(num)
158 } else {
159 base := NewUint(num)
160 z.Add(z, base.Mul(base, mult))
161 }
162 // Chop off another 19 characters
163 if remaining > 19 {
164 bs = bs[0 : remaining-19]
165 }
166 remaining -= 19
167 }
168 return nil
169}
170
171// Byte sets z to the value of the byte at position n,
172// with 'z' considered as a big-endian 32-byte integer
173// if 'n' > 32, f is set to 0
174// Example: f = '5', n=31 => 5
175func (z *Uint) Byte(n *Uint) *Uint {
176 // in z, z.arr[0] is the least significant
177 if number, overflow := n.Uint64WithOverflow(); !overflow {
178 if number < 32 {
179 number := z.arr[4-1-number/8]
180 offset := (n.arr[0] & 0x7) << 3 // 8*(n.d % 8)
181 z.arr[0] = (number & (0xff00000000000000 >> offset)) >> (56 - offset)
182 z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
183 return z
184 }
185 }
186
187 return z.Clear()
188}
189
190// BitLen returns the number of bits required to represent z
191func (z *Uint) BitLen() int {
192 switch {
193 case z.arr[3] != 0:
194 return 192 + bits.Len64(z.arr[3])
195 case z.arr[2] != 0:
196 return 128 + bits.Len64(z.arr[2])
197 case z.arr[1] != 0:
198 return 64 + bits.Len64(z.arr[1])
199 default:
200 return bits.Len64(z.arr[0])
201 }
202}
203
204// ByteLen returns the number of bytes required to represent z
205func (z *Uint) ByteLen() int {
206 return (z.BitLen() + 7) / 8
207}
208
209// Clear sets z to 0
210func (z *Uint) Clear() *Uint {
211 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = 0, 0, 0, 0
212 return z
213}
214
215const (
216 // hextable = "0123456789abcdef"
217 bintable = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x02\x03\x04\x05\x06\a\b\t\xff\xff\xff\xff\xff\xff\xff\n\v\f\r\x0e\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\n\v\f\r\x0e\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
218 badNibble = 0xff
219)
220
221// SetFromHex sets z from the given string, interpreted as a hexadecimal number.
222// OBS! This method is _not_ strictly identical to the (*big.Int).SetString(..., 16) method.
223// Notable differences:
224// - This method _require_ "0x" or "0X" prefix.
225// - This method does not accept zero-prefixed hex, e.g. "0x0001"
226// - This method does not accept underscore input, e.g. "100_000",
227// - This method does not accept negative zero as valid, e.g "-0x0",
228// - (this method does not accept any negative input as valid)
229func (z *Uint) SetFromHex(hex string) error {
230 return z.fromHex(hex)
231}
232
233// fromHex is the internal implementation of parsing a hex-string.
234func (z *Uint) fromHex(hex string) error {
235 if err := checkNumberS(hex); err != nil {
236 return err
237 }
238 if len(hex) > 66 {
239 return ErrBig256Range
240 }
241 z.Clear()
242 end := len(hex)
243 for i := 0; i < 4; i++ {
244 start := end - 16
245 if start < 2 {
246 start = 2
247 }
248 for ri := start; ri < end; ri++ {
249 nib := bintable[hex[ri]]
250 if nib == badNibble {
251 return ErrSyntax
252 }
253 z.arr[i] = z.arr[i] << 4
254 z.arr[i] += uint64(nib)
255 }
256 end = start
257 }
258 return nil
259}
260
261// FromHex is a convenience-constructor to create an Uint from
262// a hexadecimal string. The string is required to be '0x'-prefixed
263// Numbers larger than 256 bits are not accepted.
264func FromHex(hex string) (*Uint, error) {
265 var z Uint
266 if err := z.fromHex(hex); err != nil {
267 return nil, err
268 }
269 return &z, nil
270}
271
272// MustFromHex is a convenience-constructor to create an Uint from
273// a hexadecimal string.
274// Returns a new Uint and panics if any error occurred.
275func MustFromHex(hex string) *Uint {
276 var z Uint
277 if err := z.fromHex(hex); err != nil {
278 panic(err)
279 }
280 return &z
281}
282
283// Clone creates a new Uint identical to z
284func (z *Uint) Clone() *Uint {
285 var x Uint
286 x.arr[0] = z.arr[0]
287 x.arr[1] = z.arr[1]
288 x.arr[2] = z.arr[2]
289 x.arr[3] = z.arr[3]
290
291 return &x
292}