mirror of https://github.com/zcash/halo2.git
Compare commits
5 Commits
1055bfe982
...
4ed0c95b56
Author | SHA1 | Date |
---|---|---|
Nalin | 4ed0c95b56 | |
Daira Emma Hopwood | 58e797da93 | |
Daira Emma Hopwood | bae30538b5 | |
Jonathan Wang | 3489dcde9e | |
Nalin Bhardwaj | 0ca2296921 |
|
@ -14,3 +14,22 @@ pub(crate) trait CurveRead: CurveAffine {
|
|||
}
|
||||
|
||||
impl<C: CurveAffine> CurveRead for C {}
|
||||
|
||||
/// Converts a slice of `bool` into a `u8`.
|
||||
///
|
||||
/// Panics if the slice has length greater than 8.
|
||||
pub fn pack(bits: &[bool]) -> u8 {
|
||||
let mut value = 0u8;
|
||||
assert!(bits.len() <= 8);
|
||||
for (bit_index, bit) in bits.iter().enumerate() {
|
||||
value |= (*bit as u8) << bit_index;
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
/// Writes the first `bits.len()` bits of a `u8` into `bits`.
|
||||
pub fn unpack(byte: u8, bits: &mut [bool]) {
|
||||
for (bit_index, bit) in bits.iter_mut().enumerate() {
|
||||
*bit = (byte >> bit_index) & 1 == 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,10 @@ use blake2b_simd::Params as Blake2bParams;
|
|||
use group::ff::{Field, FromUniformBytes, PrimeField};
|
||||
|
||||
use crate::arithmetic::CurveAffine;
|
||||
use crate::helpers::{pack, unpack, CurveRead};
|
||||
use crate::poly::{
|
||||
Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, PinnedEvaluationDomain,
|
||||
Polynomial,
|
||||
commitment::Params, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff,
|
||||
PinnedEvaluationDomain, Polynomial,
|
||||
};
|
||||
use crate::transcript::{ChallengeScalar, EncodedChallenge, Transcript};
|
||||
|
||||
|
@ -47,17 +48,131 @@ pub struct VerifyingKey<C: CurveAffine> {
|
|||
cs_degree: usize,
|
||||
/// The representative of this `VerifyingKey` in transcripts.
|
||||
transcript_repr: C::Scalar,
|
||||
selectors: Vec<Vec<bool>>,
|
||||
}
|
||||
|
||||
impl<C: CurveAffine> VerifyingKey<C>
|
||||
where
|
||||
C::Scalar: FromUniformBytes<64>,
|
||||
{
|
||||
/// Writes a verifying key to a buffer.
|
||||
pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||
// 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 {
|
||||
// since `selector` is filled with `bool`, we pack them 8 at a time into bytes and then write
|
||||
for bits in selector.chunks(8) {
|
||||
writer.write_all(&[pack(bits)])?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Reads a verifying key from a buffer.
|
||||
pub fn read<R: io::Read, ConcreteCircuit: Circuit<C::Scalar>>(
|
||||
reader: &mut R,
|
||||
params: &Params<C>,
|
||||
) -> io::Result<Self> {
|
||||
let (domain, cs, _) = keygen::create_domain::<C, ConcreteCircuit>(params);
|
||||
|
||||
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::<io::Result<_>>()?;
|
||||
|
||||
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<bool>> = vec![vec![false; params.n as usize]; cs.num_selectors]
|
||||
.into_iter()
|
||||
.map(|mut selector| {
|
||||
let mut selector_bytes = vec![0u8; (selector.len() + 7) / 8];
|
||||
reader.read_exact(&mut selector_bytes)?;
|
||||
for (bits, byte) in selector.chunks_mut(8).zip(selector_bytes) {
|
||||
unpack(byte, bits);
|
||||
}
|
||||
Ok(selector)
|
||||
})
|
||||
.collect::<io::Result<_>>()?;
|
||||
|
||||
let (cs, _) = cs.compress_selectors(selectors.clone());
|
||||
|
||||
Ok(Self::from_parts(
|
||||
domain,
|
||||
fixed_commitments,
|
||||
permutation,
|
||||
cs,
|
||||
selectors,
|
||||
))
|
||||
}
|
||||
|
||||
/// Writes a verifying key to a vector of bytes.
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = Vec::<u8>::with_capacity(self.bytes_length());
|
||||
self.write(&mut bytes)
|
||||
.expect("Writing to vector should not fail");
|
||||
bytes
|
||||
}
|
||||
|
||||
/// Reads a verifying key from a slice of bytes.
|
||||
pub fn from_bytes<ConcreteCircuit: Circuit<C::Scalar>>(
|
||||
mut bytes: &[u8],
|
||||
params: &Params<C>,
|
||||
) -> io::Result<Self> {
|
||||
Self::read::<_, ConcreteCircuit>(&mut bytes, params)
|
||||
}
|
||||
|
||||
/// Gets the total number of bytes in the serialization of `self`.
|
||||
fn bytes_length(&self) -> usize {
|
||||
1 + 4
|
||||
+ self.fixed_commitments.len() * C::default().to_bytes().as_ref().len()
|
||||
+ self.permutation.bytes_length()
|
||||
+ 4
|
||||
+ self.selectors.len()
|
||||
* self
|
||||
.selectors
|
||||
.get(0)
|
||||
.map(|selector| (selector.len() + 7) / 8)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
fn from_parts(
|
||||
domain: EvaluationDomain<C::Scalar>,
|
||||
fixed_commitments: Vec<C>,
|
||||
permutation: permutation::VerifyingKey<C>,
|
||||
cs: ConstraintSystem<C::Scalar>,
|
||||
selectors: Vec<Vec<bool>>,
|
||||
) -> Self {
|
||||
// Compute cached values.
|
||||
let cs_degree = cs.degree();
|
||||
|
@ -70,6 +185,7 @@ where
|
|||
cs_degree,
|
||||
// Temporary, this is not pinned.
|
||||
transcript_repr: C::Scalar::ZERO,
|
||||
selectors,
|
||||
};
|
||||
|
||||
let mut hasher = Blake2bParams::new()
|
||||
|
|
|
@ -219,7 +219,7 @@ where
|
|||
)?;
|
||||
|
||||
let mut fixed = batch_invert_assigned(assembly.fixed);
|
||||
let (cs, selector_polys) = cs.compress_selectors(assembly.selectors);
|
||||
let (cs, selector_polys) = cs.compress_selectors(assembly.selectors.clone());
|
||||
fixed.extend(
|
||||
selector_polys
|
||||
.into_iter()
|
||||
|
@ -240,6 +240,7 @@ where
|
|||
fixed_commitments,
|
||||
permutation_vk,
|
||||
cs,
|
||||
assembly.selectors,
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ pub(crate) mod keygen;
|
|||
pub(crate) mod prover;
|
||||
pub(crate) mod verifier;
|
||||
|
||||
use crate::helpers::CurveRead;
|
||||
use std::io;
|
||||
|
||||
/// A permutation argument.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct Argument {
|
||||
|
@ -75,6 +78,37 @@ pub(crate) struct VerifyingKey<C: CurveAffine> {
|
|||
commitments: Vec<C>,
|
||||
}
|
||||
|
||||
impl<C: CurveAffine> VerifyingKey<C> {
|
||||
pub(crate) fn write<W: io::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())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn read<R: io::Read>(reader: &mut R, argument: &Argument) -> io::Result<Self> {
|
||||
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::<io::Result<_>>()?;
|
||||
Ok(VerifyingKey { commitments })
|
||||
}
|
||||
|
||||
pub(crate) fn bytes_length(&self) -> usize {
|
||||
4 + self.commitments.len() * C::default().to_bytes().as_ref().len()
|
||||
}
|
||||
}
|
||||
|
||||
/// The proving key for a single permutation argument.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct ProvingKey<C: CurveAffine> {
|
||||
|
|
Loading…
Reference in New Issue