Skip to content

Commit 92d9356

Browse files
Committed Instances (#7)
* FS: add instance length before instances and not after (more intuitive) * prover: rename variable * add support for committed instances * examples: adapt [vector-ops-unblinded] to test committed instances * prover: create support for [commit_to_instances] * examples: generalize example on committed instances * Address PR feedback
1 parent 8303031 commit 92d9356

File tree

8 files changed

+244
-47
lines changed

8 files changed

+244
-47
lines changed

Cargo.toml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ blake2b_simd = "1" # MSRV 1.66.0
5050
sha3 = "0.9.1"
5151
rand_chacha = "0.3"
5252
serde = { version = "1", optional = true, features = ["derive"] }
53-
serde_derive = { version = "1", optional = true}
53+
serde_derive = { version = "1", optional = true }
5454
rayon = "1.8"
5555

5656
# Developer tooling dependencies
@@ -87,7 +87,18 @@ sanity-checks = []
8787
circuit-params = []
8888
cost-estimator = ["serde", "serde_derive"]
8989
derive_serde = ["halo2curves/derive_serde"]
90-
truncated-challenges = [] # This feature truncates challenges to half the size of the scalar field.
90+
91+
# This feature truncates challenges to half the size of the scalar field.
92+
truncated-challenges = []
93+
94+
# This feature adds a new argument to prover and verifier functions, which
95+
# represents instances in committed form (e.g. in the form of a polynomial
96+
# commitment instead of a vector of scalars).
97+
# The verifier may not know what the content of the commitment is, but can
98+
# be sure that the content is constrained according to the circuit rules.
99+
#
100+
# This feature is very powerful for proving statements on committed data.
101+
committed-instances = []
91102

92103
[lib]
93104
bench = false

benches/plonk.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ fn criterion_benchmark(c: &mut Criterion) {
284284
params,
285285
pk,
286286
&[circuit],
287+
#[cfg(feature = "committed-instances")]
288+
0,
287289
&[&[]],
288290
rng,
289291
&mut transcript,
@@ -300,6 +302,8 @@ fn criterion_benchmark(c: &mut Criterion) {
300302
let mut transcript = CircuitTranscript::init_from_bytes(proof);
301303
assert!(prepare::<bn256::Fr, KZGCommitmentScheme<bn256::Bn256>, _>(
302304
vk,
305+
#[cfg(feature = "committed-instances")]
306+
&[&[]],
303307
&[&[]],
304308
&mut transcript
305309
)

examples/serialization.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ fn main() {
157157
&params,
158158
&pk,
159159
&[circuit],
160+
#[cfg(feature = "committed-instances")]
161+
0,
160162
&[instances],
161163
OsRng,
162164
&mut transcript,
@@ -169,6 +171,8 @@ fn main() {
169171

170172
assert!(prepare::<Fr, KZGCommitmentScheme<Bn256>, _>(
171173
pk.get_vk(),
174+
#[cfg(feature = "committed-instances")]
175+
&[&[]],
172176
&[instances],
173177
&mut transcript,
174178
)

examples/vector-ops-unblinded.rs

Lines changed: 68 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ trait NumericInstructions<F: Field>: Chip<F> {
5454
layouter: impl Layouter<F>,
5555
num: &Self::Num,
5656
row: usize,
57+
instance_col: usize,
5758
) -> Result<(), Error>;
5859
}
5960
// ANCHOR_END: instructions
@@ -75,13 +76,18 @@ struct AddChip<F: Field> {
7576
}
7677
// ANCHOR_END: chip
7778

79+
const NB_INSTANCE_COLS: usize = 5;
80+
81+
#[cfg(feature = "committed-instances")]
82+
const NB_INSTANCE_COMS: usize = 2;
83+
7884
// ANCHOR: chip-config
7985
/// Chip state is stored in a config struct. This is generated by the chip
8086
/// during configuration, and then stored inside the chip.
8187
#[derive(Clone, Debug)]
8288
struct FieldConfig {
8389
advice: [Column<Advice>; 3],
84-
instance: Column<Instance>,
90+
instance_cols: [Column<Instance>; NB_INSTANCE_COLS],
8591
s: Selector,
8692
}
8793

@@ -96,9 +102,11 @@ impl<F: Field> MultChip<F> {
96102
fn configure(
97103
meta: &mut ConstraintSystem<F>,
98104
advice: [Column<Advice>; 3],
99-
instance: Column<Instance>,
105+
instance_cols: [Column<Instance>; NB_INSTANCE_COLS],
100106
) -> <Self as Chip<F>>::Config {
101-
meta.enable_equality(instance);
107+
for column in &instance_cols {
108+
meta.enable_equality(*column);
109+
}
102110
for column in &advice {
103111
meta.enable_equality(*column);
104112
}
@@ -116,7 +124,7 @@ impl<F: Field> MultChip<F> {
116124

117125
FieldConfig {
118126
advice,
119-
instance,
127+
instance_cols,
120128
s,
121129
}
122130
}
@@ -133,9 +141,11 @@ impl<F: Field> AddChip<F> {
133141
fn configure(
134142
meta: &mut ConstraintSystem<F>,
135143
advice: [Column<Advice>; 3],
136-
instance: Column<Instance>,
144+
instance_cols: [Column<Instance>; NB_INSTANCE_COLS],
137145
) -> <Self as Chip<F>>::Config {
138-
meta.enable_equality(instance);
146+
for column in &instance_cols {
147+
meta.enable_equality(*column);
148+
}
139149
for column in &advice {
140150
meta.enable_equality(*column);
141151
}
@@ -153,7 +163,7 @@ impl<F: Field> AddChip<F> {
153163

154164
FieldConfig {
155165
advice,
156-
instance,
166+
instance_cols,
157167
s,
158168
}
159169
}
@@ -268,10 +278,11 @@ impl<F: Field> NumericInstructions<F> for MultChip<F> {
268278
mut layouter: impl Layouter<F>,
269279
num: &Self::Num,
270280
row: usize,
281+
instance_col: usize,
271282
) -> Result<(), Error> {
272283
let config = self.config();
273284

274-
layouter.constrain_instance(num.0.cell(), config.instance, row)
285+
layouter.constrain_instance(num.0.cell(), config.instance_cols[instance_col], row)
275286
}
276287
}
277288
// ANCHOR_END: instructions-impl
@@ -350,10 +361,11 @@ impl<F: Field> NumericInstructions<F> for AddChip<F> {
350361
mut layouter: impl Layouter<F>,
351362
num: &Self::Num,
352363
row: usize,
364+
instance_col: usize,
353365
) -> Result<(), Error> {
354366
let config = self.config();
355367

356-
layouter.constrain_instance(num.0.cell(), config.instance, row)
368+
layouter.constrain_instance(num.0.cell(), config.instance_cols[instance_col], row)
357369
}
358370
}
359371

@@ -383,9 +395,9 @@ impl<F: Field> Circuit<F> for MulCircuit<F> {
383395
];
384396

385397
// We also need an instance column to store public inputs.
386-
let instance = meta.instance_column();
398+
let instance_cols = std::array::from_fn(|_| meta.instance_column());
387399

388-
MultChip::configure(meta, advice, instance)
400+
MultChip::configure(meta, advice, instance_cols)
389401
}
390402

391403
fn synthesize(
@@ -403,7 +415,12 @@ impl<F: Field> Circuit<F> for MulCircuit<F> {
403415

404416
for (i, c) in ab.iter().enumerate() {
405417
// Expose the result as a public input to the circuit.
406-
field_chip.expose_public(layouter.namespace(|| "expose c"), c, i)?;
418+
field_chip.expose_public(
419+
layouter.namespace(|| "expose c"),
420+
c,
421+
i / NB_INSTANCE_COLS,
422+
i % NB_INSTANCE_COLS,
423+
)?;
407424
}
408425
Ok(())
409426
}
@@ -436,9 +453,9 @@ impl<F: Field> Circuit<F> for AddCircuit<F> {
436453
];
437454

438455
// We also need an instance column to store public inputs.
439-
let instance = meta.instance_column();
456+
let instance_cols = std::array::from_fn(|_| meta.instance_column());
440457

441-
AddChip::configure(meta, advice, instance)
458+
AddChip::configure(meta, advice, instance_cols)
442459
}
443460

444461
fn synthesize(
@@ -456,7 +473,12 @@ impl<F: Field> Circuit<F> for AddCircuit<F> {
456473

457474
for (i, c) in ab.iter().enumerate() {
458475
// Expose the result as a public input to the circuit.
459-
field_chip.expose_public(layouter.namespace(|| "expose c"), c, i)?;
476+
field_chip.expose_public(
477+
layouter.namespace(|| "expose c"),
478+
c,
479+
i / NB_INSTANCE_COLS,
480+
i % NB_INSTANCE_COLS,
481+
)?;
460482
}
461483
Ok(())
462484
}
@@ -480,7 +502,20 @@ where
480502
{
481503
let params: ParamsKZG<E> = ParamsKZG::unsafe_setup(k, OsRng);
482504
let vk = keygen_vk_with_k(&params, &circuit, k).unwrap();
483-
let pk = keygen_pk(vk, &circuit).unwrap();
505+
let pk = keygen_pk(vk.clone(), &circuit).unwrap();
506+
507+
let mut public_inputs = vec![vec![]; NB_INSTANCE_COLS];
508+
for i in 0..instances.len() {
509+
public_inputs[i % NB_INSTANCE_COLS].push(instances[i]);
510+
}
511+
let public_inputs: Vec<&[E::Fr]> = public_inputs.iter().map(|v| v.as_slice()).collect();
512+
513+
#[cfg(feature = "committed-instances")]
514+
let instance_commitments = public_inputs
515+
.iter()
516+
.take(NB_INSTANCE_COMS)
517+
.map(|v| commit_to_instances::<E::Fr, KZGCommitmentScheme<E>>(&params, vk.get_domain(), v))
518+
.collect::<Vec<_>>();
484519

485520
let proof = {
486521
let mut transcript = CircuitTranscript::<State>::init();
@@ -489,7 +524,9 @@ where
489524
&params,
490525
&pk,
491526
&[circuit],
492-
&[&[&instances]],
527+
#[cfg(feature = "committed-instances")]
528+
NB_INSTANCE_COMS,
529+
&[&public_inputs],
493530
OsRng,
494531
&mut transcript,
495532
)
@@ -501,9 +538,18 @@ where
501538
let accepted = {
502539
let mut transcript = CircuitTranscript::<State>::init_from_bytes(&proof[..]);
503540

504-
prepare::<E::Fr, KZGCommitmentScheme<E>, _>(pk.get_vk(), &[&[&instances]], &mut transcript)
505-
.unwrap()
506-
.verify(&params.verifier_params())
541+
prepare::<E::Fr, KZGCommitmentScheme<E>, _>(
542+
pk.get_vk(),
543+
#[cfg(feature = "committed-instances")]
544+
&[&instance_commitments],
545+
#[cfg(feature = "committed-instances")]
546+
&[&public_inputs[NB_INSTANCE_COMS..]],
547+
#[cfg(not(feature = "committed-instances"))]
548+
&[&public_inputs],
549+
&mut transcript,
550+
)
551+
.unwrap()
552+
.verify(&params.verifier_params())
507553
};
508554

509555
assert_eq!(accepted.is_ok(), expected);
@@ -520,8 +566,8 @@ fn main() {
520566
let k = 7;
521567

522568
// Prepare the inputs to the circuit!
523-
let a = [Fr::from(2); N];
524-
let b = [Fr::from(3); N];
569+
let a: [Fr; N] = std::array::from_fn(|i| Fr::from(i as u64));
570+
let b: [Fr; N] = std::array::from_fn(|i| Fr::from(2 * i as u64));
525571
let c_mul: Vec<Fr> = a.iter().zip(b).map(|(&a, b)| a * b).collect();
526572
let c_add: Vec<Fr> = a.iter().zip(b).map(|(&a, b)| a + b).collect();
527573

src/dev/cost_model.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,8 @@ mod tests {
886886
&params,
887887
&pk,
888888
&[circuit.clone()],
889+
#[cfg(feature = "committed-instances")]
890+
0,
889891
&[instances],
890892
OsRng,
891893
&mut transcript,

0 commit comments

Comments
 (0)