EIP-7212: Precompiled for secp256r1 Curve Support

As an RIP, the proposal has not been planned for the Ethereum mainnet yet. It can be considered in the future.

Integration Update

With the Napoli Hard Fork in the Polygon PoS Chain, RIP-7212 is active on the mainnet. Congrats to the team for being the first to implement an RIP on the mainnet.

Announcement Tweet

1 Like

Do you guys have a code snippet on how to implement it onchain in Solidity? Thank you

Fastest implementation is here

Actually i’m still working on it and will push a version around 160K in April which will go to an audit.

You can easily adapt this script to bench extra libraries ONCHAIN (this one demonstrate benching of daimo and FCL). (it is easy to forgot to configure toml effectively, or cancel stack optimization).

Thanks for sharing additional resources @rdubois-crypto!

Also, sharing basic wrapper contract to call the precompile contract.

Function here
    /**
     * @notice Calls the verifier function with given params
     * @param verifier address     - Address of the verifier contract
     * @param hash bytes32         - Signed data hash
     * @param rs bytes32[2]        - Signature array for the r and s values
     * @param pubKey bytes32[2]    - Public key coordinates array for the x and y values
     * @return - bool - Return the success of the verification
     */
    function callVerifier(
        address verifier,
        bytes32 hash,
        bytes32[2] memory rs,
        bytes32[2] memory pubKey
    ) internal view returns (bool) {
        /**
         * Prepare the input format
         * input[  0: 32] = signed data hash
         * input[ 32: 64] = signature r
         * input[ 64: 96] = signature s
         * input[ 96:128] = public key x
         * input[128:160] = public key y
         */
        bytes memory input = abi.encodePacked(hash, rs[0], rs[1], pubKey[0], pubKey[1]);

        // Make a call to verify the signature
        (bool success, bytes memory data) = verifier.staticcall(input);

        uint256 returnValue;
        // Return true if the call was successful and the return value is 1
        if (success && data.length > 0) {
            assembly {
                returnValue := mload(add(data, 0x20))
            }
            return returnValue == 1;
        }

        // Otherwise return false for the unsucessful calls and invalid signatures
        return false;
    }
1 Like

Check out the interesting conversation with @ulerdogan on the present Signature scheme, special Elliptic Curves & a deep dive inside EOA while providing the overview of RIP7212 on PEEPanEIP

1 Like

Hi ulerdogan
I’m a developer from BSC.
BSC is part of the EVM ecosystem, and the client is based on a fork of go-ethereum, and will continue to provide feedback on any bugs found.
I hope when setting these EIPs, we can consider BSC: the BSC precompile addresses 0x100~0x105 are already in use,
Can the RIP-related precompile addresses use a different address range? For example, starting from 0x1000.

The RIP is already deployed on several L2s.

See Polygon: PIP-27: Precompiled for secp256r1 Curve Support - #7 by ulerdogan - Canonical PIPs - Polygon Community Forum
See Arbitrum: AIP: Support RIP-7212 for Account Abstraction Wallets - #13 by cliffton.eth - Proposals - Arbitrum
See zkSync: zkSync Protocol Upgrade v24: New precompiles, more blobs, Validiums, and more. · zkSync-Community-Hub/zksync-developers · Discussion #519 · GitHub

I don’t think it’s reasonable to change it now and disrupt all the code that was deployed to take advantage of this new EIP and prove its utility for next Ethereum upgrade.

Furthermore, that reserved RIP range is to enshrine a range for experimentation for L2s so it’s fine for EVM forks to also use this knowing Ethereum L1s changes won’t reuse that range. See also: RollCall Breakout #3: Precompiles and the RIP Process

2 Likes

@mratsim thanks for the explanations!

Hi @NathanBSC, isn’t 0x1000 range also blocked by these? Also, I couldn’t find what blocks the 0x100 range. In case of misunderstanding: 0x1000x0000000000000000000000000000000000000100

A couple of questions regarding the P256 Verifier precompile.

  • There was some discussion about adding a progressive precompile from Daimo where their precompile address was 0xc2b78104907F722DABAc4C69f826a522B2754De4 but the deployment of precompile was at address 0x100. And similarly the FreshCryptoLib’s implementation address was 0xE9399D1183a5cf9E14B120875A616b6E2bcB840a. So, If I am building something using Daimo or FreshCryptoLib implementation, I will to create a wrapper that fallbacks to 0x100 address, right?

  • @rdubois-crypto does the current state of FreshCryptoLib implementation use the 0x100 address? Also, when are you expecting a complete audited implementation?

  • If I want to directly call the precompile from solidity, I will have to do address(100).staticcall({params}) or is there any wrapper like ecrecover?

Answer to first question is “yes”. (Solving third ?).

Considering the second question :

FCL is not gonna be audited, but has been scrutinized by Base cryptographer’s team. We believe that 7212 is amazing at the current moment, but we also believe that it is too limited to introduce only one curve, while a generic precompile can be introduced for (quasi) no extra cost, leading to several use cases:

Using RIP7696 you can emulate P256, Ed25519, starkcurve, babyjujub, palla, vesta, …

We are now pushing 7696, which can emulate 7212 as a specific case.

  • As a progressive compile in solidity for a lower cost (160K) than FCL(200K) or Daimo (330K).
    You will find an example of all wychproof vectors assessment here:
    crypto-lib/test/libSCL_ecdsa.t.sol at audit-cryptoexperts · get-smooth/crypto-lib · GitHub

  • As a circuit/node implementation: Optimizations are independant of the language (just pure algorithmic), so it is transposable to any circuit/node implementation (of course it requires some work). We are working with a L2 on a tradeoff rn.

RIP7696 solidity implementation is going through 2 independant audits. The first is running right now, ending end of June, before a second one starting 1st July.