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  }