diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index 5506f94a68..78bfc21501 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -60,6 +60,9 @@ pub struct VerifyingKey { compress_selectors: bool, } +// Current version of the VK +const VERSION: u8 = 0x03; + impl VerifyingKey where C::Scalar: SerdePrimeField + FromUniformBytes<64>, @@ -75,8 +78,11 @@ where /// WITHOUT performing the expensive Montgomery reduction. pub fn write(&self, writer: &mut W, format: SerdeFormat) -> io::Result<()> { // Version byte that will be checked on read. - writer.write_all(&[0x02])?; - writer.write_all(&self.domain.k().to_le_bytes())?; + writer.write_all(&[VERSION])?; + let k = &self.domain.k(); + assert!(*k <= C::Scalar::S); + // k value fits in 1 byte + writer.write_all(&[*k as u8])?; writer.write_all(&[self.compress_selectors as u8])?; writer.write_all(&(self.fixed_commitments.len() as u32).to_le_bytes())?; for commitment in &self.fixed_commitments { @@ -114,15 +120,26 @@ where ) -> io::Result { let mut version_byte = [0u8; 1]; reader.read_exact(&mut version_byte)?; - if 0x02 != version_byte[0] { + if VERSION != version_byte[0] { return Err(io::Error::new( io::ErrorKind::InvalidData, "unexpected version byte", )); } - let mut k = [0u8; 4]; + + let mut k = [0u8; 1]; reader.read_exact(&mut k)?; - let k = u32::from_le_bytes(k); + let k = u8::from_le_bytes(k); + if k as u32 > C::Scalar::S { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + format!( + "circuit size value (k): {} exceeds maxium: {}", + k, + C::Scalar::S + ), + )); + } let mut compress_selectors = [0u8; 1]; reader.read_exact(&mut compress_selectors)?; if compress_selectors[0] != 0 && compress_selectors[0] != 1 { @@ -133,7 +150,7 @@ where } let compress_selectors = compress_selectors[0] == 1; let (domain, cs, _) = keygen::create_domain::( - k, + k as u32, #[cfg(feature = "circuit-params")] params, );