github.com/ethereum/go-ethereum@v1.16.1/common/math/big.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package math provides integer math utilities.
    18  package math
    19  
    20  import (
    21  	"fmt"
    22  	"math/big"
    23  )
    24  
    25  // Various big integer limit values.
    26  var (
    27  	tt256     = BigPow(2, 256)
    28  	tt256m1   = new(big.Int).Sub(tt256, big.NewInt(1))
    29  	MaxBig256 = new(big.Int).Set(tt256m1)
    30  )
    31  
    32  const (
    33  	// number of bits in a big.Word
    34  	wordBits = 32 << (uint64(^big.Word(0)) >> 63)
    35  	// number of bytes in a big.Word
    36  	wordBytes = wordBits / 8
    37  )
    38  
    39  // HexOrDecimal256 marshals big.Int as hex or decimal.
    40  type HexOrDecimal256 big.Int
    41  
    42  // NewHexOrDecimal256 creates a new HexOrDecimal256
    43  func NewHexOrDecimal256(x int64) *HexOrDecimal256 {
    44  	b := big.NewInt(x)
    45  	h := HexOrDecimal256(*b)
    46  	return &h
    47  }
    48  
    49  // UnmarshalJSON implements json.Unmarshaler.
    50  //
    51  // It is similar to UnmarshalText, but allows parsing real decimals too, not just
    52  // quoted decimal strings.
    53  func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error {
    54  	if len(input) > 1 && input[0] == '"' {
    55  		input = input[1 : len(input)-1]
    56  	}
    57  	return i.UnmarshalText(input)
    58  }
    59  
    60  // UnmarshalText implements encoding.TextUnmarshaler.
    61  func (i *HexOrDecimal256) UnmarshalText(input []byte) error {
    62  	bigint, ok := ParseBig256(string(input))
    63  	if !ok {
    64  		return fmt.Errorf("invalid hex or decimal integer %q", input)
    65  	}
    66  	*i = HexOrDecimal256(*bigint)
    67  	return nil
    68  }
    69  
    70  // MarshalText implements encoding.TextMarshaler.
    71  func (i *HexOrDecimal256) MarshalText() ([]byte, error) {
    72  	if i == nil {
    73  		return []byte("0x0"), nil
    74  	}
    75  	return fmt.Appendf(nil, "%#x", (*big.Int)(i)), nil
    76  }
    77  
    78  // Decimal256 unmarshals big.Int as a decimal string. When unmarshalling,
    79  // it however accepts either "0x"-prefixed (hex encoded) or non-prefixed (decimal)
    80  type Decimal256 big.Int
    81  
    82  // NewDecimal256 creates a new Decimal256
    83  func NewDecimal256(x int64) *Decimal256 {
    84  	b := big.NewInt(x)
    85  	d := Decimal256(*b)
    86  	return &d
    87  }
    88  
    89  // UnmarshalText implements encoding.TextUnmarshaler.
    90  func (i *Decimal256) UnmarshalText(input []byte) error {
    91  	bigint, ok := ParseBig256(string(input))
    92  	if !ok {
    93  		return fmt.Errorf("invalid hex or decimal integer %q", input)
    94  	}
    95  	*i = Decimal256(*bigint)
    96  	return nil
    97  }
    98  
    99  // MarshalText implements encoding.TextMarshaler.
   100  func (i *Decimal256) MarshalText() ([]byte, error) {
   101  	return []byte(i.String()), nil
   102  }
   103  
   104  // String implements Stringer.
   105  func (i *Decimal256) String() string {
   106  	if i == nil {
   107  		return "0"
   108  	}
   109  	return fmt.Sprintf("%#d", (*big.Int)(i))
   110  }
   111  
   112  // ParseBig256 parses s as a 256 bit integer in decimal or hexadecimal syntax.
   113  // Leading zeros are accepted. The empty string parses as zero.
   114  func ParseBig256(s string) (*big.Int, bool) {
   115  	if s == "" {
   116  		return new(big.Int), true
   117  	}
   118  	var bigint *big.Int
   119  	var ok bool
   120  	if len(s) >= 2 && (s[:2] == "0x" || s[:2] == "0X") {
   121  		bigint, ok = new(big.Int).SetString(s[2:], 16)
   122  	} else {
   123  		bigint, ok = new(big.Int).SetString(s, 10)
   124  	}
   125  	if ok && bigint.BitLen() > 256 {
   126  		bigint, ok = nil, false
   127  	}
   128  	return bigint, ok
   129  }
   130  
   131  // MustParseBig256 parses s as a 256 bit big integer and panics if the string is invalid.
   132  func MustParseBig256(s string) *big.Int {
   133  	v, ok := ParseBig256(s)
   134  	if !ok {
   135  		panic("invalid 256 bit integer: " + s)
   136  	}
   137  	return v
   138  }
   139  
   140  // BigPow returns a ** b as a big integer.
   141  func BigPow(a, b int64) *big.Int {
   142  	r := big.NewInt(a)
   143  	return r.Exp(r, big.NewInt(b), nil)
   144  }
   145  
   146  // PaddedBigBytes encodes a big integer as a big-endian byte slice. The length
   147  // of the slice is at least n bytes.
   148  func PaddedBigBytes(bigint *big.Int, n int) []byte {
   149  	if bigint.BitLen()/8 >= n {
   150  		return bigint.Bytes()
   151  	}
   152  	ret := make([]byte, n)
   153  	ReadBits(bigint, ret)
   154  	return ret
   155  }
   156  
   157  // ReadBits encodes the absolute value of bigint as big-endian bytes. Callers must ensure
   158  // that buf has enough space. If buf is too short the result will be incomplete.
   159  func ReadBits(bigint *big.Int, buf []byte) {
   160  	i := len(buf)
   161  	for _, d := range bigint.Bits() {
   162  		for j := 0; j < wordBytes && i > 0; j++ {
   163  			i--
   164  			buf[i] = byte(d)
   165  			d >>= 8
   166  		}
   167  	}
   168  }
   169  
   170  // U256 encodes x as a 256 bit two's complement number. This operation is destructive.
   171  func U256(x *big.Int) *big.Int {
   172  	return x.And(x, tt256m1)
   173  }
   174  
   175  // U256Bytes converts a big Int into a 256bit EVM number.
   176  // This operation is destructive.
   177  func U256Bytes(n *big.Int) []byte {
   178  	return PaddedBigBytes(U256(n), 32)
   179  }