uint256.gno
6.11 Kb ยท 248 lines
1package uint256
2
3import (
4 "errors"
5 "math/bits"
6 "strconv"
7)
8
9const (
10 MAX_UINT64 = ^uint64(0)
11 MAX_UINT256 = "115792089237316195423570985008687907853269984665640564039457584007913129639935"
12)
13
14var ErrBig256Range = errors.New("decimal number > 256 bits")
15
16var (
17 zero = Uint{0, 0, 0, 0}
18 one = Uint{1, 0, 0, 0}
19 two = Uint{2, 0, 0, 0}
20 three = Uint{3, 0, 0, 0}
21)
22
23// Uint represents a 256-bit unsigned integer.
24// It is stored as an array of 4 uint64 in little-endian order,
25// where arr[0] is the least significant and arr[3] is the most significant.
26type Uint [4]uint64
27
28// NewUint returns a new Uint initialized with the given uint64 value.
29func NewUint(val uint64) *Uint {
30 return &Uint{val, 0, 0, 0}
31}
32
33// NewUintFromInt64 returns a new Uint initialized with the given int64 value.
34// Panics if val is negative.
35func NewUintFromInt64(val int64) *Uint {
36 if val < 0 {
37 panic("val is negative")
38 }
39 return &Uint{uint64(val), 0, 0, 0}
40}
41
42// Zero returns a new Uint with value 0.
43func Zero() *Uint {
44 return &Uint{0, 0, 0, 0}
45}
46
47// One returns a new Uint with value 1.
48func One() *Uint {
49 return &Uint{1, 0, 0, 0}
50}
51
52// SetAllOne sets z to the maximum 256-bit value (all bits set to 1) and returns z.
53func (z *Uint) SetAllOne() *Uint {
54 z[3], z[2], z[1], z[0] = MAX_UINT64, MAX_UINT64, MAX_UINT64, MAX_UINT64
55 return z
56}
57
58// Set sets z to x and returns z.
59func (z *Uint) Set(x *Uint) *Uint {
60 *z = *x
61 return z
62}
63
64// SetOne sets z to 1 and returns z.
65func (z *Uint) SetOne() *Uint {
66 z[3], z[2], z[1], z[0] = 0, 0, 0, 1
67 return z
68}
69
70// SetFromDecimal sets z from a decimal string and returns an error if invalid.
71// Accepts an optional leading "+" sign but rejects underscores and negative values.
72// Returns ErrBig256Range if the number exceeds 256 bits.
73func (z *Uint) SetFromDecimal(s string) (err error) {
74 sLen := len(s)
75 // Remove max one leading +
76 if sLen > 0 && s[0] == '+' {
77 s = s[1:]
78 sLen--
79 }
80 // Remove any number of leading zeroes
81 if sLen > 0 && s[0] == '0' {
82 var i int
83 var c rune
84 for i, c = range s {
85 if c != '0' {
86 break
87 }
88 }
89 s = s[i:]
90 sLen = len(s)
91 }
92
93 maxLen := len(MAX_UINT256)
94 if sLen < maxLen {
95 return z.fromDecimal(s)
96 }
97 if sLen == maxLen {
98 if s > MAX_UINT256 {
99 return ErrBig256Range
100 }
101 return z.fromDecimal(s)
102 }
103 return ErrBig256Range
104}
105
106// FromDecimal creates a new Uint from a decimal string.
107// Returns an error if the number exceeds 256 bits or is invalid.
108func FromDecimal(decimal string) (*Uint, error) {
109 var z Uint
110 if err := z.SetFromDecimal(decimal); err != nil {
111 return nil, err
112 }
113 return &z, nil
114}
115
116// MustFromDecimal creates a new Uint from a decimal string.
117// Panics if the string is invalid or the number exceeds 256 bits.
118func MustFromDecimal(decimal string) *Uint {
119 var z Uint
120 if err := z.SetFromDecimal(decimal); err != nil {
121 panic(err)
122 }
123 return &z
124}
125
126// multipliers holds the values that are needed for fromDecimal
127var multipliers = [5]Uint{
128 {0, 0, 0, 0}, // 1 (no multiplication needed in the first round)
129 {10000000000000000000, 0, 0, 0}, // 10 ^ 19
130 {687399551400673280, 5421010862427522170, 0, 0}, // 10 ^ 38
131 {5332261958806667264, 17004971331911604867, 2938735877055718769, 0}, // 10 ^ 57
132 {0, 8607968719199866880, 532749306367912313, 1593091911132452277}, // 10 ^ 76
133}
134
135// fromDecimal parses a decimal string by processing it in 19-character chunks.
136// Each chunk is multiplied by the appropriate power of 10 and accumulated.
137func (z *Uint) fromDecimal(bs string) error {
138 // first clear the input
139 z.Clear()
140 // the maximum value of uint64 is 18446744073709551615, which is 20 characters
141 // one less means that a string of 19 9's is always within the uint64 limit
142 var (
143 num uint64
144 err error
145 remaining = len(bs)
146 )
147 if remaining == 0 {
148 return errors.New("EOF")
149 }
150
151 // We proceed in steps of 19 characters (nibbles), from least significant to most significant.
152 // This means that the first (up to) 19 characters do not need to be multiplied.
153 // In the second iteration, our slice of 19 characters needs to be multiplied
154 // by a factor of 10^19. Et cetera.
155 for i := range multipliers {
156 if remaining <= 0 {
157 return nil // Done
158 }
159 if remaining > 19 {
160 num, err = strconv.ParseUint(bs[remaining-19:remaining], 10, 64)
161 } else {
162 // Final round
163 num, err = strconv.ParseUint(bs, 10, 64)
164 }
165 if err != nil {
166 return err
167 }
168 // add that number to our running total
169 if i == 0 {
170 z.SetUint64(num)
171 } else {
172 base := &Uint{uint64(num), 0, 0, 0}
173 // Check for overflow in multiplication
174 base, overflow := base.MulOverflow(base, &multipliers[i])
175 if overflow {
176 return ErrBig256Range
177 }
178 // Check for overflow in addition
179 base, overflow = base.AddOverflow(base, z)
180 if overflow {
181 return ErrBig256Range
182 }
183 z.Set(base)
184 }
185 // Chop off another 19 characters
186 if remaining > 19 {
187 bs = bs[0 : remaining-19]
188 }
189 remaining -= 19
190 }
191 return nil
192}
193
194// Byte returns the value of the byte at position n as a Uint.
195// Position n is counted from the right (0 = least significant byte).
196// Returns 0 if n >= 32.
197func (z *Uint) Byte(n *Uint) *Uint {
198 // in z, z[0] is the least significant
199 if number, overflow := n.Uint64WithOverflow(); !overflow {
200 if number < 32 {
201 number := z[4-1-number/8]
202 offset := (n[0] & 0x7) << 3 // 8*(n.d % 8)
203 z[0] = (number & (0xff00000000000000 >> offset)) >> (56 - offset)
204 z[3], z[2], z[1] = 0, 0, 0
205 return z
206 }
207 }
208
209 return z.Clear()
210}
211
212// BitLen returns the number of bits required to represent z.
213// BitLen(0) returns 0.
214func (z *Uint) BitLen() int {
215 switch {
216 case z[3] != 0:
217 return 192 + bits.Len64(z[3])
218 case z[2] != 0:
219 return 128 + bits.Len64(z[2])
220 case z[1] != 0:
221 return 64 + bits.Len64(z[1])
222 default:
223 return bits.Len64(z[0])
224 }
225}
226
227// ByteLen returns the number of bytes required to represent z.
228// ByteLen(0) returns 0.
229func (z *Uint) ByteLen() int {
230 return (z.BitLen() + 7) / 8
231}
232
233// Clear sets z to 0 and returns z.
234func (z *Uint) Clear() *Uint {
235 z[3], z[2], z[1], z[0] = 0, 0, 0, 0
236 return z
237}
238
239// Clone returns a new Uint with the same value as z.
240func (z *Uint) Clone() *Uint {
241 var x Uint
242 x[0] = z[0]
243 x[1] = z[1]
244 x[2] = z[2]
245 x[3] = z[3]
246
247 return &x
248}