github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/chain/core/vm/contracts.go (about)

     1  package vm
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"encoding/binary"
     6  	"errors"
     7  	"math/big"
     8  
     9  	"github.com/neatio-net/neatio/utilities/crypto/blake2b"
    10  
    11  	"github.com/neatio-net/neatio/params"
    12  	"github.com/neatio-net/neatio/utilities/common"
    13  	"github.com/neatio-net/neatio/utilities/common/math"
    14  	"github.com/neatio-net/neatio/utilities/crypto"
    15  	"github.com/neatio-net/neatio/utilities/crypto/bn256"
    16  	"golang.org/x/crypto/ripemd160"
    17  )
    18  
    19  type PrecompiledContract interface {
    20  	RequiredGas(input []byte) uint64
    21  	Run(input []byte) ([]byte, error)
    22  }
    23  
    24  var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{
    25  	common.BytesToAddress([]byte{1}): &ecrecover{},
    26  	common.BytesToAddress([]byte{2}): &sha256hash{},
    27  	common.BytesToAddress([]byte{3}): &ripemd160hash{},
    28  	common.BytesToAddress([]byte{4}): &dataCopy{},
    29  }
    30  
    31  var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
    32  	common.BytesToAddress([]byte{1}): &ecrecover{},
    33  	common.BytesToAddress([]byte{2}): &sha256hash{},
    34  	common.BytesToAddress([]byte{3}): &ripemd160hash{},
    35  	common.BytesToAddress([]byte{4}): &dataCopy{},
    36  	common.BytesToAddress([]byte{5}): &bigModExp{},
    37  	common.BytesToAddress([]byte{6}): &bn256AddByzantium{},
    38  	common.BytesToAddress([]byte{7}): &bn256ScalarMulByzantium{},
    39  	common.BytesToAddress([]byte{8}): &bn256PairingByzantium{},
    40  }
    41  
    42  var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
    43  	common.BytesToAddress([]byte{1}): &ecrecover{},
    44  	common.BytesToAddress([]byte{2}): &sha256hash{},
    45  	common.BytesToAddress([]byte{3}): &ripemd160hash{},
    46  	common.BytesToAddress([]byte{4}): &dataCopy{},
    47  	common.BytesToAddress([]byte{5}): &bigModExp{},
    48  	common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
    49  	common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
    50  	common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
    51  	common.BytesToAddress([]byte{9}): &blake2F{},
    52  }
    53  
    54  func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error) {
    55  	gas := p.RequiredGas(input)
    56  	if contract.UseGas(gas) {
    57  		return p.Run(input)
    58  	}
    59  	return nil, ErrOutOfGas
    60  }
    61  
    62  type ecrecover struct{}
    63  
    64  func (c *ecrecover) RequiredGas(input []byte) uint64 {
    65  	return params.EcrecoverGas
    66  }
    67  
    68  func (c *ecrecover) Run(input []byte) ([]byte, error) {
    69  	const ecRecoverInputLength = 128
    70  
    71  	input = common.RightPadBytes(input, ecRecoverInputLength)
    72  
    73  	r := new(big.Int).SetBytes(input[64:96])
    74  	s := new(big.Int).SetBytes(input[96:128])
    75  	v := input[63] - 27
    76  
    77  	if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) {
    78  		return nil, nil
    79  	}
    80  
    81  	sig := make([]byte, 65)
    82  	copy(sig, input[64:128])
    83  	sig[64] = v
    84  
    85  	pubKey, err := crypto.Ecrecover(input[:32], sig)
    86  
    87  	if err != nil {
    88  		return nil, nil
    89  	}
    90  
    91  	return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil
    92  }
    93  
    94  type sha256hash struct{}
    95  
    96  func (c *sha256hash) RequiredGas(input []byte) uint64 {
    97  	return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas
    98  }
    99  func (c *sha256hash) Run(input []byte) ([]byte, error) {
   100  	h := sha256.Sum256(input)
   101  	return h[:], nil
   102  }
   103  
   104  type ripemd160hash struct{}
   105  
   106  func (c *ripemd160hash) RequiredGas(input []byte) uint64 {
   107  	return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas
   108  }
   109  func (c *ripemd160hash) Run(input []byte) ([]byte, error) {
   110  	ripemd := ripemd160.New()
   111  	ripemd.Write(input)
   112  	return common.LeftPadBytes(ripemd.Sum(nil), 32), nil
   113  }
   114  
   115  type dataCopy struct{}
   116  
   117  func (c *dataCopy) RequiredGas(input []byte) uint64 {
   118  	return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas
   119  }
   120  func (c *dataCopy) Run(in []byte) ([]byte, error) {
   121  	return in, nil
   122  }
   123  
   124  type bigModExp struct{}
   125  
   126  var (
   127  	big1      = big.NewInt(1)
   128  	big4      = big.NewInt(4)
   129  	big8      = big.NewInt(8)
   130  	big16     = big.NewInt(16)
   131  	big32     = big.NewInt(32)
   132  	big64     = big.NewInt(64)
   133  	big96     = big.NewInt(96)
   134  	big480    = big.NewInt(480)
   135  	big1024   = big.NewInt(1024)
   136  	big3072   = big.NewInt(3072)
   137  	big199680 = big.NewInt(199680)
   138  )
   139  
   140  func (c *bigModExp) RequiredGas(input []byte) uint64 {
   141  	var (
   142  		baseLen = new(big.Int).SetBytes(getData(input, 0, 32))
   143  		expLen  = new(big.Int).SetBytes(getData(input, 32, 32))
   144  		modLen  = new(big.Int).SetBytes(getData(input, 64, 32))
   145  	)
   146  	if len(input) > 96 {
   147  		input = input[96:]
   148  	} else {
   149  		input = input[:0]
   150  	}
   151  
   152  	var expHead *big.Int
   153  	if big.NewInt(int64(len(input))).Cmp(baseLen) <= 0 {
   154  		expHead = new(big.Int)
   155  	} else {
   156  		if expLen.Cmp(big32) > 0 {
   157  			expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), 32))
   158  		} else {
   159  			expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), expLen.Uint64()))
   160  		}
   161  	}
   162  
   163  	var msb int
   164  	if bitlen := expHead.BitLen(); bitlen > 0 {
   165  		msb = bitlen - 1
   166  	}
   167  	adjExpLen := new(big.Int)
   168  	if expLen.Cmp(big32) > 0 {
   169  		adjExpLen.Sub(expLen, big32)
   170  		adjExpLen.Mul(big8, adjExpLen)
   171  	}
   172  	adjExpLen.Add(adjExpLen, big.NewInt(int64(msb)))
   173  
   174  	gas := new(big.Int).Set(math.BigMax(modLen, baseLen))
   175  	switch {
   176  	case gas.Cmp(big64) <= 0:
   177  		gas.Mul(gas, gas)
   178  	case gas.Cmp(big1024) <= 0:
   179  		gas = new(big.Int).Add(
   180  			new(big.Int).Div(new(big.Int).Mul(gas, gas), big4),
   181  			new(big.Int).Sub(new(big.Int).Mul(big96, gas), big3072),
   182  		)
   183  	default:
   184  		gas = new(big.Int).Add(
   185  			new(big.Int).Div(new(big.Int).Mul(gas, gas), big16),
   186  			new(big.Int).Sub(new(big.Int).Mul(big480, gas), big199680),
   187  		)
   188  	}
   189  	gas.Mul(gas, math.BigMax(adjExpLen, big1))
   190  	gas.Div(gas, new(big.Int).SetUint64(params.ModExpQuadCoeffDiv))
   191  
   192  	if gas.BitLen() > 64 {
   193  		return math.MaxUint64
   194  	}
   195  	return gas.Uint64()
   196  }
   197  
   198  func (c *bigModExp) Run(input []byte) ([]byte, error) {
   199  	var (
   200  		baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64()
   201  		expLen  = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64()
   202  		modLen  = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64()
   203  	)
   204  	if len(input) > 96 {
   205  		input = input[96:]
   206  	} else {
   207  		input = input[:0]
   208  	}
   209  
   210  	if baseLen == 0 && modLen == 0 {
   211  		return []byte{}, nil
   212  	}
   213  
   214  	var (
   215  		base = new(big.Int).SetBytes(getData(input, 0, baseLen))
   216  		exp  = new(big.Int).SetBytes(getData(input, baseLen, expLen))
   217  		mod  = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen))
   218  	)
   219  	if mod.BitLen() == 0 {
   220  
   221  		return common.LeftPadBytes([]byte{}, int(modLen)), nil
   222  	}
   223  	return common.LeftPadBytes(base.Exp(base, exp, mod).Bytes(), int(modLen)), nil
   224  }
   225  
   226  func newCurvePoint(blob []byte) (*bn256.G1, error) {
   227  	p := new(bn256.G1)
   228  	if _, err := p.Unmarshal(blob); err != nil {
   229  		return nil, err
   230  	}
   231  	return p, nil
   232  }
   233  
   234  func newTwistPoint(blob []byte) (*bn256.G2, error) {
   235  	p := new(bn256.G2)
   236  	if _, err := p.Unmarshal(blob); err != nil {
   237  		return nil, err
   238  	}
   239  	return p, nil
   240  }
   241  
   242  func runBn256Add(input []byte) ([]byte, error) {
   243  	x, err := newCurvePoint(getData(input, 0, 64))
   244  	if err != nil {
   245  		return nil, err
   246  	}
   247  	y, err := newCurvePoint(getData(input, 64, 64))
   248  	if err != nil {
   249  		return nil, err
   250  	}
   251  	res := new(bn256.G1)
   252  	res.Add(x, y)
   253  	return res.Marshal(), nil
   254  }
   255  
   256  type bn256AddIstanbul struct{}
   257  
   258  func (c *bn256AddIstanbul) RequiredGas(input []byte) uint64 {
   259  	return params.Bn256AddGasIstanbul
   260  }
   261  
   262  func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) {
   263  	return runBn256Add(input)
   264  }
   265  
   266  type bn256AddByzantium struct{}
   267  
   268  func (c *bn256AddByzantium) RequiredGas(input []byte) uint64 {
   269  	return params.Bn256AddGasByzantium
   270  }
   271  
   272  func (c *bn256AddByzantium) Run(input []byte) ([]byte, error) {
   273  	return runBn256Add(input)
   274  }
   275  
   276  func runBn256ScalarMul(input []byte) ([]byte, error) {
   277  	p, err := newCurvePoint(getData(input, 0, 64))
   278  	if err != nil {
   279  		return nil, err
   280  	}
   281  	res := new(bn256.G1)
   282  	res.ScalarMult(p, new(big.Int).SetBytes(getData(input, 64, 32)))
   283  	return res.Marshal(), nil
   284  }
   285  
   286  type bn256ScalarMulIstanbul struct{}
   287  
   288  func (c *bn256ScalarMulIstanbul) RequiredGas(input []byte) uint64 {
   289  	return params.Bn256ScalarMulGasIstanbul
   290  }
   291  
   292  func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) {
   293  	return runBn256ScalarMul(input)
   294  }
   295  
   296  type bn256ScalarMulByzantium struct{}
   297  
   298  func (c *bn256ScalarMulByzantium) RequiredGas(input []byte) uint64 {
   299  	return params.Bn256ScalarMulGasByzantium
   300  }
   301  
   302  func (c *bn256ScalarMulByzantium) Run(input []byte) ([]byte, error) {
   303  	return runBn256ScalarMul(input)
   304  }
   305  
   306  var (
   307  	true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
   308  
   309  	false32Byte = make([]byte, 32)
   310  
   311  	errBadPairingInput = errors.New("bad elliptic curve pairing size")
   312  )
   313  
   314  func runBn256Pairing(input []byte) ([]byte, error) {
   315  
   316  	if len(input)%192 > 0 {
   317  		return nil, errBadPairingInput
   318  	}
   319  
   320  	var (
   321  		cs []*bn256.G1
   322  		ts []*bn256.G2
   323  	)
   324  	for i := 0; i < len(input); i += 192 {
   325  		c, err := newCurvePoint(input[i : i+64])
   326  		if err != nil {
   327  			return nil, err
   328  		}
   329  		t, err := newTwistPoint(input[i+64 : i+192])
   330  		if err != nil {
   331  			return nil, err
   332  		}
   333  		cs = append(cs, c)
   334  		ts = append(ts, t)
   335  	}
   336  
   337  	if bn256.PairingCheck(cs, ts) {
   338  		return true32Byte, nil
   339  	}
   340  	return false32Byte, nil
   341  }
   342  
   343  type bn256PairingIstanbul struct{}
   344  
   345  func (c *bn256PairingIstanbul) RequiredGas(input []byte) uint64 {
   346  	return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul
   347  }
   348  
   349  func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) {
   350  	return runBn256Pairing(input)
   351  }
   352  
   353  type bn256PairingByzantium struct{}
   354  
   355  func (c *bn256PairingByzantium) RequiredGas(input []byte) uint64 {
   356  	return params.Bn256PairingBaseGasByzantium + uint64(len(input)/192)*params.Bn256PairingPerPointGasByzantium
   357  }
   358  
   359  func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) {
   360  	return runBn256Pairing(input)
   361  }
   362  
   363  type blake2F struct{}
   364  
   365  func (c *blake2F) RequiredGas(input []byte) uint64 {
   366  
   367  	if len(input) != blake2FInputLength {
   368  		return 0
   369  	}
   370  	return uint64(binary.BigEndian.Uint32(input[0:4]))
   371  }
   372  
   373  const (
   374  	blake2FInputLength        = 213
   375  	blake2FFinalBlockBytes    = byte(1)
   376  	blake2FNonFinalBlockBytes = byte(0)
   377  )
   378  
   379  var (
   380  	errBlake2FInvalidInputLength = errors.New("invalid input length")
   381  	errBlake2FInvalidFinalFlag   = errors.New("invalid final flag")
   382  )
   383  
   384  func (c *blake2F) Run(input []byte) ([]byte, error) {
   385  
   386  	if len(input) != blake2FInputLength {
   387  		return nil, errBlake2FInvalidInputLength
   388  	}
   389  	if input[212] != blake2FNonFinalBlockBytes && input[212] != blake2FFinalBlockBytes {
   390  		return nil, errBlake2FInvalidFinalFlag
   391  	}
   392  
   393  	var (
   394  		rounds = binary.BigEndian.Uint32(input[0:4])
   395  		final  = (input[212] == blake2FFinalBlockBytes)
   396  
   397  		h [8]uint64
   398  		m [16]uint64
   399  		t [2]uint64
   400  	)
   401  	for i := 0; i < 8; i++ {
   402  		offset := 4 + i*8
   403  		h[i] = binary.LittleEndian.Uint64(input[offset : offset+8])
   404  	}
   405  	for i := 0; i < 16; i++ {
   406  		offset := 68 + i*8
   407  		m[i] = binary.LittleEndian.Uint64(input[offset : offset+8])
   408  	}
   409  	t[0] = binary.LittleEndian.Uint64(input[196:204])
   410  	t[1] = binary.LittleEndian.Uint64(input[204:212])
   411  
   412  	blake2b.F(&h, m, t, final, rounds)
   413  
   414  	output := make([]byte, 64)
   415  	for i := 0; i < 8; i++ {
   416  		offset := i * 8
   417  		binary.LittleEndian.PutUint64(output[offset:offset+8], h[i])
   418  	}
   419  	return output, nil
   420  }