Kind Pure package
Name v0
Namespace onbloc / uint256
Exported functions n/a — not supported for pure packages by the node (vm/qfuncs)
Module gno.land/p/onbloc/uint256/v0
gno 0.9 uint256.gno gno
⧉
1 // Ported from https://github.com/holiman/uint256 2 // This package provides a 256-bit unsigned integer type, Uint256, and associated functions. 3 package uint256 4 5 import ( 6 "errors" 7 "math/bits" not supported for pure packages by the node (vm/qfuncs)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
8
"strconv"
9 )
10
11 const (
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
18 type Uint struct {
19 arr [ 4 ] uint64
20 }
21
22 // NewUint returns a new initialized Uint.
23 func 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.
29 func Zero() *Uint {
30 return NewUint( 0 )
31 }
32
33 // One returns a new Uint initialized to one.
34 func One() *Uint {
35 return NewUint( 1 )
36 }
37
38 // SetAllOne sets all the bits of z to 1
39 func (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.
45 func (z *Uint) Set(x *Uint) *Uint {
46 *z = *x
47
48 return z
49 }
50
51 // SetOne sets z to 1
52 func (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
57 const 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))
65 func (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.
95 func 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.
106 func 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
115 var 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.
126 func (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
175 func (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
191 func (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
205 func (z *Uint) ByteLen() int {
206 return (z.BitLen() + 7 ) / 8
207 }
208
209 // Clear sets z to 0
210 func (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
215 const (
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)
229 func (z *Uint) SetFromHex(hex string ) error {
230 return z.fromHex(hex)
231 }
232
233 // fromHex is the internal implementation of parsing a hex-string.
234 func (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.
264 func 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.
275 func 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
284 func (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 }
293