diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index 04e1657b..024cca5f 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -57,15 +57,19 @@ where { /// Writes a verifying key to a buffer. pub fn write(&self, writer: &mut W) -> io::Result<()> { - writer.write_all(&(self.fixed_commitments.len() as u32).to_be_bytes())?; + // Version byte that will be checked on read. + writer.write_all(&[0x01])?; + + writer.write_all(&(u32::try_from(self.fixed_commitments.len()).unwrap()).to_le_bytes())?; for commitment in &self.fixed_commitments { writer.write_all(commitment.to_bytes().as_ref())?; } self.permutation.write(writer)?; // write self.selectors + writer.write_all(&(u32::try_from(self.selectors.len()).unwrap()).to_le_bytes())?; for selector in &self.selectors { - let mut selector_bytes = vec![0u8; selector.len() / 8 + 1]; + let mut selector_bytes = vec![0u8; (selector.len() + 7) / 8]; for (i, selector_idx) in selector.iter().enumerate() { let byte_index = i / 8; let bit_index = i % 8; @@ -83,24 +87,41 @@ where params: &Params, ) -> io::Result { let (domain, cs, _) = keygen::create_domain::(params); - let mut num_fixed_columns_be_bytes = [0u8; 4]; - reader.read_exact(&mut num_fixed_columns_be_bytes)?; - let num_fixed_columns = u32::from_be_bytes(num_fixed_columns_be_bytes); + + let mut version_byte = [0u8; 1]; + reader.read_exact(&mut version_byte)?; + if 0x01 != version_byte[0] { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "unexpected version byte", + )); + } + + let mut num_fixed_columns_le_bytes = [0u8; 4]; + reader.read_exact(&mut num_fixed_columns_le_bytes)?; + let num_fixed_columns = u32::from_le_bytes(num_fixed_columns_le_bytes); let fixed_commitments: Vec<_> = (0..num_fixed_columns) .map(|_| C::read(reader)) - .collect::>()?; + .collect::>()?; let permutation = permutation::VerifyingKey::read(reader, &cs.permutation)?; // read selectors + let mut num_selectors_le_bytes = [0u8; 4]; + reader.read_exact(&mut num_selectors_le_bytes)?; + let num_selectors = u32::from_le_bytes(num_selectors_le_bytes); + if cs.num_selectors != num_selectors.try_into().unwrap() { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "unexpected number of selectors", + )); + } let selectors: Vec> = vec![vec![false; params.n as usize]; cs.num_selectors] .into_iter() .map(|mut selector| { - let mut selector_bytes = vec![0u8; selector.len() / 8 + 1]; - reader - .read_exact(&mut selector_bytes) - .expect("unable to read selector bytes"); + let mut selector_bytes = vec![0u8; (selector.len() + 7) / 8]; + reader.read_exact(&mut selector_bytes)?; for (i, selector_idx) in selector.iter_mut().enumerate() { let byte_index = i / 8; let bit_index = i % 8; @@ -108,8 +129,8 @@ where } Ok(selector) }) - .collect::>, &str>>() - .unwrap(); + .collect::>()?; + let (cs, _) = cs.compress_selectors(selectors.clone()); Ok(Self::from_parts( diff --git a/halo2_proofs/src/plonk/permutation.rs b/halo2_proofs/src/plonk/permutation.rs index c7180f89..d6b00994 100644 --- a/halo2_proofs/src/plonk/permutation.rs +++ b/halo2_proofs/src/plonk/permutation.rs @@ -80,6 +80,7 @@ pub(crate) struct VerifyingKey { impl VerifyingKey { pub(crate) fn write(&self, writer: &mut W) -> io::Result<()> { + writer.write_all(&(u32::try_from(self.commitments.len()).unwrap()).to_le_bytes())?; for commitment in &self.commitments { writer.write_all(commitment.to_bytes().as_ref())?; } @@ -88,9 +89,18 @@ impl VerifyingKey { } pub(crate) fn read(reader: &mut R, argument: &Argument) -> io::Result { - let commitments = (0..argument.columns.len()) + let mut num_commitments_le_bytes = [0u8; 4]; + reader.read_exact(&mut num_commitments_le_bytes)?; + let num_commitments = u32::from_le_bytes(num_commitments_le_bytes); + if argument.columns.len() != num_commitments.try_into().unwrap() { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "unexpected number of column commitments", + )); + } + let commitments: Vec<_> = (0..argument.columns.len()) .map(|_| C::read(reader)) - .collect::, _>>()?; + .collect::>()?; Ok(VerifyingKey { commitments }) } }