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 {}
|
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 group::ff::{Field, FromUniformBytes, PrimeField};
|
||||||
|
|
||||||
use crate::arithmetic::CurveAffine;
|
use crate::arithmetic::CurveAffine;
|
||||||
|
use crate::helpers::{pack, unpack, CurveRead};
|
||||||
use crate::poly::{
|
use crate::poly::{
|
||||||
Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, PinnedEvaluationDomain,
|
commitment::Params, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff,
|
||||||
Polynomial,
|
PinnedEvaluationDomain, Polynomial,
|
||||||
};
|
};
|
||||||
use crate::transcript::{ChallengeScalar, EncodedChallenge, Transcript};
|
use crate::transcript::{ChallengeScalar, EncodedChallenge, Transcript};
|
||||||
|
|
||||||
|
@ -47,17 +48,131 @@ pub struct VerifyingKey<C: CurveAffine> {
|
||||||
cs_degree: usize,
|
cs_degree: usize,
|
||||||
/// The representative of this `VerifyingKey` in transcripts.
|
/// The representative of this `VerifyingKey` in transcripts.
|
||||||
transcript_repr: C::Scalar,
|
transcript_repr: C::Scalar,
|
||||||
|
selectors: Vec<Vec<bool>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> VerifyingKey<C>
|
impl<C: CurveAffine> VerifyingKey<C>
|
||||||
where
|
where
|
||||||
C::Scalar: FromUniformBytes<64>,
|
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(
|
fn from_parts(
|
||||||
domain: EvaluationDomain<C::Scalar>,
|
domain: EvaluationDomain<C::Scalar>,
|
||||||
fixed_commitments: Vec<C>,
|
fixed_commitments: Vec<C>,
|
||||||
permutation: permutation::VerifyingKey<C>,
|
permutation: permutation::VerifyingKey<C>,
|
||||||
cs: ConstraintSystem<C::Scalar>,
|
cs: ConstraintSystem<C::Scalar>,
|
||||||
|
selectors: Vec<Vec<bool>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Compute cached values.
|
// Compute cached values.
|
||||||
let cs_degree = cs.degree();
|
let cs_degree = cs.degree();
|
||||||
|
@ -70,6 +185,7 @@ where
|
||||||
cs_degree,
|
cs_degree,
|
||||||
// Temporary, this is not pinned.
|
// Temporary, this is not pinned.
|
||||||
transcript_repr: C::Scalar::ZERO,
|
transcript_repr: C::Scalar::ZERO,
|
||||||
|
selectors,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut hasher = Blake2bParams::new()
|
let mut hasher = Blake2bParams::new()
|
||||||
|
|
|
@ -219,7 +219,7 @@ where
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut fixed = batch_invert_assigned(assembly.fixed);
|
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(
|
fixed.extend(
|
||||||
selector_polys
|
selector_polys
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -240,6 +240,7 @@ where
|
||||||
fixed_commitments,
|
fixed_commitments,
|
||||||
permutation_vk,
|
permutation_vk,
|
||||||
cs,
|
cs,
|
||||||
|
assembly.selectors,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@ pub(crate) mod keygen;
|
||||||
pub(crate) mod prover;
|
pub(crate) mod prover;
|
||||||
pub(crate) mod verifier;
|
pub(crate) mod verifier;
|
||||||
|
|
||||||
|
use crate::helpers::CurveRead;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
/// A permutation argument.
|
/// A permutation argument.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Argument {
|
pub(crate) struct Argument {
|
||||||
|
@ -75,6 +78,37 @@ pub(crate) struct VerifyingKey<C: CurveAffine> {
|
||||||
commitments: Vec<C>,
|
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.
|
/// The proving key for a single permutation argument.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct ProvingKey<C: CurveAffine> {
|
pub(crate) struct ProvingKey<C: CurveAffine> {
|
||||||
|
|
Loading…
Reference in New Issue