Skip to content

Commit

Permalink
Merge pull request #14 from zkcrypto/fix_linear
Browse files Browse the repository at this point in the history
Add public vector to the transcript in linear proof
  • Loading branch information
cathieyun authored Jan 23, 2023
2 parents df6c41b + 635cbc3 commit a4aa4c5
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 23 deletions.
8 changes: 5 additions & 3 deletions benches/linear_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ fn create_linear_proof_helper(c: &mut Criterion) {
G.clone(),
&F,
&B,
);
)
.unwrap();
})
},
TEST_SIZES,
Expand Down Expand Up @@ -141,7 +142,8 @@ fn linear_verify(c: &mut Criterion) {
G.clone(),
&F,
&B,
);
)
.unwrap();

(proof, C)
};
Expand All @@ -150,7 +152,7 @@ fn linear_verify(c: &mut Criterion) {
bench.iter(|| {
let mut verifier_transcript = Transcript::new(b"LinearProofBenchmark");
proof
.verify(*n, &mut verifier_transcript, &C, &G, &F, &B, b.clone())
.verify(&mut verifier_transcript, &C, &G, &F, &B, b.clone())
.unwrap();
});
},
Expand Down
6 changes: 6 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ pub enum ProofError {
error("Invalid generators size, too few generators for proof")
)]
InvalidGeneratorsLength,
/// This error occurs when inputs are the incorrect length for the proof.
#[cfg_attr(
feature = "std",
error("Invalid input size, incorrect input length for proof")
)]
InvalidInputLength,
/// This error results from an internal error during proving.
///
/// The single-party prover is implemented by performing
Expand Down
66 changes: 46 additions & 20 deletions src/linear_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,31 @@ impl LinearProof {
F: &RistrettoPoint,
// Pedersen generator B, for committing to the blinding value
B: &RistrettoPoint,
) -> LinearProof {
let mut n = a_vec.len();
) -> Result<LinearProof, ProofError> {
let mut n = b_vec.len();
// All of the input vectors must have the same length.
if G_vec.len() != n {
return Err(ProofError::InvalidGeneratorsLength);
}
if a_vec.len() != n {
return Err(ProofError::InvalidInputLength);
}
// All of the input vectors must have a length that is a power of two.
if !n.is_power_of_two() {
return Err(ProofError::InvalidInputLength);
}

// Append all public data to the transcript
transcript.innerproduct_domain_sep(n as u64);
transcript.append_point(b"C", &C);
for b_i in &b_vec {
transcript.append_scalar(b"b_i", b_i);
}
for G_i in &G_vec {
transcript.append_point(b"G_i", &G_i.compress());
}
transcript.append_point(b"F", &F.compress());
transcript.append_point(b"B", &B.compress());

// Create slices G, H, a, b backed by their respective
// vectors. This lets us reslice as we compress the lengths
Expand All @@ -64,17 +87,6 @@ impl LinearProof {
let mut a = &mut a_vec[..];
let mut b = &mut b_vec[..];

// All of the input vectors must have the same length.
assert_eq!(G.len(), n);
assert_eq!(a.len(), n);
assert_eq!(b.len(), n);

// All of the input vectors must have a length that is a power of two.
assert!(n.is_power_of_two());

transcript.innerproduct_domain_sep(n as u64);
transcript.append_point(b"C", &C);

let lg_n = n.next_power_of_two().trailing_zeros() as usize;
let mut L_vec = Vec::with_capacity(lg_n);
let mut R_vec = Vec::with_capacity(lg_n);
Expand Down Expand Up @@ -140,18 +152,17 @@ impl LinearProof {
let a_star = s_star + x_star * a[0];
let r_star = t_star + x_star * r;

LinearProof {
Ok(LinearProof {
L_vec,
R_vec,
S,
a: a_star,
r: r_star,
}
})
}

pub fn verify(
&self,
n: usize,
transcript: &mut Transcript,
// Commitment to witness
C: &CompressedRistretto,
Expand All @@ -164,10 +175,24 @@ impl LinearProof {
// Public scalar vector b
b_vec: Vec<Scalar>,
) -> Result<(), ProofError> {
let n = b_vec.len();
if G.len() != n {
return Err(ProofError::InvalidGeneratorsLength);
}

// Append all public data to the transcript
transcript.innerproduct_domain_sep(n as u64);
transcript.append_point(b"C", &C);
let (x_vec, x_inv_vec, b_0) = self.verification_scalars(n, transcript, b_vec)?;
for b_i in &b_vec {
transcript.append_scalar(b"b_i", b_i);
}
for G_i in G {
transcript.append_point(b"G_i", &G_i.compress());
}
transcript.append_point(b"F", &F.compress());
transcript.append_point(b"B", &B.compress());

let (x_vec, x_inv_vec, b_0) = self.verification_scalars(n, transcript, b_vec)?;
transcript.append_point(b"S", &self.S);
let x_star = transcript.challenge_scalar(b"x_star");

Expand Down Expand Up @@ -422,11 +447,12 @@ mod tests {
G.clone(),
&F,
&B,
);
)
.unwrap();

let mut verifier_transcript = Transcript::new(b"linearprooftest");
assert!(proof
.verify(n, &mut verifier_transcript, &C, &G, &F, &B, b.clone())
.verify(&mut verifier_transcript, &C, &G, &F, &B, b.clone())
.is_ok());

// Test serialization and deserialization
Expand All @@ -436,7 +462,7 @@ mod tests {
let deserialized_proof = LinearProof::from_bytes(&serialized_proof).unwrap();
let mut serde_verifier_transcript = Transcript::new(b"linearprooftest");
assert!(deserialized_proof
.verify(n, &mut serde_verifier_transcript, &C, &G, &F, &B, b)
.verify(&mut serde_verifier_transcript, &C, &G, &F, &B, b)
.is_ok());
}

Expand Down

0 comments on commit a4aa4c5

Please sign in to comment.