github.com/dominant-strategies/go-quai@v0.28.2/core/vm/contracts.go (about) 1 // Copyright 2014 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 vm 18 19 import ( 20 "crypto/sha256" 21 "encoding/binary" 22 "errors" 23 "math/big" 24 25 "github.com/dominant-strategies/go-quai/common" 26 "github.com/dominant-strategies/go-quai/common/math" 27 "github.com/dominant-strategies/go-quai/crypto" 28 "github.com/dominant-strategies/go-quai/crypto/blake2b" 29 "github.com/dominant-strategies/go-quai/crypto/bn256" 30 "github.com/dominant-strategies/go-quai/params" 31 32 //lint:ignore SA1019 Needed for precompile 33 "golang.org/x/crypto/ripemd160" 34 ) 35 36 // PrecompiledContract is the basic interface for native Go contracts. The implementation 37 // requires a deterministic gas count based on the input size of the Run method of the 38 // contract. 39 type PrecompiledContract interface { 40 RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use 41 Run(input []byte) ([]byte, error) // Run runs the precompiled contract 42 } 43 44 var TranslatedAddresses = map[common.AddressBytes]int{ 45 common.AddressBytes(intToByteArray20(1)): 0, 46 common.AddressBytes(intToByteArray20(2)): 1, 47 common.AddressBytes(intToByteArray20(3)): 2, 48 common.AddressBytes(intToByteArray20(4)): 3, 49 common.AddressBytes(intToByteArray20(5)): 4, 50 common.AddressBytes(intToByteArray20(6)): 5, 51 common.AddressBytes(intToByteArray20(7)): 6, 52 common.AddressBytes(intToByteArray20(8)): 7, 53 common.AddressBytes(intToByteArray20(9)): 8, 54 } 55 56 var ( 57 PrecompiledContracts map[common.AddressBytes]PrecompiledContract = make(map[common.AddressBytes]PrecompiledContract) 58 PrecompiledAddresses map[string][]common.Address = make(map[string][]common.Address) 59 ) 60 61 func InitializePrecompiles() { 62 PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][0].Bytes20()] = &ecrecover{} 63 PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][1].Bytes20()] = &sha256hash{} 64 PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][2].Bytes20()] = &ripemd160hash{} 65 PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][3].Bytes20()] = &dataCopy{} 66 PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][4].Bytes20()] = &bigModExp{} 67 PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][5].Bytes20()] = &bn256Add{} 68 PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][6].Bytes20()] = &bn256ScalarMul{} 69 PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][7].Bytes20()] = &bn256Pairing{} 70 PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][8].Bytes20()] = &blake2F{} 71 } 72 73 func init() { 74 75 PrecompiledAddresses["cyprus1"] = []common.Address{ 76 common.HexToAddress("0x1400000000000000000000000000000000000001"), 77 common.HexToAddress("0x1400000000000000000000000000000000000002"), 78 common.HexToAddress("0x1400000000000000000000000000000000000003"), 79 common.HexToAddress("0x1400000000000000000000000000000000000004"), 80 common.HexToAddress("0x1400000000000000000000000000000000000005"), 81 common.HexToAddress("0x1400000000000000000000000000000000000006"), 82 common.HexToAddress("0x1400000000000000000000000000000000000007"), 83 common.HexToAddress("0x1400000000000000000000000000000000000008"), 84 common.HexToAddress("0x1400000000000000000000000000000000000009"), 85 } 86 PrecompiledAddresses["cyprus2"] = []common.Address{ 87 common.HexToAddress("0x2000000000000000000000000000000000000001"), 88 common.HexToAddress("0x2000000000000000000000000000000000000002"), 89 common.HexToAddress("0x2000000000000000000000000000000000000003"), 90 common.HexToAddress("0x2000000000000000000000000000000000000004"), 91 common.HexToAddress("0x2000000000000000000000000000000000000005"), 92 common.HexToAddress("0x2000000000000000000000000000000000000006"), 93 common.HexToAddress("0x2000000000000000000000000000000000000007"), 94 common.HexToAddress("0x2000000000000000000000000000000000000008"), 95 common.HexToAddress("0x2000000000000000000000000000000000000009"), 96 } 97 PrecompiledAddresses["cyprus3"] = []common.Address{ 98 common.HexToAddress("0x3E00000000000000000000000000000000000001"), 99 common.HexToAddress("0x3E00000000000000000000000000000000000002"), 100 common.HexToAddress("0x3E00000000000000000000000000000000000003"), 101 common.HexToAddress("0x3E00000000000000000000000000000000000004"), 102 common.HexToAddress("0x3E00000000000000000000000000000000000005"), 103 common.HexToAddress("0x3E00000000000000000000000000000000000006"), 104 common.HexToAddress("0x3E00000000000000000000000000000000000007"), 105 common.HexToAddress("0x3E00000000000000000000000000000000000008"), 106 common.HexToAddress("0x3E00000000000000000000000000000000000009"), 107 } 108 PrecompiledAddresses["paxos1"] = []common.Address{ 109 common.HexToAddress("0x5A00000000000000000000000000000000000001"), 110 common.HexToAddress("0x5A00000000000000000000000000000000000002"), 111 common.HexToAddress("0x5A00000000000000000000000000000000000003"), 112 common.HexToAddress("0x5A00000000000000000000000000000000000004"), 113 common.HexToAddress("0x5A00000000000000000000000000000000000005"), 114 common.HexToAddress("0x5A00000000000000000000000000000000000006"), 115 common.HexToAddress("0x5A00000000000000000000000000000000000007"), 116 common.HexToAddress("0x5A00000000000000000000000000000000000008"), 117 common.HexToAddress("0x5A00000000000000000000000000000000000009"), 118 } 119 PrecompiledAddresses["paxos2"] = []common.Address{ 120 common.HexToAddress("0x7800000000000000000000000000000000000001"), 121 common.HexToAddress("0x7800000000000000000000000000000000000002"), 122 common.HexToAddress("0x7800000000000000000000000000000000000003"), 123 common.HexToAddress("0x7800000000000000000000000000000000000004"), 124 common.HexToAddress("0x7800000000000000000000000000000000000005"), 125 common.HexToAddress("0x7800000000000000000000000000000000000006"), 126 common.HexToAddress("0x7800000000000000000000000000000000000007"), 127 common.HexToAddress("0x7800000000000000000000000000000000000008"), 128 common.HexToAddress("0x7800000000000000000000000000000000000009"), 129 } 130 PrecompiledAddresses["paxos3"] = []common.Address{ 131 common.HexToAddress("0x9600000000000000000000000000000000000001"), 132 common.HexToAddress("0x9600000000000000000000000000000000000002"), 133 common.HexToAddress("0x9600000000000000000000000000000000000003"), 134 common.HexToAddress("0x9600000000000000000000000000000000000004"), 135 common.HexToAddress("0x9600000000000000000000000000000000000005"), 136 common.HexToAddress("0x9600000000000000000000000000000000000006"), 137 common.HexToAddress("0x9600000000000000000000000000000000000007"), 138 common.HexToAddress("0x9600000000000000000000000000000000000008"), 139 common.HexToAddress("0x9600000000000000000000000000000000000009"), 140 } 141 PrecompiledAddresses["hydra1"] = []common.Address{ 142 common.HexToAddress("0xB400000000000000000000000000000000000001"), 143 common.HexToAddress("0xB400000000000000000000000000000000000002"), 144 common.HexToAddress("0xB400000000000000000000000000000000000003"), 145 common.HexToAddress("0xB400000000000000000000000000000000000004"), 146 common.HexToAddress("0xB400000000000000000000000000000000000005"), 147 common.HexToAddress("0xB400000000000000000000000000000000000006"), 148 common.HexToAddress("0xB400000000000000000000000000000000000007"), 149 common.HexToAddress("0xB400000000000000000000000000000000000008"), 150 common.HexToAddress("0xB400000000000000000000000000000000000009"), 151 } 152 PrecompiledAddresses["hydra2"] = []common.Address{ 153 common.HexToAddress("0xD200000000000000000000000000000000000001"), 154 common.HexToAddress("0xD200000000000000000000000000000000000002"), 155 common.HexToAddress("0xD200000000000000000000000000000000000003"), 156 common.HexToAddress("0xD200000000000000000000000000000000000004"), 157 common.HexToAddress("0xD200000000000000000000000000000000000005"), 158 common.HexToAddress("0xD200000000000000000000000000000000000006"), 159 common.HexToAddress("0xD200000000000000000000000000000000000007"), 160 common.HexToAddress("0xD200000000000000000000000000000000000008"), 161 common.HexToAddress("0xD200000000000000000000000000000000000009"), 162 } 163 PrecompiledAddresses["hydra3"] = []common.Address{ 164 common.HexToAddress("0xF000000000000000000000000000000000000001"), 165 common.HexToAddress("0xF000000000000000000000000000000000000002"), 166 common.HexToAddress("0xF000000000000000000000000000000000000003"), 167 common.HexToAddress("0xF000000000000000000000000000000000000004"), 168 common.HexToAddress("0xF000000000000000000000000000000000000005"), 169 common.HexToAddress("0xF000000000000000000000000000000000000006"), 170 common.HexToAddress("0xF000000000000000000000000000000000000007"), 171 common.HexToAddress("0xF000000000000000000000000000000000000008"), 172 common.HexToAddress("0xF000000000000000000000000000000000000009"), 173 } 174 } 175 176 // ActivePrecompiles returns the precompiles enabled with the current configuration. 177 func ActivePrecompiles(rules params.Rules) []common.Address { 178 return PrecompiledAddresses[common.NodeLocation.Name()] 179 } 180 181 // RunPrecompiledContract runs and evaluates the output of a precompiled contract. 182 // It returns 183 // - the returned bytes, 184 // - the _remaining_ gas, 185 // - any error that occurred 186 func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64) (ret []byte, remainingGas uint64, err error) { 187 gasCost := p.RequiredGas(input) 188 if suppliedGas < gasCost { 189 return nil, 0, ErrOutOfGas 190 } 191 suppliedGas -= gasCost 192 output, err := p.Run(input) 193 return output, suppliedGas, err 194 } 195 196 // ECRECOVER implemented as a native contract. 197 type ecrecover struct{} 198 199 func (c *ecrecover) RequiredGas(input []byte) uint64 { 200 return params.EcrecoverGas 201 } 202 203 func (c *ecrecover) Run(input []byte) ([]byte, error) { 204 const ecRecoverInputLength = 128 205 206 input = common.RightPadBytes(input, ecRecoverInputLength) 207 // "input" is (hash, v, r, s), each 32 bytes 208 // but for ecrecover we want (r, s, v) 209 210 r := new(big.Int).SetBytes(input[64:96]) 211 s := new(big.Int).SetBytes(input[96:128]) 212 v := input[63] - 27 213 214 // tighter sig s values input only apply to tx sigs 215 if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s) { 216 return nil, nil 217 } 218 // We must make sure not to modify the 'input', so placing the 'v' along with 219 // the signature needs to be done on a new allocation 220 sig := make([]byte, 65) 221 copy(sig, input[64:128]) 222 sig[64] = v 223 // v needs to be at the end for libsecp256k1 224 pubKey, err := crypto.Ecrecover(input[:32], sig) 225 // make sure the public key is a valid one 226 if err != nil { 227 return nil, nil 228 } 229 230 // the first byte of pubkey is bitcoin heritage 231 return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil 232 } 233 234 // SHA256 implemented as a native contract. 235 type sha256hash struct{} 236 237 // RequiredGas returns the gas required to execute the pre-compiled contract. 238 // 239 // This method does not require any overflow checking as the input size gas costs 240 // required for anything significant is so high it's impossible to pay for. 241 func (c *sha256hash) RequiredGas(input []byte) uint64 { 242 return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas 243 } 244 func (c *sha256hash) Run(input []byte) ([]byte, error) { 245 h := sha256.Sum256(input) 246 return h[:], nil 247 } 248 249 // RIPEMD160 implemented as a native contract. 250 type ripemd160hash struct{} 251 252 // RequiredGas returns the gas required to execute the pre-compiled contract. 253 // 254 // This method does not require any overflow checking as the input size gas costs 255 // required for anything significant is so high it's impossible to pay for. 256 func (c *ripemd160hash) RequiredGas(input []byte) uint64 { 257 return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas 258 } 259 func (c *ripemd160hash) Run(input []byte) ([]byte, error) { 260 ripemd := ripemd160.New() 261 ripemd.Write(input) 262 return common.LeftPadBytes(ripemd.Sum(nil), 32), nil 263 } 264 265 // data copy implemented as a native contract. 266 type dataCopy struct{} 267 268 // RequiredGas returns the gas required to execute the pre-compiled contract. 269 // 270 // This method does not require any overflow checking as the input size gas costs 271 // required for anything significant is so high it's impossible to pay for. 272 func (c *dataCopy) RequiredGas(input []byte) uint64 { 273 return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas 274 } 275 func (c *dataCopy) Run(in []byte) ([]byte, error) { 276 return in, nil 277 } 278 279 // bigModExp implements a native big integer exponential modular operation. 280 type bigModExp struct { 281 } 282 283 var ( 284 big0 = big.NewInt(0) 285 big1 = big.NewInt(1) 286 big2 = big.NewInt(2) 287 big3 = big.NewInt(3) 288 big4 = big.NewInt(4) 289 big7 = big.NewInt(7) 290 big8 = big.NewInt(8) 291 big16 = big.NewInt(16) 292 big20 = big.NewInt(20) 293 big32 = big.NewInt(32) 294 big64 = big.NewInt(64) 295 big96 = big.NewInt(96) 296 big480 = big.NewInt(480) 297 big1024 = big.NewInt(1024) 298 big3072 = big.NewInt(3072) 299 big199680 = big.NewInt(199680) 300 ) 301 302 // modexpMultComplexity implements bigModexp multComplexity formula 303 // 304 // def mult_complexity(x): 305 // 306 // if x <= 64: return x ** 2 307 // elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072 308 // else: return x ** 2 // 16 + 480 * x - 199680 309 // 310 // where is x is max(length_of_MODULUS, length_of_BASE) 311 func modexpMultComplexity(x *big.Int) *big.Int { 312 switch { 313 case x.Cmp(big64) <= 0: 314 x.Mul(x, x) // x ** 2 315 case x.Cmp(big1024) <= 0: 316 // (x ** 2 // 4 ) + ( 96 * x - 3072) 317 x = new(big.Int).Add( 318 new(big.Int).Div(new(big.Int).Mul(x, x), big4), 319 new(big.Int).Sub(new(big.Int).Mul(big96, x), big3072), 320 ) 321 default: 322 // (x ** 2 // 16) + (480 * x - 199680) 323 x = new(big.Int).Add( 324 new(big.Int).Div(new(big.Int).Mul(x, x), big16), 325 new(big.Int).Sub(new(big.Int).Mul(big480, x), big199680), 326 ) 327 } 328 return x 329 } 330 331 // RequiredGas returns the gas required to execute the pre-compiled contract. 332 func (c *bigModExp) RequiredGas(input []byte) uint64 { 333 var ( 334 baseLen = new(big.Int).SetBytes(getData(input, 0, 32)) 335 expLen = new(big.Int).SetBytes(getData(input, 32, 32)) 336 modLen = new(big.Int).SetBytes(getData(input, 64, 32)) 337 ) 338 if len(input) > 96 { 339 input = input[96:] 340 } else { 341 input = input[:0] 342 } 343 // Retrieve the head 32 bytes of exp for the adjusted exponent length 344 var expHead *big.Int 345 if big.NewInt(int64(len(input))).Cmp(baseLen) <= 0 { 346 expHead = new(big.Int) 347 } else { 348 if expLen.Cmp(big32) > 0 { 349 expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), 32)) 350 } else { 351 expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), expLen.Uint64())) 352 } 353 } 354 // Calculate the adjusted exponent length 355 var msb int 356 if bitlen := expHead.BitLen(); bitlen > 0 { 357 msb = bitlen - 1 358 } 359 adjExpLen := new(big.Int) 360 if expLen.Cmp(big32) > 0 { 361 adjExpLen.Sub(expLen, big32) 362 adjExpLen.Mul(big8, adjExpLen) 363 } 364 adjExpLen.Add(adjExpLen, big.NewInt(int64(msb))) 365 // Calculate the gas cost of the operation 366 gas := new(big.Int).Set(math.BigMax(modLen, baseLen)) 367 gas = gas.Add(gas, big7) 368 gas = gas.Div(gas, big8) 369 gas.Mul(gas, gas) 370 371 gas.Mul(gas, math.BigMax(adjExpLen, big1)) 372 373 gas.Div(gas, big3) 374 if gas.BitLen() > 64 { 375 return math.MaxUint64 376 } 377 378 if gas.Uint64() < 200 { 379 return 200 380 } 381 return gas.Uint64() 382 } 383 384 func (c *bigModExp) Run(input []byte) ([]byte, error) { 385 var ( 386 baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64() 387 expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64() 388 modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64() 389 ) 390 if len(input) > 96 { 391 input = input[96:] 392 } else { 393 input = input[:0] 394 } 395 // Handle a special case when both the base and mod length is zero 396 if baseLen == 0 && modLen == 0 { 397 return []byte{}, nil 398 } 399 // Retrieve the operands and execute the exponentiation 400 var ( 401 base = new(big.Int).SetBytes(getData(input, 0, baseLen)) 402 exp = new(big.Int).SetBytes(getData(input, baseLen, expLen)) 403 mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen)) 404 ) 405 if mod.BitLen() == 0 { 406 // Modulo 0 is undefined, return zero 407 return common.LeftPadBytes([]byte{}, int(modLen)), nil 408 } 409 return common.LeftPadBytes(base.Exp(base, exp, mod).Bytes(), int(modLen)), nil 410 } 411 412 // newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point, 413 // returning it, or an error if the point is invalid. 414 func newCurvePoint(blob []byte) (*bn256.G1, error) { 415 p := new(bn256.G1) 416 if _, err := p.Unmarshal(blob); err != nil { 417 return nil, err 418 } 419 return p, nil 420 } 421 422 // newTwistPoint unmarshals a binary blob into a bn256 elliptic curve point, 423 // returning it, or an error if the point is invalid. 424 func newTwistPoint(blob []byte) (*bn256.G2, error) { 425 p := new(bn256.G2) 426 if _, err := p.Unmarshal(blob); err != nil { 427 return nil, err 428 } 429 return p, nil 430 } 431 432 // runBn256Add implements the Bn256Add precompile 433 func runBn256Add(input []byte) ([]byte, error) { 434 x, err := newCurvePoint(getData(input, 0, 64)) 435 if err != nil { 436 return nil, err 437 } 438 y, err := newCurvePoint(getData(input, 64, 64)) 439 if err != nil { 440 return nil, err 441 } 442 res := new(bn256.G1) 443 res.Add(x, y) 444 return res.Marshal(), nil 445 } 446 447 // bn256Add implements a native elliptic curve point addition conforming to consensus rules. 448 type bn256Add struct{} 449 450 // RequiredGas returns the gas required to execute the pre-compiled contract. 451 func (c *bn256Add) RequiredGas(input []byte) uint64 { 452 return params.Bn256AddGas 453 } 454 455 func (c *bn256Add) Run(input []byte) ([]byte, error) { 456 return runBn256Add(input) 457 } 458 459 // runBn256ScalarMul implements the Bn256ScalarMul precompile 460 func runBn256ScalarMul(input []byte) ([]byte, error) { 461 p, err := newCurvePoint(getData(input, 0, 64)) 462 if err != nil { 463 return nil, err 464 } 465 res := new(bn256.G1) 466 res.ScalarMult(p, new(big.Int).SetBytes(getData(input, 64, 32))) 467 return res.Marshal(), nil 468 } 469 470 // bn256ScalarMul implements a native elliptic curve scalar 471 // multiplication conforming to consensus rules. 472 type bn256ScalarMul struct{} 473 474 // RequiredGas returns the gas required to execute the pre-compiled contract. 475 func (c *bn256ScalarMul) RequiredGas(input []byte) uint64 { 476 return params.Bn256ScalarMulGas 477 } 478 479 func (c *bn256ScalarMul) Run(input []byte) ([]byte, error) { 480 return runBn256ScalarMul(input) 481 } 482 483 var ( 484 // true32Byte is returned if the bn256 pairing check succeeds. 485 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} 486 487 // false32Byte is returned if the bn256 pairing check fails. 488 false32Byte = make([]byte, 32) 489 490 // errBadPairingInput is returned if the bn256 pairing input is invalid. 491 errBadPairingInput = errors.New("bad elliptic curve pairing size") 492 ) 493 494 // runBn256Pairing implements the Bn256Pairing precompile 495 func runBn256Pairing(input []byte) ([]byte, error) { 496 // Handle some corner cases cheaply 497 if len(input)%192 > 0 { 498 return nil, errBadPairingInput 499 } 500 // Convert the input into a set of coordinates 501 var ( 502 cs []*bn256.G1 503 ts []*bn256.G2 504 ) 505 for i := 0; i < len(input); i += 192 { 506 c, err := newCurvePoint(input[i : i+64]) 507 if err != nil { 508 return nil, err 509 } 510 t, err := newTwistPoint(input[i+64 : i+192]) 511 if err != nil { 512 return nil, err 513 } 514 cs = append(cs, c) 515 ts = append(ts, t) 516 } 517 // Execute the pairing checks and return the results 518 if bn256.PairingCheck(cs, ts) { 519 return true32Byte, nil 520 } 521 return false32Byte, nil 522 } 523 524 // bn256Pairing implements a pairing pre-compile for the bn256 curve 525 // conforming to consensus rules. 526 type bn256Pairing struct{} 527 528 // RequiredGas returns the gas required to execute the pre-compiled contract. 529 func (c *bn256Pairing) RequiredGas(input []byte) uint64 { 530 return params.Bn256PairingBaseGas + uint64(len(input)/192)*params.Bn256PairingPerPointGas 531 } 532 533 func (c *bn256Pairing) Run(input []byte) ([]byte, error) { 534 return runBn256Pairing(input) 535 } 536 537 type blake2F struct{} 538 539 func (c *blake2F) RequiredGas(input []byte) uint64 { 540 // If the input is malformed, we can't calculate the gas, return 0 and let the 541 // actual call choke and fault. 542 if len(input) != blake2FInputLength { 543 return 0 544 } 545 return uint64(binary.BigEndian.Uint32(input[0:4])) 546 } 547 548 const ( 549 blake2FInputLength = 213 550 blake2FFinalBlockBytes = byte(1) 551 blake2FNonFinalBlockBytes = byte(0) 552 ) 553 554 var ( 555 errBlake2FInvalidInputLength = errors.New("invalid input length") 556 errBlake2FInvalidFinalFlag = errors.New("invalid final flag") 557 ) 558 559 func (c *blake2F) Run(input []byte) ([]byte, error) { 560 // Make sure the input is valid (correct length and final flag) 561 if len(input) != blake2FInputLength { 562 return nil, errBlake2FInvalidInputLength 563 } 564 if input[212] != blake2FNonFinalBlockBytes && input[212] != blake2FFinalBlockBytes { 565 return nil, errBlake2FInvalidFinalFlag 566 } 567 // Parse the input into the Blake2b call parameters 568 var ( 569 rounds = binary.BigEndian.Uint32(input[0:4]) 570 final = (input[212] == blake2FFinalBlockBytes) 571 572 h [8]uint64 573 m [16]uint64 574 t [2]uint64 575 ) 576 for i := 0; i < 8; i++ { 577 offset := 4 + i*8 578 h[i] = binary.LittleEndian.Uint64(input[offset : offset+8]) 579 } 580 for i := 0; i < 16; i++ { 581 offset := 68 + i*8 582 m[i] = binary.LittleEndian.Uint64(input[offset : offset+8]) 583 } 584 t[0] = binary.LittleEndian.Uint64(input[196:204]) 585 t[1] = binary.LittleEndian.Uint64(input[204:212]) 586 587 // Execute the compression function, extract and return the result 588 blake2b.F(&h, m, t, final, rounds) 589 590 output := make([]byte, 64) 591 for i := 0; i < 8; i++ { 592 offset := i * 8 593 binary.LittleEndian.PutUint64(output[offset:offset+8], h[i]) 594 } 595 return output, nil 596 } 597 598 func intToByteArray20(n uint8) [20]byte { 599 var byteArray [20]byte 600 byteArray[19] = byte(n) // Use the last byte for the integer 601 return byteArray 602 }