Skip to content

Repository files navigation

solana-secp256k1-program

With the deprecation of native precompiles on Solana (as outlined in SIMD-0568), support for the native KeccakSecp256k11111111111111111111111111111 precompile is being removed.

To support protocols that rely on secp256k1 ECDSA signature verification, this repository provides a configurable BPF-compatible alternative. It is split into two core components:

  1. solana-secp256k1-verify: A fast, stateless, zero-allocation library for in-program verification.
  2. solana-secp256k1-program: A standalone SBF program to verify signatures on-chain.

Migration Guide: Moving Away from Precompiles

If your protocol currently relies on the secp256k1 precompile, you can migrate to use this library and program in one of the following three approaches.

1. In-Program Verification via Library (Recommended)

The most efficient approach is to bundle the verification logic directly into your own program using the solana-secp256k1-verify crate.

The library utilizes a builder pattern to configure the verifier prior to execution. By default, the verifier adheres strictly to Ethereum (EIP-2) standards by enforcing low-s signatures to prevent malleability.

Usage:

use solana_secp256k1_verify::{Secp256k1Verifier, EvmAddress};

// 1. Initialize the stateless verifier with standard EVM defaults
let verifier = Secp256k1Verifier::default();

// 2. Wrap your expected 20-byte Ethereum address
let expected_address = EvmAddress([0xab; 20]);

// 3. Execute the verification pipeline
verifier.verify_signature(
expected_address,
&signature, // &[u8; 64]
recovery_id, // u8 (0, 1, 2, or 3)
&message // &[u8] dynamic message payload
)?;

Note: To support legacy systems that produce high-s signatures, the verifier can be configured to automatically mutate high-s signatures into valid low-s signatures using .auto_normalize_s(). You can also completely disable malleability checks using .allow_high_s().

2. Cross-Program Invocation (CPI)

If you prefer to offload the verification to a separate program, you can invoke solana-secp256k1-program via a Cross-Program Invocation (CPI).

Instruction Data Layout: The program expects a minimum of 85 bytes of instruction data, formatted as follows:

  • [0..20]: The 20-byte Ethereum address.
  • [20..84]: The 64-byte signature.
  • [84]: The 1-byte recovery ID.
  • [85..]: The dynamic message payload.

You can easily construct this instruction using the provided SDK helper:

use solana_secp256k1_program::{verify, ID as SECP256K1_PROGRAM_ID};
use solana_cpi::invoke;

let instruction = verify(
&SECP256K1_PROGRAM_ID,
evm_address, // [u8; 20]
signature, // [u8; 64]
recovery_id, // u8
message, // &[u8]
);

// Submit via CPI
invoke(&instruction, &[])?;

3. Instruction Introspection

Historically, many legacy applications relied on placing the precompile invocation alongside their program's invocation in the transaction, and using the Instructions sysvar to inspect the sibling instruction.

You can replicate this legacy pattern by pushing the solana-secp256k1-program instruction to the transaction instead of the old precompile. Your on-chain program will need to:

  1. Load the Instructions sysvar.
  2. Find the sibling instruction and verify that its program_id matches the new solana-secp256k1-program.
  3. Parse its instruction data according to the layout described in the CPI section ([0..20] for address, [20..84] for signature, etc.).

Performance & Compute Units (CU)

This repository is optimized for ultra-low compute unit consumption by leveraging a stateless, zero-allocation architecture (#![no_std]) and direct native syscall pipelines.

Because the underlying sol_secp256k1_recover syscall consumes a flat physical baseline of 25,000 CUs, this library aims to add as close to zero overhead as possible.

  • Strict EVM (Default) -- ~25,316 CUs: Full Ethereum compliance (Keccak-256, 20-byte address match, Low-S enforced).
  • Bare-Minimum Preset -- ~25,046 CUs: Pre-hashed payload, raw 64-byte pubkey match, and malleability checks bypassed.

For a precise breakdown of how each builder configuration flag affects the compute unit budget (such as allowing high-S signatures or mutating malleability), please see the detailed breakdown in the solana-secp256k1-verify documentation.

About

Solana program for secp256k1 curve operations and signature verification

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages