Public inputs (#113)

With this approach, we don't need `Target::PublicInput`; any routable `Target` can be marked as a public input via `register_public_input`.  The circuit itself hashes these targets, and routes the hash output to the first four wires of a `PublicInputGate`, which is placed at an arbitrary location in the circuit.

All gates have direct access to the purported hash of public inputs. We could think of them as accessing `PI_hash_i(x)` (as in Plonk), but these are now (four) constant functions, so they effectively have direct access to the hash itself.

`PublicInputGate` checks that its first four wires match this purported public input hash. The other gates ignore the hash.

Resolves #64.
This commit is contained in:
Daniel Lubarov 2021-07-21 08:26:19 -07:00 committed by GitHub
parent 48f5c9347f
commit b8ce1d1967
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 230 additions and 49 deletions

View File

@ -50,8 +50,8 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
let circuit = builder.build();
let inputs = PartialWitness::new();
let proof = circuit.prove(inputs)?;
let proof_bytes = serde_cbor::to_vec(&proof).unwrap();
let proof_with_pis = circuit.prove(inputs)?;
let proof_bytes = serde_cbor::to_vec(&proof_with_pis).unwrap();
info!("Proof length: {} bytes", proof_bytes.len());
circuit.verify(proof)
circuit.verify(proof_with_pis)
}

View File

@ -17,6 +17,7 @@ use crate::gates::constant::ConstantGate;
use crate::gates::gate::{GateInstance, GateRef, PrefixedGate};
use crate::gates::gate_tree::Tree;
use crate::gates::noop::NoopGate;
use crate::gates::public_input::PublicInputGate;
use crate::generator::{CopyGenerator, RandomValueGenerator, WitnessGenerator};
use crate::hash::hash_n_to_hash;
use crate::permutation_argument::TargetPartition;
@ -39,8 +40,8 @@ pub struct CircuitBuilder<F: Extendable<D>, const D: usize> {
/// The concrete placement of each gate.
gate_instances: Vec<GateInstance<F, D>>,
/// The next available index for a public input.
public_input_index: usize,
/// Targets to be made public.
public_inputs: Vec<Target>,
/// The next available index for a `VirtualTarget`.
virtual_target_index: usize,
@ -66,7 +67,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
config,
gates: HashSet::new(),
gate_instances: Vec::new(),
public_input_index: 0,
public_inputs: Vec::new(),
virtual_target_index: 0,
copy_constraints: Vec::new(),
context_log: ContextTree::new(),
@ -81,14 +82,14 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.gate_instances.len()
}
pub fn add_public_input(&mut self) -> Target {
let index = self.public_input_index;
self.public_input_index += 1;
Target::PublicInput { index }
/// Registers the given target as a public input.
pub fn register_public_input(&mut self, target: Target) {
self.public_inputs.push(target);
}
pub fn add_public_inputs(&mut self, n: usize) -> Vec<Target> {
(0..n).map(|_i| self.add_public_input()).collect()
/// Registers the given targets as public inputs.
pub fn register_public_inputs(&mut self, targets: &[Target]) {
targets.iter().for_each(|&t| self.register_public_input(t));
}
/// Adds a new "virtual" target. This is not an actual wire in the witness, but just a target
@ -462,10 +463,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let degree_log = log2_strict(degree);
let mut target_partition = TargetPartition::new(|t| match t {
Target::Wire(Wire { gate, input }) => gate * self.config.num_routed_wires + input,
Target::PublicInput { index } => degree * self.config.num_routed_wires + index,
Target::VirtualTarget { index } => {
degree * self.config.num_routed_wires + self.public_input_index + index
}
Target::VirtualTarget { index } => degree * self.config.num_routed_wires + index,
});
for gate in 0..degree {
@ -474,10 +472,6 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
}
for index in 0..self.public_input_index {
target_partition.add(Target::PublicInput { index });
}
for index in 0..self.virtual_target_index {
target_partition.add(Target::VirtualTarget { index });
}
@ -500,6 +494,19 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
pub fn build(mut self) -> CircuitData<F, D> {
let quotient_degree_factor = 7; // TODO: add this as a parameter.
let start = Instant::now();
// Hash the public inputs, and route them to a `PublicInputGate` which will enforce that
// those hash wires match the claimed public inputs.
let public_inputs_hash = self.hash_n_to_hash(self.public_inputs.clone(), true);
let pi_gate = self.add_gate_no_constants(PublicInputGate::get());
for (&hash_part, wire) in public_inputs_hash
.elements
.iter()
.zip(PublicInputGate::wires_public_inputs_hash())
{
self.route(hash_part, Target::wire(pi_gate, wire))
}
info!(
"Degree before blinding & padding: {}",
self.gate_instances.len()
@ -552,6 +559,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
subgroup,
copy_constraints: self.copy_constraints,
gate_instances: self.gate_instances,
public_inputs: self.public_inputs,
marked_targets: self.marked_targets,
};

View File

@ -9,8 +9,9 @@ use crate::fri::FriConfig;
use crate::gates::gate::{GateInstance, PrefixedGate};
use crate::generator::WitnessGenerator;
use crate::polynomial::commitment::ListPolynomialCommitment;
use crate::proof::{Hash, HashTarget, Proof};
use crate::proof::{Hash, HashTarget, ProofWithPublicInputs};
use crate::prover::prove;
use crate::target::Target;
use crate::util::marking::MarkedTargets;
use crate::verifier::verify;
use crate::witness::PartialWitness;
@ -78,12 +79,12 @@ pub struct CircuitData<F: Extendable<D>, const D: usize> {
}
impl<F: Extendable<D>, const D: usize> CircuitData<F, D> {
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<Proof<F, D>> {
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
prove(&self.prover_only, &self.common, inputs)
}
pub fn verify(&self, proof: Proof<F, D>) -> Result<()> {
verify(proof, &self.verifier_only, &self.common)
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, D>) -> Result<()> {
verify(proof_with_pis, &self.verifier_only, &self.common)
}
}
@ -100,7 +101,7 @@ pub struct ProverCircuitData<F: Extendable<D>, const D: usize> {
}
impl<F: Extendable<D>, const D: usize> ProverCircuitData<F, D> {
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<Proof<F, D>> {
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
prove(&self.prover_only, &self.common, inputs)
}
}
@ -112,8 +113,8 @@ pub struct VerifierCircuitData<F: Extendable<D>, const D: usize> {
}
impl<F: Extendable<D>, const D: usize> VerifierCircuitData<F, D> {
pub fn verify(&self, proof: Proof<F, D>) -> Result<()> {
verify(proof, &self.verifier_only, &self.common)
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, D>) -> Result<()> {
verify(proof_with_pis, &self.verifier_only, &self.common)
}
}
@ -130,6 +131,8 @@ pub(crate) struct ProverOnlyCircuitData<F: Extendable<D>, const D: usize> {
pub copy_constraints: Vec<CopyConstraint>,
/// The concrete placement of each gate in the circuit.
pub gate_instances: Vec<GateInstance<F, D>>,
/// Targets to be made public.
pub public_inputs: Vec<Target>,
/// A vector of marked targets. The values assigned to these targets will be displayed by the prover.
pub marked_targets: Vec<MarkedTargets<D>>,
}

View File

@ -31,9 +31,11 @@ pub trait Gate<F: Extendable<D>, const D: usize>: 'static + Send + Sync {
.iter()
.map(|w| F::Extension::from_basefield(*w))
.collect::<Vec<_>>();
let public_inputs_hash = &vars_base.public_inputs_hash;
let vars = EvaluationVars {
local_constants,
local_wires,
public_inputs_hash,
};
let values = self.eval_unfiltered(vars);

View File

@ -2,6 +2,7 @@ use crate::field::extension_field::Extendable;
use crate::field::field::Field;
use crate::gates::gate::GateRef;
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
use crate::proof::Hash;
use crate::util::{log2_ceil, transpose};
use crate::vars::EvaluationVars;
@ -17,6 +18,7 @@ pub(crate) fn test_low_degree<F: Extendable<D>, const D: usize>(gate: GateRef<F,
let wire_ldes = random_low_degree_matrix::<F::Extension>(gate.num_wires(), rate_bits);
let constant_ldes = random_low_degree_matrix::<F::Extension>(gate.num_constants(), rate_bits);
assert_eq!(wire_ldes.len(), constant_ldes.len());
let public_inputs_hash = &Hash::rand();
let constraint_evals = wire_ldes
.iter()
@ -24,6 +26,7 @@ pub(crate) fn test_low_degree<F: Extendable<D>, const D: usize>(gate: GateRef<F,
.map(|(local_wires, local_constants)| EvaluationVars {
local_constants,
local_wires,
public_inputs_hash,
})
.map(|vars| gate.eval_unfiltered(vars))
.collect::<Vec<_>>();

View File

@ -326,6 +326,7 @@ mod tests {
use crate::gates::gmimc::{GMiMCGate, W};
use crate::generator::generate_partial_witness;
use crate::gmimc::gmimc_permute_naive;
use crate::proof::Hash;
use crate::vars::{EvaluationTargets, EvaluationVars};
use crate::verifier::verify;
use crate::wire::Wire;
@ -416,9 +417,11 @@ mod tests {
let gate = Gate::with_constants(constants);
let wires = FF::rand_vec(Gate::end());
let public_inputs_hash = &Hash::rand();
let vars = EvaluationVars {
local_constants: &[],
local_wires: &wires,
public_inputs_hash,
};
let ev = gate.0.eval_unfiltered(vars);
@ -427,9 +430,14 @@ mod tests {
for i in 0..Gate::end() {
pw.set_extension_target(wires_t[i], wires[i]);
}
let public_inputs_hash_t = builder.add_virtual_hash();
pw.set_hash_target(public_inputs_hash_t, *public_inputs_hash);
let vars_t = EvaluationTargets {
local_constants: &[],
local_wires: &wires_t,
public_inputs_hash: &public_inputs_hash_t,
};
let ev_t = gate.0.eval_unfiltered_recursively(&mut builder, vars_t);

View File

@ -288,6 +288,7 @@ mod tests {
use crate::gates::gate::Gate;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::insertion::InsertionGate;
use crate::proof::Hash;
use crate::vars::EvaluationVars;
#[test]
@ -366,6 +367,7 @@ mod tests {
let vars = EvaluationVars {
local_constants: &[],
local_wires: &get_wires(orig_vec, insertion_index, element_to_insert),
public_inputs_hash: &Hash::rand(),
};
assert!(

View File

@ -271,6 +271,7 @@ mod tests {
use crate::gates::gate_testing::test_low_degree;
use crate::gates::interpolation::InterpolationGate;
use crate::polynomial::polynomial::PolynomialCoeffs;
use crate::proof::Hash;
use crate::vars::EvaluationVars;
#[test]
@ -352,6 +353,7 @@ mod tests {
let vars = EvaluationVars {
local_constants: &[],
local_wires: &get_wires(2, coeffs, points, eval_point),
public_inputs_hash: &Hash::rand(),
};
assert!(

View File

@ -10,6 +10,7 @@ pub mod gmimc;
pub mod insertion;
pub mod interpolation;
pub(crate) mod noop;
pub(crate) mod public_input;
#[cfg(test)]
mod gate_testing;

84
src/gates/public_input.rs Normal file
View File

@ -0,0 +1,84 @@
use std::ops::Range;
use crate::circuit_builder::CircuitBuilder;
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable;
use crate::gates::gate::{Gate, GateRef};
use crate::generator::WitnessGenerator;
use crate::vars::{EvaluationTargets, EvaluationVars};
/// A gate whose first four wires will be equal to a hash of public inputs.
pub struct PublicInputGate;
impl PublicInputGate {
pub fn get<F: Extendable<D>, const D: usize>() -> GateRef<F, D> {
GateRef::new(PublicInputGate)
}
pub fn wires_public_inputs_hash() -> Range<usize> {
0..4
}
}
impl<F: Extendable<D>, const D: usize> Gate<F, D> for PublicInputGate {
fn id(&self) -> String {
"PublicInputGate".into()
}
fn eval_unfiltered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension> {
Self::wires_public_inputs_hash()
.zip(vars.public_inputs_hash.elements)
.map(|(wire, hash_part)| vars.local_wires[wire] - hash_part.into())
.collect()
}
fn eval_unfiltered_recursively(
&self,
builder: &mut CircuitBuilder<F, D>,
vars: EvaluationTargets<D>,
) -> Vec<ExtensionTarget<D>> {
Self::wires_public_inputs_hash()
.zip(vars.public_inputs_hash.elements)
.map(|(wire, hash_part)| {
let hash_part_ext = builder.convert_to_ext(hash_part);
builder.sub_extension(vars.local_wires[wire], hash_part_ext)
})
.collect()
}
fn generators(
&self,
_gate_index: usize,
_local_constants: &[F],
) -> Vec<Box<dyn WitnessGenerator<F>>> {
Vec::new()
}
fn num_wires(&self) -> usize {
4
}
fn num_constants(&self) -> usize {
0
}
fn degree(&self) -> usize {
1
}
fn num_constraints(&self) -> usize {
4
}
}
#[cfg(test)]
mod tests {
use crate::field::crandall_field::CrandallField;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::public_input::PublicInputGate;
#[test]
fn low_degree() {
test_low_degree(PublicInputGate::get::<CrandallField, 4>())
}
}

View File

@ -37,6 +37,12 @@ impl<F: Field> Hash<F> {
elements: [elements[0], elements[1], elements[2], elements[3]],
}
}
pub(crate) fn rand() -> Self {
Self {
elements: [F::rand(), F::rand(), F::rand(), F::rand()],
}
}
}
/// Represents a ~256 bit hash output.
@ -79,6 +85,13 @@ pub struct Proof<F: Extendable<D>, const D: usize> {
pub opening_proof: OpeningProof<F, D>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "")]
pub struct ProofWithPublicInputs<F: Extendable<D>, const D: usize> {
pub proof: Proof<F, D>,
pub public_inputs: Vec<F>,
}
pub struct ProofTarget<const D: usize> {
pub wires_root: HashTarget,
pub plonk_zs_partial_products_root: HashTarget,
@ -87,6 +100,11 @@ pub struct ProofTarget<const D: usize> {
pub opening_proof: OpeningProofTarget<D>,
}
pub struct ProofWithPublicInputsTarget<const D: usize> {
pub proof: ProofTarget<D>,
pub public_inputs: Vec<Target>,
}
/// Evaluations and Merkle proof produced by the prover in a FRI query step.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "")]

View File

@ -7,11 +7,12 @@ use rayon::prelude::*;
use crate::circuit_data::{CommonCircuitData, ProverOnlyCircuitData};
use crate::field::extension_field::Extendable;
use crate::generator::generate_partial_witness;
use crate::hash::hash_n_to_hash;
use crate::plonk_challenger::Challenger;
use crate::plonk_common::{PlonkPolynomials, ZeroPolyOnCoset};
use crate::polynomial::commitment::ListPolynomialCommitment;
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
use crate::proof::Proof;
use crate::proof::{Hash, Proof, ProofWithPublicInputs};
use crate::timed;
use crate::util::partial_products::partial_products;
use crate::util::{log2_ceil, transpose};
@ -23,7 +24,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
prover_data: &ProverOnlyCircuitData<F, D>,
common_data: &CommonCircuitData<F, D>,
inputs: PartialWitness<F>,
) -> Result<Proof<F, D>> {
) -> Result<ProofWithPublicInputs<F, D>> {
let config = &common_data.config;
let num_wires = config.num_wires;
let num_challenges = config.num_challenges;
@ -39,6 +40,9 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
"to generate witness"
);
let public_inputs = partial_witness.get_targets(&prover_data.public_inputs);
let public_inputs_hash = hash_n_to_hash(public_inputs.clone(), true);
// Display the marked targets for debugging purposes.
for m in &prover_data.marked_targets {
m.display(&partial_witness);
@ -119,6 +123,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
compute_quotient_polys(
common_data,
prover_data,
&public_inputs_hash,
&wires_commitment,
&zs_partial_products_commitment,
&betas,
@ -178,12 +183,16 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
start_proof_gen.elapsed().as_secs_f32()
);
Ok(Proof {
let proof = Proof {
wires_root: wires_commitment.merkle_tree.root,
plonk_zs_partial_products_root: zs_partial_products_commitment.merkle_tree.root,
quotient_polys_root: quotient_polys_commitment.merkle_tree.root,
openings,
opening_proof,
};
Ok(ProofWithPublicInputs {
proof,
public_inputs,
})
}
@ -284,6 +293,7 @@ fn compute_z<F: Extendable<D>, const D: usize>(
fn compute_quotient_polys<'a, F: Extendable<D>, const D: usize>(
common_data: &CommonCircuitData<F, D>,
prover_data: &'a ProverOnlyCircuitData<F, D>,
public_inputs_hash: &Hash<F>,
wires_commitment: &'a ListPolynomialCommitment<F>,
zs_partial_products_commitment: &'a ListPolynomialCommitment<F>,
betas: &[F],
@ -337,6 +347,7 @@ fn compute_quotient_polys<'a, F: Extendable<D>, const D: usize>(
let vars = EvaluationVarsBase {
local_constants,
local_wires,
public_inputs_hash,
};
let mut quotient_values = eval_vanishing_poly_base(
common_data,

View File

@ -3,7 +3,7 @@ use crate::circuit_data::{CircuitConfig, CommonCircuitData, VerifierCircuitTarge
use crate::context;
use crate::field::extension_field::Extendable;
use crate::plonk_challenger::RecursiveChallenger;
use crate::proof::{HashTarget, ProofTarget};
use crate::proof::{HashTarget, ProofWithPublicInputsTarget};
use crate::util::scaling::ReducingFactorTarget;
use crate::vanishing_poly::eval_vanishing_poly_recursively;
use crate::vars::EvaluationTargets;
@ -15,15 +15,21 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
/// Recursively verifies an inner proof.
pub fn add_recursive_verifier(
&mut self,
proof: ProofTarget<D>,
proof_with_pis: ProofWithPublicInputsTarget<D>,
inner_config: &CircuitConfig,
inner_verifier_data: &VerifierCircuitTarget,
inner_common_data: &CommonCircuitData<F, D>,
) {
assert!(self.config.num_wires >= MIN_WIRES);
assert!(self.config.num_wires >= MIN_ROUTED_WIRES);
let ProofWithPublicInputsTarget {
proof,
public_inputs,
} = proof_with_pis;
let one = self.one_extension();
let public_inputs_hash = &self.hash_n_to_hash(public_inputs, true);
let num_challenges = inner_config.num_challenges;
let mut challenger = RecursiveChallenger::new(self);
@ -53,6 +59,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let vars = EvaluationTargets {
local_constants,
local_wires,
public_inputs_hash,
};
let local_zs = &proof.openings.plonk_zs;
let next_zs = &proof.openings.plonk_zs_right;
@ -127,7 +134,7 @@ mod tests {
use crate::polynomial::commitment::OpeningProofTarget;
use crate::proof::{
FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget,
OpeningSetTarget, Proof,
OpeningSetTarget, Proof, ProofTarget, ProofWithPublicInputs,
};
use crate::verifier::verify;
use crate::witness::PartialWitness;
@ -167,9 +174,14 @@ mod tests {
// Construct a `ProofTarget` with the same dimensions as `proof`.
fn proof_to_proof_target<F: Extendable<D>, const D: usize>(
proof: &Proof<F, D>,
proof_with_pis: &ProofWithPublicInputs<F, D>,
builder: &mut CircuitBuilder<F, D>,
) -> ProofTarget<D> {
) -> ProofWithPublicInputsTarget<D> {
let ProofWithPublicInputs {
proof,
public_inputs,
} = proof_with_pis;
let wires_root = builder.add_virtual_hash();
let plonk_zs_root = builder.add_virtual_hash();
let quotient_polys_root = builder.add_virtual_hash();
@ -208,21 +220,41 @@ mod tests {
},
};
ProofTarget {
let proof = ProofTarget {
wires_root,
plonk_zs_partial_products_root: plonk_zs_root,
quotient_polys_root,
openings,
opening_proof,
};
let public_inputs = builder.add_virtual_targets(public_inputs.len());
ProofWithPublicInputsTarget {
proof,
public_inputs,
}
}
// Set the targets in a `ProofTarget` to their corresponding values in a `Proof`.
fn set_proof_target<F: Extendable<D>, const D: usize>(
proof: &Proof<F, D>,
pt: &ProofTarget<D>,
proof: &ProofWithPublicInputs<F, D>,
pt: &ProofWithPublicInputsTarget<D>,
pw: &mut PartialWitness<F>,
) {
let ProofWithPublicInputs {
proof,
public_inputs,
} = proof;
let ProofWithPublicInputsTarget {
proof: pt,
public_inputs: pi_targets,
} = pt;
// Set public inputs.
for (&pi_t, &pi) in pi_targets.iter().zip(public_inputs) {
pw.set_target(pi_t, pi);
}
pw.set_hash_target(pt.wires_root, proof.wires_root);
pw.set_hash_target(
pt.plonk_zs_partial_products_root,
@ -343,7 +375,7 @@ mod tests {
num_query_rounds: 40,
},
};
let (proof, vd, cd) = {
let (proof_with_pis, vd, cd) = {
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
let _two = builder.two();
let _two = builder.hash_n_to_hash(vec![_two], true).elements[0];
@ -357,12 +389,12 @@ mod tests {
data.common,
)
};
verify(proof.clone(), &vd, &cd)?;
verify(proof_with_pis.clone(), &vd, &cd)?;
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
let mut pw = PartialWitness::new();
let pt = proof_to_proof_target(&proof, &mut builder);
set_proof_target(&proof, &pt, &mut pw);
let pt = proof_to_proof_target(&proof_with_pis, &mut builder);
set_proof_target(&proof_with_pis, &pt, &mut pw);
let inner_data = VerifierCircuitTarget {
constants_sigmas_root: builder.add_virtual_hash(),

View File

@ -7,9 +7,6 @@ use crate::wire::Wire;
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum Target {
Wire(Wire),
PublicInput {
index: usize,
},
/// A target that doesn't have any inherent location in the witness (but it can be copied to
/// another target that does). This is useful for representing intermediate values in witness
/// generation.
@ -26,7 +23,6 @@ impl Target {
pub fn is_routable(&self, config: &CircuitConfig) -> bool {
match self {
Target::Wire(wire) => wire.is_routable(config),
Target::PublicInput { .. } => true,
Target::VirtualTarget { .. } => true,
}
}

View File

@ -5,17 +5,20 @@ use crate::field::extension_field::algebra::ExtensionAlgebra;
use crate::field::extension_field::target::{ExtensionAlgebraTarget, ExtensionTarget};
use crate::field::extension_field::Extendable;
use crate::field::field::Field;
use crate::proof::{Hash, HashTarget};
#[derive(Debug, Copy, Clone)]
pub struct EvaluationVars<'a, F: Extendable<D>, const D: usize> {
pub(crate) local_constants: &'a [F::Extension],
pub(crate) local_wires: &'a [F::Extension],
pub(crate) public_inputs_hash: &'a Hash<F>,
}
#[derive(Debug, Copy, Clone)]
pub struct EvaluationVarsBase<'a, F: Field> {
pub(crate) local_constants: &'a [F],
pub(crate) local_wires: &'a [F],
pub(crate) public_inputs_hash: &'a Hash<F>,
}
impl<'a, F: Extendable<D>, const D: usize> EvaluationVars<'a, F, D> {
@ -49,6 +52,7 @@ impl<'a, const D: usize> EvaluationTargets<'a, D> {
pub struct EvaluationTargets<'a, const D: usize> {
pub(crate) local_constants: &'a [ExtensionTarget<D>],
pub(crate) local_wires: &'a [ExtensionTarget<D>],
pub(crate) public_inputs_hash: &'a HashTarget,
}
impl<'a, const D: usize> EvaluationTargets<'a, D> {

View File

@ -3,20 +3,27 @@ use anyhow::{ensure, Result};
use crate::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData};
use crate::field::extension_field::Extendable;
use crate::field::field::Field;
use crate::hash::hash_n_to_hash;
use crate::plonk_challenger::Challenger;
use crate::plonk_common::reduce_with_powers;
use crate::proof::Proof;
use crate::proof::ProofWithPublicInputs;
use crate::vanishing_poly::eval_vanishing_poly;
use crate::vars::EvaluationVars;
pub(crate) fn verify<F: Extendable<D>, const D: usize>(
proof: Proof<F, D>,
proof_with_pis: ProofWithPublicInputs<F, D>,
verifier_data: &VerifierOnlyCircuitData<F>,
common_data: &CommonCircuitData<F, D>,
) -> Result<()> {
let ProofWithPublicInputs {
proof,
public_inputs,
} = proof_with_pis;
let config = &common_data.config;
let num_challenges = config.num_challenges;
let public_inputs_hash = &hash_n_to_hash(public_inputs, true);
let mut challenger = Challenger::new();
// Observe the instance.
// TODO: Need to include public inputs as well.
@ -37,6 +44,7 @@ pub(crate) fn verify<F: Extendable<D>, const D: usize>(
let vars = EvaluationVars {
local_constants,
local_wires,
public_inputs_hash,
};
let local_zs = &proof.openings.plonk_zs;
let next_zs = &proof.openings.plonk_zs_right;

View File

@ -193,7 +193,6 @@ impl<F: Field> PartialWitness<F> {
gate,
gate_instances[*gate].gate_type.0.id()
),
Target::PublicInput { index } => format!("{}-th public input", index),
Target::VirtualTarget { index } => format!("{}-th virtual target", index),
}
};