EIP-7212: Precompiled for secp256r1 Curve Support

It seems there are other option to achieve the same goal as well. Does anyone know JoyID? Their team have done some hard crypto work and achieved the same results without adding precompiled contract or modifying Ethereum itself. I have been testing it for a few weeks

AFAIK They works on Nervos which has a precompiled for P256 curve.

While I’m very excited of the possibilities r1 may introduce, I oppose adding support on L1 for the following reasons:

The chances of r1 having a backdoor, while as small as they may be, should be taken serious. Ethereum has a responsibility towards its users that should not be waived via arguing r1 is not a protocol level supported curve while being introduced with the goal of increasing onboarding.

I think we should utilize the L2 landscape as playground. Different L2s may set their priorities wrt to security vs onboarding differently. Securing increasing value via r1 increases the incentive to utilize the backdoor for everyone knowing about it. Once r1 secured high value over a long timeframe on (multiple) L2(s), it will be easier to gather support for an L1 support.

In case of a backdoor, the decision whether to remove the support is also highly political, among the obvious of breaking backwards compatibility. When exactly do we deem crypto insecure? Starting at <100 bit (like the still supported alt_bn256 curve), <80?

The inconsistency of the precompile wrt to ecrecover may also lead to many more bugs and more complex code. Furthermore, the proposed precompile does not allow verifying an elliptic curve multiplication like ecrecover (see vitalik’s post). This also makes verifying Schnorr signatures impossible (see this post).

The chances of r1 having a backdoor, while as small as they may be, should be taken serious. Ethereum has a responsibility towards its users that should not be waived via arguing r1 is not a protocol level supported curve while being introduced with the goal of increasing onboarding.

There are billions of devices with hardware P256 support and 0 public attacks demonstrating that P256 is broken, 14 years after Bitcoin chose k1 because of this concern. I fully expect, and welcome, a viable P256 attack to end this silly debate, however, I imagine it will happen roughly the same time k1 is broken due to quantum computing (at which point there will also be a massively political discussion to remove k1 support).

It should also be reinforced that this is for an optional precompile, not a mandated curve change for EOAs.

Several people seem to be arguing that this proposal breaks ecrecover; I agree on this point. This seems like it would need to be solved as Ethereum moves from 1 to n curves regardless (e.g. when we add ed25519). I’m curious to hear from @ulerdogan on this point. I suspect core devs have a proposal on how to resolve (via novel op codes?)

2 Likes

Currently, we are exploring turning to recovery to present a similar interface and provide backward compatibility with the k1 curve applications. Why do you think it breaks ecrecover? If just because of the change in interface, why does it have to follow the same interface?

1 Like

I agree that it doesn’t need to follow the same interface, however, I imagine that any solution here should be interoperable with goals for precompiles for other curves. This would influence whether you create a bespoke ecrecover_r1 vs. some generic variant with an interface that allows for any curve where this would be applicable.

Without seeing the code I’m not quite sure I follow what you are describing as the solution here (a new ecrecover that defaults to k1 and allows for parametrization of the curves and curve format?)

Can you elaborate your question a bit more?

@doganalpaslan sorry, I should have just reviewed the EIP again before commenting. I would echo the other comments made here around wishing there was consistency against the existing ecrecover implementation.

I appreciate concerns around multiplying curves with various distinct interfaces; I think in an ideal world one could choose the desired curve points and format through a generic interface, but that seems unlikely at this point and I wouldn’t hold up this precompile waiting for such an effort.

1 Like

Hello. We implemented a secp256r1 verification and presented it at ethCC Paris.
https://eprint.iacr.org/2023/939

If having an ecrecover version benefits to the probability of adoption, it is trivial to modify the front code that relay the ouput of the authenticator from the ‘classic’ edsa to ‘ecdsa with recovery’ version. It only requires to add the parity of Q. While not of interest in the context of 4337, it would also enable to have a ‘multiplier checking with witness’ from the precompile.

We also advocate for ed25519, but it will require to implement sha512 in the nodes (while secp256r1 implementation only requires sha256). Also current authenticator implements the r1 and not the ed25519.

It could also be considered that if not choosing an ecrecover version, pushing a double scalar multiplication with addition would get rid of the hash function (the overcost of a single opcode being negligible compared to the whole computation), and compatible with zk mechanisms (hash function like sha and keccak are restraining their use). That is why a EC_MULMULADD performing uP+vQ would be superior in this context. (zk implementations like Circom implementation replaces SHA by poseidon in the ecdsa).

4 Likes

Hello everyone.

I implemented P256VERIFY as a precompile inside Revm, which is the EVM implementation used in Reth, the new execution layer by Paradigm.

Here is my branch where you can find it: GitHub - alessandromazza98/revm at eip-7212

Specifically here is the precompile: https://github.com/alessandromazza98/revm/blob/eip-7212/crates/precompile/src/secp256r1.rs

The only difference is the address. The EIP says 0x19 while right now I used 0x0a only because of some assumptions that Revm uses about precompiles being in a crescent order without any wholes in between. But it is super easy to change that address.

I also wrote a little blog article to explain the steps if you are curios: Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.

3 Likes

It’s a great contribution!

Can you elaborate on this more?

Can you explain more why current version wouldn’t support hash functions other than sha and keccak? EIP itself doesn’t have a restriction on which hash to use, so I think it should be possible to use it with, say, Poseidon or other ZK-friendly hashes.

  • If one want to tweak the precompile to compute u.G like in You can *kinda* abuse ECRECOVER to do ECMUL in secp256k1 today - Applications - Ethereum Research, the parity of the point is missing. you only obtain the x coordinates of the result (might be sufficient in many cases)

  • to use the precompile in a userOp, one will have to use it with the target hash function. As it is not strictly ecdsa (you have to sequence it with another call to the hash), why not designing uG+vQ as the precompile, which would have more use than only ECDSA ? Using UG+vQ, one can directly implement Schnorr. In my opinion there are 3 ways:
    ** precompile returns uG+vQ : can be used directly in many protocols (ECDSA, Schnorr)
    ** mimic ecrecover : backward compatibility for use cases using ecrecover on k1 without breaking APIs, can be used to compute uG+vQ, providing the hash as a witness
    ** ecdsa verification from hash (current specification) : only provide the x-value of the result uG+vQ if ‘abused’ not compatible with existing.

1 Like

Would you have the resulting gas cost of a single verification of this implementation pls ?

It should be 26974 units of gas

How is it calculated? It has to be constant for clients following the Final specification.

Sorry, maybe I did not understand properly the previous question.

The P256VERIFY precompile consumes a fixed amount of gas which is specified in the EIP itself, which is 3450

1 Like

I wasn’t clear, my question was about the cost of the REVM resulting gas cost for a verification without precompile.

Concerning the pricing of the precompile, sec256k1 allows fastest verification thanks to the GLV speed up, which is not possible over sec256r1. This speed up cut the cost by 50%. Following this logic the cost of the precompile (and the extra burden on nodes) should be 6000.

I don’t think that it depends on different clients.

My test cases show that p256verify is ~15% slower than ecrecover. Do you think that there is incorrect calculation or method? Maybe we should include comparisons for more clients.

Also, what do you mean by “extra burden”?

The fact that it is only 15% indicates that GLV method is not used in this specific implementation. Asymptotically sec256k1 is twice faster. This means that the precompile cost shall be doubled. This is fact I was describing as a 'burden". Replacing k1 by r1 would lead to more workload on nodes.

The test cases have run in the geth client. As geth is the major client with a huge use, I think that we can consider GLV not dominant or used in Ethereum and ignore the GLV performance boost of the k1.

So, I don’t think that we should change the gas cost.

Since it’s not a replacement for the k1 curve, why do you think that it’s a workload?