@@ -30,6 +30,7 @@ import (
30
30
"github.com/scroll-tech/go-ethereum/crypto/bls12381"
31
31
"github.com/scroll-tech/go-ethereum/crypto/bn256"
32
32
"github.com/scroll-tech/go-ethereum/crypto/kzg4844"
33
+ "github.com/scroll-tech/go-ethereum/crypto/secp256r1"
33
34
"github.com/scroll-tech/go-ethereum/params"
34
35
"golang.org/x/crypto/ripemd160"
35
36
)
@@ -126,6 +127,12 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
126
127
common .BytesToAddress ([]byte {18 }): & bls12381MapG2 {},
127
128
}
128
129
130
+ // PrecompiledContractsP256Verify contains the precompiled Ethereum
131
+ // contract specified in EIP-7212/RIP-7212. This is exported for testing purposes.
132
+ var PrecompiledContractsP256Verify = map [common.Address ]PrecompiledContract {
133
+ common .BytesToAddress ([]byte {0x01 , 0x00 }): & p256Verify {},
134
+ }
135
+
129
136
// PrecompiledContractsArchimedes contains the default set of pre-compiled Ethereum
130
137
// contracts used in the Archimedes release. Same as Berlin but without sha2, blake2f, ripemd160
131
138
var PrecompiledContractsArchimedes = map [common.Address ]PrecompiledContract {
@@ -1224,3 +1231,37 @@ func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {
1224
1231
1225
1232
return h
1226
1233
}
1234
+
1235
+ // P256VERIFY (secp256r1 signature verification)
1236
+ // implemented as a native contract
1237
+ type p256Verify struct {}
1238
+
1239
+ // RequiredGas returns the gas required to execute the precompiled contract
1240
+ func (c * p256Verify ) RequiredGas (input []byte ) uint64 {
1241
+ return params .P256VerifyGas
1242
+ }
1243
+
1244
+ // Run executes the precompiled contract with given 160 bytes of param, returning the output and the used gas
1245
+ func (c * p256Verify ) Run (input []byte ) ([]byte , error ) {
1246
+ // Required input length is 160 bytes
1247
+ const p256VerifyInputLength = 160
1248
+ // Check the input length
1249
+ if len (input ) != p256VerifyInputLength {
1250
+ // Input length is invalid
1251
+ return nil , nil
1252
+ }
1253
+
1254
+ // Extract the hash, r, s, x, y from the input
1255
+ hash := input [0 :32 ]
1256
+ r , s := new (big.Int ).SetBytes (input [32 :64 ]), new (big.Int ).SetBytes (input [64 :96 ])
1257
+ x , y := new (big.Int ).SetBytes (input [96 :128 ]), new (big.Int ).SetBytes (input [128 :160 ])
1258
+
1259
+ // Verify the secp256r1 signature
1260
+ if secp256r1 .Verify (hash , r , s , x , y ) {
1261
+ // Signature is valid
1262
+ return common .LeftPadBytes ([]byte {1 }, 32 ), nil
1263
+ } else {
1264
+ // Signature is invalid
1265
+ return nil , nil
1266
+ }
1267
+ }
0 commit comments