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 }