[runtime]: bind SP1 BEEFY proofs to a committed nonce for anti-theft #924
Merged
Conversation
…d on solidity + rust
…tates, Bob signer)
royvardhan
approved these changes
May 27, 2026
…daemon + all Prover::new callers
…dup in provers guide
…, uncles decreasing)
… initialize_state; DeployIsmp v6.1 verifier
d4adc11 to
b2d8224
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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-proofsrequire that nonce to equal thesubmit_proofsigner. This:UnauthorizedProof) because the committed account ≠ the signer, and the committed account can't be changed without re-running the SP1 proof.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 wholeRewardCurve. 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/PublicInputsgain anonce: H256committed verbatim by the program. New vkey:0x007d1720c695842ed647a1a72e981751f9b5e26fc5ca038523b23430a1292f08.EVM:
nonceadded toSP1BeefyProof/PublicInputsinTypes.sol, reconstructed inSP1Beefy.sol; ABI regenerated.Rust:
nonceadded tobeefy_verifier_primitives::Sp1BeefyProof, the verifier's reconstructedPublicInputs, andconversions.rs.ismp-beefyis unchanged — it decodes the sharedSp1BeefyProofand stays nonce-agnostic (binding/dedup is the pallet's job).Pallet (
pallet-beefy-consensus-proofs): enforcecommitted nonce == ensure_signed(origin)on first-proof and uncle paths; dedup on account (AcceptedProofHashes→AcceptedProvers); drop the old keccak/canonical re-encoding dance. Storagev1 → v2with aClearAcceptedProofHashesmigration (wired into gargantua + nexus).Relayer (
zk-beefy): commits the submission signer (SubstrateClient::address) as the nonce; dep bumped tosp1-beefyv1.1.0.Verification
Fixture regenerated against mainnet (committing Bob's account as the nonce); both verifiers confirmed against it:
SP1BeefyTest::testVerifySp1Beefybeefy-verifier::test_sp1_verify_consensus_accepts_solidity_fixtureBenchmark + simtest re-wired to the new fixture (vkey
0x007d1720…, Bob signer).Follow-up
set_sp1_vkey_hashand in the EVMSP1Beefyconstructor at deploy time.