Compare commits

...

26 Commits

Author SHA1 Message Date
Ulaş Erdoğan 3826cc69bb
Merge e7ebe92f27 into 5e1a39d67f 2024-11-24 21:54:39 -08:00
Daniel Liu 5e1a39d67f
internal/flags: fix "flag redefined" bug for alias on custom flags (#30796)
This change fixes a bug on the `DirectoryFlag` and the `BigFlag`, which would trigger a `panic` with the message "flag redefined" in case an alias was added to such a flag.
2024-11-24 20:09:38 +01:00
Ulaş Erdoğan e7ebe92f27 Merge branch 'master' into ulerdogan-secp256r1 2024-06-21 12:24:37 +03:00
Danyal Prout 75062a6998 remove redundant x/y check 2024-04-26 03:59:36 +03:00
Danyal Prout 9b0bc8a525 Add missing test cases
(cherry picked from commit 91b12c0741676c33419e56bf098be7e2421fd408)
2024-04-26 03:59:18 +03:00
Ulaş Erdoğan 384dbd6c8b Merge branch 'ulerdogan-secp256r1-test' into ulerdogan-secp256r1 2024-02-08 14:48:48 +03:00
Yukai Tu 520d4f7da9 Add wycheproof test vector
(cherry picked from commit c5ea58073d76c7a0078192cdca627ac0dadbdb68)
2024-02-08 14:46:54 +03:00
Ulaş Erdoğan 827716f0d1
Merge branch 'ethereum:master' into ulerdogan-secp256r1 2024-01-16 17:17:25 +03:00
Ulaş Erdoğan b5a6bb06d4 core/vm: change the implementation address to 0x100 2023-12-21 20:03:00 +03:00
Ulaş Erdoğan b5ad1a799b
Merge branch 'ethereum:master' into ulerdogan-secp256r1 2023-11-30 22:47:32 +03:00
Ulaş Erdoğan 99c44aec7e core/vm: change the implementation address to 0x0b 2023-11-30 22:45:49 +03:00
Ulaş Erdoğan cec0b05811 crypto/secp256r1: remove malleability check due to spec 2023-10-07 16:08:05 +03:00
Ulaş Erdoğan 7e0bc9271b
Merge branch 'master' into ulerdogan-secp256r1 2023-09-24 04:59:03 +03:00
Ulaş Erdoğan 98f10b0d5e crypto/secp256r1: reject the reference pubKey coordinates 2023-09-24 04:54:00 +03:00
Ulaş Erdoğan 21f4932c9b core/vm: force the input length of p256verify 2023-09-24 04:42:41 +03:00
Ulaş Erdoğan 1be1875156 crypto/secp256r1: refactor by simplfying return 2023-08-11 00:36:35 +03:00
Ulaş Erdoğan 2820903f59 core, crypto/secp256r1: fix error reverts tx error 2023-06-23 01:13:27 +03:00
Ulaş Erdoğan f5b6d7e995 core/vm: update the eip number 2023-06-22 15:40:47 +03:00
Ulaş Erdoğan 6bf9e70b68 all: merge branch master into ulerdogan-secp256r1 2023-06-16 02:46:00 +03:00
Ulaş Erdoğan ec17e788ad core/vm: fix testdata non-malleable for p256Verify 2023-05-22 22:39:55 +02:00
Ulaş Erdoğan 066a31f634 crypto/secp25r1: fix reverse malleability issue 2023-05-22 22:38:41 +02:00
Ulaş Erdoğan d245194e77 core/vm: simplify the return values format 2023-05-22 17:57:24 +02:00
Ulaş Erdoğan 6c7028a904 core/vm, params: rename precompiled to p256verify 2023-05-16 18:05:43 +03:00
Ulaş Erdoğan c0554c0764 params: add new precompiled gas price 2023-05-08 04:13:19 +03:00
Ulaş Erdoğan a8c0a2e05c core/vm: implement secp256r1 verifier precompiled 2023-05-08 04:12:57 +03:00
Ulaş Erdoğan fb89b61cdc crypto/secp2561r1: add secp256r1 curve verifiers 2023-05-08 04:11:54 +03:00
7 changed files with 5571 additions and 2 deletions

View File

@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/crypto/blake2b" "github.com/ethereum/go-ethereum/crypto/blake2b"
"github.com/ethereum/go-ethereum/crypto/bn256" "github.com/ethereum/go-ethereum/crypto/bn256"
"github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/crypto/secp256r1"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"golang.org/x/crypto/ripemd160" "golang.org/x/crypto/ripemd160"
) )
@ -139,6 +140,12 @@ var PrecompiledContractsPrague = PrecompiledContracts{
common.BytesToAddress([]byte{0x13}): &bls12381MapG2{}, common.BytesToAddress([]byte{0x13}): &bls12381MapG2{},
} }
// PrecompiledContractsP256Verify contains the precompiled Ethereum
// contract specified in RIP-7212. This is exported for testing purposes.
var PrecompiledContractsP256Verify = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}
var PrecompiledContractsBLS = PrecompiledContractsPrague var PrecompiledContractsBLS = PrecompiledContractsPrague
var PrecompiledContractsVerkle = PrecompiledContractsPrague var PrecompiledContractsVerkle = PrecompiledContractsPrague
@ -1260,3 +1267,37 @@ func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {
return h 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
}
// 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(big1.Bytes(), 32), nil
} else {
// Signature is invalid
return nil, nil
}
}

View File

@ -58,6 +58,8 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{9}): &blake2F{}, common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
common.BytesToAddress([]byte{0x0f, 0x0a}): &bls12381G1Add{}, common.BytesToAddress([]byte{0x0f, 0x0a}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1Mul{}, common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1Mul{},
common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G1MultiExp{}, common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G1MultiExp{},
@ -397,3 +399,15 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
} }
benchmarkPrecompiled("f0f", testcase, b) benchmarkPrecompiled("f0f", 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) }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
package secp256r1
import (
"crypto/ecdsa"
"crypto/elliptic"
"math/big"
)
// Generates appropriate public key format from given coordinates
func newPublicKey(x, y *big.Int) *ecdsa.PublicKey {
// Check if the given coordinates are valid
if x == nil || y == nil || !elliptic.P256().IsOnCurve(x, y) {
return nil
}
return &ecdsa.PublicKey{
Curve: elliptic.P256(),
X: x,
Y: y,
}
}

View File

@ -0,0 +1,22 @@
package secp256r1
import (
"crypto/ecdsa"
"math/big"
)
// Verify verifies the given signature (r, s) for the given hash and public key (x, y).
// It returns true if the signature is valid, false otherwise.
func Verify(hash []byte, r, s, x, y *big.Int) bool {
// Create the public key format
publicKey := newPublicKey(x, y)
// Check if they are invalid public key coordinates
if publicKey == nil {
return false
}
// Verify the signature with the public key,
// then return true if it's valid, false otherwise
return ecdsa.Verify(publicKey, hash, r, s)
}

View File

@ -90,7 +90,7 @@ func (f *DirectoryFlag) Apply(set *flag.FlagSet) error {
} }
} }
eachName(f, func(name string) { eachName(f, func(name string) {
set.Var(&f.Value, f.Name, f.Usage) set.Var(&f.Value, name, f.Usage)
}) })
return nil return nil
} }
@ -172,7 +172,7 @@ func (f *BigFlag) Apply(set *flag.FlagSet) error {
} }
eachName(f, func(name string) { eachName(f, func(name string) {
f.Value = new(big.Int) f.Value = new(big.Int)
set.Var((*bigValue)(f.Value), f.Name, f.Usage) set.Var((*bigValue)(f.Value), name, f.Usage)
}) })
return nil return nil
} }

View File

@ -160,6 +160,8 @@ const (
Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation
Bls12381MapG2Gas uint64 = 75000 // Gas price for BLS12-381 mapping field element to G2 operation Bls12381MapG2Gas uint64 = 75000 // Gas price for BLS12-381 mapping field element to G2 operation
P256VerifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price
// The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529, // The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529,
// up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529 // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529
RefundQuotient uint64 = 2 RefundQuotient uint64 = 2