Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f3d127d
crypto/secp2561r1: add secp256r1 curve verifiers
ulerdogan May 8, 2023
a285071
core/vm: implement secp256r1 verifier precompiled
ulerdogan May 8, 2023
6fe3894
params: add new precompiled gas price
ulerdogan May 8, 2023
4c7625e
core/vm, params: rename precompiled to p256verify
ulerdogan May 16, 2023
87be74c
core/vm: simplify the return values format
ulerdogan May 22, 2023
1609c74
crypto/secp25r1: fix reverse malleability issue
ulerdogan May 22, 2023
b0f362e
core/vm: fix testdata non-malleable for p256Verify
ulerdogan May 22, 2023
6657f97
core/vm: update the eip number
ulerdogan Jun 22, 2023
f102856
core, crypto/secp256r1: fix error reverts tx error
ulerdogan Jun 22, 2023
4b7e559
crypto/secp256r1: refactor by simplfying return
ulerdogan Aug 10, 2023
b54ce6c
core/vm: force the input length of p256verify
ulerdogan Sep 24, 2023
4d66067
crypto/secp256r1: reject the reference pubKey coordinates
ulerdogan Sep 24, 2023
54df5c3
crypto/secp256r1: remove malleability check due to spec
ulerdogan Oct 7, 2023
fcacd79
core/vm: change the implementation address to 0x0b
ulerdogan Nov 30, 2023
0b781d9
core/vm: change the implementation address to 0x100
ulerdogan Dec 21, 2023
2333447
Enable on fjord
Jan 3, 2024
929581a
Add wycheproof test vector
yukaitu-cb Feb 8, 2024
6503f50
fix intent
yukaitu-cb Feb 8, 2024
91b12c0
Add missing test cases
danyalprout Apr 22, 2024
1d63923
change from constant to literal
danyalprout Apr 22, 2024
1aa4e22
remove redundant x/y check
danyalprout Apr 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/crypto/bls12381"
"github.com/ethereum/go-ethereum/crypto/bn256"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/crypto/secp256r1"
"github.com/ethereum/go-ethereum/params"
"golang.org/x/crypto/ripemd160"
)
Expand Down Expand Up @@ -107,6 +108,22 @@ var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
}

// PrecompiledContractsFjord contains the default set of pre-compiled Ethereum
// contracts used in the Fjord release.
var PrecompiledContractsFjord = 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{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
Comment thread
sebastianst marked this conversation as resolved.
}

// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
// contracts specified in EIP-2537. These are exported for testing purposes.
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
Expand All @@ -122,6 +139,7 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
}

var (
PrecompiledAddressesFjord []common.Address
PrecompiledAddressesCancun []common.Address
PrecompiledAddressesBerlin []common.Address
PrecompiledAddressesIstanbul []common.Address
Expand All @@ -145,11 +163,16 @@ func init() {
for k := range PrecompiledContractsCancun {
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
}
for k := range PrecompiledContractsFjord {
PrecompiledAddressesFjord = append(PrecompiledAddressesFjord, k)
}
}

// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) []common.Address {
switch {
case rules.IsOptimismFjord:
return PrecompiledAddressesFjord
case rules.IsCancun:
return PrecompiledAddressesCancun
case rules.IsBerlin:
Expand Down Expand Up @@ -1134,3 +1157,37 @@ func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {

return h
}

// P256VERIFY (secp256r1 signature verification)
// implemented as a native contract
type p256Verify struct{}

// RequiredGas returns the gas required to execute the precompiled contract
func (c *p256Verify) RequiredGas(input []byte) uint64 {
return params.P256VerifyGas
}

// Run executes the precompiled contract with given 160 bytes of param, returning the output and the used gas
func (c *p256Verify) Run(input []byte) ([]byte, error) {
// Required input length is 160 bytes
const p256VerifyInputLength = 160
// Check the input length
if len(input) != p256VerifyInputLength {
// Input length is invalid
return nil, nil
Comment thread
sebastianst marked this conversation as resolved.
}

// Extract the hash, r, s, x, y from the input
hash := input[0:32]
r, s := new(big.Int).SetBytes(input[32:64]), new(big.Int).SetBytes(input[64:96])
x, y := new(big.Int).SetBytes(input[96:128]), new(big.Int).SetBytes(input[128:160])

// Verify the secp256r1 signature
if secp256r1.Verify(hash, r, s, x, y) {
// Signature is valid
return common.LeftPadBytes([]byte{1}, 32), nil
} else {
// Signature is invalid
return nil, nil
Comment thread
sebastianst marked this conversation as resolved.
}
}
14 changes: 14 additions & 0 deletions core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},

common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},

common.BytesToAddress([]byte{0x0f, 0x0a}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1Mul{},
common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G1MultiExp{},
Expand Down Expand Up @@ -395,3 +397,15 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
}
benchmarkPrecompiled("0f", testcase, b)
}

// Benchmarks the sample inputs from the P256VERIFY precompile.
func BenchmarkPrecompiledP256Verify(bench *testing.B) {
t := precompiledTest{
Input: "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e",
Expected: "0000000000000000000000000000000000000000000000000000000000000001",
Name: "p256Verify",
}
benchmarkPrecompiled("100", t, bench)
}

func TestPrecompiledP256Verify(t *testing.T) { testJson("p256Verify", "100", t) }
2 changes: 2 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ type (
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
var precompiles map[common.Address]PrecompiledContract
switch {
case evm.chainRules.IsOptimismFjord:
precompiles = PrecompiledContractsFjord
case evm.chainRules.IsCancun:
precompiles = PrecompiledContractsCancun
case evm.chainRules.IsBerlin:
Expand Down
Loading