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