mirror of https://github.com/zcash/halo2.git
Merge 5c84d46c89
into 7df93fd855
This commit is contained in:
commit
93f145a18a
|
@ -6,6 +6,7 @@ use halo2_proofs::{
|
||||||
plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Fixed, Instance, Selector},
|
plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Fixed, Instance, Selector},
|
||||||
poly::Rotation,
|
poly::Rotation,
|
||||||
};
|
};
|
||||||
|
use pasta_curves::EqAffine;
|
||||||
|
|
||||||
// ANCHOR: instructions
|
// ANCHOR: instructions
|
||||||
trait NumericInstructions<F: Field>: Chip<F> {
|
trait NumericInstructions<F: Field>: Chip<F> {
|
||||||
|
@ -237,7 +238,7 @@ impl<F: Field> NumericInstructions<F> for FieldChip<F> {
|
||||||
/// In this struct we store the private input variables. We use `Option<F>` because
|
/// In this struct we store the private input variables. We use `Option<F>` because
|
||||||
/// they won't have any value during key generation. During proving, if any of these
|
/// they won't have any value during key generation. During proving, if any of these
|
||||||
/// were `None` we would get an error.
|
/// were `None` we would get an error.
|
||||||
#[derive(Default)]
|
#[derive(Copy, Clone)]
|
||||||
struct MyCircuit<F: Field> {
|
struct MyCircuit<F: Field> {
|
||||||
constant: F,
|
constant: F,
|
||||||
a: Value<F>,
|
a: Value<F>,
|
||||||
|
@ -250,7 +251,11 @@ impl<F: Field> Circuit<F> for MyCircuit<F> {
|
||||||
type FloorPlanner = SimpleFloorPlanner;
|
type FloorPlanner = SimpleFloorPlanner;
|
||||||
|
|
||||||
fn without_witnesses(&self) -> Self {
|
fn without_witnesses(&self) -> Self {
|
||||||
Self::default()
|
Self {
|
||||||
|
constant: self.constant,
|
||||||
|
a: Value::default(),
|
||||||
|
b: Value::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
|
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
|
||||||
|
@ -308,7 +313,7 @@ fn main() {
|
||||||
// ANCHOR: test-circuit
|
// ANCHOR: test-circuit
|
||||||
// The number of rows in our circuit cannot exceed 2^k. Since our example
|
// The number of rows in our circuit cannot exceed 2^k. Since our example
|
||||||
// circuit is very small, we can pick a very small value here.
|
// circuit is very small, we can pick a very small value here.
|
||||||
let k = 4;
|
const K: u32 = 4;
|
||||||
|
|
||||||
// Prepare the private and public inputs to the circuit!
|
// Prepare the private and public inputs to the circuit!
|
||||||
let constant = Fp::from(7);
|
let constant = Fp::from(7);
|
||||||
|
@ -328,12 +333,14 @@ fn main() {
|
||||||
let mut public_inputs = vec![c];
|
let mut public_inputs = vec![c];
|
||||||
|
|
||||||
// Given the correct public input, our circuit will verify.
|
// Given the correct public input, our circuit will verify.
|
||||||
let prover = MockProver::run(k, &circuit, vec![public_inputs.clone()]).unwrap();
|
let prover = MockProver::run(K, &circuit, vec![public_inputs.clone()]).unwrap();
|
||||||
assert_eq!(prover.verify(), Ok(()));
|
assert_eq!(prover.verify(), Ok(()));
|
||||||
|
|
||||||
|
assert!(circuit.test_prove_and_verify::<K, EqAffine>(&[&public_inputs]));
|
||||||
|
|
||||||
// If we try some other public input, the proof will fail!
|
// If we try some other public input, the proof will fail!
|
||||||
public_inputs[0] += Fp::one();
|
public_inputs[0] += Fp::one();
|
||||||
let prover = MockProver::run(k, &circuit, vec![public_inputs]).unwrap();
|
let prover = MockProver::run(K, &circuit, vec![public_inputs]).unwrap();
|
||||||
assert!(prover.verify().is_err());
|
assert!(prover.verify().is_err());
|
||||||
// ANCHOR_END: test-circuit
|
// ANCHOR_END: test-circuit
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::{
|
||||||
circuit::{Layouter, Region, Value},
|
circuit::{Layouter, Region, Value},
|
||||||
poly::Rotation,
|
poly::Rotation,
|
||||||
};
|
};
|
||||||
|
use pasta_curves::arithmetic::CurveAffine;
|
||||||
|
|
||||||
mod compress_selectors;
|
mod compress_selectors;
|
||||||
|
|
||||||
|
@ -482,6 +483,42 @@ pub trait Circuit<F: Field> {
|
||||||
/// the caller will be different depending on the context, and they may or
|
/// the caller will be different depending on the context, and they may or
|
||||||
/// may not expect to have a witness present.
|
/// may not expect to have a witness present.
|
||||||
fn synthesize(&self, config: Self::Config, layouter: impl Layouter<F>) -> Result<(), Error>;
|
fn synthesize(&self, config: Self::Config, layouter: impl Layouter<F>) -> Result<(), Error>;
|
||||||
|
|
||||||
|
/// Test proof creation and verification for this circuit.
|
||||||
|
fn test_prove_and_verify<const K: u32, C>(self, instance: &[&[C::Scalar]]) -> bool
|
||||||
|
where
|
||||||
|
C: CurveAffine<ScalarExt = F>,
|
||||||
|
C::Scalar: ff::FromUniformBytes<64>,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
use crate::{
|
||||||
|
plonk::{create_proof, keygen_pk, keygen_vk, verify_proof, SingleVerifier},
|
||||||
|
poly::commitment::Params,
|
||||||
|
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
|
||||||
|
};
|
||||||
|
|
||||||
|
let params = Params::<C>::new(K);
|
||||||
|
|
||||||
|
let vk = keygen_vk(¶ms, &self.without_witnesses()).expect("keygen_vk should not fail");
|
||||||
|
let pk =
|
||||||
|
keygen_pk(¶ms, vk, &self.without_witnesses()).expect("keygen_pk should not fail");
|
||||||
|
|
||||||
|
let mut transcript = Blake2bWrite::<_, _, Challenge255<C>>::init(vec![]);
|
||||||
|
create_proof(
|
||||||
|
¶ms,
|
||||||
|
&pk,
|
||||||
|
&[self],
|
||||||
|
&[instance],
|
||||||
|
rand_core::OsRng,
|
||||||
|
&mut transcript,
|
||||||
|
)
|
||||||
|
.expect("proof generation should not fail");
|
||||||
|
let proof: Vec<u8> = transcript.finalize();
|
||||||
|
|
||||||
|
let strategy = SingleVerifier::new(¶ms);
|
||||||
|
let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
|
||||||
|
verify_proof(¶ms, pk.get_vk(), strategy, &[instance], &mut transcript).is_ok()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Low-degree expression representing an identity that must hold over the committed columns.
|
/// Low-degree expression representing an identity that must hold over the committed columns.
|
||||||
|
|
Loading…
Reference in New Issue