Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: optionally unblinded advice columns #220

30 changes: 30 additions & 0 deletions halo2_proofs/src/plonk/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1555,6 +1555,9 @@ pub struct ConstraintSystem<F: Field> {
pub(crate) num_selectors: usize,
pub(crate) num_challenges: usize,

/// Contains the index of each advice column that is left unblinded.
pub(crate) unblinded_advice_columns: Vec<usize>,

/// Contains the phase for each advice column. Should have same length as num_advice_columns.
pub(crate) advice_column_phase: Vec<sealed::Phase>,
/// Contains the phase for each challenge. Should have same length as num_challenges.
Expand Down Expand Up @@ -1662,6 +1665,7 @@ impl<F: Field> Default for ConstraintSystem<F> {
num_instance_columns: 0,
num_selectors: 0,
num_challenges: 0,
unblinded_advice_columns: Vec::new(),
advice_column_phase: Vec::new(),
challenge_phase: Vec::new(),
selector_map: vec![],
Expand Down Expand Up @@ -2139,11 +2143,37 @@ impl<F: Field> ConstraintSystem<F> {
tmp
}

/// Allocate a new unblinded advice column at `FirstPhase`
pub fn unblinded_advice_column(&mut self) -> Column<Advice> {
self.unblinded_advice_column_in(FirstPhase)
}

/// Allocate a new advice column at `FirstPhase`
pub fn advice_column(&mut self) -> Column<Advice> {
self.advice_column_in(FirstPhase)
}

/// Allocate a new advice column in given phase
alexander-camuto marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you extend a bit more the docs to actually mention what does it imply to have this type of column and what is designed to be useful for?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have added 2 extra sentences to provide a bit more context. We have some longer form description of the utility of this in two articles:

(creds also due to @han0110 for helping sanity check these)

Lmk if you think we should link to these explicitly in the docs or if we should instead incorporate fragments of them

pub fn unblinded_advice_column_in<P: Phase>(&mut self, phase: P) -> Column<Advice> {
let phase = phase.to_sealed();
if let Some(previous_phase) = phase.prev() {
self.assert_phase_exists(
previous_phase,
format!("Column<Advice> in later phase {:?}", phase).as_str(),
);
}

let tmp = Column {
index: self.num_advice_columns,
column_type: Advice { phase },
};
self.unblinded_advice_columns.push(tmp.index);
self.num_advice_columns += 1;
self.num_advice_queries.push(0);
self.advice_column_phase.push(phase);
tmp
CPerezz marked this conversation as resolved.
Show resolved Hide resolved
}

/// Allocate a new advice column in given phase
pub fn advice_column_in<P: Phase>(&mut self, phase: P) -> Column<Advice> {
let phase = phase.to_sealed();
Expand Down
24 changes: 19 additions & 5 deletions halo2_proofs/src/plonk/prover.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ff::{Field, FromUniformBytes, WithSmallOrderMulGroup};
use group::Curve;
use rand_core::RngCore;
use std::collections::BTreeSet;
use std::collections::{BTreeSet, HashSet};
use std::ops::RangeTo;
use std::{collections::HashMap, iter};

Expand Down Expand Up @@ -147,6 +147,7 @@ where
k: u32,
current_phase: sealed::Phase,
advice: Vec<Polynomial<Assigned<F>, LagrangeCoeff>>,
unblinded_advice: HashSet<usize>,
alexander-camuto marked this conversation as resolved.
Show resolved Hide resolved
challenges: &'a HashMap<usize, F>,
instances: &'a [&'a [F]],
usable_rows: RangeTo<usize>,
Expand Down Expand Up @@ -319,6 +320,9 @@ where
k: params.k(),
current_phase,
advice: vec![domain.empty_lagrange_assigned(); meta.num_advice_columns],
unblinded_advice: HashSet::from_iter(
meta.unblinded_advice_columns.clone().into_iter(),
),
alexander-camuto marked this conversation as resolved.
Show resolved Hide resolved
instances,
challenges: &challenges,
// The prover will not be allowed to assign values to advice
Expand Down Expand Up @@ -353,16 +357,26 @@ where
);

// Add blinding factors to advice columns
for advice_values in &mut advice_values {
for (column_index, advice_values) in &mut advice_values.iter_mut().enumerate() {
for cell in &mut advice_values[unusable_rows_start..] {
*cell = Scheme::Scalar::random(&mut rng);
if witness.unblinded_advice.contains(&column_index) {
*cell = Blind::default().0;
} else {
*cell = Scheme::Scalar::random(&mut rng);
}
alexander-camuto marked this conversation as resolved.
Show resolved Hide resolved
}
}

// Compute commitments to advice column polynomials
let blinds: Vec<_> = advice_values
.iter()
.map(|_| Blind(Scheme::Scalar::random(&mut rng)))
let blinds: Vec<_> = (0..meta.num_advice_columns)
.map(|i| {
if witness.unblinded_advice.contains(&i) {
alexander-camuto marked this conversation as resolved.
Show resolved Hide resolved
Blind::default()
} else {
Blind(Scheme::Scalar::random(&mut rng))
}
})
.collect();
let advice_commitments_projective: Vec<_> = advice_values
.iter()
Expand Down
Loading