Skip to content

Commit

Permalink
Merge pull request #96 from han0110/feature/configurable-instance-query
Browse files Browse the repository at this point in the history
Configurable instance query
  • Loading branch information
han0110 authored Oct 22, 2022
2 parents adefd9a + 432d72f commit 5fc8ce8
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 75 deletions.
89 changes: 49 additions & 40 deletions halo2_proofs/src/plonk/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,26 +88,32 @@ pub fn create_proof<
return Err(Error::InstanceTooLarge);
}
for (poly, value) in poly.iter_mut().zip(values.iter()) {
if !P::QUERY_INSTANCE {
transcript.common_scalar(*value)?;
}
*poly = *value;
}
Ok(poly)
})
.collect::<Result<Vec<_>, _>>()?;
let instance_commitments_projective: Vec<_> = instance_values
.iter()
.map(|poly| params.commit_lagrange(poly, Blind::default()))
.collect();
let mut instance_commitments =
vec![Scheme::Curve::identity(); instance_commitments_projective.len()];
<Scheme::Curve as CurveAffine>::CurveExt::batch_normalize(
&instance_commitments_projective,
&mut instance_commitments,
);
let instance_commitments = instance_commitments;
drop(instance_commitments_projective);

for commitment in &instance_commitments {
transcript.common_point(*commitment)?;

if P::QUERY_INSTANCE {
let instance_commitments_projective: Vec<_> = instance_values
.iter()
.map(|poly| params.commit_lagrange(poly, Blind::default()))
.collect();
let mut instance_commitments =
vec![Scheme::Curve::identity(); instance_commitments_projective.len()];
<Scheme::Curve as CurveAffine>::CurveExt::batch_normalize(
&instance_commitments_projective,
&mut instance_commitments,
);
let instance_commitments = instance_commitments;
drop(instance_commitments_projective);

for commitment in &instance_commitments {
transcript.common_point(*commitment)?;
}
}

let instance_polys: Vec<_> = instance_values
Expand Down Expand Up @@ -504,23 +510,25 @@ pub fn create_proof<
let x: ChallengeX<_> = transcript.squeeze_challenge_scalar();
let xn = x.pow(&[params.n() as u64, 0, 0, 0]);

// Compute and hash instance evals for each circuit instance
for instance in instance.iter() {
// Evaluate polynomials at omega^i x
let instance_evals: Vec<_> = meta
.instance_queries
.iter()
.map(|&(column, at)| {
eval_polynomial(
&instance.instance_polys[column.index()],
domain.rotate_omega(*x, at),
)
})
.collect();
if P::QUERY_INSTANCE {
// Compute and hash instance evals for each circuit instance
for instance in instance.iter() {
// Evaluate polynomials at omega^i x
let instance_evals: Vec<_> = meta
.instance_queries
.iter()
.map(|&(column, at)| {
eval_polynomial(
&instance.instance_polys[column.index()],
domain.rotate_omega(*x, at),
)
})
.collect();

// Hash each instance column evaluation
for eval in instance_evals.iter() {
transcript.write_scalar(*eval)?;
// Hash each instance column evaluation
for eval in instance_evals.iter() {
transcript.write_scalar(*eval)?;
}
}
}

Expand Down Expand Up @@ -588,15 +596,16 @@ pub fn create_proof<
.flat_map(|(((instance, advice), permutation), lookups)| {
iter::empty()
.chain(
pk.vk
.cs
.instance_queries
.iter()
.map(move |&(column, at)| ProverQuery {
point: domain.rotate_omega(*x, at),
poly: &instance.instance_polys[column.index()],
blind: Blind::default(),
}),
P::QUERY_INSTANCE
.then_some(pk.vk.cs.instance_queries.iter().map(move |&(column, at)| {
ProverQuery {
point: domain.rotate_omega(*x, at),
poly: &instance.instance_polys[column.index()],
blind: Blind::default(),
}
}))
.into_iter()
.flatten(),
)
.chain(
pk.vk
Expand Down
132 changes: 97 additions & 35 deletions halo2_proofs/src/plonk/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::{
vanishing, ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, ChallengeY, Error,
VerifyingKey,
};
use crate::arithmetic::{CurveAffine, FieldExt};
use crate::arithmetic::{compute_inner_product, CurveAffine, FieldExt};
use crate::poly::commitment::{CommitmentScheme, Verifier};
use crate::poly::VerificationStrategy;
use crate::poly::{
Expand Down Expand Up @@ -45,34 +45,48 @@ pub fn verify_proof<
}
}

let instance_commitments = instances
.iter()
.map(|instance| {
instance
.iter()
.map(|instance| {
if instance.len() > params.n() as usize - (vk.cs.blinding_factors() + 1) {
return Err(Error::InstanceTooLarge);
}
let mut poly = instance.to_vec();
poly.resize(params.n() as usize, Scheme::Scalar::zero());
let poly = vk.domain.lagrange_from_vec(poly);

Ok(params.commit_lagrange(&poly, Blind::default()).to_affine())
})
.collect::<Result<Vec<_>, _>>()
})
.collect::<Result<Vec<_>, _>>()?;
let instance_commitments = if V::QUERY_INSTANCE {
instances
.iter()
.map(|instance| {
instance
.iter()
.map(|instance| {
if instance.len() > params.n() as usize - (vk.cs.blinding_factors() + 1) {
return Err(Error::InstanceTooLarge);
}
let mut poly = instance.to_vec();
poly.resize(params.n() as usize, Scheme::Scalar::zero());
let poly = vk.domain.lagrange_from_vec(poly);

Ok(params.commit_lagrange(&poly, Blind::default()).to_affine())
})
.collect::<Result<Vec<_>, _>>()
})
.collect::<Result<Vec<_>, _>>()?
} else {
vec![vec![]; instances.len()]
};

let num_proofs = instance_commitments.len();

// Hash verification key into transcript
vk.hash_into(transcript)?;

for instance_commitments in instance_commitments.iter() {
// Hash the instance (external) commitments into the transcript
for commitment in instance_commitments {
transcript.common_point(*commitment)?
if V::QUERY_INSTANCE {
for instance_commitments in instance_commitments.iter() {
// Hash the instance (external) commitments into the transcript
for commitment in instance_commitments {
transcript.common_point(*commitment)?
}
}
} else {
for instance in instances.iter() {
for instance in instance.iter() {
for value in instance.iter() {
transcript.common_scalar(*value)?;
}
}
}
}

Expand Down Expand Up @@ -153,9 +167,52 @@ pub fn verify_proof<
// Sample x challenge, which is used to ensure the circuit is
// satisfied with high probability.
let x: ChallengeX<_> = transcript.squeeze_challenge_scalar();
let instance_evals = (0..num_proofs)
.map(|_| -> Result<Vec<_>, _> { read_n_scalars(transcript, vk.cs.instance_queries.len()) })
.collect::<Result<Vec<_>, _>>()?;
let instance_evals = if V::QUERY_INSTANCE {
(0..num_proofs)
.map(|_| -> Result<Vec<_>, _> {
read_n_scalars(transcript, vk.cs.instance_queries.len())
})
.collect::<Result<Vec<_>, _>>()?
} else {
let xn = x.pow(&[params.n() as u64, 0, 0, 0]);
let (min_rotation, max_rotation) =
vk.cs
.instance_queries
.iter()
.fold((0, 0), |(min, max), (_, rotation)| {
if rotation.0 < min {
(rotation.0, max)
} else if rotation.0 > max {
(min, rotation.0)
} else {
(min, max)
}
});
let max_instance_len = instances
.iter()
.flat_map(|instance| instance.iter().map(|instance| instance.len()))
.max_by(Ord::cmp)
.unwrap_or_default();
let l_i_s = &vk.domain.l_i_range(
*x,
xn,
-max_rotation..max_instance_len as i32 + min_rotation.abs(),
);
instances
.iter()
.map(|instances| {
vk.cs
.instance_queries
.iter()
.map(|(column, rotation)| {
let instances = instances[column.index()];
let offset = (max_rotation - rotation.0) as usize;
compute_inner_product(instances, &l_i_s[offset..offset + instances.len()])
})
.collect::<Vec<_>>()
})
.collect::<Vec<_>>()
};

let advice_evals = (0..num_proofs)
.map(|_| -> Result<Vec<_>, _> { read_n_scalars(transcript, vk.cs.advice_queries.len()) })
Expand Down Expand Up @@ -282,15 +339,20 @@ pub fn verify_proof<
lookups,
)| {
iter::empty()
.chain(vk.cs.instance_queries.iter().enumerate().map(
move |(query_index, &(column, at))| {
VerifierQuery::new_commitment(
&instance_commitments[column.index()],
vk.domain.rotate_omega(*x, at),
instance_evals[query_index],
)
},
))
.chain(
V::QUERY_INSTANCE
.then_some(vk.cs.instance_queries.iter().enumerate().map(
move |(query_index, &(column, at))| {
VerifierQuery::new_commitment(
&instance_commitments[column.index()],
vk.domain.rotate_omega(*x, at),
instance_evals[query_index],
)
},
))
.into_iter()
.flatten(),
)
.chain(vk.cs.advice_queries.iter().enumerate().map(
move |(query_index, &(column, at))| {
VerifierQuery::new_commitment(
Expand Down
6 changes: 6 additions & 0 deletions halo2_proofs/src/poly/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ pub trait MSM<C: CurveAffine>: Clone + Debug {

/// Common multi-open prover interface for various commitment schemes
pub trait Prover<'params, Scheme: CommitmentScheme> {
/// Query instance or not
const QUERY_INSTANCE: bool;

/// Creates new prover instance
fn new(params: &'params Scheme::ParamsProver) -> Self;

Expand Down Expand Up @@ -156,6 +159,9 @@ pub trait Verifier<'params, Scheme: CommitmentScheme> {
/// Accumulator fot comressed verification
type MSMAccumulator;

/// Query instance or not
const QUERY_INSTANCE: bool;

/// Creates new verifier instance
fn new(params: &'params Scheme::ParamsVerifier) -> Self;

Expand Down
2 changes: 2 additions & 0 deletions halo2_proofs/src/poly/ipa/multiopen/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub struct ProverIPA<'params, C: CurveAffine> {
}

impl<'params, C: CurveAffine> Prover<'params, IPACommitmentScheme<C>> for ProverIPA<'params, C> {
const QUERY_INSTANCE: bool = true;

fn new(params: &'params ParamsIPA<C>) -> Self {
Self { params }
}
Expand Down
2 changes: 2 additions & 0 deletions halo2_proofs/src/poly/ipa/multiopen/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ impl<'params, C: CurveAffine> Verifier<'params, IPACommitmentScheme<C>>
type Guard = GuardIPA<'params, C>;
type MSMAccumulator = MSMIPA<'params, C>;

const QUERY_INSTANCE: bool = true;

fn new(params: &'params ParamsVerifierIPA<C>) -> Self {
Self { params }
}
Expand Down
2 changes: 2 additions & 0 deletions halo2_proofs/src/poly/kzg/multiopen/gwc/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub struct ProverGWC<'params, E: Engine> {

/// Create a multi-opening proof
impl<'params, E: Engine + Debug> Prover<'params, KZGCommitmentScheme<E>> for ProverGWC<'params, E> {
const QUERY_INSTANCE: bool = false;

fn new(params: &'params ParamsKZG<E>) -> Self {
Self { params }
}
Expand Down
2 changes: 2 additions & 0 deletions halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ impl<'params, E: MultiMillerLoop + Debug> Verifier<'params, KZGCommitmentScheme<
type Guard = GuardKZG<'params, E>;
type MSMAccumulator = DualMSM<'params, E>;

const QUERY_INSTANCE: bool = false;

fn new(params: &'params ParamsKZG<E>) -> Self {
Self { params }
}
Expand Down
2 changes: 2 additions & 0 deletions halo2_proofs/src/poly/kzg/multiopen/shplonk/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ impl<'a, E: Engine> ProverSHPLONK<'a, E> {
impl<'params, E: Engine + Debug> Prover<'params, KZGCommitmentScheme<E>>
for ProverSHPLONK<'params, E>
{
const QUERY_INSTANCE: bool = false;

fn new(params: &'params ParamsKZG<E>) -> Self {
Self { params }
}
Expand Down
2 changes: 2 additions & 0 deletions halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ impl<'params, E: MultiMillerLoop + Debug> Verifier<'params, KZGCommitmentScheme<
type Guard = GuardKZG<'params, E>;
type MSMAccumulator = DualMSM<'params, E>;

const QUERY_INSTANCE: bool = false;

fn new(params: &'params ParamsKZG<E>) -> Self {
Self { params }
}
Expand Down

0 comments on commit 5fc8ce8

Please sign in to comment.