github.com/codingfuture/orig-energi3@v0.8.4/core/vm/contracts.go (about) 1 // Copyright 2018 The Energi Core Authors 2 // Copyright 2014 The go-ethereum Authors 3 // This file is part of the Energi Core library. 4 // 5 // The Energi Core library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The Energi Core library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>. 17 18 package vm 19 20 import ( 21 "crypto/sha256" 22 "errors" 23 "math/big" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/common/math" 27 "github.com/ethereum/go-ethereum/crypto" 28 "github.com/ethereum/go-ethereum/crypto/bn256" 29 "github.com/ethereum/go-ethereum/params" 30 "golang.org/x/crypto/ripemd160" 31 ) 32 33 // PrecompiledContract is the basic interface for native Go contracts. The implementation 34 // requires a deterministic gas count based on the input size of the Run method of the 35 // contract. 36 type PrecompiledContract interface { 37 RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use 38 Run(input []byte) ([]byte, error) // Run runs the precompiled contract 39 } 40 41 // PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum 42 // contracts used in the Frontier and Homestead releases. 43 var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{ 44 common.BytesToAddress([]byte{1}): &ecrecover{}, 45 common.BytesToAddress([]byte{2}): &sha256hash{}, 46 common.BytesToAddress([]byte{3}): &ripemd160hash{}, 47 common.BytesToAddress([]byte{4}): &dataCopy{}, 48 } 49 50 // PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum 51 // contracts used in the Byzantium release. 52 var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{ 53 common.BytesToAddress([]byte{1}): &ecrecover{}, 54 common.BytesToAddress([]byte{2}): &sha256hash{}, 55 common.BytesToAddress([]byte{3}): &ripemd160hash{}, 56 common.BytesToAddress([]byte{4}): &dataCopy{}, 57 common.BytesToAddress([]byte{5}): &bigModExp{}, 58 common.BytesToAddress([]byte{6}): &bn256Add{}, 59 common.BytesToAddress([]byte{7}): &bn256ScalarMul{}, 60 common.BytesToAddress([]byte{8}): &bn256Pairing{}, 61 } 62 63 // RunPrecompiledContract runs and evaluates the output of a precompiled contract. 64 func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error) { 65 gas := p.RequiredGas(input) 66 if contract.UseGas(gas) { 67 return p.Run(input) 68 } 69 return nil, ErrOutOfGas 70 } 71 72 // ECRECOVER implemented as a native contract. 73 type ecrecover struct{} 74 75 func (c *ecrecover) RequiredGas(input []byte) uint64 { 76 // If length is less then it gets padded and falls into BTC mode 77 if len(input) < 64 || input[63] <= 1 { 78 return (params.EcrecoverGas + 79 params.Sha256BaseGas + 80 params.Sha256PerWordGas + 81 params.Ripemd160BaseGas + 82 params.Ripemd160PerWordGas) 83 } 84 return params.EcrecoverGas 85 } 86 87 func (c *ecrecover) Run(input []byte) ([]byte, error) { 88 const ecRecoverInputLength = 128 89 90 input = common.RightPadBytes(input, ecRecoverInputLength) 91 // "input" is (hash, v, r, s), each 32 bytes 92 // but for ecrecover we want (r, s, v) 93 94 r := new(big.Int).SetBytes(input[64:96]) 95 s := new(big.Int).SetBytes(input[96:128]) 96 v := input[63] 97 is_btc := v <= 1 98 is_eth := v == 27 || v == 28 99 100 if is_eth { 101 v -= 27 102 } 103 104 // tighter sig s values input homestead only apply to tx sigs 105 if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) { 106 return nil, nil 107 } 108 // v needs to be at the end for libsecp256k1 109 pubKey, err := crypto.Ecrecover(input[:32], append(input[64:128], v)) 110 // make sure the public key is a valid one 111 if err != nil { 112 return nil, nil 113 } 114 115 if is_btc { 116 pubKey_obj, err := crypto.UnmarshalPubkey(pubKey) 117 if err != nil { 118 return nil, nil 119 } 120 121 basehash := sha256.Sum256(crypto.CompressPubkey(pubKey_obj)) 122 ripemd := ripemd160.New() 123 ripemd.Write(basehash[:]) 124 return common.LeftPadBytes(ripemd.Sum(nil), 32), nil 125 } 126 127 // the first byte of pubkey is bitcoin heritage 128 return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil 129 } 130 131 // SHA256 implemented as a native contract. 132 type sha256hash struct{} 133 134 // RequiredGas returns the gas required to execute the pre-compiled contract. 135 // 136 // This method does not require any overflow checking as the input size gas costs 137 // required for anything significant is so high it's impossible to pay for. 138 func (c *sha256hash) RequiredGas(input []byte) uint64 { 139 return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas 140 } 141 func (c *sha256hash) Run(input []byte) ([]byte, error) { 142 h := sha256.Sum256(input) 143 return h[:], nil 144 } 145 146 // RIPEMD160 implemented as a native contract. 147 type ripemd160hash struct{} 148 149 // RequiredGas returns the gas required to execute the pre-compiled contract. 150 // 151 // This method does not require any overflow checking as the input size gas costs 152 // required for anything significant is so high it's impossible to pay for. 153 func (c *ripemd160hash) RequiredGas(input []byte) uint64 { 154 return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas 155 } 156 func (c *ripemd160hash) Run(input []byte) ([]byte, error) { 157 ripemd := ripemd160.New() 158 ripemd.Write(input) 159 return common.LeftPadBytes(ripemd.Sum(nil), 32), nil 160 } 161 162 // data copy implemented as a native contract. 163 type dataCopy struct{} 164 165 // RequiredGas returns the gas required to execute the pre-compiled contract. 166 // 167 // This method does not require any overflow checking as the input size gas costs 168 // required for anything significant is so high it's impossible to pay for. 169 func (c *dataCopy) RequiredGas(input []byte) uint64 { 170 return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas 171 } 172 func (c *dataCopy) Run(in []byte) ([]byte, error) { 173 return in, nil 174 } 175 176 // bigModExp implements a native big integer exponential modular operation. 177 type bigModExp struct{} 178 179 var ( 180 big1 = big.NewInt(1) 181 big4 = big.NewInt(4) 182 big8 = big.NewInt(8) 183 big16 = big.NewInt(16) 184 big32 = big.NewInt(32) 185 big64 = big.NewInt(64) 186 big96 = big.NewInt(96) 187 big480 = big.NewInt(480) 188 big1024 = big.NewInt(1024) 189 big3072 = big.NewInt(3072) 190 big199680 = big.NewInt(199680) 191 ) 192 193 // RequiredGas returns the gas required to execute the pre-compiled contract. 194 func (c *bigModExp) RequiredGas(input []byte) uint64 { 195 var ( 196 baseLen = new(big.Int).SetBytes(getData(input, 0, 32)) 197 expLen = new(big.Int).SetBytes(getData(input, 32, 32)) 198 modLen = new(big.Int).SetBytes(getData(input, 64, 32)) 199 ) 200 if len(input) > 96 { 201 input = input[96:] 202 } else { 203 input = input[:0] 204 } 205 // Retrieve the head 32 bytes of exp for the adjusted exponent length 206 var expHead *big.Int 207 if big.NewInt(int64(len(input))).Cmp(baseLen) <= 0 { 208 expHead = new(big.Int) 209 } else { 210 if expLen.Cmp(big32) > 0 { 211 expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), 32)) 212 } else { 213 expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), expLen.Uint64())) 214 } 215 } 216 // Calculate the adjusted exponent length 217 var msb int 218 if bitlen := expHead.BitLen(); bitlen > 0 { 219 msb = bitlen - 1 220 } 221 adjExpLen := new(big.Int) 222 if expLen.Cmp(big32) > 0 { 223 adjExpLen.Sub(expLen, big32) 224 adjExpLen.Mul(big8, adjExpLen) 225 } 226 adjExpLen.Add(adjExpLen, big.NewInt(int64(msb))) 227 228 // Calculate the gas cost of the operation 229 gas := new(big.Int).Set(math.BigMax(modLen, baseLen)) 230 switch { 231 case gas.Cmp(big64) <= 0: 232 gas.Mul(gas, gas) 233 case gas.Cmp(big1024) <= 0: 234 gas = new(big.Int).Add( 235 new(big.Int).Div(new(big.Int).Mul(gas, gas), big4), 236 new(big.Int).Sub(new(big.Int).Mul(big96, gas), big3072), 237 ) 238 default: 239 gas = new(big.Int).Add( 240 new(big.Int).Div(new(big.Int).Mul(gas, gas), big16), 241 new(big.Int).Sub(new(big.Int).Mul(big480, gas), big199680), 242 ) 243 } 244 gas.Mul(gas, math.BigMax(adjExpLen, big1)) 245 gas.Div(gas, new(big.Int).SetUint64(params.ModExpQuadCoeffDiv)) 246 247 if gas.BitLen() > 64 { 248 return math.MaxUint64 249 } 250 return gas.Uint64() 251 } 252 253 func (c *bigModExp) Run(input []byte) ([]byte, error) { 254 var ( 255 baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64() 256 expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64() 257 modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64() 258 ) 259 if len(input) > 96 { 260 input = input[96:] 261 } else { 262 input = input[:0] 263 } 264 // Handle a special case when both the base and mod length is zero 265 if baseLen == 0 && modLen == 0 { 266 return []byte{}, nil 267 } 268 // Retrieve the operands and execute the exponentiation 269 var ( 270 base = new(big.Int).SetBytes(getData(input, 0, baseLen)) 271 exp = new(big.Int).SetBytes(getData(input, baseLen, expLen)) 272 mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen)) 273 ) 274 if mod.BitLen() == 0 { 275 // Modulo 0 is undefined, return zero 276 return common.LeftPadBytes([]byte{}, int(modLen)), nil 277 } 278 return common.LeftPadBytes(base.Exp(base, exp, mod).Bytes(), int(modLen)), nil 279 } 280 281 // newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point, 282 // returning it, or an error if the point is invalid. 283 func newCurvePoint(blob []byte) (*bn256.G1, error) { 284 p := new(bn256.G1) 285 if _, err := p.Unmarshal(blob); err != nil { 286 return nil, err 287 } 288 return p, nil 289 } 290 291 // newTwistPoint unmarshals a binary blob into a bn256 elliptic curve point, 292 // returning it, or an error if the point is invalid. 293 func newTwistPoint(blob []byte) (*bn256.G2, error) { 294 p := new(bn256.G2) 295 if _, err := p.Unmarshal(blob); err != nil { 296 return nil, err 297 } 298 return p, nil 299 } 300 301 // bn256Add implements a native elliptic curve point addition. 302 type bn256Add struct{} 303 304 // RequiredGas returns the gas required to execute the pre-compiled contract. 305 func (c *bn256Add) RequiredGas(input []byte) uint64 { 306 return params.Bn256AddGas 307 } 308 309 func (c *bn256Add) Run(input []byte) ([]byte, error) { 310 x, err := newCurvePoint(getData(input, 0, 64)) 311 if err != nil { 312 return nil, err 313 } 314 y, err := newCurvePoint(getData(input, 64, 64)) 315 if err != nil { 316 return nil, err 317 } 318 res := new(bn256.G1) 319 res.Add(x, y) 320 return res.Marshal(), nil 321 } 322 323 // bn256ScalarMul implements a native elliptic curve scalar multiplication. 324 type bn256ScalarMul struct{} 325 326 // RequiredGas returns the gas required to execute the pre-compiled contract. 327 func (c *bn256ScalarMul) RequiredGas(input []byte) uint64 { 328 return params.Bn256ScalarMulGas 329 } 330 331 func (c *bn256ScalarMul) Run(input []byte) ([]byte, error) { 332 p, err := newCurvePoint(getData(input, 0, 64)) 333 if err != nil { 334 return nil, err 335 } 336 res := new(bn256.G1) 337 res.ScalarMult(p, new(big.Int).SetBytes(getData(input, 64, 32))) 338 return res.Marshal(), nil 339 } 340 341 var ( 342 // true32Byte is returned if the bn256 pairing check succeeds. 343 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} 344 345 // false32Byte is returned if the bn256 pairing check fails. 346 false32Byte = make([]byte, 32) 347 348 // errBadPairingInput is returned if the bn256 pairing input is invalid. 349 errBadPairingInput = errors.New("bad elliptic curve pairing size") 350 ) 351 352 // bn256Pairing implements a pairing pre-compile for the bn256 curve 353 type bn256Pairing struct{} 354 355 // RequiredGas returns the gas required to execute the pre-compiled contract. 356 func (c *bn256Pairing) RequiredGas(input []byte) uint64 { 357 return params.Bn256PairingBaseGas + uint64(len(input)/192)*params.Bn256PairingPerPointGas 358 } 359 360 func (c *bn256Pairing) Run(input []byte) ([]byte, error) { 361 // Handle some corner cases cheaply 362 if len(input)%192 > 0 { 363 return nil, errBadPairingInput 364 } 365 // Convert the input into a set of coordinates 366 var ( 367 cs []*bn256.G1 368 ts []*bn256.G2 369 ) 370 for i := 0; i < len(input); i += 192 { 371 c, err := newCurvePoint(input[i : i+64]) 372 if err != nil { 373 return nil, err 374 } 375 t, err := newTwistPoint(input[i+64 : i+192]) 376 if err != nil { 377 return nil, err 378 } 379 cs = append(cs, c) 380 ts = append(ts, t) 381 } 382 // Execute the pairing checks and return the results 383 if bn256.PairingCheck(cs, ts) { 384 return true32Byte, nil 385 } 386 return false32Byte, nil 387 }