Skip to content

feat(sdk): add solana.Secp256k1Recover - #10

Merged
Mister-Meeseeks merged 1 commit into
CrocSwap:mainfrom
paulbalaji:syscall-secp256k1-recover
Oct 19, 2026
Merged

Mister-Meeseeks merged 1 commit into
CrocSwap:mainfrom
paulbalaji:syscall-secp256k1-recover

Conversation

@paulbalaji

@paulbalaji paulbalaji commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Problem

There's no way to recover a secp256k1 key in SDK 2, and doing it in software isn't viable on CU. Any program that verifies EVM-style ECDSA signatures is blocked. In Hyperlane that's five of eleven programs.

Solution

solana.Secp256k1Recover(c, hash, recoveryID, signature, output) uint64 wraps sol_secp256k1_recover (fogo-v0 by name, solana-v3 hash 0x17e40350) and writes the 64-byte key.

  • Wrong lengths return a new code, 2018, without making the syscall.
  • Runtime codes 2 and 3 pass through and leave output untouched.
  • High-s signatures are accepted, as in the runtime. Callers that need low-s check it themselves.

Tests

  • Native and boundary differentials.
  • Real SBF on both profiles against an independent math/big oracle: both parities, high-s, recovery IDs 4 and 255, zero and out-of-range scalars, wrong lengths.

Linked work

Closes #1, together with #9, #11. If this merges first, #1 should stay open until the rest land. #13 numbers its new code 2020 to avoid this PR's 2018. Used by hyperlane-xyz/hyperlane-monorepo#9852. Refreshes example SDK snapshots; sdk_sha256 conflicts with the other SDK PRs are mechanical.

Secp256k1Recover(c, hash, recoveryID, signature, output) calls the runtime's
sol_secp256k1_recover syscall (by name on fogo-v0, by its static hash
0x17e40350 on solana-v3) and writes the 64-byte uncompressed public key.
Wrong hash, signature or output lengths return the new status 2018 without a
syscall; runtime statuses (2 invalid recovery ID, 3 invalid signature)
propagate unchanged and leave the output untouched. Native contexts supply a
RecoverSecp256k1 callback.

The C adapter lives in secp256k1.c.txt and is emitted only for programs that
call Secp256k1Recover (usesSDK), so every existing program keeps
byte-identical C and ELFs; the pre-Check corpus still matches.

Tests: native bounds/status/copy checks, a native-Go/generated-C boundary
differential, and a real-SBF suite on both profiles that compares recovered
keys and statuses with an independent math/big oracle (valid signatures, the
other parity, high-s, recovery IDs above 3 and 255, zero and out-of-range
scalars, and a wrong-length call). The committed SDK-2 example snapshots are
refreshed for the new API file.
@paulbalaji paulbalaji changed the title Add solana.Secp256k1Recover for SDK 2 feat(sdk): add solana.Secp256k1Recover Oct 19, 2026
@Mister-Meeseeks
Mister-Meeseeks merged commit 5bb6de4 into CrocSwap:main Oct 19, 2026
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.

SDK 2: bind sol_get_return_data, sol_secp256k1_recover and sol_keccak256

2 participants