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