mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-10 09:43:09 +00:00
First pass
This commit is contained in:
parent
2cf82636f8
commit
ce71b536bf
@ -27,10 +27,12 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
rate_bits: 3,
|
||||
num_challenges: 3,
|
||||
zero_knowledge: false,
|
||||
cap_height: 1,
|
||||
fri_config: FriConfig {
|
||||
proof_of_work_bits: 20,
|
||||
reduction_arity_bits: vec![2, 2, 2, 2, 2, 2],
|
||||
num_query_rounds: 35,
|
||||
cap_height: 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
values: Vec<PolynomialValues<F>>,
|
||||
rate_bits: usize,
|
||||
blinding: bool,
|
||||
cap_height: usize,
|
||||
timing: &mut TimingTree,
|
||||
) -> Self {
|
||||
let coeffs = timed!(
|
||||
@ -42,7 +43,7 @@ impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
values.par_iter().map(|v| v.ifft()).collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
Self::from_coeffs(coeffs, rate_bits, blinding, timing)
|
||||
Self::from_coeffs(coeffs, rate_bits, blinding, cap_height, timing)
|
||||
}
|
||||
|
||||
/// Creates a list polynomial commitment for the polynomials `polynomials`.
|
||||
@ -50,6 +51,7 @@ impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
polynomials: Vec<PolynomialCoeffs<F>>,
|
||||
rate_bits: usize,
|
||||
blinding: bool,
|
||||
cap_height: usize,
|
||||
timing: &mut TimingTree,
|
||||
) -> Self {
|
||||
let degree = polynomials[0].len();
|
||||
@ -61,7 +63,11 @@ impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
|
||||
let mut leaves = timed!(timing, "transpose LDEs", transpose(&lde_values));
|
||||
reverse_index_bits_in_place(&mut leaves);
|
||||
let merkle_tree = timed!(timing, "build Merkle tree", MerkleTree::new(leaves, false));
|
||||
let merkle_tree = timed!(
|
||||
timing,
|
||||
"build Merkle tree",
|
||||
MerkleTree::new(leaves, cap_height, false)
|
||||
);
|
||||
|
||||
Self {
|
||||
polynomials,
|
||||
@ -250,7 +256,8 @@ mod tests {
|
||||
let degree = 1 << degree_log;
|
||||
|
||||
(0..k)
|
||||
.map(|_| PolynomialValues::new(F::rand_vec(degree)))
|
||||
// .map(|_| PolynomialValues::new(F::rand_vec(degree)))
|
||||
.map(|_| PolynomialValues::new((1..=degree).map(F::from_canonical_usize).collect()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -274,6 +281,7 @@ mod tests {
|
||||
proof_of_work_bits: 2,
|
||||
reduction_arity_bits: vec![2, 3, 1, 2],
|
||||
num_query_rounds: 3,
|
||||
cap_height: 0,
|
||||
};
|
||||
// We only care about `fri_config, num_constants`, and `num_routed_wires` here.
|
||||
let common_data = CommonCircuitData {
|
||||
@ -297,13 +305,15 @@ mod tests {
|
||||
PolynomialBatchCommitment::<F>::from_values(
|
||||
gen_random_test_case(ks[i], degree_bits),
|
||||
common_data.config.rate_bits,
|
||||
PlonkPolynomials::polynomials(i).blinding,
|
||||
false,
|
||||
common_data.config.cap_height,
|
||||
&mut TimingTree::default(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let zeta = gen_random_point::<F, D>(degree_bits);
|
||||
let zeta = F::Extension::MULTIPLICATIVE_GROUP_GENERATOR;
|
||||
let (proof, os) = PolynomialBatchCommitment::open_plonk::<D>(
|
||||
&[&lpcs[0], &lpcs[1], &lpcs[2], &lpcs[3]],
|
||||
zeta,
|
||||
@ -313,10 +323,10 @@ mod tests {
|
||||
);
|
||||
|
||||
let merkle_roots = &[
|
||||
lpcs[0].merkle_tree.root,
|
||||
lpcs[1].merkle_tree.root,
|
||||
lpcs[2].merkle_tree.root,
|
||||
lpcs[3].merkle_tree.root,
|
||||
lpcs[0].merkle_tree.root.clone(),
|
||||
lpcs[1].merkle_tree.root.clone(),
|
||||
lpcs[2].merkle_tree.root.clone(),
|
||||
lpcs[3].merkle_tree.root.clone(),
|
||||
];
|
||||
|
||||
verify_fri_proof(
|
||||
|
||||
@ -20,6 +20,8 @@ pub struct FriConfig {
|
||||
|
||||
/// Number of query rounds to perform.
|
||||
pub num_query_rounds: usize,
|
||||
|
||||
pub cap_height: usize,
|
||||
}
|
||||
|
||||
fn fri_delta(rate_log: usize, conjecture: bool) -> f64 {
|
||||
|
||||
@ -4,8 +4,9 @@ use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::Field;
|
||||
use crate::gadgets::polynomial::PolynomialCoeffsExtTarget;
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget};
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget};
|
||||
use crate::hash::merkle_proofs::{MerkleProof, MerkleProofTarget};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::plonk_common::PolynomialsIndexBlinding;
|
||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||
@ -77,7 +78,7 @@ pub struct FriQueryRoundTarget<const D: usize> {
|
||||
#[serde(bound = "")]
|
||||
pub struct FriProof<F: Extendable<D>, const D: usize> {
|
||||
/// A Merkle root for each reduced polynomial in the commit phase.
|
||||
pub commit_phase_merkle_roots: Vec<HashOut<F>>,
|
||||
pub commit_phase_merkle_roots: Vec<MerkleCap<F>>,
|
||||
/// Query rounds proofs
|
||||
pub query_round_proofs: Vec<FriQueryRound<F, D>>,
|
||||
/// The final polynomial in coefficient form.
|
||||
@ -87,7 +88,7 @@ pub struct FriProof<F: Extendable<D>, const D: usize> {
|
||||
}
|
||||
|
||||
pub struct FriProofTarget<const D: usize> {
|
||||
pub commit_phase_merkle_roots: Vec<HashOutTarget>,
|
||||
pub commit_phase_merkle_roots: Vec<MerkleCapTarget>,
|
||||
pub query_round_proofs: Vec<FriQueryRoundTarget<D>>,
|
||||
pub final_poly: PolynomialCoeffsExtTarget<D>,
|
||||
pub pow_witness: Target,
|
||||
|
||||
@ -53,7 +53,7 @@ pub fn fri_proof<F: Field + Extendable<D>, const D: usize>(
|
||||
fri_prover_query_rounds(initial_merkle_trees, &trees, challenger, n, config);
|
||||
|
||||
FriProof {
|
||||
commit_phase_merkle_roots: trees.iter().map(|t| t.root).collect(),
|
||||
commit_phase_merkle_roots: trees.iter().map(|t| t.root.clone()).collect(),
|
||||
query_round_proofs,
|
||||
final_poly: final_coeffs,
|
||||
pow_witness,
|
||||
@ -80,10 +80,11 @@ fn fri_committed_trees<F: Field + Extendable<D>, const D: usize>(
|
||||
.par_chunks(arity)
|
||||
.map(|chunk: &[F::Extension]| flatten(chunk))
|
||||
.collect(),
|
||||
config.cap_height,
|
||||
false,
|
||||
);
|
||||
|
||||
challenger.observe_hash(&tree.root);
|
||||
challenger.observe_cap(&tree.root);
|
||||
trees.push(tree);
|
||||
|
||||
let beta = challenger.get_extension_challenge();
|
||||
@ -155,6 +156,7 @@ fn fri_prover_query_round<F: Field + Extendable<D>, const D: usize>(
|
||||
let arity_bits = config.reduction_arity_bits[i];
|
||||
let arity = 1 << arity_bits;
|
||||
let mut evals = unflatten(tree.get(x_index >> arity_bits));
|
||||
dbg!(&evals);
|
||||
evals.remove(x_index & (arity - 1));
|
||||
let merkle_proof = tree.prove(x_index >> arity_bits);
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::Field;
|
||||
use crate::fri::proof::{FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget};
|
||||
use crate::fri::FriConfig;
|
||||
use crate::hash::hash_types::HashOutTarget;
|
||||
use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget};
|
||||
use crate::iop::challenger::RecursiveChallenger;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -83,7 +83,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
os: &OpeningSetTarget<D>,
|
||||
// Point at which the PLONK polynomials are opened.
|
||||
zeta: ExtensionTarget<D>,
|
||||
initial_merkle_roots: &[HashOutTarget],
|
||||
initial_merkle_roots: &[MerkleCapTarget],
|
||||
proof: &FriProofTarget<D>,
|
||||
challenger: &mut RecursiveChallenger,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
@ -111,7 +111,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.commit_phase_merkle_roots
|
||||
.iter()
|
||||
.map(|root| {
|
||||
challenger.observe_hash(root);
|
||||
challenger.observe_cap(root);
|
||||
challenger.get_extension_challenge(self)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
@ -176,9 +176,9 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
&mut self,
|
||||
x_index_bits: &[Target],
|
||||
proof: &FriInitialTreeProofTarget,
|
||||
initial_merkle_roots: &[HashOutTarget],
|
||||
initial_merkle_roots: &[MerkleCapTarget],
|
||||
) {
|
||||
for (i, ((evals, merkle_proof), &root)) in proof
|
||||
for (i, ((evals, merkle_proof), root)) in proof
|
||||
.evals_proofs
|
||||
.iter()
|
||||
.zip(initial_merkle_roots)
|
||||
@ -270,7 +270,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
zeta: ExtensionTarget<D>,
|
||||
alpha: ExtensionTarget<D>,
|
||||
precomputed_reduced_evals: PrecomputedReducedEvalsTarget<D>,
|
||||
initial_merkle_roots: &[HashOutTarget],
|
||||
initial_merkle_roots: &[MerkleCapTarget],
|
||||
proof: &FriProofTarget<D>,
|
||||
challenger: &mut RecursiveChallenger,
|
||||
n: usize,
|
||||
@ -347,7 +347,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
self.verify_merkle_proof(
|
||||
flatten_target(&evals),
|
||||
&high_x_index_bits,
|
||||
proof.commit_phase_merkle_roots[i],
|
||||
&proof.commit_phase_merkle_roots[i],
|
||||
&round_proof.steps[i].merkle_proof,
|
||||
)
|
||||
);
|
||||
|
||||
@ -8,6 +8,7 @@ use crate::fri::FriConfig;
|
||||
use crate::hash::hash_types::HashOut;
|
||||
use crate::hash::hashing::hash_n_to_1;
|
||||
use crate::hash::merkle_proofs::verify_merkle_proof;
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::challenger::Challenger;
|
||||
use crate::plonk::circuit_data::CommonCircuitData;
|
||||
use crate::plonk::plonk_common::PlonkPolynomials;
|
||||
@ -73,7 +74,7 @@ pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
|
||||
os: &OpeningSet<F, D>,
|
||||
// Point at which the PLONK polynomials are opened.
|
||||
zeta: F::Extension,
|
||||
initial_merkle_roots: &[HashOut<F>],
|
||||
initial_merkle_roots: &[MerkleCap<F>],
|
||||
proof: &FriProof<F, D>,
|
||||
challenger: &mut Challenger<F>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
@ -98,7 +99,7 @@ pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
|
||||
.commit_phase_merkle_roots
|
||||
.iter()
|
||||
.map(|root| {
|
||||
challenger.observe_hash(root);
|
||||
challenger.observe_cap(root);
|
||||
challenger.get_extension_challenge()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@ -139,9 +140,9 @@ pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
|
||||
fn fri_verify_initial_proof<F: Field>(
|
||||
x_index: usize,
|
||||
proof: &FriInitialTreeProof<F>,
|
||||
initial_merkle_roots: &[HashOut<F>],
|
||||
initial_merkle_roots: &[MerkleCap<F>],
|
||||
) -> Result<()> {
|
||||
for ((evals, merkle_proof), &root) in proof.evals_proofs.iter().zip(initial_merkle_roots) {
|
||||
for ((evals, merkle_proof), root) in proof.evals_proofs.iter().zip(initial_merkle_roots) {
|
||||
verify_merkle_proof(evals.clone(), x_index, root, merkle_proof, false)?;
|
||||
}
|
||||
|
||||
@ -244,7 +245,7 @@ fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>(
|
||||
zeta: F::Extension,
|
||||
alpha: F::Extension,
|
||||
precomputed_reduced_evals: PrecomputedReducedEvals<F, D>,
|
||||
initial_merkle_roots: &[HashOut<F>],
|
||||
initial_merkle_roots: &[MerkleCap<F>],
|
||||
proof: &FriProof<F, D>,
|
||||
challenger: &mut Challenger<F>,
|
||||
n: usize,
|
||||
@ -297,7 +298,7 @@ fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>(
|
||||
verify_merkle_proof(
|
||||
flatten(&evals),
|
||||
x_index >> arity_bits,
|
||||
proof.commit_phase_merkle_roots[i],
|
||||
&proof.commit_phase_merkle_roots[i],
|
||||
&round_proof.steps[i].merkle_proof,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -61,3 +61,6 @@ impl HashOutTarget {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MerkleCapTarget(pub Vec<HashOutTarget>);
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use anyhow::{ensure, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::Field;
|
||||
use crate::gates::gmimc::GMiMCGate;
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget};
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget};
|
||||
use crate::hash::hashing::{compress, hash_or_noop, GMIMC_ROUNDS};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -28,30 +32,29 @@ pub struct MerkleProofTarget {
|
||||
pub(crate) fn verify_merkle_proof<F: Field>(
|
||||
leaf_data: Vec<F>,
|
||||
leaf_index: usize,
|
||||
merkle_root: HashOut<F>,
|
||||
merkle_cap: &MerkleCap<F>,
|
||||
proof: &MerkleProof<F>,
|
||||
reverse_bits: bool,
|
||||
) -> Result<()> {
|
||||
ensure!(
|
||||
leaf_index >> proof.siblings.len() == 0,
|
||||
"Merkle leaf index is too large."
|
||||
);
|
||||
|
||||
let index = if reverse_bits {
|
||||
let mut index = if reverse_bits {
|
||||
crate::util::reverse_bits(leaf_index, proof.siblings.len())
|
||||
} else {
|
||||
leaf_index
|
||||
};
|
||||
let mut current_digest = hash_or_noop(leaf_data);
|
||||
for (i, &sibling_digest) in proof.siblings.iter().enumerate() {
|
||||
let bit = (index >> i & 1) == 1;
|
||||
current_digest = if bit {
|
||||
for &sibling_digest in proof.siblings.iter() {
|
||||
let bit = index & 1;
|
||||
index >>= 1;
|
||||
current_digest = if bit == 1 {
|
||||
compress(sibling_digest, current_digest)
|
||||
} else {
|
||||
compress(current_digest, sibling_digest)
|
||||
}
|
||||
}
|
||||
ensure!(current_digest == merkle_root, "Invalid Merkle proof.");
|
||||
ensure!(
|
||||
current_digest == merkle_cap.0[index],
|
||||
"Invalid Merkle proof."
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -63,7 +66,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
&mut self,
|
||||
leaf_data: Vec<Target>,
|
||||
leaf_index_bits: &[Target],
|
||||
merkle_root: HashOutTarget,
|
||||
merkle_root: &MerkleCapTarget,
|
||||
proof: &MerkleProofTarget,
|
||||
) {
|
||||
let zero = self.zero();
|
||||
@ -108,7 +111,25 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
)
|
||||
}
|
||||
|
||||
self.named_assert_hashes_equal(state, merkle_root, "check Merkle root".into())
|
||||
let index = self.le_sum(leaf_index_bits[proof.siblings.len()..].to_vec().into_iter());
|
||||
let mut state_ext = [zero; D];
|
||||
for i in 0..D {
|
||||
state_ext[i] = state.elements[i];
|
||||
}
|
||||
let state_ext = ExtensionTarget(state_ext);
|
||||
let cap_ext = merkle_root
|
||||
.0
|
||||
.iter()
|
||||
.map(|h| {
|
||||
let mut tmp = [zero; D];
|
||||
for i in 0..D {
|
||||
tmp[i] = h.elements[i];
|
||||
}
|
||||
ExtensionTarget(tmp)
|
||||
})
|
||||
.collect();
|
||||
self.random_access(index, state_ext, cap_ext);
|
||||
// self.named_assert_hashes_equal(state, merkle_root, "check Merkle root".into())
|
||||
}
|
||||
|
||||
pub(crate) fn assert_hashes_equal(&mut self, x: HashOutTarget, y: HashOutTarget) {
|
||||
@ -159,8 +180,9 @@ mod tests {
|
||||
|
||||
let log_n = 8;
|
||||
let n = 1 << log_n;
|
||||
let cap_height = 1;
|
||||
let leaves = random_data::<F>(n, 7);
|
||||
let tree = MerkleTree::new(leaves, false);
|
||||
let tree = MerkleTree::new(leaves, cap_height, false);
|
||||
let i: usize = thread_rng().gen_range(0..n);
|
||||
let proof = tree.prove(i);
|
||||
|
||||
@ -171,8 +193,8 @@ mod tests {
|
||||
pw.set_hash_target(proof_t.siblings[i], proof.siblings[i]);
|
||||
}
|
||||
|
||||
let root_t = builder.add_virtual_hash();
|
||||
pw.set_hash_target(root_t, tree.root);
|
||||
let root_t = builder.add_virtual_cap(cap_height);
|
||||
pw.set_cap_target(&root_t, &tree.root);
|
||||
|
||||
let i_c = builder.constant(F::from_canonical_usize(i));
|
||||
let i_bits = builder.split_le(i_c, log_n);
|
||||
@ -182,7 +204,7 @@ mod tests {
|
||||
pw.set_target(data[j], tree.leaves[i][j]);
|
||||
}
|
||||
|
||||
builder.verify_merkle_proof(data, &i_bits, root_t, &proof_t);
|
||||
builder.verify_merkle_proof(data, &i_bits, &root_t, &proof_t);
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::field::field_types::Field;
|
||||
use crate::hash::hash_types::HashOut;
|
||||
@ -6,6 +7,10 @@ use crate::hash::hashing::{compress, hash_or_noop};
|
||||
use crate::hash::merkle_proofs::MerkleProof;
|
||||
use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(bound = "")]
|
||||
pub struct MerkleCap<F: Field>(pub Vec<HashOut<F>>);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MerkleTree<F: Field> {
|
||||
/// The data in the leaves of the Merkle tree.
|
||||
@ -14,8 +19,8 @@ pub struct MerkleTree<F: Field> {
|
||||
/// The layers of hashes in the tree. The first layer is the one at the bottom.
|
||||
pub layers: Vec<Vec<HashOut<F>>>,
|
||||
|
||||
/// The Merkle root.
|
||||
pub root: HashOut<F>,
|
||||
/// The Merkle cap.
|
||||
pub root: MerkleCap<F>,
|
||||
|
||||
/// If true, the indices are in bit-reversed form, so that the leaf at index `i`
|
||||
/// contains the leaf originally at index `reverse_bits(i)`.
|
||||
@ -23,7 +28,7 @@ pub struct MerkleTree<F: Field> {
|
||||
}
|
||||
|
||||
impl<F: Field> MerkleTree<F> {
|
||||
pub fn new(mut leaves: Vec<Vec<F>>, reverse_bits: bool) -> Self {
|
||||
pub fn new(mut leaves: Vec<Vec<F>>, cap_height: usize, reverse_bits: bool) -> Self {
|
||||
if reverse_bits {
|
||||
reverse_index_bits_in_place(&mut leaves);
|
||||
}
|
||||
@ -32,7 +37,7 @@ impl<F: Field> MerkleTree<F> {
|
||||
.map(|l| hash_or_noop(l.clone()))
|
||||
.collect::<Vec<_>>()];
|
||||
while let Some(l) = layers.last() {
|
||||
if l.len() == 1 {
|
||||
if l.len() == 1 << cap_height {
|
||||
break;
|
||||
}
|
||||
let next_layer = l
|
||||
@ -41,11 +46,11 @@ impl<F: Field> MerkleTree<F> {
|
||||
.collect::<Vec<_>>();
|
||||
layers.push(next_layer);
|
||||
}
|
||||
let root = layers.pop().unwrap()[0];
|
||||
let cap = layers.pop().unwrap();
|
||||
Self {
|
||||
leaves,
|
||||
layers,
|
||||
root,
|
||||
root: MerkleCap(cap),
|
||||
reverse_bits,
|
||||
}
|
||||
}
|
||||
@ -97,10 +102,10 @@ mod tests {
|
||||
n: usize,
|
||||
reverse_bits: bool,
|
||||
) -> Result<()> {
|
||||
let tree = MerkleTree::new(leaves.clone(), reverse_bits);
|
||||
let tree = MerkleTree::new(leaves.clone(), 1, reverse_bits);
|
||||
for i in 0..n {
|
||||
let proof = tree.prove(i);
|
||||
verify_merkle_proof(leaves[i].clone(), i, tree.root, &proof, reverse_bits)?;
|
||||
verify_merkle_proof(leaves[i].clone(), i, &tree.root, &proof, reverse_bits)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -3,8 +3,9 @@ use std::convert::TryInto;
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::Field;
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget};
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget};
|
||||
use crate::hash::hashing::{permute, SPONGE_RATE, SPONGE_WIDTH};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::proof::{OpeningSet, OpeningSetTarget};
|
||||
@ -93,6 +94,12 @@ impl<F: Field> Challenger<F> {
|
||||
self.observe_elements(&hash.elements)
|
||||
}
|
||||
|
||||
pub fn observe_cap(&mut self, cap: &MerkleCap<F>) {
|
||||
for hash in &cap.0 {
|
||||
self.observe_elements(&hash.elements)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_challenge(&mut self) -> F {
|
||||
self.absorb_buffered_inputs();
|
||||
|
||||
@ -239,6 +246,12 @@ impl RecursiveChallenger {
|
||||
self.observe_elements(&hash.elements)
|
||||
}
|
||||
|
||||
pub fn observe_cap(&mut self, cap: &MerkleCapTarget) {
|
||||
for hash in &cap.0 {
|
||||
self.observe_hash(hash)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn observe_extension_element<const D: usize>(&mut self, element: ExtensionTarget<D>) {
|
||||
self.observe_elements(&element.0);
|
||||
}
|
||||
|
||||
@ -6,8 +6,9 @@ use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::Field;
|
||||
use crate::gates::gate::GateInstance;
|
||||
use crate::hash::hash_types::HashOut;
|
||||
use crate::hash::hash_types::HashOutTarget;
|
||||
use crate::hash::hash_types::{HashOut, MerkleCapTarget};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::plonk::copy_constraint::CopyConstraint;
|
||||
@ -147,6 +148,12 @@ impl<F: Field> PartialWitness<F> {
|
||||
.for_each(|(&t, x)| self.set_target(t, x));
|
||||
}
|
||||
|
||||
pub fn set_cap_target(&mut self, ct: &MerkleCapTarget, value: &MerkleCap<F>) {
|
||||
for (ht, h) in ct.0.iter().zip(&value.0) {
|
||||
self.set_hash_target(*ht, *h);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_extension_target<const D: usize>(
|
||||
&mut self,
|
||||
et: ExtensionTarget<D>,
|
||||
|
||||
@ -13,8 +13,9 @@ use crate::gates::gate::{Gate, GateInstance, GateRef, PrefixedGate};
|
||||
use crate::gates::gate_tree::Tree;
|
||||
use crate::gates::noop::NoopGate;
|
||||
use crate::gates::public_input::PublicInputGate;
|
||||
use crate::hash::hash_types::HashOutTarget;
|
||||
use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget};
|
||||
use crate::hash::hashing::hash_n_to_hash;
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::generator::{CopyGenerator, RandomValueGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
@ -111,6 +112,10 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
HashOutTarget::from_vec(self.add_virtual_targets(4))
|
||||
}
|
||||
|
||||
pub fn add_virtual_cap(&mut self, cap_height: usize) -> MerkleCapTarget {
|
||||
MerkleCapTarget(self.add_virtual_hashes(1 << cap_height))
|
||||
}
|
||||
|
||||
pub fn add_virtual_hashes(&mut self, n: usize) -> Vec<HashOutTarget> {
|
||||
(0..n).map(|_i| self.add_virtual_hash()).collect()
|
||||
}
|
||||
@ -561,12 +566,13 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
constants_sigmas_vecs,
|
||||
self.config.rate_bits,
|
||||
self.config.zero_knowledge & PlonkPolynomials::CONSTANTS_SIGMAS.blinding,
|
||||
self.config.cap_height,
|
||||
&mut timing,
|
||||
);
|
||||
|
||||
let constants_sigmas_root = constants_sigmas_commitment.merkle_tree.root;
|
||||
let constants_sigmas_root = constants_sigmas_commitment.merkle_tree.root.clone();
|
||||
let verifier_only = VerifierOnlyCircuitData {
|
||||
constants_sigmas_root,
|
||||
constants_sigmas_root: constants_sigmas_root.clone(),
|
||||
};
|
||||
|
||||
let prover_only = ProverOnlyCircuitData {
|
||||
@ -597,7 +603,11 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
// TODO: This should also include an encoding of gate constraints.
|
||||
let circuit_digest_parts = [
|
||||
constants_sigmas_root.elements.to_vec(),
|
||||
constants_sigmas_root
|
||||
.0
|
||||
.into_iter()
|
||||
.flat_map(|h| h.elements)
|
||||
.collect::<Vec<_>>(),
|
||||
vec![/* Add other circuit data here */],
|
||||
];
|
||||
let circuit_digest = hash_n_to_hash(circuit_digest_parts.concat(), false);
|
||||
|
||||
@ -7,7 +7,8 @@ use crate::field::field_types::Field;
|
||||
use crate::fri::commitment::PolynomialBatchCommitment;
|
||||
use crate::fri::FriConfig;
|
||||
use crate::gates::gate::{GateInstance, PrefixedGate};
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget};
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::generator::WitnessGenerator;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
@ -27,6 +28,7 @@ pub struct CircuitConfig {
|
||||
/// `degree / |F|`.
|
||||
pub num_challenges: usize,
|
||||
pub zero_knowledge: bool,
|
||||
pub cap_height: usize,
|
||||
|
||||
// TODO: Find a better place for this.
|
||||
pub fri_config: FriConfig,
|
||||
@ -41,10 +43,12 @@ impl Default for CircuitConfig {
|
||||
rate_bits: 3,
|
||||
num_challenges: 3,
|
||||
zero_knowledge: true,
|
||||
cap_height: 1,
|
||||
fri_config: FriConfig {
|
||||
proof_of_work_bits: 1,
|
||||
reduction_arity_bits: vec![1, 1, 1, 1],
|
||||
num_query_rounds: 1,
|
||||
cap_height: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -63,10 +67,12 @@ impl CircuitConfig {
|
||||
rate_bits: 3,
|
||||
num_challenges: 3,
|
||||
zero_knowledge: true,
|
||||
cap_height: 1,
|
||||
fri_config: FriConfig {
|
||||
proof_of_work_bits: 1,
|
||||
reduction_arity_bits: vec![1, 1, 1, 1],
|
||||
num_query_rounds: 1,
|
||||
cap_height: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -143,7 +149,7 @@ pub(crate) struct ProverOnlyCircuitData<F: Extendable<D>, const D: usize> {
|
||||
/// Circuit data required by the verifier, but not the prover.
|
||||
pub(crate) struct VerifierOnlyCircuitData<F: Field> {
|
||||
/// A commitment to each constant polynomial and each permutation polynomial.
|
||||
pub(crate) constants_sigmas_root: HashOut<F>,
|
||||
pub(crate) constants_sigmas_root: MerkleCap<F>,
|
||||
}
|
||||
|
||||
/// Circuit data required by both the prover and the verifier.
|
||||
@ -233,5 +239,5 @@ impl<F: Extendable<D>, const D: usize> CommonCircuitData<F, D> {
|
||||
/// dynamic, at least not without setting a maximum wire count and paying for the worst case.
|
||||
pub struct VerifierCircuitTarget {
|
||||
/// A commitment to each constant polynomial and each permutation polynomial.
|
||||
pub(crate) constants_sigmas_root: HashOutTarget,
|
||||
pub(crate) constants_sigmas_root: MerkleCapTarget,
|
||||
}
|
||||
|
||||
@ -5,7 +5,8 @@ use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::fri::commitment::PolynomialBatchCommitment;
|
||||
use crate::fri::proof::{FriProof, FriProofTarget};
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget};
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_data::CommonCircuitData;
|
||||
|
||||
@ -13,11 +14,11 @@ use crate::plonk::circuit_data::CommonCircuitData;
|
||||
#[serde(bound = "")]
|
||||
pub struct Proof<F: Extendable<D>, const D: usize> {
|
||||
/// Merkle root of LDEs of wire values.
|
||||
pub wires_root: HashOut<F>,
|
||||
pub wires_root: MerkleCap<F>,
|
||||
/// Merkle root of LDEs of Z, in the context of Plonk's permutation argument.
|
||||
pub plonk_zs_partial_products_root: HashOut<F>,
|
||||
pub plonk_zs_partial_products_root: MerkleCap<F>,
|
||||
/// Merkle root of LDEs of the quotient polynomial components.
|
||||
pub quotient_polys_root: HashOut<F>,
|
||||
pub quotient_polys_root: MerkleCap<F>,
|
||||
/// Purported values of each polynomial at the challenge point.
|
||||
pub openings: OpeningSet<F, D>,
|
||||
/// A batch FRI argument for all openings.
|
||||
@ -32,9 +33,9 @@ pub struct ProofWithPublicInputs<F: Extendable<D>, const D: usize> {
|
||||
}
|
||||
|
||||
pub struct ProofTarget<const D: usize> {
|
||||
pub wires_root: HashOutTarget,
|
||||
pub plonk_zs_partial_products_root: HashOutTarget,
|
||||
pub quotient_polys_root: HashOutTarget,
|
||||
pub wires_root: MerkleCapTarget,
|
||||
pub plonk_zs_partial_products_root: MerkleCapTarget,
|
||||
pub quotient_polys_root: MerkleCapTarget,
|
||||
pub openings: OpeningSetTarget<D>,
|
||||
pub opening_proof: FriProofTarget<D>,
|
||||
}
|
||||
|
||||
@ -85,6 +85,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
wires_values,
|
||||
config.rate_bits,
|
||||
config.zero_knowledge & PlonkPolynomials::WIRES.blinding,
|
||||
config.cap_height,
|
||||
&mut timing,
|
||||
)
|
||||
);
|
||||
@ -95,7 +96,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
challenger.observe_hash(&common_data.circuit_digest);
|
||||
challenger.observe_hash(&public_inputs_hash);
|
||||
|
||||
challenger.observe_hash(&wires_commitment.merkle_tree.root);
|
||||
challenger.observe_cap(&wires_commitment.merkle_tree.root);
|
||||
let betas = challenger.get_n_challenges(num_challenges);
|
||||
let gammas = challenger.get_n_challenges(num_challenges);
|
||||
|
||||
@ -129,11 +130,12 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
zs_partial_products,
|
||||
config.rate_bits,
|
||||
config.zero_knowledge & PlonkPolynomials::ZS_PARTIAL_PRODUCTS.blinding,
|
||||
config.cap_height,
|
||||
&mut timing,
|
||||
)
|
||||
);
|
||||
|
||||
challenger.observe_hash(&zs_partial_products_commitment.merkle_tree.root);
|
||||
challenger.observe_cap(&zs_partial_products_commitment.merkle_tree.root);
|
||||
|
||||
let alphas = challenger.get_n_challenges(num_challenges);
|
||||
|
||||
@ -177,11 +179,12 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
all_quotient_poly_chunks,
|
||||
config.rate_bits,
|
||||
config.zero_knowledge & PlonkPolynomials::QUOTIENT.blinding,
|
||||
config.cap_height,
|
||||
&mut timing
|
||||
)
|
||||
);
|
||||
|
||||
challenger.observe_hash("ient_polys_commitment.merkle_tree.root);
|
||||
challenger.observe_cap("ient_polys_commitment.merkle_tree.root);
|
||||
|
||||
let zeta = challenger.get_extension_challenge();
|
||||
|
||||
|
||||
@ -44,14 +44,14 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
challenger.observe_hash(&digest);
|
||||
challenger.observe_hash(&public_inputs_hash);
|
||||
|
||||
challenger.observe_hash(&proof.wires_root);
|
||||
challenger.observe_cap(&proof.wires_root);
|
||||
let betas = challenger.get_n_challenges(self, num_challenges);
|
||||
let gammas = challenger.get_n_challenges(self, num_challenges);
|
||||
|
||||
challenger.observe_hash(&proof.plonk_zs_partial_products_root);
|
||||
challenger.observe_cap(&proof.plonk_zs_partial_products_root);
|
||||
let alphas = challenger.get_n_challenges(self, num_challenges);
|
||||
|
||||
challenger.observe_hash(&proof.quotient_polys_root);
|
||||
challenger.observe_cap(&proof.quotient_polys_root);
|
||||
let zeta = challenger.get_extension_challenge(self);
|
||||
|
||||
(betas, gammas, alphas, zeta)
|
||||
@ -108,7 +108,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
});
|
||||
|
||||
let merkle_roots = &[
|
||||
inner_verifier_data.constants_sigmas_root,
|
||||
inner_verifier_data.constants_sigmas_root.clone(),
|
||||
proof.wires_root,
|
||||
proof.plonk_zs_partial_products_root,
|
||||
proof.quotient_polys_root,
|
||||
@ -129,355 +129,355 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
|
||||
use super::*;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::fri::proof::{
|
||||
FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget,
|
||||
};
|
||||
use crate::fri::FriConfig;
|
||||
use crate::gadgets::polynomial::PolynomialCoeffsExtTarget;
|
||||
use crate::hash::merkle_proofs::MerkleProofTarget;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::plonk::proof::{OpeningSetTarget, Proof, ProofTarget, ProofWithPublicInputs};
|
||||
use crate::plonk::verifier::verify;
|
||||
|
||||
// Construct a `FriQueryRoundTarget` with the same dimensions as the ones in `proof`.
|
||||
fn get_fri_query_round<F: Extendable<D>, const D: usize>(
|
||||
proof: &Proof<F, D>,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> FriQueryRoundTarget<D> {
|
||||
let mut query_round = FriQueryRoundTarget {
|
||||
initial_trees_proof: FriInitialTreeProofTarget {
|
||||
evals_proofs: vec![],
|
||||
},
|
||||
steps: vec![],
|
||||
};
|
||||
for (v, merkle_proof) in &proof.opening_proof.query_round_proofs[0]
|
||||
.initial_trees_proof
|
||||
.evals_proofs
|
||||
{
|
||||
query_round.initial_trees_proof.evals_proofs.push((
|
||||
builder.add_virtual_targets(v.len()),
|
||||
MerkleProofTarget {
|
||||
siblings: builder.add_virtual_hashes(merkle_proof.siblings.len()),
|
||||
},
|
||||
));
|
||||
}
|
||||
for step in &proof.opening_proof.query_round_proofs[0].steps {
|
||||
query_round.steps.push(FriQueryStepTarget {
|
||||
evals: builder.add_virtual_extension_targets(step.evals.len()),
|
||||
merkle_proof: MerkleProofTarget {
|
||||
siblings: builder.add_virtual_hashes(step.merkle_proof.siblings.len()),
|
||||
},
|
||||
});
|
||||
}
|
||||
query_round
|
||||
}
|
||||
|
||||
// Construct a `ProofTarget` with the same dimensions as `proof`.
|
||||
fn proof_to_proof_target<F: Extendable<D>, const D: usize>(
|
||||
proof_with_pis: &ProofWithPublicInputs<F, D>,
|
||||
builder: &mut CircuitBuilder<F, 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();
|
||||
|
||||
let openings = OpeningSetTarget {
|
||||
constants: builder.add_virtual_extension_targets(proof.openings.constants.len()),
|
||||
plonk_sigmas: builder.add_virtual_extension_targets(proof.openings.plonk_sigmas.len()),
|
||||
wires: builder.add_virtual_extension_targets(proof.openings.wires.len()),
|
||||
plonk_zs: builder.add_virtual_extension_targets(proof.openings.plonk_zs.len()),
|
||||
plonk_zs_right: builder
|
||||
.add_virtual_extension_targets(proof.openings.plonk_zs_right.len()),
|
||||
partial_products: builder
|
||||
.add_virtual_extension_targets(proof.openings.partial_products.len()),
|
||||
quotient_polys: builder
|
||||
.add_virtual_extension_targets(proof.openings.quotient_polys.len()),
|
||||
};
|
||||
let query_round_proofs = (0..proof.opening_proof.query_round_proofs.len())
|
||||
.map(|_| get_fri_query_round(proof, builder))
|
||||
.collect();
|
||||
let commit_phase_merkle_roots = (0..proof.opening_proof.commit_phase_merkle_roots.len())
|
||||
.map(|_| builder.add_virtual_hash())
|
||||
.collect();
|
||||
let opening_proof = FriProofTarget {
|
||||
commit_phase_merkle_roots,
|
||||
query_round_proofs,
|
||||
final_poly: PolynomialCoeffsExtTarget(
|
||||
builder.add_virtual_extension_targets(proof.opening_proof.final_poly.len()),
|
||||
),
|
||||
pow_witness: builder.add_virtual_target(),
|
||||
};
|
||||
|
||||
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: &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,
|
||||
proof.plonk_zs_partial_products_root,
|
||||
);
|
||||
pw.set_hash_target(pt.quotient_polys_root, proof.quotient_polys_root);
|
||||
|
||||
for (&t, &x) in pt.openings.wires.iter().zip(&proof.openings.wires) {
|
||||
pw.set_extension_target(t, x);
|
||||
}
|
||||
for (&t, &x) in pt.openings.constants.iter().zip(&proof.openings.constants) {
|
||||
pw.set_extension_target(t, x);
|
||||
}
|
||||
for (&t, &x) in pt
|
||||
.openings
|
||||
.plonk_sigmas
|
||||
.iter()
|
||||
.zip(&proof.openings.plonk_sigmas)
|
||||
{
|
||||
pw.set_extension_target(t, x);
|
||||
}
|
||||
for (&t, &x) in pt.openings.plonk_zs.iter().zip(&proof.openings.plonk_zs) {
|
||||
pw.set_extension_target(t, x);
|
||||
}
|
||||
for (&t, &x) in pt
|
||||
.openings
|
||||
.plonk_zs_right
|
||||
.iter()
|
||||
.zip(&proof.openings.plonk_zs_right)
|
||||
{
|
||||
pw.set_extension_target(t, x);
|
||||
}
|
||||
for (&t, &x) in pt
|
||||
.openings
|
||||
.partial_products
|
||||
.iter()
|
||||
.zip(&proof.openings.partial_products)
|
||||
{
|
||||
pw.set_extension_target(t, x);
|
||||
}
|
||||
for (&t, &x) in pt
|
||||
.openings
|
||||
.quotient_polys
|
||||
.iter()
|
||||
.zip(&proof.openings.quotient_polys)
|
||||
{
|
||||
pw.set_extension_target(t, x);
|
||||
}
|
||||
|
||||
let fri_proof = &proof.opening_proof;
|
||||
let fpt = &pt.opening_proof;
|
||||
|
||||
pw.set_target(fpt.pow_witness, fri_proof.pow_witness);
|
||||
|
||||
for (&t, &x) in fpt.final_poly.0.iter().zip(&fri_proof.final_poly.coeffs) {
|
||||
pw.set_extension_target(t, x);
|
||||
}
|
||||
|
||||
for (&t, &x) in fpt
|
||||
.commit_phase_merkle_roots
|
||||
.iter()
|
||||
.zip(&fri_proof.commit_phase_merkle_roots)
|
||||
{
|
||||
pw.set_hash_target(t, x);
|
||||
}
|
||||
|
||||
for (qt, q) in fpt
|
||||
.query_round_proofs
|
||||
.iter()
|
||||
.zip(&fri_proof.query_round_proofs)
|
||||
{
|
||||
for (at, a) in qt
|
||||
.initial_trees_proof
|
||||
.evals_proofs
|
||||
.iter()
|
||||
.zip(&q.initial_trees_proof.evals_proofs)
|
||||
{
|
||||
for (&t, &x) in at.0.iter().zip(&a.0) {
|
||||
pw.set_target(t, x);
|
||||
}
|
||||
for (&t, &x) in at.1.siblings.iter().zip(&a.1.siblings) {
|
||||
pw.set_hash_target(t, x);
|
||||
}
|
||||
}
|
||||
|
||||
for (st, s) in qt.steps.iter().zip(&q.steps) {
|
||||
for (&t, &x) in st.evals.iter().zip(&s.evals) {
|
||||
pw.set_extension_target(t, x);
|
||||
}
|
||||
for (&t, &x) in st
|
||||
.merkle_proof
|
||||
.siblings
|
||||
.iter()
|
||||
.zip(&s.merkle_proof.siblings)
|
||||
{
|
||||
pw.set_hash_target(t, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_recursive_verifier() -> Result<()> {
|
||||
env_logger::init();
|
||||
type F = CrandallField;
|
||||
const D: usize = 4;
|
||||
let config = CircuitConfig {
|
||||
num_wires: 126,
|
||||
num_routed_wires: 33,
|
||||
security_bits: 128,
|
||||
rate_bits: 3,
|
||||
num_challenges: 3,
|
||||
zero_knowledge: false,
|
||||
fri_config: FriConfig {
|
||||
proof_of_work_bits: 1,
|
||||
reduction_arity_bits: vec![2, 2, 2, 2, 2, 2],
|
||||
num_query_rounds: 40,
|
||||
},
|
||||
};
|
||||
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];
|
||||
for _ in 0..10000 {
|
||||
let _two = builder.mul(_two, _two);
|
||||
}
|
||||
let data = builder.build();
|
||||
(
|
||||
data.prove(PartialWitness::new(config.num_wires))?,
|
||||
data.verifier_only,
|
||||
data.common,
|
||||
)
|
||||
};
|
||||
verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
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(),
|
||||
};
|
||||
pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root);
|
||||
|
||||
builder.add_recursive_verifier(pt, &config, &inner_data, &cd);
|
||||
|
||||
builder.print_gate_counts(0);
|
||||
let data = builder.build();
|
||||
let recursive_proof = data.prove(pw)?;
|
||||
|
||||
verify(recursive_proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_recursive_recursive_verifier() -> Result<()> {
|
||||
env_logger::init();
|
||||
type F = CrandallField;
|
||||
const D: usize = 4;
|
||||
let config = CircuitConfig {
|
||||
num_wires: 126,
|
||||
num_routed_wires: 33,
|
||||
security_bits: 128,
|
||||
rate_bits: 3,
|
||||
num_challenges: 3,
|
||||
zero_knowledge: false,
|
||||
fri_config: FriConfig {
|
||||
proof_of_work_bits: 1,
|
||||
reduction_arity_bits: vec![2, 2, 2, 2, 2, 2],
|
||||
num_query_rounds: 40,
|
||||
},
|
||||
};
|
||||
let (proof_with_pis, 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];
|
||||
for _ in 0..10000 {
|
||||
let _two = builder.mul(_two, _two);
|
||||
}
|
||||
let data = builder.build();
|
||||
(
|
||||
data.prove(PartialWitness::new(config.num_wires))?,
|
||||
data.verifier_only,
|
||||
data.common,
|
||||
)
|
||||
};
|
||||
verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
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(),
|
||||
};
|
||||
pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root);
|
||||
|
||||
builder.add_recursive_verifier(pt, &config, &inner_data, &cd);
|
||||
|
||||
let data = builder.build();
|
||||
let recursive_proof = data.prove(pw)?;
|
||||
(recursive_proof, data.verifier_only, data.common)
|
||||
};
|
||||
|
||||
verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
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(),
|
||||
};
|
||||
pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root);
|
||||
|
||||
builder.add_recursive_verifier(pt, &config, &inner_data, &cd);
|
||||
|
||||
builder.print_gate_counts(0);
|
||||
let data = builder.build();
|
||||
let recursive_proof = data.prove(pw)?;
|
||||
verify(recursive_proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
}
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use anyhow::Result;
|
||||
//
|
||||
// use super::*;
|
||||
// use crate::field::crandall_field::CrandallField;
|
||||
// use crate::fri::proof::{
|
||||
// FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget,
|
||||
// };
|
||||
// use crate::fri::FriConfig;
|
||||
// use crate::gadgets::polynomial::PolynomialCoeffsExtTarget;
|
||||
// use crate::hash::merkle_proofs::MerkleProofTarget;
|
||||
// use crate::iop::witness::PartialWitness;
|
||||
// use crate::plonk::proof::{OpeningSetTarget, Proof, ProofTarget, ProofWithPublicInputs};
|
||||
// use crate::plonk::verifier::verify;
|
||||
//
|
||||
// // Construct a `FriQueryRoundTarget` with the same dimensions as the ones in `proof`.
|
||||
// fn get_fri_query_round<F: Extendable<D>, const D: usize>(
|
||||
// proof: &Proof<F, D>,
|
||||
// builder: &mut CircuitBuilder<F, D>,
|
||||
// ) -> FriQueryRoundTarget<D> {
|
||||
// let mut query_round = FriQueryRoundTarget {
|
||||
// initial_trees_proof: FriInitialTreeProofTarget {
|
||||
// evals_proofs: vec![],
|
||||
// },
|
||||
// steps: vec![],
|
||||
// };
|
||||
// for (v, merkle_proof) in &proof.opening_proof.query_round_proofs[0]
|
||||
// .initial_trees_proof
|
||||
// .evals_proofs
|
||||
// {
|
||||
// query_round.initial_trees_proof.evals_proofs.push((
|
||||
// builder.add_virtual_targets(v.len()),
|
||||
// MerkleProofTarget {
|
||||
// siblings: builder.add_virtual_hashes(merkle_proof.siblings.len()),
|
||||
// },
|
||||
// ));
|
||||
// }
|
||||
// for step in &proof.opening_proof.query_round_proofs[0].steps {
|
||||
// query_round.steps.push(FriQueryStepTarget {
|
||||
// evals: builder.add_virtual_extension_targets(step.evals.len()),
|
||||
// merkle_proof: MerkleProofTarget {
|
||||
// siblings: builder.add_virtual_hashes(step.merkle_proof.siblings.len()),
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
// query_round
|
||||
// }
|
||||
//
|
||||
// // Construct a `ProofTarget` with the same dimensions as `proof`.
|
||||
// fn proof_to_proof_target<F: Extendable<D>, const D: usize>(
|
||||
// proof_with_pis: &ProofWithPublicInputs<F, D>,
|
||||
// builder: &mut CircuitBuilder<F, 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();
|
||||
//
|
||||
// let openings = OpeningSetTarget {
|
||||
// constants: builder.add_virtual_extension_targets(proof.openings.constants.len()),
|
||||
// plonk_sigmas: builder.add_virtual_extension_targets(proof.openings.plonk_sigmas.len()),
|
||||
// wires: builder.add_virtual_extension_targets(proof.openings.wires.len()),
|
||||
// plonk_zs: builder.add_virtual_extension_targets(proof.openings.plonk_zs.len()),
|
||||
// plonk_zs_right: builder
|
||||
// .add_virtual_extension_targets(proof.openings.plonk_zs_right.len()),
|
||||
// partial_products: builder
|
||||
// .add_virtual_extension_targets(proof.openings.partial_products.len()),
|
||||
// quotient_polys: builder
|
||||
// .add_virtual_extension_targets(proof.openings.quotient_polys.len()),
|
||||
// };
|
||||
// let query_round_proofs = (0..proof.opening_proof.query_round_proofs.len())
|
||||
// .map(|_| get_fri_query_round(proof, builder))
|
||||
// .collect();
|
||||
// let commit_phase_merkle_roots = (0..proof.opening_proof.commit_phase_merkle_roots.len())
|
||||
// .map(|_| builder.add_virtual_hash())
|
||||
// .collect();
|
||||
// let opening_proof = FriProofTarget {
|
||||
// commit_phase_merkle_roots,
|
||||
// query_round_proofs,
|
||||
// final_poly: PolynomialCoeffsExtTarget(
|
||||
// builder.add_virtual_extension_targets(proof.opening_proof.final_poly.len()),
|
||||
// ),
|
||||
// pow_witness: builder.add_virtual_target(),
|
||||
// };
|
||||
//
|
||||
// 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: &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,
|
||||
// proof.plonk_zs_partial_products_root,
|
||||
// );
|
||||
// pw.set_hash_target(pt.quotient_polys_root, proof.quotient_polys_root);
|
||||
//
|
||||
// for (&t, &x) in pt.openings.wires.iter().zip(&proof.openings.wires) {
|
||||
// pw.set_extension_target(t, x);
|
||||
// }
|
||||
// for (&t, &x) in pt.openings.constants.iter().zip(&proof.openings.constants) {
|
||||
// pw.set_extension_target(t, x);
|
||||
// }
|
||||
// for (&t, &x) in pt
|
||||
// .openings
|
||||
// .plonk_sigmas
|
||||
// .iter()
|
||||
// .zip(&proof.openings.plonk_sigmas)
|
||||
// {
|
||||
// pw.set_extension_target(t, x);
|
||||
// }
|
||||
// for (&t, &x) in pt.openings.plonk_zs.iter().zip(&proof.openings.plonk_zs) {
|
||||
// pw.set_extension_target(t, x);
|
||||
// }
|
||||
// for (&t, &x) in pt
|
||||
// .openings
|
||||
// .plonk_zs_right
|
||||
// .iter()
|
||||
// .zip(&proof.openings.plonk_zs_right)
|
||||
// {
|
||||
// pw.set_extension_target(t, x);
|
||||
// }
|
||||
// for (&t, &x) in pt
|
||||
// .openings
|
||||
// .partial_products
|
||||
// .iter()
|
||||
// .zip(&proof.openings.partial_products)
|
||||
// {
|
||||
// pw.set_extension_target(t, x);
|
||||
// }
|
||||
// for (&t, &x) in pt
|
||||
// .openings
|
||||
// .quotient_polys
|
||||
// .iter()
|
||||
// .zip(&proof.openings.quotient_polys)
|
||||
// {
|
||||
// pw.set_extension_target(t, x);
|
||||
// }
|
||||
//
|
||||
// let fri_proof = &proof.opening_proof;
|
||||
// let fpt = &pt.opening_proof;
|
||||
//
|
||||
// pw.set_target(fpt.pow_witness, fri_proof.pow_witness);
|
||||
//
|
||||
// for (&t, &x) in fpt.final_poly.0.iter().zip(&fri_proof.final_poly.coeffs) {
|
||||
// pw.set_extension_target(t, x);
|
||||
// }
|
||||
//
|
||||
// for (&t, &x) in fpt
|
||||
// .commit_phase_merkle_roots
|
||||
// .iter()
|
||||
// .zip(&fri_proof.commit_phase_merkle_roots)
|
||||
// {
|
||||
// pw.set_hash_target(t, x);
|
||||
// }
|
||||
//
|
||||
// for (qt, q) in fpt
|
||||
// .query_round_proofs
|
||||
// .iter()
|
||||
// .zip(&fri_proof.query_round_proofs)
|
||||
// {
|
||||
// for (at, a) in qt
|
||||
// .initial_trees_proof
|
||||
// .evals_proofs
|
||||
// .iter()
|
||||
// .zip(&q.initial_trees_proof.evals_proofs)
|
||||
// {
|
||||
// for (&t, &x) in at.0.iter().zip(&a.0) {
|
||||
// pw.set_target(t, x);
|
||||
// }
|
||||
// for (&t, &x) in at.1.siblings.iter().zip(&a.1.siblings) {
|
||||
// pw.set_hash_target(t, x);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (st, s) in qt.steps.iter().zip(&q.steps) {
|
||||
// for (&t, &x) in st.evals.iter().zip(&s.evals) {
|
||||
// pw.set_extension_target(t, x);
|
||||
// }
|
||||
// for (&t, &x) in st
|
||||
// .merkle_proof
|
||||
// .siblings
|
||||
// .iter()
|
||||
// .zip(&s.merkle_proof.siblings)
|
||||
// {
|
||||
// pw.set_hash_target(t, x);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// #[ignore]
|
||||
// fn test_recursive_verifier() -> Result<()> {
|
||||
// env_logger::init();
|
||||
// type F = CrandallField;
|
||||
// const D: usize = 4;
|
||||
// let config = CircuitConfig {
|
||||
// num_wires: 126,
|
||||
// num_routed_wires: 33,
|
||||
// security_bits: 128,
|
||||
// rate_bits: 3,
|
||||
// num_challenges: 3,
|
||||
// zero_knowledge: false,
|
||||
// fri_config: FriConfig {
|
||||
// proof_of_work_bits: 1,
|
||||
// reduction_arity_bits: vec![2, 2, 2, 2, 2, 2],
|
||||
// num_query_rounds: 40,
|
||||
// },
|
||||
// };
|
||||
// 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];
|
||||
// for _ in 0..10000 {
|
||||
// let _two = builder.mul(_two, _two);
|
||||
// }
|
||||
// let data = builder.build();
|
||||
// (
|
||||
// data.prove(PartialWitness::new(config.num_wires))?,
|
||||
// data.verifier_only,
|
||||
// data.common,
|
||||
// )
|
||||
// };
|
||||
// verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
//
|
||||
// let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
// let mut pw = PartialWitness::new(config.num_wires);
|
||||
// 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(),
|
||||
// };
|
||||
// pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root);
|
||||
//
|
||||
// builder.add_recursive_verifier(pt, &config, &inner_data, &cd);
|
||||
//
|
||||
// builder.print_gate_counts(0);
|
||||
// let data = builder.build();
|
||||
// let recursive_proof = data.prove(pw)?;
|
||||
//
|
||||
// verify(recursive_proof, &data.verifier_only, &data.common)
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// #[ignore]
|
||||
// fn test_recursive_recursive_verifier() -> Result<()> {
|
||||
// env_logger::init();
|
||||
// type F = CrandallField;
|
||||
// const D: usize = 4;
|
||||
// let config = CircuitConfig {
|
||||
// num_wires: 126,
|
||||
// num_routed_wires: 33,
|
||||
// security_bits: 128,
|
||||
// rate_bits: 3,
|
||||
// num_challenges: 3,
|
||||
// zero_knowledge: false,
|
||||
// fri_config: FriConfig {
|
||||
// proof_of_work_bits: 1,
|
||||
// reduction_arity_bits: vec![2, 2, 2, 2, 2, 2],
|
||||
// num_query_rounds: 40,
|
||||
// },
|
||||
// };
|
||||
// let (proof_with_pis, 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];
|
||||
// for _ in 0..10000 {
|
||||
// let _two = builder.mul(_two, _two);
|
||||
// }
|
||||
// let data = builder.build();
|
||||
// (
|
||||
// data.prove(PartialWitness::new(config.num_wires))?,
|
||||
// data.verifier_only,
|
||||
// data.common,
|
||||
// )
|
||||
// };
|
||||
// verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
//
|
||||
// let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
// let mut pw = PartialWitness::new(config.num_wires);
|
||||
// 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(),
|
||||
// };
|
||||
// pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root);
|
||||
//
|
||||
// builder.add_recursive_verifier(pt, &config, &inner_data, &cd);
|
||||
//
|
||||
// let data = builder.build();
|
||||
// let recursive_proof = data.prove(pw)?;
|
||||
// (recursive_proof, data.verifier_only, data.common)
|
||||
// };
|
||||
//
|
||||
// verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
// let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
// let mut pw = PartialWitness::new(config.num_wires);
|
||||
// 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(),
|
||||
// };
|
||||
// pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root);
|
||||
//
|
||||
// builder.add_recursive_verifier(pt, &config, &inner_data, &cd);
|
||||
//
|
||||
// builder.print_gate_counts(0);
|
||||
// let data = builder.build();
|
||||
// let recursive_proof = data.prove(pw)?;
|
||||
// verify(recursive_proof, &data.verifier_only, &data.common)
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -31,14 +31,14 @@ pub(crate) fn verify<F: Extendable<D>, const D: usize>(
|
||||
challenger.observe_hash(&common_data.circuit_digest);
|
||||
challenger.observe_hash(&public_inputs_hash);
|
||||
|
||||
challenger.observe_hash(&proof.wires_root);
|
||||
challenger.observe_cap(&proof.wires_root);
|
||||
let betas = challenger.get_n_challenges(num_challenges);
|
||||
let gammas = challenger.get_n_challenges(num_challenges);
|
||||
|
||||
challenger.observe_hash(&proof.plonk_zs_partial_products_root);
|
||||
challenger.observe_cap(&proof.plonk_zs_partial_products_root);
|
||||
let alphas = challenger.get_n_challenges(num_challenges);
|
||||
|
||||
challenger.observe_hash(&proof.quotient_polys_root);
|
||||
challenger.observe_cap(&proof.quotient_polys_root);
|
||||
let zeta = challenger.get_extension_challenge();
|
||||
|
||||
let local_constants = &proof.openings.constants;
|
||||
@ -84,7 +84,7 @@ pub(crate) fn verify<F: Extendable<D>, const D: usize>(
|
||||
}
|
||||
|
||||
let merkle_roots = &[
|
||||
verifier_data.constants_sigmas_root,
|
||||
verifier_data.constants_sigmas_root.clone(),
|
||||
proof.wires_root,
|
||||
proof.plonk_zs_partial_products_root,
|
||||
proof.quotient_polys_root,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user