Skip to content

ACP-204: Precompile for secp256r1 Curve Support#204

Merged
avalanche-foundation-admin merged 2 commits intoavalanche-foundation:mainfrom
scammi:main
Jun 4, 2025
Merged

ACP-204: Precompile for secp256r1 Curve Support#204
avalanche-foundation-admin merged 2 commits intoavalanche-foundation:mainfrom
scammi:main

Conversation

@scammi
Copy link
Copy Markdown
Contributor

@scammi scammi commented May 23, 2025

This ACP proposes implementing a precompiled contract for secp256r1 (P-256) signature verification on Avalanche's C-Chain and L1s/subnets. Modern devices use secp256r1 for secure hardware-based signing (Apple's Secure Enclave, Android Keystore, WebAuthn/Passkeys).

Currently Avalanche only supports secp256k1 natively, forcing expensive on-chain verification. This precompile makes device-native authentication practical for Web3 applications.

@scammi scammi marked this pull request as draft May 23, 2025 15:26
Comment thread ACPs/196-precompile-secp256r1/README.md Outdated
Comment thread ACPs/196-precompile-secp256r1/README.md Outdated
Comment thread ACPs/196-precompile-secp256r1/README.md Outdated

## Motivation

The secp256r1 (P-256) elliptic curve is the standard cryptographic curve used by modern device security systems, including Apple's Secure Enclave, Android Keystore, WebAuthn, and Passkeys. However, Avalanche currently only supports secp256k1 natively, forcing developers to use expensive Solidity-based verification that costs 200k-330k gas per signature verification.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the 200k-330k estimate from?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few smart contract based verifiers implemented, the following posts goes through each of the solutions and display how much each cost.

https://hackmd.io/@1ofB8klpQky-YoR5pmPXFQ/SJ0nuzD1T#Smart-Contract-Based-Verifiers

https://www.alchemy.com/blog/what-is-rip-7212#how-does-rip-7212-compare-to-other-solutions

Comment thread ACPs/196-precompile-secp256r1/README.md Outdated
Comment thread ACPs/196-precompile-secp256r1/README.md Outdated

## Specification

This ACP implements [EIP-7212](https://eips.ethereum.org/EIPS/eip-7212) for secp256r1 signature verification on Avalanche. The specification follows EIP-7212 exactly, with the precompiled contract deployed at address `0x0000000000000000000000000000000000000100`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will need to be a relatively standalone document, not reliant on something that can change in another ecosystem. EIP-7212 has already become RIP-7212 and the contents may change too.

Copy link
Copy Markdown
Contributor Author

@scammi scammi May 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ARR4N we should include the full technical specification directly in the ACP ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. @meaghanfitzgerald knows best though. How much needs to be included in an ACP vs referenced?

Comment thread ACPs/196-precompile-secp256r1/README.md Outdated

### Core Functionality
- **Input**: 160 bytes (message hash + signature components r,s + public key coordinates x,y)
- **Output**: 32 bytes (success: `0x...01`, failure: empty)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Output: 32 bytes

This will be in the returndata buffer, which would typically be copied to memory and not the stack, so I don't think it's necessary to use an entire word as this increases the memory usage of the caller.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree, but it breaks compatibility with other chains' EIP-7212 implementations.

Is this something we care about?

I understand that this should be a standalone document, so optimizing for efficiency makes sense.

Copy link
Copy Markdown
Contributor

@ARR4N ARR4N Jun 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'm in favour of ecosystem compatibility.

Do you know how many chains have implemented RIP-7212? With EIPs we always wait until they're live on Ethereum mainnet because then we know that it's a stable interface. I'd hate to release something, the rest of the ecosystem does something different, and we don't have shared tooling.

That said, we can always create a later ACP to add alternative interfaces if necessary. Same precompile, multiple ways to interact with it.

EDIT: I see that RIP-7212 is marked as final so we can consider the interface stable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rollups are on their way to have this implemented.

Live

Proposed

Regarding Ethereum, I doubt it will soon be added, the community is very conservative when it comes to precompiles, you can go through the magicians forum, has a great discussion about it.

It does seem that the RIP-7212 is in Final status tho.

Comment thread ACPs/196-precompile-secp256r1/README.md Outdated
Comment thread ACPs/196-precompile-secp256r1/README.md Outdated
### Cryptographic Security
- The secp256r1 curve is standardized by NIST and widely vetted
- Security properties are comparable to secp256k1 (used by ECRECOVER)
- Implementation follows NIST FIPS 186-5 specification exactly
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Implementation follows NIST FIPS 186-5 specification exactly

Which implementation does? This one?

Copy link
Copy Markdown
Contributor Author

@scammi scammi May 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and to be accurate, Go's implementation actually follows FIPS 186-3. But the P-256 curve itself is identical across FIPS 186-3, 186-4, and 186-5. The core mathematical parameters, signature verification algorithms, and implementation approach are the same.

I'm specifying we are using the version FIPS 186-3, as that's what the Go implementation uses.

Comment thread ACPs/196-precompile-secp256r1/README.md Outdated

### Implementation Security
- Signature verification (not recovery) approach maximizes compatibility with existing P-256 ecosystem
- No malleability check included to match NIST specification, but wrapper libraries should add this
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? If every wrapper library adds it then every single one needs to be correct, instead of the precompile just being correct.

@yacovm please can you give an opinion?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't check this with secp256k1, as we pass false here, which disables the half order check.

So not checking it means we are consistent across the two curves.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM 👍

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We most definitely enforce that signatures are in the lower order.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, the comment was about the ecrecover precompile. I thought we were referring to transaction signatures when discussing secp256k1.

sgtm.

Comment thread ACPs/196-precompile-secp256r1/README.md Outdated

The implementation will build upon existing work:

1. **EIP-7212 Reference**: The [go-ethereum implementation](https://github.com/ethereum/go-ethereum) of EIP-7212 provides the foundation
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find an implementation anywhere in their repo.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it is. Also, updating the link.

Copy link
Copy Markdown
Contributor

@ARR4N ARR4N Jun 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I see it's from an original here: https://github.com/ethereum/go-ethereum/pull/27540/files

Just noting so I don't later forget where it is.

Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
Comment thread ACPs/204-precompile-secp256r1/README.md
Comment thread ACPs/204-precompile-secp256r1/README.md
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
@scammi scammi changed the title ACP-196: Precompile for secp256r1 Curve Support ACP-204: Precompile for secp256r1 Curve Support May 27, 2025
@scammi scammi requested a review from ARR4N May 30, 2025 18:31
Copy link
Copy Markdown
Contributor

@ARR4N ARR4N left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pending suggestions, LGTM

Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
@scammi scammi marked this pull request as ready for review June 3, 2025 13:51
Comment thread ACPs/204-precompile-secp256r1/README.md Outdated
@avalanche-foundation-admin
Copy link
Copy Markdown
Contributor

This repository requires signed commits. @scammi could you please force-push this branch to only include signed commits? See Signing Commits.

Co-authored-by: Stephen Buttolph <stephen@avalabs.org>
@avalanche-foundation-admin avalanche-foundation-admin merged commit dcc0f97 into avalanche-foundation:main Jun 4, 2025
ARR4N added a commit to ava-labs/libevm that referenced this pull request Jun 10, 2025
## Why this should be merged

Implementation for
[ACP-204](avalanche-foundation/ACPs#204).

## How this works

Implements
[RIP-7212](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md)
and an additional `Pack(hash,r,s,key)` function with
precompile-compatible output.

## How this was tested

Unit tests including fuzzing, test case from the proposed but unmerged
geth implementation, and vectors from [Project
Wycheproof](https://github.com/C2SP/wycheproof).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants