mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
core: add ed25519 signature verification precompile
This commit is contained in:
parent
50dbe8e244
commit
9e2cbb9b6e
3 changed files with 45 additions and 0 deletions
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/bn256"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
|
|
@ -59,6 +60,20 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
|
|||
common.BytesToAddress([]byte{8}): &bn256Pairing{},
|
||||
}
|
||||
|
||||
// PrecompiledContractsConstantinople contains the default set of pre-compiled Ethereum
|
||||
// contracts used in the Constantinople release.
|
||||
var PrecompiledContractsConstantinople = map[common.Address]PrecompiledContract{
|
||||
common.BytesToAddress([]byte{1}): &ecrecover{},
|
||||
common.BytesToAddress([]byte{2}): &sha256hash{},
|
||||
common.BytesToAddress([]byte{3}): &ripemd160hash{},
|
||||
common.BytesToAddress([]byte{4}): &dataCopy{},
|
||||
common.BytesToAddress([]byte{5}): &bigModExp{},
|
||||
common.BytesToAddress([]byte{6}): &bn256Add{},
|
||||
common.BytesToAddress([]byte{7}): &bn256ScalarMul{},
|
||||
common.BytesToAddress([]byte{8}): &bn256Pairing{},
|
||||
common.BytesToAddress([]byte{9}): &ed25519Verify{},
|
||||
}
|
||||
|
||||
// RunPrecompiledContract runs and evaluates the output of a precompiled contract.
|
||||
func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error) {
|
||||
gas := p.RequiredGas(input)
|
||||
|
|
@ -358,3 +373,26 @@ func (c *bn256Pairing) Run(input []byte) ([]byte, error) {
|
|||
}
|
||||
return false32Byte, nil
|
||||
}
|
||||
|
||||
// ed25519Verify implements a native Ed25519 signature verification.
|
||||
type ed25519Verify struct{}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *ed25519Verify) RequiredGas(input []byte) uint64 {
|
||||
return params.Ed25519VerifyGas
|
||||
}
|
||||
|
||||
func (c *ed25519Verify) Run(input []byte) ([]byte, error) {
|
||||
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-665.md#specification
|
||||
message := getData(input, 0, 32)
|
||||
publicKey := getData(input, 32, 32)
|
||||
sig := getData(input, 64, 64)
|
||||
|
||||
// Verify the Ed25519 signature against the public key and message
|
||||
// and return result
|
||||
// https://godoc.org/golang.org/x/crypto/ed25519#Verify
|
||||
if ed25519.Verify(publicKey, message, sig) {
|
||||
return true32Byte, nil
|
||||
}
|
||||
return false32Byte, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ func run(evm *EVM, contract *Contract, input []byte) ([]byte, error) {
|
|||
if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
|
||||
precompiles = PrecompiledContractsByzantium
|
||||
}
|
||||
if evm.ChainConfig().IsConstantinople(evm.BlockNumber) {
|
||||
precompiles = PrecompiledContractsConstantinople
|
||||
}
|
||||
if p := precompiles[*contract.CodeAddr]; p != nil {
|
||||
return RunPrecompiledContract(p, input, contract)
|
||||
}
|
||||
|
|
@ -159,6 +162,9 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
|
||||
precompiles = PrecompiledContractsByzantium
|
||||
}
|
||||
if evm.ChainConfig().IsConstantinople(evm.BlockNumber) {
|
||||
precompiles = PrecompiledContractsConstantinople
|
||||
}
|
||||
if precompiles[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 {
|
||||
return nil, gas, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ const (
|
|||
Bn256ScalarMulGas uint64 = 40000 // Gas needed for an elliptic curve scalar multiplication
|
||||
Bn256PairingBaseGas uint64 = 100000 // Base price for an elliptic curve pairing check
|
||||
Bn256PairingPerPointGas uint64 = 80000 // Per-point price for an elliptic curve pairing check
|
||||
Ed25519VerifyGas uint64 = 2000 // Ed25519 signature verification gas price
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
Loading…
Reference in a new issue