Compare commits

...

6 Commits

Author SHA1 Message Date
ying tong 93f145a18a
Merge 5c84d46c89 into 7df93fd855 2024-03-01 11:27:10 -07:00
Daira-Emma Hopwood 7df93fd855
Merge pull request #814 from adria0/fix/mdbook
Fix MD book generation
2024-02-26 23:50:17 +00:00
adria0 daaa638966 fix(mdbook): fix generation 2024-02-22 22:28:36 +01:00
therealyingtong 5c84d46c89 simple-example: Fix without_witnesses() 2023-04-28 19:20:54 +02:00
therealyingtong 01c2f62290 simple-example: Failing to verify real proof
The constant value is passed in through the MyCircuit struct.
In MyCircuit::without_witnesses(), this constant is set to F::ZERO
(F::default()). Because keygen uses without_witnesses() to define
the circuit, the constant value is set to zero in ConstraintSystem;
however, at proving time, MyCircuit passes in a nonzero constant.
This causes the equality constraint in assign_advice_from_constant
to fail.

In general, fixed values should be copied in without_witnesses().
2023-04-28 19:11:39 +02:00
therealyingtong dd4da393ba plonk::circuit::Circuit: test_prove_and_verify 2023-04-28 19:10:00 +02:00
4 changed files with 56 additions and 9 deletions

View File

@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
toolchain: '1.76.0'
override: true
# - name: Setup mdBook
@ -26,7 +26,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: install
args: mdbook --git https://github.com/HollowMan6/mdBook.git --rev 62e01b34c23b957579c04ee1b24b57814ed8a4d5
args: mdbook --git https://github.com/HollowMan6/mdBook.git --rev 5830c9555a4dc051675d17f1fcb04dd0920543e8
- name: Install mdbook-katex and mdbook-pdf
uses: actions-rs/cargo@v1
@ -40,6 +40,11 @@ jobs:
- name: Build halo2 book
run: mdbook build book/
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2023-10-05
override: true
- name: Build latest rustdocs
uses: actions-rs/cargo@v1
with:

View File

@ -14,8 +14,6 @@ title = "The halo2 Book"
macros = "macros.txt"
renderers = ["html"]
[output.katex]
[output.html]
[output.html.print]

View File

@ -6,6 +6,7 @@ use halo2_proofs::{
plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Fixed, Instance, Selector},
poly::Rotation,
};
use pasta_curves::EqAffine;
// ANCHOR: instructions
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
/// they won't have any value during key generation. During proving, if any of these
/// were `None` we would get an error.
#[derive(Default)]
#[derive(Copy, Clone)]
struct MyCircuit<F: Field> {
constant: F,
a: Value<F>,
@ -250,7 +251,11 @@ impl<F: Field> Circuit<F> for MyCircuit<F> {
type FloorPlanner = SimpleFloorPlanner;
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 {
@ -308,7 +313,7 @@ fn main() {
// ANCHOR: test-circuit
// 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.
let k = 4;
const K: u32 = 4;
// Prepare the private and public inputs to the circuit!
let constant = Fp::from(7);
@ -328,12 +333,14 @@ fn main() {
let mut public_inputs = vec![c];
// 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!(circuit.test_prove_and_verify::<K, EqAffine>(&[&public_inputs]));
// If we try some other public input, the proof will fail!
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());
// ANCHOR_END: test-circuit
}

View File

@ -11,6 +11,7 @@ use crate::{
circuit::{Layouter, Region, Value},
poly::Rotation,
};
use pasta_curves::arithmetic::CurveAffine;
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
/// may not expect to have a witness present.
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(&params, &self.without_witnesses()).expect("keygen_vk should not fail");
let pk =
keygen_pk(&params, vk, &self.without_witnesses()).expect("keygen_pk should not fail");
let mut transcript = Blake2bWrite::<_, _, Challenge255<C>>::init(vec![]);
create_proof(
&params,
&pk,
&[self],
&[instance],
rand_core::OsRng,
&mut transcript,
)
.expect("proof generation should not fail");
let proof: Vec<u8> = transcript.finalize();
let strategy = SingleVerifier::new(&params);
let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
verify_proof(&params, pk.get_vk(), strategy, &[instance], &mut transcript).is_ok()
}
}
/// Low-degree expression representing an identity that must hold over the committed columns.