mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-05-28 12:49:54 +00:00
Somewhat working
This commit is contained in:
parent
ea3e31504a
commit
d2a5e67980
@ -14,6 +14,7 @@ use crate::hash::path_compression::{compress_merkle_proofs, decompress_merkle_pr
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::plonk::circuit_data::CommonCircuitData;
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::plonk_common::PolynomialsIndexBlinding;
|
use crate::plonk::plonk_common::PolynomialsIndexBlinding;
|
||||||
|
use crate::plonk::proof::ProofChallenges;
|
||||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||||
|
|
||||||
/// Evaluations and Merkle proof produced by the prover in a FRI query step.
|
/// Evaluations and Merkle proof produced by the prover in a FRI query step.
|
||||||
@ -164,9 +165,12 @@ impl<F: RichField + Extendable<D>, const D: usize> FriProof<F, D> {
|
|||||||
initial_trees_proofs[i].push(proof);
|
initial_trees_proofs[i].push(proof);
|
||||||
}
|
}
|
||||||
for (i, query_step) in steps.into_iter().enumerate() {
|
for (i, query_step) in steps.into_iter().enumerate() {
|
||||||
|
let index_within_coset = index & ((1 << reduction_arity_bits[i]) - 1);
|
||||||
index >>= reduction_arity_bits[i];
|
index >>= reduction_arity_bits[i];
|
||||||
steps_indices[i].push(index);
|
steps_indices[i].push(index);
|
||||||
steps_evals[i].push(query_step.evals);
|
let mut evals = query_step.evals;
|
||||||
|
evals.remove(index_within_coset);
|
||||||
|
steps_evals[i].push(evals);
|
||||||
steps_proofs[i].push(query_step.merkle_proof);
|
steps_proofs[i].push(query_step.merkle_proof);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,9 +232,9 @@ impl<F: RichField + Extendable<D>, const D: usize> FriProof<F, D> {
|
|||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> CompressedFriProof<F, D> {
|
impl<F: RichField + Extendable<D>, const D: usize> CompressedFriProof<F, D> {
|
||||||
/// Decompress all the Merkle paths in the FRI proof and reinsert duplicate indices.
|
/// Decompress all the Merkle paths in the FRI proof and reinsert duplicate indices.
|
||||||
pub fn decompress(
|
pub(crate) fn decompress(
|
||||||
self,
|
self,
|
||||||
indices: &[usize],
|
challenges: &ProofChallenges<F, D>,
|
||||||
common_data: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> FriProof<F, D> {
|
) -> FriProof<F, D> {
|
||||||
let CompressedFriProof {
|
let CompressedFriProof {
|
||||||
@ -240,6 +244,16 @@ impl<F: RichField + Extendable<D>, const D: usize> CompressedFriProof<F, D> {
|
|||||||
pow_witness,
|
pow_witness,
|
||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
let ProofChallenges {
|
||||||
|
fri_query_indices: indices,
|
||||||
|
fri_query_inferred_elements,
|
||||||
|
..
|
||||||
|
} = challenges;
|
||||||
|
let fri_query_inferred_elements = if let Some(v) = fri_query_inferred_elements {
|
||||||
|
v
|
||||||
|
} else {
|
||||||
|
panic!()
|
||||||
|
};
|
||||||
let cap_height = common_data.config.cap_height;
|
let cap_height = common_data.config.cap_height;
|
||||||
let reduction_arity_bits = &common_data.fri_params.reduction_arity_bits;
|
let reduction_arity_bits = &common_data.fri_params.reduction_arity_bits;
|
||||||
let num_reductions = reduction_arity_bits.len();
|
let num_reductions = reduction_arity_bits.len();
|
||||||
@ -267,7 +281,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CompressedFriProof<F, D> {
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for mut index in indices.iter().copied() {
|
for (round, mut index) in indices.iter().copied().enumerate() {
|
||||||
let initial_trees_proof = query_round_proofs.initial_trees_proofs[&index].clone();
|
let initial_trees_proof = query_round_proofs.initial_trees_proofs[&index].clone();
|
||||||
for (i, (leaves_data, proof)) in
|
for (i, (leaves_data, proof)) in
|
||||||
initial_trees_proof.evals_proofs.into_iter().enumerate()
|
initial_trees_proof.evals_proofs.into_iter().enumerate()
|
||||||
@ -277,11 +291,16 @@ impl<F: RichField + Extendable<D>, const D: usize> CompressedFriProof<F, D> {
|
|||||||
initial_trees_proofs[i].push(proof);
|
initial_trees_proofs[i].push(proof);
|
||||||
}
|
}
|
||||||
for i in 0..num_reductions {
|
for i in 0..num_reductions {
|
||||||
|
let index_within_coset = index & ((1 << reduction_arity_bits[i]) - 1);
|
||||||
index >>= reduction_arity_bits[i];
|
index >>= reduction_arity_bits[i];
|
||||||
let query_step = query_round_proofs.steps[i][&index].clone();
|
let FriQueryStep {
|
||||||
|
mut evals,
|
||||||
|
merkle_proof,
|
||||||
|
} = query_round_proofs.steps[i][&index].clone();
|
||||||
steps_indices[i].push(index);
|
steps_indices[i].push(index);
|
||||||
steps_evals[i].push(flatten(&query_step.evals));
|
evals.insert(index_within_coset, fri_query_inferred_elements[round][i]);
|
||||||
steps_proofs[i].push(query_step.merkle_proof);
|
steps_evals[i].push(flatten(&evals));
|
||||||
|
steps_proofs[i].push(merkle_proof);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place};
|
|||||||
|
|
||||||
/// Computes P'(x^arity) from {P(x*g^i)}_(i=0..arity), where g is a `arity`-th root of unity
|
/// Computes P'(x^arity) from {P(x*g^i)}_(i=0..arity), where g is a `arity`-th root of unity
|
||||||
/// and P' is the FRI reduced polynomial.
|
/// and P' is the FRI reduced polynomial.
|
||||||
fn compute_evaluation<F: Field + Extendable<D>, const D: usize>(
|
pub(crate) fn compute_evaluation<F: Field + Extendable<D>, const D: usize>(
|
||||||
x: F,
|
x: F,
|
||||||
x_index_within_coset: usize,
|
x_index_within_coset: usize,
|
||||||
arity_bits: usize,
|
arity_bits: usize,
|
||||||
@ -83,10 +83,11 @@ pub(crate) fn verify_fri_proof<F: RichField + Extendable<D>, const D: usize>(
|
|||||||
|
|
||||||
let precomputed_reduced_evals =
|
let precomputed_reduced_evals =
|
||||||
PrecomputedReducedEvals::from_os_and_alpha(os, challenges.fri_alpha);
|
PrecomputedReducedEvals::from_os_and_alpha(os, challenges.fri_alpha);
|
||||||
for (&x_index, round_proof) in challenges
|
for (round, (&x_index, round_proof)) in challenges
|
||||||
.fri_query_indices
|
.fri_query_indices
|
||||||
.iter()
|
.iter()
|
||||||
.zip(&proof.query_round_proofs)
|
.zip(&proof.query_round_proofs)
|
||||||
|
.enumerate()
|
||||||
{
|
{
|
||||||
fri_verifier_query_round(
|
fri_verifier_query_round(
|
||||||
challenges,
|
challenges,
|
||||||
@ -95,6 +96,7 @@ pub(crate) fn verify_fri_proof<F: RichField + Extendable<D>, const D: usize>(
|
|||||||
&proof,
|
&proof,
|
||||||
x_index,
|
x_index,
|
||||||
n,
|
n,
|
||||||
|
round,
|
||||||
round_proof,
|
round_proof,
|
||||||
common_data,
|
common_data,
|
||||||
)?;
|
)?;
|
||||||
@ -218,6 +220,7 @@ fn fri_verifier_query_round<F: RichField + Extendable<D>, const D: usize>(
|
|||||||
proof: &FriProof<F, D>,
|
proof: &FriProof<F, D>,
|
||||||
mut x_index: usize,
|
mut x_index: usize,
|
||||||
n: usize,
|
n: usize,
|
||||||
|
round: usize,
|
||||||
round_proof: &FriQueryRound<F, D>,
|
round_proof: &FriQueryRound<F, D>,
|
||||||
common_data: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -259,13 +262,18 @@ fn fri_verifier_query_round<F: RichField + Extendable<D>, const D: usize>(
|
|||||||
ensure!(evals[x_index_within_coset] == old_eval);
|
ensure!(evals[x_index_within_coset] == old_eval);
|
||||||
|
|
||||||
// Infer P(y) from {P(x)}_{x^arity=y}.
|
// Infer P(y) from {P(x)}_{x^arity=y}.
|
||||||
old_eval = compute_evaluation(
|
old_eval = if let Some(v) = &challenges.fri_query_inferred_elements {
|
||||||
subgroup_x,
|
dbg!("yo");
|
||||||
x_index_within_coset,
|
v[round][i]
|
||||||
arity_bits,
|
} else {
|
||||||
evals,
|
compute_evaluation(
|
||||||
challenges.fri_betas[i],
|
subgroup_x,
|
||||||
);
|
x_index_within_coset,
|
||||||
|
arity_bits,
|
||||||
|
evals,
|
||||||
|
challenges.fri_betas[i],
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
verify_merkle_proof(
|
verify_merkle_proof(
|
||||||
flatten(evals),
|
flatten(evals),
|
||||||
|
|||||||
@ -138,7 +138,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CompressedProofWithPublicInpu
|
|||||||
challenger.observe_cap(cap);
|
challenger.observe_cap(cap);
|
||||||
challenger.get_extension_challenge()
|
challenger.get_extension_challenge()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
challenger.observe_extension_elements(&self.proof.opening_proof.final_poly.coeffs);
|
challenger.observe_extension_elements(&self.proof.opening_proof.final_poly.coeffs);
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CompressedProofWithPublicInpu
|
|||||||
|
|
||||||
let fri_query_indices = (0..num_fri_queries)
|
let fri_query_indices = (0..num_fri_queries)
|
||||||
.map(|_| challenger.get_challenge().to_canonical_u64() as usize % lde_size)
|
.map(|_| challenger.get_challenge().to_canonical_u64() as usize % lde_size)
|
||||||
.collect();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut fri_query_inferred_elements = Vec::new();
|
let mut fri_query_inferred_elements = Vec::new();
|
||||||
let log_n = common_data.degree_bits + common_data.config.rate_bits;
|
let log_n = common_data.degree_bits + common_data.config.rate_bits;
|
||||||
@ -164,16 +164,23 @@ impl<F: RichField + Extendable<D>, const D: usize> CompressedProofWithPublicInpu
|
|||||||
let mut x_index = fri_query_indices[query_round];
|
let mut x_index = fri_query_indices[query_round];
|
||||||
let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR
|
let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR
|
||||||
* F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64);
|
* F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64);
|
||||||
let evals = &self.proof.opening_proof..steps[query_round].evals;
|
for (i, &arity_bits) in common_data
|
||||||
for &arity_bits in &common_data.config.fri_config.reduction_strategy {
|
.fri_params
|
||||||
|
.reduction_arity_bits
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
let arity = 1 << arity_bits;
|
let arity = 1 << arity_bits;
|
||||||
|
let evals = &self.proof.opening_proof.query_round_proofs.steps[i]
|
||||||
|
[&(x_index >> arity_bits)]
|
||||||
|
.evals;
|
||||||
let x_index_within_coset = x_index & (arity - 1);
|
let x_index_within_coset = x_index & (arity - 1);
|
||||||
let elmt = compute_evaluation(
|
let elmt = compute_evaluation(
|
||||||
subgroup_x,
|
subgroup_x,
|
||||||
x_index_within_coset,
|
x_index_within_coset,
|
||||||
arity_bits,
|
arity_bits,
|
||||||
evals,
|
evals,
|
||||||
challenges.fri_betas[i],
|
fri_betas[i],
|
||||||
);
|
);
|
||||||
query_round_inferred_elements.push(elmt);
|
query_round_inferred_elements.push(elmt);
|
||||||
subgroup_x = subgroup_x.exp_power_of_2(arity_bits);
|
subgroup_x = subgroup_x.exp_power_of_2(arity_bits);
|
||||||
|
|||||||
@ -10,7 +10,8 @@ use crate::hash::hash_types::{HashOut, MerkleCapTarget};
|
|||||||
use crate::hash::hashing::hash_n_to_hash;
|
use crate::hash::hashing::hash_n_to_hash;
|
||||||
use crate::hash::merkle_tree::MerkleCap;
|
use crate::hash::merkle_tree::MerkleCap;
|
||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::plonk::circuit_data::CommonCircuitData;
|
use crate::plonk::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData};
|
||||||
|
use crate::plonk::verifier::verify_with_challenges;
|
||||||
use crate::util::serialization::Buffer;
|
use crate::util::serialization::Buffer;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
|
||||||
@ -118,9 +119,9 @@ pub struct CompressedProof<F: Extendable<D>, const D: usize> {
|
|||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> CompressedProof<F, D> {
|
impl<F: RichField + Extendable<D>, const D: usize> CompressedProof<F, D> {
|
||||||
/// Decompress the proof.
|
/// Decompress the proof.
|
||||||
pub fn decompress(
|
pub(crate) fn decompress(
|
||||||
self,
|
self,
|
||||||
indices: &[usize],
|
challenges: &ProofChallenges<F, D>,
|
||||||
common_data: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> Proof<F, D> {
|
) -> Proof<F, D> {
|
||||||
let CompressedProof {
|
let CompressedProof {
|
||||||
@ -136,7 +137,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CompressedProof<F, D> {
|
|||||||
plonk_zs_partial_products_cap,
|
plonk_zs_partial_products_cap,
|
||||||
quotient_polys_cap,
|
quotient_polys_cap,
|
||||||
openings,
|
openings,
|
||||||
opening_proof: opening_proof.decompress(indices, common_data),
|
opening_proof: opening_proof.decompress(challenges, common_data),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,14 +154,33 @@ impl<F: RichField + Extendable<D>, const D: usize> CompressedProofWithPublicInpu
|
|||||||
self,
|
self,
|
||||||
common_data: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> anyhow::Result<ProofWithPublicInputs<F, D>> {
|
) -> anyhow::Result<ProofWithPublicInputs<F, D>> {
|
||||||
let indices = self.fri_query_indices(common_data)?;
|
let challenges = self.get_challenges(common_data)?;
|
||||||
let compressed_proof = self.proof.decompress(&indices, common_data);
|
let compressed_proof = self.proof.decompress(&challenges, common_data);
|
||||||
Ok(ProofWithPublicInputs {
|
Ok(ProofWithPublicInputs {
|
||||||
public_inputs: self.public_inputs,
|
public_inputs: self.public_inputs,
|
||||||
proof: compressed_proof,
|
proof: compressed_proof,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn verify(
|
||||||
|
self,
|
||||||
|
verifier_data: &VerifierOnlyCircuitData<F>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let challenges = self.get_challenges(common_data)?;
|
||||||
|
dbg!(&challenges.fri_query_inferred_elements);
|
||||||
|
let compressed_proof = self.proof.decompress(&challenges, common_data);
|
||||||
|
verify_with_challenges(
|
||||||
|
ProofWithPublicInputs {
|
||||||
|
public_inputs: self.public_inputs,
|
||||||
|
proof: compressed_proof,
|
||||||
|
},
|
||||||
|
challenges,
|
||||||
|
verifier_data,
|
||||||
|
common_data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_public_inputs_hash(&self) -> HashOut<F> {
|
pub(crate) fn get_public_inputs_hash(&self) -> HashOut<F> {
|
||||||
hash_n_to_hash(self.public_inputs.clone(), true)
|
hash_n_to_hash(self.public_inputs.clone(), true)
|
||||||
}
|
}
|
||||||
@ -203,6 +223,8 @@ pub(crate) struct ProofChallenges<F: RichField + Extendable<D>, const D: usize>
|
|||||||
pub fri_pow_response: F,
|
pub fri_pow_response: F,
|
||||||
|
|
||||||
pub fri_query_indices: Vec<usize>,
|
pub fri_query_indices: Vec<usize>,
|
||||||
|
|
||||||
|
pub fri_query_inferred_elements: Option<Vec<Vec<F::Extension>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ProofWithPublicInputsTarget<const D: usize> {
|
pub struct ProofWithPublicInputsTarget<const D: usize> {
|
||||||
@ -273,6 +295,7 @@ mod tests {
|
|||||||
|
|
||||||
use crate::field::crandall_field::CrandallField;
|
use crate::field::crandall_field::CrandallField;
|
||||||
use crate::field::field_types::Field;
|
use crate::field::field_types::Field;
|
||||||
|
use crate::fri::reduction_strategies::FriReductionStrategy;
|
||||||
use crate::iop::witness::PartialWitness;
|
use crate::iop::witness::PartialWitness;
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::plonk::circuit_data::CircuitConfig;
|
use crate::plonk::circuit_data::CircuitConfig;
|
||||||
@ -284,6 +307,7 @@ mod tests {
|
|||||||
const D: usize = 4;
|
const D: usize = 4;
|
||||||
|
|
||||||
let mut config = CircuitConfig::large_config();
|
let mut config = CircuitConfig::large_config();
|
||||||
|
config.fri_config.reduction_strategy = FriReductionStrategy::Fixed(vec![1]);
|
||||||
config.fri_config.num_query_rounds = 50;
|
config.fri_config.num_query_rounds = 50;
|
||||||
|
|
||||||
let pw = PartialWitness::new();
|
let pw = PartialWitness::new();
|
||||||
@ -303,9 +327,10 @@ mod tests {
|
|||||||
|
|
||||||
// Verify that `decompress ∘ compress = identity`.
|
// Verify that `decompress ∘ compress = identity`.
|
||||||
let compressed_proof = proof.clone().compress(&data.common)?;
|
let compressed_proof = proof.clone().compress(&data.common)?;
|
||||||
let decompressed_compressed_proof = compressed_proof.decompress(&data.common)?;
|
let decompressed_compressed_proof = compressed_proof.clone().decompress(&data.common)?;
|
||||||
assert_eq!(proof, decompressed_compressed_proof);
|
assert_eq!(proof, decompressed_compressed_proof);
|
||||||
|
|
||||||
verify(proof, &data.verifier_only, &data.common)
|
verify(proof, &data.verifier_only, &data.common)?;
|
||||||
|
compressed_proof.verify(&data.verifier_only, &data.common)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use crate::field::field_types::{Field, RichField};
|
|||||||
use crate::fri::verifier::verify_fri_proof;
|
use crate::fri::verifier::verify_fri_proof;
|
||||||
use crate::plonk::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData};
|
use crate::plonk::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData};
|
||||||
use crate::plonk::plonk_common::reduce_with_powers;
|
use crate::plonk::plonk_common::reduce_with_powers;
|
||||||
use crate::plonk::proof::ProofWithPublicInputs;
|
use crate::plonk::proof::{ProofChallenges, ProofWithPublicInputs};
|
||||||
use crate::plonk::vanishing_poly::eval_vanishing_poly;
|
use crate::plonk::vanishing_poly::eval_vanishing_poly;
|
||||||
use crate::plonk::vars::EvaluationVars;
|
use crate::plonk::vars::EvaluationVars;
|
||||||
|
|
||||||
@ -14,9 +14,17 @@ pub(crate) fn verify<F: RichField + Extendable<D>, const D: usize>(
|
|||||||
verifier_data: &VerifierOnlyCircuitData<F>,
|
verifier_data: &VerifierOnlyCircuitData<F>,
|
||||||
common_data: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let public_inputs_hash = &proof_with_pis.get_public_inputs_hash();
|
|
||||||
|
|
||||||
let challenges = proof_with_pis.get_challenges(common_data)?;
|
let challenges = proof_with_pis.get_challenges(common_data)?;
|
||||||
|
verify_with_challenges(proof_with_pis, challenges, verifier_data, common_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn verify_with_challenges<F: RichField + Extendable<D>, const D: usize>(
|
||||||
|
proof_with_pis: ProofWithPublicInputs<F, D>,
|
||||||
|
challenges: ProofChallenges<F, D>,
|
||||||
|
verifier_data: &VerifierOnlyCircuitData<F>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let public_inputs_hash = &proof_with_pis.get_public_inputs_hash();
|
||||||
|
|
||||||
let ProofWithPublicInputs { proof, .. } = proof_with_pis;
|
let ProofWithPublicInputs { proof, .. } = proof_with_pis;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user