Skip to content

Commit

Permalink
Apply zcash#661
Browse files Browse the repository at this point in the history
Signed-off-by: parazyd <[email protected]>
  • Loading branch information
parazyd committed Jun 29, 2023
1 parent c05547a commit 8672419
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 3 deletions.
74 changes: 72 additions & 2 deletions halo2_proofs/src/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use blake2b_simd::Params as Blake2bParams;
use group::ff::{Field, FromUniformBytes, PrimeField};

use crate::arithmetic::CurveAffine;
use crate::helpers::CurveRead;
use crate::poly::{
Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, PinnedEvaluationDomain,
Polynomial,
commitment::Params, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff,
PinnedEvaluationDomain, Polynomial,
};
use crate::transcript::{ChallengeScalar, EncodedChallenge, Transcript};

Expand Down Expand Up @@ -47,17 +48,85 @@ 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<()> {
writer.write_all(&(self.fixed_commitments.len() as u32).to_be_bytes())?;
for commitment in &self.fixed_commitments {
writer.write_all(commitment.to_bytes().as_ref())?;
}
self.permutation.write(writer)?;

// write self.selectors
for selector in &self.selectors {
let mut selector_bytes = vec![0u8; selector.len() / 8 + 1];
for (i, selector_idx) in selector.iter().enumerate() {
let byte_index = i / 8;
let bit_index = i % 8;
selector_bytes[byte_index] |= (*selector_idx as u8) << bit_index;
}
writer.write_all(&selector_bytes)?;
}

Ok(())
}

/// Reads a verification 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 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 fixed_commitments: Vec<_> = (0..num_fixed_columns)
.map(|_| C::read(reader))
.collect::<Result<_, _>>()?;

let permutation = permutation::VerifyingKey::read(reader, &cs.permutation)?;

// read 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() / 8 + 1];
reader
.read_exact(&mut selector_bytes)
.expect("unable to read selector bytes");
for (i, selector_idx) in selector.iter_mut().enumerate() {
let byte_index = i / 8;
let bit_index = i % 8;
*selector_idx = (selector_bytes[byte_index] >> bit_index) & 1 == 1;
}
Ok(selector)
})
.collect::<Result<Vec<Vec<bool>>, &str>>()
.unwrap();
let (cs, _) = cs.compress_selectors(selectors.clone());

Ok(Self::from_parts(
domain,
fixed_commitments,
permutation,
cs,
selectors,
))
}

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();
Expand All @@ -70,6 +139,7 @@ where
cs_degree,
// Temporary, this is not pinned.
transcript_repr: C::Scalar::ZERO,
selectors,
};

let mut hasher = Blake2bParams::new()
Expand Down
3 changes: 2 additions & 1 deletion halo2_proofs/src/plonk/keygen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -240,6 +240,7 @@ where
fixed_commitments,
permutation_vk,
cs,
assembly.selectors,
))
}

Expand Down
21 changes: 21 additions & 0 deletions halo2_proofs/src/plonk/permutation.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::circuit::{Any, Column};
use crate::{
arithmetic::CurveAffine,
helpers::CurveRead,
poly::{Coeff, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial},
};

Expand Down Expand Up @@ -75,6 +76,26 @@ pub(crate) struct VerifyingKey<C: CurveAffine> {
commitments: Vec<C>,
}

impl<C: CurveAffine> VerifyingKey<C> {
pub(crate) fn write<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
for commitment in &self.commitments {
writer.write_all(commitment.to_bytes().as_ref())?;
}

Ok(())
}

pub(crate) fn read<R: std::io::Read>(
reader: &mut R,
argument: &Argument,
) -> std::io::Result<Self> {
let commitments = (0..argument.columns.len())
.map(|_| C::read(reader))
.collect::<Result<Vec<_>, _>>()?;
Ok(VerifyingKey { commitments })
}
}

/// The proving key for a single permutation argument.
#[derive(Clone, Debug)]
pub(crate) struct ProvingKey<C: CurveAffine> {
Expand Down

0 comments on commit 8672419

Please sign in to comment.