mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 23:03:08 +00:00
Merge pull request #481 from mir-protocol/fix_hash_or_noop_merkle_proof
Use `hash_or_noop` for Merkle tree leaves
This commit is contained in:
commit
f4640bb5a1
@ -1,3 +1,5 @@
|
||||
#![feature(generic_const_exprs)]
|
||||
|
||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
@ -9,7 +11,10 @@ use tynm::type_name;
|
||||
|
||||
const ELEMS_PER_LEAF: usize = 135;
|
||||
|
||||
pub(crate) fn bench_merkle_tree<F: RichField, H: Hasher<F>>(c: &mut Criterion) {
|
||||
pub(crate) fn bench_merkle_tree<F: RichField, H: Hasher<F>>(c: &mut Criterion)
|
||||
where
|
||||
[(); H::HASH_SIZE]:,
|
||||
{
|
||||
let mut group = c.benchmark_group(&format!(
|
||||
"merkle-tree<{}, {}>",
|
||||
type_name::<F>(),
|
||||
|
||||
@ -12,7 +12,7 @@ use crate::fri::FriParams;
|
||||
use crate::hash::hash_types::RichField;
|
||||
use crate::hash::merkle_tree::MerkleTree;
|
||||
use crate::iop::challenger::Challenger;
|
||||
use crate::plonk::config::GenericConfig;
|
||||
use crate::plonk::config::{GenericConfig, Hasher};
|
||||
use crate::timed;
|
||||
use crate::util::reducing::ReducingFactor;
|
||||
use crate::util::reverse_bits;
|
||||
@ -43,7 +43,10 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
cap_height: usize,
|
||||
timing: &mut TimingTree,
|
||||
fft_root_table: Option<&FftRootTable<F>>,
|
||||
) -> Self {
|
||||
) -> Self
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let coeffs = timed!(
|
||||
timing,
|
||||
"IFFT",
|
||||
@ -68,7 +71,10 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
cap_height: usize,
|
||||
timing: &mut TimingTree,
|
||||
fft_root_table: Option<&FftRootTable<F>>,
|
||||
) -> Self {
|
||||
) -> Self
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let degree = polynomials[0].len();
|
||||
let lde_values = timed!(
|
||||
timing,
|
||||
@ -133,7 +139,10 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
fri_params: &FriParams,
|
||||
timing: &mut TimingTree,
|
||||
) -> FriProof<F, C::Hasher, D> {
|
||||
) -> FriProof<F, C::Hasher, D>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
assert!(D > 1, "Not implemented for D=1.");
|
||||
let alpha = challenger.get_extension_challenge::<D>();
|
||||
let mut alpha = ReducingFactor::new(alpha);
|
||||
|
||||
@ -245,7 +245,10 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> CompressedFriPr
|
||||
challenges: &ProofChallenges<F, D>,
|
||||
fri_inferred_elements: FriInferredElements<F, D>,
|
||||
params: &FriParams,
|
||||
) -> FriProof<F, H, D> {
|
||||
) -> FriProof<F, H, D>
|
||||
where
|
||||
[(); H::HASH_SIZE]:,
|
||||
{
|
||||
let CompressedFriProof {
|
||||
commit_phase_merkle_caps,
|
||||
query_round_proofs,
|
||||
|
||||
@ -24,7 +24,10 @@ pub fn fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
fri_params: &FriParams,
|
||||
timing: &mut TimingTree,
|
||||
) -> FriProof<F, C::Hasher, D> {
|
||||
) -> FriProof<F, C::Hasher, D>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let n = lde_polynomial_values.len();
|
||||
assert_eq!(lde_polynomial_coeffs.len(), n);
|
||||
|
||||
@ -68,7 +71,10 @@ fn fri_committed_trees<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
|
||||
) -> (
|
||||
Vec<MerkleTree<F, C::Hasher>>,
|
||||
PolynomialCoeffs<F::Extension>,
|
||||
) {
|
||||
)
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let mut trees = Vec::new();
|
||||
|
||||
let mut shift = F::MULTIPLICATIVE_GROUP_GENERATOR;
|
||||
|
||||
@ -56,18 +56,17 @@ pub(crate) fn fri_verify_proof_of_work<F: RichField + Extendable<D>, const D: us
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn verify_fri_proof<
|
||||
F: RichField + Extendable<D>,
|
||||
C: GenericConfig<D, F = F>,
|
||||
const D: usize,
|
||||
>(
|
||||
pub fn verify_fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
|
||||
instance: &FriInstanceInfo<F, D>,
|
||||
openings: &FriOpenings<F, D>,
|
||||
challenges: &FriChallenges<F, D>,
|
||||
initial_merkle_caps: &[MerkleCap<F, C::Hasher>],
|
||||
proof: &FriProof<F, C::Hasher, D>,
|
||||
params: &FriParams,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
ensure!(
|
||||
params.final_poly_len() == proof.final_poly.len(),
|
||||
"Final polynomial has wrong degree."
|
||||
@ -112,7 +111,10 @@ fn fri_verify_initial_proof<F: RichField, H: Hasher<F>>(
|
||||
x_index: usize,
|
||||
proof: &FriInitialTreeProof<F, H>,
|
||||
initial_merkle_caps: &[MerkleCap<F, H>],
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); H::HASH_SIZE]:,
|
||||
{
|
||||
for ((evals, merkle_proof), cap) in proof.evals_proofs.iter().zip(initial_merkle_caps) {
|
||||
verify_merkle_proof::<F, H>(evals.clone(), x_index, cap, merkle_proof)?;
|
||||
}
|
||||
@ -177,7 +179,10 @@ fn fri_verifier_query_round<
|
||||
n: usize,
|
||||
round_proof: &FriQueryRound<F, C::Hasher, D>,
|
||||
params: &FriParams,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
fri_verify_initial_proof::<F, C::Hasher>(
|
||||
x_index,
|
||||
&round_proof.initial_trees_proof,
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::hash::hash_types::RichField;
|
||||
use crate::iop::witness::{PartialWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CircuitConfig;
|
||||
use crate::plonk::config::GenericConfig;
|
||||
use crate::plonk::config::{GenericConfig, Hasher};
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch};
|
||||
use crate::plonk::verifier::verify;
|
||||
use crate::util::transpose;
|
||||
@ -92,7 +92,10 @@ pub fn test_eval_fns<
|
||||
const D: usize,
|
||||
>(
|
||||
gate: G,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
// Test that `eval_unfiltered` and `eval_unfiltered_base` are coherent.
|
||||
let wires_base = F::rand_vec(gate.num_wires());
|
||||
let constants_base = F::rand_vec(gate.num_constants());
|
||||
|
||||
@ -12,16 +12,6 @@ pub(crate) const SPONGE_RATE: usize = 8;
|
||||
pub(crate) const SPONGE_CAPACITY: usize = 4;
|
||||
pub const SPONGE_WIDTH: usize = SPONGE_RATE + SPONGE_CAPACITY;
|
||||
|
||||
/// Hash the slice if necessary to reduce its length to ~256 bits. If it already fits, this is a
|
||||
/// no-op.
|
||||
pub fn hash_or_noop<F: RichField, P: PlonkyPermutation<F>>(inputs: &[F]) -> HashOut<F> {
|
||||
if inputs.len() <= 4 {
|
||||
HashOut::from_partial(inputs)
|
||||
} else {
|
||||
hash_n_to_hash_no_pad::<F, P>(inputs)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn hash_or_noop<H: AlgebraicHasher<F>>(&mut self, inputs: Vec<Target>) -> HashOutTarget {
|
||||
let zero = self.zero();
|
||||
|
||||
@ -30,9 +30,12 @@ pub(crate) fn verify_merkle_proof<F: RichField, H: Hasher<F>>(
|
||||
leaf_index: usize,
|
||||
merkle_cap: &MerkleCap<F, H>,
|
||||
proof: &MerkleProof<F, H>,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); H::HASH_SIZE]:,
|
||||
{
|
||||
let mut index = leaf_index;
|
||||
let mut current_digest = H::hash_no_pad(&leaf_data);
|
||||
let mut current_digest = H::hash_or_noop(&leaf_data);
|
||||
for &sibling_digest in proof.siblings.iter() {
|
||||
let bit = index & 1;
|
||||
index >>= 1;
|
||||
|
||||
@ -60,10 +60,13 @@ fn capacity_up_to_mut<T>(v: &mut Vec<T>, len: usize) -> &mut [MaybeUninit<T>] {
|
||||
fn fill_subtree<F: RichField, H: Hasher<F>>(
|
||||
digests_buf: &mut [MaybeUninit<H::Hash>],
|
||||
leaves: &[Vec<F>],
|
||||
) -> H::Hash {
|
||||
) -> H::Hash
|
||||
where
|
||||
[(); H::HASH_SIZE]:,
|
||||
{
|
||||
assert_eq!(leaves.len(), digests_buf.len() / 2 + 1);
|
||||
if digests_buf.is_empty() {
|
||||
H::hash_no_pad(&leaves[0])
|
||||
H::hash_or_noop(&leaves[0])
|
||||
} else {
|
||||
// Layout is: left recursive output || left child digest
|
||||
// || right child digest || right recursive output.
|
||||
@ -89,7 +92,9 @@ fn fill_digests_buf<F: RichField, H: Hasher<F>>(
|
||||
cap_buf: &mut [MaybeUninit<H::Hash>],
|
||||
leaves: &[Vec<F>],
|
||||
cap_height: usize,
|
||||
) {
|
||||
) where
|
||||
[(); H::HASH_SIZE]:,
|
||||
{
|
||||
// Special case of a tree that's all cap. The usual case will panic because we'll try to split
|
||||
// an empty slice into chunks of `0`. (We would not need this if there was a way to split into
|
||||
// `blah` chunks as opposed to chunks _of_ `blah`.)
|
||||
@ -99,7 +104,7 @@ fn fill_digests_buf<F: RichField, H: Hasher<F>>(
|
||||
.par_iter_mut()
|
||||
.zip(leaves)
|
||||
.for_each(|(cap_buf, leaf)| {
|
||||
cap_buf.write(H::hash_no_pad(leaf));
|
||||
cap_buf.write(H::hash_or_noop(leaf));
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -121,7 +126,10 @@ fn fill_digests_buf<F: RichField, H: Hasher<F>>(
|
||||
}
|
||||
|
||||
impl<F: RichField, H: Hasher<F>> MerkleTree<F, H> {
|
||||
pub fn new(leaves: Vec<Vec<F>>, cap_height: usize) -> Self {
|
||||
pub fn new(leaves: Vec<Vec<F>>, cap_height: usize) -> Self
|
||||
where
|
||||
[(); H::HASH_SIZE]:,
|
||||
{
|
||||
let log2_leaves_len = log2_strict(leaves.len());
|
||||
assert!(
|
||||
cap_height <= log2_leaves_len,
|
||||
@ -208,14 +216,13 @@ mod tests {
|
||||
(0..n).map(|_| F::rand_vec(k)).collect()
|
||||
}
|
||||
|
||||
fn verify_all_leaves<
|
||||
F: RichField + Extendable<D>,
|
||||
C: GenericConfig<D, F = F>,
|
||||
const D: usize,
|
||||
>(
|
||||
fn verify_all_leaves<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
|
||||
leaves: Vec<Vec<F>>,
|
||||
cap_height: usize,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let tree = MerkleTree::<F, C::Hasher>::new(leaves.clone(), cap_height);
|
||||
for (i, leaf) in leaves.into_iter().enumerate() {
|
||||
let proof = tree.prove(i);
|
||||
|
||||
@ -57,7 +57,10 @@ pub(crate) fn decompress_merkle_proofs<F: RichField, H: Hasher<F>>(
|
||||
compressed_proofs: &[MerkleProof<F, H>],
|
||||
height: usize,
|
||||
cap_height: usize,
|
||||
) -> Vec<MerkleProof<F, H>> {
|
||||
) -> Vec<MerkleProof<F, H>>
|
||||
where
|
||||
[(); H::HASH_SIZE]:,
|
||||
{
|
||||
let num_leaves = 1 << height;
|
||||
let compressed_proofs = compressed_proofs.to_vec();
|
||||
let mut decompressed_proofs = Vec::with_capacity(compressed_proofs.len());
|
||||
@ -66,7 +69,7 @@ pub(crate) fn decompress_merkle_proofs<F: RichField, H: Hasher<F>>(
|
||||
|
||||
for (&i, v) in leaves_indices.iter().zip(leaves_data) {
|
||||
// Observe the leaves.
|
||||
seen.insert(i + num_leaves, H::hash_no_pad(v));
|
||||
seen.insert(i + num_leaves, H::hash_or_noop(v));
|
||||
}
|
||||
|
||||
// Iterators over the siblings.
|
||||
|
||||
@ -610,7 +610,10 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
|
||||
/// Builds a "full circuit", with both prover and verifier data.
|
||||
pub fn build<C: GenericConfig<D, F = F>>(mut self) -> CircuitData<F, C, D> {
|
||||
pub fn build<C: GenericConfig<D, F = F>>(mut self) -> CircuitData<F, C, D>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let mut timing = TimingTree::new("preprocess", Level::Trace);
|
||||
let start = Instant::now();
|
||||
let rate_bits = self.config.fri_config.rate_bits;
|
||||
@ -776,7 +779,10 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
|
||||
/// Builds a "prover circuit", with data needed to generate proofs but not verify them.
|
||||
pub fn build_prover<C: GenericConfig<D, F = F>>(self) -> ProverCircuitData<F, C, D> {
|
||||
pub fn build_prover<C: GenericConfig<D, F = F>>(self) -> ProverCircuitData<F, C, D>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
// TODO: Can skip parts of this.
|
||||
let CircuitData {
|
||||
prover_only,
|
||||
@ -790,7 +796,10 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
|
||||
/// Builds a "verifier circuit", with data needed to verify proofs but not generate them.
|
||||
pub fn build_verifier<C: GenericConfig<D, F = F>>(self) -> VerifierCircuitData<F, C, D> {
|
||||
pub fn build_verifier<C: GenericConfig<D, F = F>>(self) -> VerifierCircuitData<F, C, D>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
// TODO: Can skip parts of this.
|
||||
let CircuitData {
|
||||
verifier_only,
|
||||
|
||||
@ -104,7 +104,10 @@ pub struct CircuitData<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
|
||||
impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
CircuitData<F, C, D>
|
||||
{
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, C, D>> {
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, C, D>>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
prove(
|
||||
&self.prover_only,
|
||||
&self.common,
|
||||
@ -113,14 +116,20 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
)
|
||||
}
|
||||
|
||||
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, C, D>) -> Result<()> {
|
||||
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, C, D>) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
verify(proof_with_pis, &self.verifier_only, &self.common)
|
||||
}
|
||||
|
||||
pub fn verify_compressed(
|
||||
&self,
|
||||
compressed_proof_with_pis: CompressedProofWithPublicInputs<F, C, D>,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
compressed_proof_with_pis.verify(&self.verifier_only, &self.common)
|
||||
}
|
||||
}
|
||||
@ -144,7 +153,10 @@ pub struct ProverCircuitData<
|
||||
impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
ProverCircuitData<F, C, D>
|
||||
{
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, C, D>> {
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, C, D>>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
prove(
|
||||
&self.prover_only,
|
||||
&self.common,
|
||||
@ -168,14 +180,20 @@ pub struct VerifierCircuitData<
|
||||
impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
VerifierCircuitData<F, C, D>
|
||||
{
|
||||
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, C, D>) -> Result<()> {
|
||||
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, C, D>) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
verify(proof_with_pis, &self.verifier_only, &self.common)
|
||||
}
|
||||
|
||||
pub fn verify_compressed(
|
||||
&self,
|
||||
compressed_proof_with_pis: CompressedProofWithPublicInputs<F, C, D>,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
compressed_proof_with_pis.verify(&self.verifier_only, &self.common)
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +46,24 @@ pub trait Hasher<F: RichField>: Sized + Clone + Debug + Eq + PartialEq {
|
||||
Self::hash_no_pad(&padded_input)
|
||||
}
|
||||
|
||||
/// Hash the slice if necessary to reduce its length to ~256 bits. If it already fits, this is a
|
||||
/// no-op.
|
||||
fn hash_or_noop(inputs: &[F]) -> Self::Hash
|
||||
where
|
||||
[(); Self::HASH_SIZE]:,
|
||||
{
|
||||
if inputs.len() <= 4 {
|
||||
let mut inputs_bytes = [0u8; Self::HASH_SIZE];
|
||||
for i in 0..inputs.len() {
|
||||
inputs_bytes[i * 8..(i + 1) * 8]
|
||||
.copy_from_slice(&inputs[i].to_canonical_u64().to_le_bytes());
|
||||
}
|
||||
Self::Hash::from_bytes(&inputs_bytes)
|
||||
} else {
|
||||
Self::hash_no_pad(inputs)
|
||||
}
|
||||
}
|
||||
|
||||
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash;
|
||||
}
|
||||
|
||||
|
||||
@ -138,7 +138,10 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
challenges: &ProofChallenges<F, D>,
|
||||
fri_inferred_elements: FriInferredElements<F, D>,
|
||||
params: &FriParams,
|
||||
) -> Proof<F, C, D> {
|
||||
) -> Proof<F, C, D>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let CompressedProof {
|
||||
wires_cap,
|
||||
plonk_zs_partial_products_cap,
|
||||
@ -174,7 +177,10 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
pub fn decompress(
|
||||
self,
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
) -> anyhow::Result<ProofWithPublicInputs<F, C, D>> {
|
||||
) -> anyhow::Result<ProofWithPublicInputs<F, C, D>>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let challenges = self.get_challenges(self.get_public_inputs_hash(), common_data)?;
|
||||
let fri_inferred_elements = self.get_inferred_elements(&challenges, common_data);
|
||||
let decompressed_proof =
|
||||
@ -190,7 +196,10 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
self,
|
||||
verifier_data: &VerifierOnlyCircuitData<C, D>,
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
) -> anyhow::Result<()> {
|
||||
) -> anyhow::Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
ensure!(
|
||||
self.public_inputs.len() == common_data.num_public_inputs,
|
||||
"Number of public inputs doesn't match circuit data."
|
||||
|
||||
@ -31,7 +31,10 @@ pub(crate) fn prove<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, co
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
inputs: PartialWitness<F>,
|
||||
timing: &mut TimingTree,
|
||||
) -> Result<ProofWithPublicInputs<F, C, D>> {
|
||||
) -> Result<ProofWithPublicInputs<F, C, D>>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let config = &common_data.config;
|
||||
let num_challenges = config.num_challenges;
|
||||
let quotient_degree = common_data.quotient_degree();
|
||||
|
||||
@ -187,7 +187,9 @@ mod tests {
|
||||
use crate::gates::noop::NoopGate;
|
||||
use crate::iop::witness::{PartialWitness, Witness};
|
||||
use crate::plonk::circuit_data::{CircuitConfig, VerifierOnlyCircuitData};
|
||||
use crate::plonk::config::{GenericConfig, KeccakGoldilocksConfig, PoseidonGoldilocksConfig};
|
||||
use crate::plonk::config::{
|
||||
GenericConfig, Hasher, KeccakGoldilocksConfig, PoseidonGoldilocksConfig,
|
||||
};
|
||||
use crate::plonk::proof::{CompressedProofWithPublicInputs, ProofWithPublicInputs};
|
||||
use crate::plonk::prover::prove;
|
||||
use crate::util::timing::TimingTree;
|
||||
@ -322,7 +324,10 @@ mod tests {
|
||||
ProofWithPublicInputs<F, C, D>,
|
||||
VerifierOnlyCircuitData<C, D>,
|
||||
CommonCircuitData<F, C, D>,
|
||||
)> {
|
||||
)>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
for _ in 0..num_dummy_gates {
|
||||
builder.add_gate(NoopGate, vec![]);
|
||||
@ -356,6 +361,7 @@ mod tests {
|
||||
)>
|
||||
where
|
||||
InnerC::Hasher: AlgebraicHasher<F>,
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new();
|
||||
@ -407,7 +413,10 @@ mod tests {
|
||||
>(
|
||||
proof: &ProofWithPublicInputs<F, C, D>,
|
||||
cd: &CommonCircuitData<F, C, D>,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let proof_bytes = proof.to_bytes()?;
|
||||
info!("Proof length: {} bytes", proof_bytes.len());
|
||||
let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, cd)?;
|
||||
|
||||
@ -15,7 +15,10 @@ pub(crate) fn verify<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, c
|
||||
proof_with_pis: ProofWithPublicInputs<F, C, D>,
|
||||
verifier_data: &VerifierOnlyCircuitData<C, D>,
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
ensure!(
|
||||
proof_with_pis.public_inputs.len() == common_data.num_public_inputs,
|
||||
"Number of public inputs doesn't match circuit data."
|
||||
@ -42,7 +45,10 @@ pub(crate) fn verify_with_challenges<
|
||||
challenges: ProofChallenges<F, D>,
|
||||
verifier_data: &VerifierOnlyCircuitData<C, D>,
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let local_constants = &proof.openings.constants;
|
||||
let local_wires = &proof.openings.wires;
|
||||
let vars = EvaluationVars {
|
||||
|
||||
@ -7,7 +7,7 @@ use plonky2::field::zero_poly_coset::ZeroPolyOnCoset;
|
||||
use plonky2::fri::oracle::PolynomialBatch;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::iop::challenger::Challenger;
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use plonky2::plonk::config::{GenericConfig, Hasher};
|
||||
use plonky2::timed;
|
||||
use plonky2::util::timing::TimingTree;
|
||||
use plonky2::util::transpose;
|
||||
@ -33,6 +33,7 @@ where
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let degree = trace.len();
|
||||
let degree_bits = log2_strict(degree);
|
||||
|
||||
@ -3,7 +3,7 @@ use plonky2::field::extension_field::{Extendable, FieldExtension};
|
||||
use plonky2::field::field_types::Field;
|
||||
use plonky2::fri::verifier::verify_fri_proof;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use plonky2::plonk::config::{GenericConfig, Hasher};
|
||||
use plonky2::plonk::plonk_common::reduce_with_powers;
|
||||
use plonky2_util::log2_strict;
|
||||
|
||||
@ -26,6 +26,7 @@ pub fn verify<
|
||||
where
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let degree_bits = log2_strict(recover_degree(&proof_with_pis.proof, config));
|
||||
let challenges = proof_with_pis.get_challenges(config, degree_bits)?;
|
||||
@ -47,6 +48,7 @@ pub(crate) fn verify_with_challenges<
|
||||
where
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
[(); C::Hasher::HASH_SIZE]:,
|
||||
{
|
||||
let StarkProofWithPublicInputs {
|
||||
proof,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user