Skip to content

Commit

Permalink
fix(sdk): .bytes() inconsistent behavior between groth16 and plonk (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ratankaliani authored Nov 20, 2024
1 parent 0d9c755 commit e2cc7af
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions crates/sdk/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ impl SP1ProofWithPublicValues {
[plonk_proof.plonk_vkey_hash[..4].to_vec(), proof_bytes].concat()
}
SP1Proof::Groth16(groth16_proof) => {
if groth16_proof.encoded_proof.is_empty() {
// If the proof is empty, then this is a mock proof. The mock SP1 verifier
// expects an empty byte array for verification, so return an empty byte array.
return Vec::new();
}

let proof_bytes =
hex::decode(&groth16_proof.encoded_proof).expect("Invalid Groth16 proof");
[groth16_proof.groth16_vkey_hash[..4].to_vec(), proof_bytes].concat()
Expand All @@ -82,3 +88,86 @@ impl SP1ProofWithPublicValues {
pub type SP1CoreProofVerificationError = MachineVerificationError<CoreSC>;

pub type SP1CompressedProofVerificationError = MachineVerificationError<InnerSC>;

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_plonk_proof_bytes() {
let plonk_proof = SP1ProofWithPublicValues {
proof: SP1Proof::Plonk(PlonkBn254Proof {
encoded_proof: "ab".to_string(),
plonk_vkey_hash: [0; 32],
public_inputs: ["".to_string(), "".to_string()],
raw_proof: "".to_string(),
}),
stdin: SP1Stdin::new(),
public_values: SP1PublicValues::new(),
sp1_version: "".to_string(),
};
let expected_bytes = [vec![0, 0, 0, 0], hex::decode("ab").unwrap()].concat();
assert_eq!(plonk_proof.bytes(), expected_bytes);
}

#[test]
fn test_groth16_proof_bytes() {
let groth16_proof = SP1ProofWithPublicValues {
proof: SP1Proof::Groth16(Groth16Bn254Proof {
encoded_proof: "ab".to_string(),
groth16_vkey_hash: [0; 32],
public_inputs: ["".to_string(), "".to_string()],
raw_proof: "".to_string(),
}),
stdin: SP1Stdin::new(),
public_values: SP1PublicValues::new(),
sp1_version: "".to_string(),
};
let expected_bytes = [vec![0, 0, 0, 0], hex::decode("ab").unwrap()].concat();
assert_eq!(groth16_proof.bytes(), expected_bytes);
}

#[test]
fn test_mock_plonk_proof_bytes() {
let mock_plonk_proof = SP1ProofWithPublicValues {
proof: SP1Proof::Plonk(PlonkBn254Proof {
encoded_proof: "".to_string(),
plonk_vkey_hash: [0; 32],
public_inputs: ["".to_string(), "".to_string()],
raw_proof: "".to_string(),
}),
stdin: SP1Stdin::new(),
public_values: SP1PublicValues::new(),
sp1_version: "".to_string(),
};
assert_eq!(mock_plonk_proof.bytes(), Vec::<u8>::new());
}

#[test]
fn test_mock_groth16_proof_bytes() {
let mock_groth16_proof = SP1ProofWithPublicValues {
proof: SP1Proof::Groth16(Groth16Bn254Proof {
encoded_proof: "".to_string(),
groth16_vkey_hash: [0; 32],
public_inputs: ["".to_string(), "".to_string()],
raw_proof: "".to_string(),
}),
stdin: SP1Stdin::new(),
public_values: SP1PublicValues::new(),
sp1_version: "".to_string(),
};
assert_eq!(mock_groth16_proof.bytes(), Vec::<u8>::new());
}

#[test]
#[should_panic(expected = "only Plonk and Groth16 proofs are verifiable onchain")]
fn test_core_proof_bytes_unimplemented() {
let core_proof = SP1ProofWithPublicValues {
proof: SP1Proof::Core(vec![]),
stdin: SP1Stdin::new(),
public_values: SP1PublicValues::new(),
sp1_version: "".to_string(),
};
core_proof.bytes();
}
}

0 comments on commit e2cc7af

Please sign in to comment.