Skip to content

[runtime]: bind SP1 BEEFY proofs to a committed nonce for anti-theft #924

Merged
seunlanlege merged 9 commits into
mainfrom
seun/dedupe-proofs
May 27, 2026
Merged

[runtime]: bind SP1 BEEFY proofs to a committed nonce for anti-theft #924
seunlanlege merged 9 commits into
mainfrom
seun/dedupe-proofs

Conversation

@seunlanlege
Copy link
Copy Markdown
Member

Closes #923. Depends on polytope-labs/sp1-beefy#15 (released as v1.1.0).

Summary

Binds every SP1 BEEFY proof to a prover-chosen nonce committed into its public values, and makes pallet-beefy-consensus-proofs require that nonce to equal the submit_proof signer. This:

  • Stops proof theft. Proof bytes sit in the public mempool; previously anyone could copy them and submit under their own account. Now a copied proof still verifies cryptographically but is rejected (UnauthorizedProof) because the committed account ≠ the signer, and the committed account can't be changed without re-running the SP1 proof.
  • Fixes uncle dedup. The old dedup keyed on keccak256(proof) and assumed Groth16 re-randomization ⇒ distinct provers — unsound, since one prover can mint unlimited distinct-byte proofs for the same public values and sweep the whole RewardCurve. Dedup now keys on the committed submission account (AcceptedProvers), so an account is rewarded at most once per height regardless of how many proof variants it produces.

Changes

Protocol / SP1 (sp1-beefy#15, v1.1.0): BeefyCommitment/PublicInputs gain a nonce: H256 committed verbatim by the program. New vkey: 0x007d1720c695842ed647a1a72e981751f9b5e26fc5ca038523b23430a1292f08.

EVM: nonce added to SP1BeefyProof/PublicInputs in Types.sol, reconstructed in SP1Beefy.sol; ABI regenerated.

Rust: nonce added to beefy_verifier_primitives::Sp1BeefyProof, the verifier's reconstructed PublicInputs, and conversions.rs. ismp-beefy is unchanged — it decodes the shared Sp1BeefyProof and stays nonce-agnostic (binding/dedup is the pallet's job).

Pallet (pallet-beefy-consensus-proofs): enforce committed nonce == ensure_signed(origin) on first-proof and uncle paths; dedup on account (AcceptedProofHashesAcceptedProvers); drop the old keccak/canonical re-encoding dance. Storage v1 → v2 with a ClearAcceptedProofHashes migration (wired into gargantua + nexus).

Relayer (zk-beefy): commits the submission signer (SubstrateClient::address) as the nonce; dep bumped to sp1-beefy v1.1.0.

Verification

Fixture regenerated against mainnet (committing Bob's account as the nonce); both verifiers confirmed against it:

  • ✅ Solidity SP1BeefyTest::testVerifySp1Beefy
  • ✅ Rust beefy-verifier::test_sp1_verify_consensus_accepts_solidity_fixture

Benchmark + simtest re-wired to the new fixture (vkey 0x007d1720…, Bob signer).

Follow-up

  • Regenerate pallet weights (the storage-name in the generated weight comments is stale; functionally unchanged).
  • Operationally, set the new vkey via set_sp1_vkey_hash and in the EVM SP1Beefy constructor at deploy time.

@seunlanlege seunlanlege changed the title [runtime]: bind SP1 BEEFY proofs to a committed nonce for anti-theft + per-account dedup [runtime]: bind SP1 BEEFY proofs to a committed nonce for anti-theft May 27, 2026
@seunlanlege seunlanlege marked this pull request as draft May 27, 2026 17:55
@seunlanlege seunlanlege force-pushed the seun/dedupe-proofs branch from d4adc11 to b2d8224 Compare May 27, 2026 18:38
@seunlanlege seunlanlege marked this pull request as ready for review May 27, 2026 18:46
@seunlanlege seunlanlege merged commit 53f3e95 into main May 27, 2026
34 checks passed
@seunlanlege seunlanlege deleted the seun/dedupe-proofs branch May 27, 2026 21:56
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.

[runtime]: bind prover-chosen nonce to SP1 BEEFY proofs for uncle dedup

2 participants