Skip to content

Commit 5868f0b

Browse files
authored
feat(verifier): check SP1 public values digest for compressed proofs (#2457)
1 parent 5f75ca0 commit 5868f0b

File tree

4 files changed

+35
-11
lines changed

4 files changed

+35
-11
lines changed

crates/verifier/src/compressed.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use sp1_recursion_core::{
1212
use sp1_stark::{baby_bear_poseidon2::BabyBearPoseidon2, *};
1313
use thiserror::Error;
1414

15+
use crate::{blake3_hash, hash_public_inputs, hash_public_inputs_with_fn};
16+
1517
// NOTE: that all these constants and types are checked by sp1_prover::tests::sp1_verifier_valid.
1618
// If you add a new proof, you MUST add to the test in that crate.
1719
//
@@ -47,15 +49,18 @@ pub const RECURSION_VK_SET: &[[u32; 8]] = &[
4749

4850
/// A reason why the verifier rejects a given proof.
4951
#[derive(Debug, Error)]
52+
#[non_exhaustive]
5053
pub enum CompressedError {
51-
#[error("failed to deserialize proof")]
54+
#[error("failed to deserialize proof: {0}")]
5255
DeserializeProof(Box<bincode::ErrorKind>),
53-
#[error("failed to deserialize vkey hash")]
56+
#[error("failed to deserialize vkey hash: {0}")]
5457
DeserializeVkeyHash(Box<bincode::ErrorKind>),
55-
#[error("failed to verify proof")]
58+
#[error("failed to verify proof: {0}")]
5659
ProofRejected(#[from] MachineVerificationError<SC>),
5760
#[error("single-shard proofs are currently unsupported by this verifier")]
5861
SingleShard,
62+
#[error("given public values do not match the commitment in the proof")]
63+
PublicValuesMismatch,
5964
}
6065

6166
/// A verifier for SP1 "compressed" proofs.
@@ -86,13 +91,17 @@ impl CompressedVerifier {
8691
/// _ => unreachable!("expected compressed proof"),
8792
/// };
8893
/// ```
89-
pub fn verify(proof: &[u8], sp1_vkey_hash: &[u8]) -> Result<(), CompressedError> {
94+
pub fn verify(
95+
proof: &[u8],
96+
sp1_public_inputs: &[u8],
97+
sp1_vkey_hash: &[u8],
98+
) -> Result<(), CompressedError> {
9099
let reduce_proof: Box<SP1ReduceProof<SC>> =
91100
bincode::deserialize(proof).map_err(CompressedError::DeserializeProof)?;
92101
let vkey_hash: [F; 8] =
93102
bincode::deserialize(sp1_vkey_hash).map_err(CompressedError::DeserializeVkeyHash)?;
94103

95-
verify_compressed(&reduce_proof, &vkey_hash)?;
104+
verify_compressed(&reduce_proof, sp1_public_inputs, &vkey_hash)?;
96105

97106
Ok(())
98107
}
@@ -103,6 +112,7 @@ impl CompressedVerifier {
103112
/// Verify a compressed proof.
104113
fn verify_compressed(
105114
proof: &SP1ReduceProof<SC>,
115+
sp1_public_inputs: &[u8],
106116
vkey_hash: &[BabyBear; 8],
107117
) -> Result<(), CompressedError> {
108118
let SP1ReduceProof { vk: compress_vk, proof } = proof;
@@ -120,7 +130,21 @@ fn verify_compressed(
120130
let machine_proof = MachineProof { shard_proofs: vec![proof.clone()] };
121131
compress_machine.verify(compress_vk, &machine_proof, &mut challenger)?;
122132

123-
// Validate public values
133+
// Validate the SP1 public values against the committed digest.
134+
let committed_value_digest_bytes = public_values
135+
.committed_value_digest
136+
.iter()
137+
.flat_map(|w| w.0.iter().map(|x| x.as_canonical_u32() as u8))
138+
.collect::<Vec<_>>();
139+
140+
if committed_value_digest_bytes.as_slice() != hash_public_inputs(sp1_public_inputs).as_slice() &&
141+
committed_value_digest_bytes.as_slice() !=
142+
hash_public_inputs_with_fn(sp1_public_inputs, blake3_hash)
143+
{
144+
return Err(CompressedError::PublicValuesMismatch);
145+
}
146+
147+
// Validate recursion's public values.
124148
if !is_recursion_public_values_valid(compress_machine.config(), public_values) {
125149
return Err(MachineVerificationError::InvalidPublicValues(
126150
"recursion public values are invalid",

crates/verifier/src/error.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ pub enum Error {
1818
FailedToGetFrFromRandomBytes,
1919

2020
// External Library Errors
21-
#[error("BN254 Field Error")]
21+
#[error("BN254 Field Error: {0}")]
2222
Field(FieldError),
23-
#[error("BN254 Group Error")]
23+
#[error("BN254 Group Error: {0}")]
2424
Group(GroupError),
25-
#[error("BN254 Curve Error")]
25+
#[error("BN254 Curve Error: {0}")]
2626
Curve(CurveError),
2727

2828
// SP1 Errors

crates/verifier/src/groth16/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub enum Groth16Error {
88
ProcessVerifyingKeyFailed,
99
#[error("Prepare inputs failed")]
1010
PrepareInputsFailed,
11-
#[error("General error")]
11+
#[error("General error: {0}")]
1212
GeneralError(#[from] crate::error::Error),
1313
#[error("Groth16 vkey hash mismatch")]
1414
Groth16VkeyHashMismatch,

crates/verifier/src/plonk/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ pub enum PlonkError {
2828
TranscriptError,
2929
#[error("Plonk vkey hash mismatch")]
3030
PlonkVkeyHashMismatch,
31-
#[error("General error")]
31+
#[error("General error: {0}")]
3232
GeneralError(#[from] crate::error::Error),
3333
}

0 commit comments

Comments
 (0)