precompute R1CSShape's digest (#57)

This commit is contained in:
Srinath Setty
2022-05-13 20:23:21 +05:30
committed by GitHub
parent fab07689eb
commit 6ac9c7706d

View File

@@ -31,6 +31,7 @@ pub struct R1CSShape<G: Group> {
A: Vec<(usize, usize, G::Scalar)>, A: Vec<(usize, usize, G::Scalar)>,
B: Vec<(usize, usize, G::Scalar)>, B: Vec<(usize, usize, G::Scalar)>,
C: Vec<(usize, usize, G::Scalar)>, C: Vec<(usize, usize, G::Scalar)>,
digest: G::Scalar, // digest of the rest of R1CSShape
} }
/// A type that holds a witness for a given R1CS instance /// A type that holds a witness for a given R1CS instance
@@ -121,6 +122,8 @@ impl<G: Group> R1CSShape<G> {
return Err(NovaError::OddInputLength); return Err(NovaError::OddInputLength);
} }
let digest = Self::compute_digest(num_cons, num_vars, num_io, A, B, C);
let shape = R1CSShape { let shape = R1CSShape {
num_cons, num_cons,
num_vars, num_vars,
@@ -128,6 +131,7 @@ impl<G: Group> R1CSShape<G> {
A: A.to_owned(), A: A.to_owned(),
B: B.to_owned(), B: B.to_owned(),
C: C.to_owned(), C: C.to_owned(),
digest,
}; };
Ok(shape) Ok(shape)
@@ -291,23 +295,31 @@ impl<G: Group> R1CSShape<G> {
} }
/// returns the digest of R1CSShape /// returns the digest of R1CSShape
fn get_digest(&self) -> G::Scalar { pub fn get_digest(&self) -> G::Scalar {
self.digest
}
fn compute_digest(
num_cons: usize,
num_vars: usize,
num_io: usize,
A: &[(usize, usize, G::Scalar)],
B: &[(usize, usize, G::Scalar)],
C: &[(usize, usize, G::Scalar)],
) -> G::Scalar {
let shape_serialized = R1CSShapeSerialized { let shape_serialized = R1CSShapeSerialized {
num_cons: self.num_cons, num_cons,
num_vars: self.num_vars, num_vars,
num_io: self.num_io, num_io,
A: self A: A
.A
.iter() .iter()
.map(|(i, j, v)| (*i, *j, v.to_repr().as_ref().to_vec())) .map(|(i, j, v)| (*i, *j, v.to_repr().as_ref().to_vec()))
.collect(), .collect(),
B: self B: B
.B
.iter() .iter()
.map(|(i, j, v)| (*i, *j, v.to_repr().as_ref().to_vec())) .map(|(i, j, v)| (*i, *j, v.to_repr().as_ref().to_vec()))
.collect(), .collect(),
C: self C: C
.C
.iter() .iter()
.map(|(i, j, v)| (*i, *j, v.to_repr().as_ref().to_vec())) .map(|(i, j, v)| (*i, *j, v.to_repr().as_ref().to_vec()))
.collect(), .collect(),
@@ -321,12 +333,12 @@ impl<G: Group> R1CSShape<G> {
// convert shape_bytes into a short digest // convert shape_bytes into a short digest
let mut hasher = Sha3_256::new(); let mut hasher = Sha3_256::new();
hasher.input(&shape_bytes); hasher.input(&shape_bytes);
let shape_digest = hasher.result(); let digest = hasher.result();
// truncate the digest to 250 bits // truncate the digest to 250 bits
let bv = (0..NUM_HASH_BITS).map(|i| { let bv = (0..NUM_HASH_BITS).map(|i| {
let (byte_pos, bit_pos) = (i / 8, i % 8); let (byte_pos, bit_pos) = (i / 8, i % 8);
let bit = (shape_digest[byte_pos] >> bit_pos) & 1; let bit = (digest[byte_pos] >> bit_pos) & 1;
bit == 1 bit == 1
}); });