Implement P256 verification via RIP-7212 precompile with Solidity fallback (#4881)
Co-authored-by: Ernesto García <ernestognw@gmail.com> Co-authored-by: cairo <cairoeth@protonmail.com> Co-authored-by: sudo rm -rf --no-preserve-root / <pcaversaccio@users.noreply.github.com>
This commit is contained in:
@ -8,9 +8,9 @@ Here are some of the more popular ones.
|
||||
|
||||
=== Checking Signatures On-Chain
|
||||
|
||||
At a high level, signatures are a set of cryptographic algorithms that allow for a _signer_ to prove himself owner of a _private key_ used to authorize an piece of information (generally a transaction or `UserOperation`). Natively, the EVM supports the Elliptic Curve Digital Signature Algorithm (https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm[ECDSA]) using the secp256r1 field, however other signature algorithms such as RSA are supported.
|
||||
At a high level, signatures are a set of cryptographic algorithms that allow for a _signer_ to prove himself owner of a _private key_ used to authorize an piece of information (generally a transaction or `UserOperation`). Natively, the EVM supports the Elliptic Curve Digital Signature Algorithm (https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm[ECDSA]) using the secp256k1 curve, however other signature algorithms such as P256 and RSA are supported.
|
||||
|
||||
==== Ethereum Signatures (secp256r1)
|
||||
==== Ethereum Signatures (secp256k1)
|
||||
|
||||
xref:api:utils.adoc#ECDSA[`ECDSA`] provides functions for recovering and managing Ethereum account ECDSA signatures. These are often generated via https://web3js.readthedocs.io/en/v1.7.3/web3-eth.html#sign[`web3.eth.sign`], and are a 65 byte array (of type `bytes` in Solidity) arranged the following way: `[[v (1)], [r (32)], [s (32)]]`.
|
||||
|
||||
@ -30,6 +30,47 @@ function _verify(bytes32 data, bytes memory signature, address account) internal
|
||||
|
||||
WARNING: Getting signature verification right is not trivial: make sure you fully read and understand xref:api:utils.adoc#MessageHashUtils[`MessageHashUtils`]'s and xref:api:utils.adoc#ECDSA[`ECDSA`]'s documentation.
|
||||
|
||||
==== P256 Signatures (secp256r1)
|
||||
|
||||
P256, also known as secp256r1, is one of the most used signature schemes. P256 signatures are standardized by the National Institute of Standards and Technology (NIST) and it's widely available in consumer hardware and software.
|
||||
|
||||
These signatures are different to regular Ethereum Signatures (secp256k1) in that they use a different elliptic curve to perform operations but have similar security guarantees.
|
||||
|
||||
[source,solidity]
|
||||
----
|
||||
using P256 for bytes32;
|
||||
|
||||
function _verify(
|
||||
bytes32 data,
|
||||
bytes32 r,
|
||||
bytes32 s,
|
||||
bytes32 qx,
|
||||
bytes32 qy
|
||||
) internal pure returns (bool) {
|
||||
return data.verify(data, r, s, qx, qy);
|
||||
}
|
||||
----
|
||||
|
||||
By default, the `verify` function will try calling the (https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md)[RIP-7212] precompile at address `0x100` and will fallback to an implementation in Solidity if not available. We encourage you to use `verifyNative` if you know the precompile is available on the chain you're working on and on any other chain on which you intend to use the same bytecode in the future. In case of any doubts regarding the implementation roadmap of the native precompile `P256` of potential future target chains, please consider using `verifySolidity`.
|
||||
|
||||
[source,solidity]
|
||||
----
|
||||
using P256 for bytes32;
|
||||
|
||||
function _verify(
|
||||
bytes32 data,
|
||||
bytes32 r,
|
||||
bytes32 s,
|
||||
bytes32 qx,
|
||||
bytes32 qy
|
||||
) internal pure returns (bool) {
|
||||
// Will only call the precompile at address(0x100)
|
||||
return data.verifyNative(data, r, s, qx, qy);
|
||||
}
|
||||
----
|
||||
|
||||
IMPORTANT: The P256 library only allows for `s` values in the lower order of the curve (i.e. `s <= N/2`) to prevent malleability. In case your tooling produces signatures in both sides of the curve, consider flipping the `s` value to keep compatibility.
|
||||
|
||||
==== RSA
|
||||
|
||||
RSA a public-key cryptosystem that was popularized by corporate and governmental public key infrastructures (https://en.wikipedia.org/wiki/Public_key_infrastructure[PKIs]) and https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions[DNSSEC].
|
||||
|
||||
Reference in New Issue
Block a user