mirror of
https://github.com/logos-storage/proof-aggregation.git
synced 2026-01-08 08:43:11 +00:00
add hashing for verifierData
This commit is contained in:
parent
69983cd2dd
commit
5acbcf1f06
@ -2,7 +2,7 @@ use std::marker::PhantomData;
|
|||||||
use plonky2::hash::hash_types::RichField;
|
use plonky2::hash::hash_types::RichField;
|
||||||
use plonky2::iop::witness::{PartialWitness, WitnessWrite};
|
use plonky2::iop::witness::{PartialWitness, WitnessWrite};
|
||||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||||
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitData, VerifierCircuitTarget};
|
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData};
|
||||||
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
|
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
|
||||||
use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget};
|
use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget};
|
||||||
use plonky2_field::extension::Extendable;
|
use plonky2_field::extension::Extendable;
|
||||||
@ -46,15 +46,6 @@ pub struct LeafTargets <
|
|||||||
pub inner_proof: ProofWithPublicInputsTarget<D>,
|
pub inner_proof: ProofWithPublicInputsTarget<D>,
|
||||||
pub verifier_data: VerifierCircuitTarget,
|
pub verifier_data: VerifierCircuitTarget,
|
||||||
}
|
}
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct LeafInput<
|
|
||||||
F: RichField + Extendable<D> + Poseidon2,
|
|
||||||
const D: usize,
|
|
||||||
C: GenericConfig<D, F = F>,
|
|
||||||
>{
|
|
||||||
pub inner_proof: ProofWithPublicInputs<F, C, D>,
|
|
||||||
pub verifier_data: VerifierCircuitData<F, C, D>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
F: RichField + Extendable<D> + Poseidon2,
|
F: RichField + Extendable<D> + Poseidon2,
|
||||||
@ -83,6 +74,15 @@ impl<
|
|||||||
// virtual target for the verifier data
|
// virtual target for the verifier data
|
||||||
let inner_verifier_data = builder.add_virtual_verifier_data(inner_common.config.fri_config.cap_height);
|
let inner_verifier_data = builder.add_virtual_verifier_data(inner_common.config.fri_config.cap_height);
|
||||||
|
|
||||||
|
// register verifier data hash as public input.
|
||||||
|
let mut vd_pub_input = vec![];
|
||||||
|
vd_pub_input.extend_from_slice(&inner_verifier_data.circuit_digest.elements);
|
||||||
|
for i in 0..builder.config.fri_config.num_cap_elements() {
|
||||||
|
vd_pub_input.extend_from_slice(&inner_verifier_data.constants_sigmas_cap.0[i].elements);
|
||||||
|
}
|
||||||
|
let hash_inner_vd_pub_input = builder.hash_n_to_hash_no_pad::<H>(vd_pub_input);
|
||||||
|
builder.register_public_inputs(&hash_inner_vd_pub_input.elements);
|
||||||
|
|
||||||
// verify the proofs in-circuit (only one )
|
// verify the proofs in-circuit (only one )
|
||||||
builder.verify_proof::<C>(&vir_proof, &inner_verifier_data, &inner_common);
|
builder.verify_proof::<C>(&vir_proof, &inner_verifier_data, &inner_common);
|
||||||
|
|
||||||
@ -99,16 +99,17 @@ impl<
|
|||||||
pub fn assign_targets(
|
pub fn assign_targets(
|
||||||
&self, pw: &mut PartialWitness<F>,
|
&self, pw: &mut PartialWitness<F>,
|
||||||
targets: &LeafTargets<D>,
|
targets: &LeafTargets<D>,
|
||||||
input: &LeafInput<F, D, C>
|
inner_proof: &ProofWithPublicInputs<F, C, D>,
|
||||||
|
verifier_only_data: &VerifierOnlyCircuitData<C, D>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// assign the proofs
|
// assign the proofs
|
||||||
pw.set_proof_with_pis_target(&targets.inner_proof, &input.inner_proof)
|
pw.set_proof_with_pis_target(&targets.inner_proof, inner_proof)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
CircuitError::ProofTargetAssignmentError("inner-proof".to_string(), e.to_string())
|
CircuitError::ProofTargetAssignmentError("inner-proof".to_string(), e.to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// assign the verifier data
|
// assign the verifier data
|
||||||
pw.set_verifier_data_target(&targets.verifier_data, &input.verifier_data.verifier_only)
|
pw.set_verifier_data_target(&targets.verifier_data, verifier_only_data)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
CircuitError::VerifierDataTargetAssignmentError(e.to_string())
|
CircuitError::VerifierDataTargetAssignmentError(e.to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::marker::PhantomData;
|
|||||||
use plonky2::hash::hash_types::RichField;
|
use plonky2::hash::hash_types::RichField;
|
||||||
use plonky2::iop::witness::{PartialWitness, WitnessWrite};
|
use plonky2::iop::witness::{PartialWitness, WitnessWrite};
|
||||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||||
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitData, VerifierCircuitTarget};
|
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData};
|
||||||
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
|
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
|
||||||
use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget};
|
use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget};
|
||||||
use plonky2_field::extension::Extendable;
|
use plonky2_field::extension::Extendable;
|
||||||
@ -47,15 +47,6 @@ pub struct NodeTargets<
|
|||||||
pub leaf_proofs: [ProofWithPublicInputsTarget<D>; 2],
|
pub leaf_proofs: [ProofWithPublicInputsTarget<D>; 2],
|
||||||
pub verifier_data: VerifierCircuitTarget,
|
pub verifier_data: VerifierCircuitTarget,
|
||||||
}
|
}
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct NodeInput<
|
|
||||||
F: RichField + Extendable<D> + Poseidon2,
|
|
||||||
const D: usize,
|
|
||||||
C: GenericConfig<D, F = F>,
|
|
||||||
>{
|
|
||||||
pub node_proofs: [ProofWithPublicInputs<F, C, D>;2],
|
|
||||||
pub verifier_data: VerifierCircuitData<F, C, D>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
F: RichField + Extendable<D> + Poseidon2,
|
F: RichField + Extendable<D> + Poseidon2,
|
||||||
@ -71,14 +62,19 @@ impl<
|
|||||||
|
|
||||||
let inner_common = self.leaf_common_data.clone();
|
let inner_common = self.leaf_common_data.clone();
|
||||||
|
|
||||||
|
// assert public input is of size 8 - 2 hashout
|
||||||
|
assert_eq!(inner_common.num_public_inputs, 8);
|
||||||
|
|
||||||
// the proof virtual targets - 2 proofs
|
// the proof virtual targets - 2 proofs
|
||||||
let mut vir_proofs = vec![];
|
let mut vir_proofs = vec![];
|
||||||
let mut pub_input = vec![];
|
let mut pub_input = vec![];
|
||||||
|
let mut inner_vd_hashes = vec![];
|
||||||
for _i in 0..2 {
|
for _i in 0..2 {
|
||||||
let vir_proof = builder.add_virtual_proof_with_pis(&inner_common);
|
let vir_proof = builder.add_virtual_proof_with_pis(&inner_common);
|
||||||
let inner_pub_input = vir_proof.public_inputs.clone();
|
let inner_pub_input = vir_proof.public_inputs.clone();
|
||||||
vir_proofs.push(vir_proof);
|
vir_proofs.push(vir_proof);
|
||||||
pub_input.extend_from_slice(&inner_pub_input);
|
pub_input.extend_from_slice(&inner_pub_input[0..4]);
|
||||||
|
inner_vd_hashes.extend_from_slice(&inner_pub_input[4..8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash the public input & make it public
|
// hash the public input & make it public
|
||||||
@ -88,6 +84,17 @@ impl<
|
|||||||
// virtual target for the verifier data
|
// virtual target for the verifier data
|
||||||
let inner_verifier_data = builder.add_virtual_verifier_data(inner_common.config.fri_config.cap_height);
|
let inner_verifier_data = builder.add_virtual_verifier_data(inner_common.config.fri_config.cap_height);
|
||||||
|
|
||||||
|
// register verifier data hash as public input. H(H_l, H_l, H_n) -> public input
|
||||||
|
let mut vd_pub_input = vec![];
|
||||||
|
vd_pub_input.extend_from_slice(&inner_verifier_data.circuit_digest.elements);
|
||||||
|
for i in 0..builder.config.fri_config.num_cap_elements() {
|
||||||
|
vd_pub_input.extend_from_slice(&inner_verifier_data.constants_sigmas_cap.0[i].elements);
|
||||||
|
}
|
||||||
|
let vd_hash = builder.hash_n_to_hash_no_pad::<H>(vd_pub_input);
|
||||||
|
inner_vd_hashes.extend_from_slice(&vd_hash.elements);
|
||||||
|
let vd_hash_all = builder.hash_n_to_hash_no_pad::<H>(inner_vd_hashes);
|
||||||
|
builder.register_public_inputs(&vd_hash_all.elements);
|
||||||
|
|
||||||
// verify the proofs in-circuit - 2 proofs
|
// verify the proofs in-circuit - 2 proofs
|
||||||
for i in 0..2 {
|
for i in 0..2 {
|
||||||
builder.verify_proof::<C>(&vir_proofs[i], &inner_verifier_data, &inner_common);
|
builder.verify_proof::<C>(&vir_proofs[i], &inner_verifier_data, &inner_common);
|
||||||
@ -108,18 +115,22 @@ impl<
|
|||||||
pub fn assign_targets(
|
pub fn assign_targets(
|
||||||
&self, pw: &mut PartialWitness<F>,
|
&self, pw: &mut PartialWitness<F>,
|
||||||
targets: &NodeTargets<D>,
|
targets: &NodeTargets<D>,
|
||||||
input: &NodeInput<F, D, C>
|
node_proofs: &[ProofWithPublicInputs<F, C, D>],
|
||||||
|
verifier_only_data: &VerifierOnlyCircuitData<C, D>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
// assert size of proofs vec
|
||||||
|
assert_eq!(node_proofs.len(), 2);
|
||||||
|
|
||||||
// assign the proofs
|
// assign the proofs
|
||||||
for i in 0..2 {
|
for i in 0..2 {
|
||||||
pw.set_proof_with_pis_target(&targets.leaf_proofs[i], &input.node_proofs[i])
|
pw.set_proof_with_pis_target(&targets.leaf_proofs[i], &node_proofs[i])
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
CircuitError::ProofTargetAssignmentError("inner-proof".to_string(), e.to_string())
|
CircuitError::ProofTargetAssignmentError("inner-proof".to_string(), e.to_string())
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign the verifier data
|
// assign the verifier data
|
||||||
pw.set_verifier_data_target(&targets.verifier_data, &input.verifier_data.verifier_only)
|
pw.set_verifier_data_target(&targets.verifier_data, &verifier_only_data)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
CircuitError::VerifierDataTargetAssignmentError(e.to_string())
|
CircuitError::VerifierDataTargetAssignmentError(e.to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use plonky2::hash::hash_types::RichField;
|
use plonky2::hash::hash_types::{HashOut, RichField};
|
||||||
use plonky2::iop::witness::PartialWitness;
|
use plonky2::iop::witness::PartialWitness;
|
||||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||||
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitData};
|
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitData, VerifierOnlyCircuitData};
|
||||||
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
|
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
|
||||||
use plonky2::plonk::proof::ProofWithPublicInputs;
|
use plonky2::plonk::proof::ProofWithPublicInputs;
|
||||||
use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2;
|
use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2;
|
||||||
use crate::recursion::circuits::inner_circuit::InnerCircuit;
|
use crate::recursion::circuits::inner_circuit::InnerCircuit;
|
||||||
use plonky2_field::extension::Extendable;
|
use plonky2_field::extension::Extendable;
|
||||||
use crate::{error::CircuitError, Result};
|
use crate::{error::CircuitError, Result};
|
||||||
use crate::recursion::uniform::{leaf::{LeafTargets,LeafInput,LeafCircuit},node::{NodeTargets,NodeInput,NodeCircuit}};
|
use crate::recursion::uniform::{leaf::{LeafTargets,LeafCircuit},node::{NodeTargets,NodeCircuit}};
|
||||||
|
|
||||||
/// tree recursion
|
/// tree recursion
|
||||||
pub struct TreeRecursion<
|
pub struct TreeRecursion<
|
||||||
@ -70,11 +70,19 @@ impl<
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_leaf_verifier_data(&self) -> VerifierCircuitData<F, C, D>{
|
||||||
|
self.leaf_circ_data.verifier_data()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_node_verifier_data(&self) -> VerifierCircuitData<F, C, D>{
|
||||||
|
self.node_circ_data.verifier_data()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn prove_tree
|
pub fn prove_tree
|
||||||
(
|
(
|
||||||
&mut self,
|
&mut self,
|
||||||
proofs_with_pi: &[ProofWithPublicInputs<F, C, D>],
|
proofs_with_pi: &[ProofWithPublicInputs<F, C, D>],
|
||||||
inner_verifier_data: VerifierCircuitData<F, C, D>,
|
inner_verifier_only_data: &VerifierOnlyCircuitData<C, D>,
|
||||||
) -> Result<(ProofWithPublicInputs<F, C, D>)>
|
) -> Result<(ProofWithPublicInputs<F, C, D>)>
|
||||||
{
|
{
|
||||||
if proofs_with_pi.len() % 2 != 0 {
|
if proofs_with_pi.len() % 2 != 0 {
|
||||||
@ -86,33 +94,29 @@ impl<
|
|||||||
// process leaves
|
// process leaves
|
||||||
let leaf_proofs = self.get_leaf_proofs(
|
let leaf_proofs = self.get_leaf_proofs(
|
||||||
proofs_with_pi,
|
proofs_with_pi,
|
||||||
inner_verifier_data,
|
inner_verifier_only_data,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// process nodes
|
// process nodes
|
||||||
let (root_proof, vd) =
|
let (root_proof, vd) =
|
||||||
self.prove(&leaf_proofs,self.leaf_circ_data.verifier_data())?;
|
self.prove(&leaf_proofs,&self.leaf_circ_data.verifier_only)?;
|
||||||
|
|
||||||
Ok(root_proof)
|
Ok(root_proof)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn get_leaf_proofs
|
fn get_leaf_proofs
|
||||||
(
|
(
|
||||||
&mut self,
|
&mut self,
|
||||||
proofs_with_pi: &[ProofWithPublicInputs<F, C, D>],
|
proofs_with_pi: &[ProofWithPublicInputs<F, C, D>],
|
||||||
inner_verifier_data: VerifierCircuitData<F, C, D>,
|
inner_verifier_only_data: &VerifierOnlyCircuitData<C, D>,
|
||||||
) -> Result<(Vec<ProofWithPublicInputs<F, C, D>>)> {
|
) -> Result<(Vec<ProofWithPublicInputs<F, C, D>>)> {
|
||||||
|
|
||||||
let mut leaf_proofs = vec![];
|
let mut leaf_proofs = vec![];
|
||||||
|
|
||||||
for proof in proofs_with_pi{
|
for proof in proofs_with_pi{
|
||||||
let mut pw = PartialWitness::<F>::new();
|
let mut pw = PartialWitness::<F>::new();
|
||||||
let leaf_in = LeafInput{
|
|
||||||
inner_proof: proof.clone(),
|
self.leaf.assign_targets(&mut pw,&self.leaf_targets,proof,inner_verifier_only_data)?;
|
||||||
verifier_data: inner_verifier_data.clone(),
|
|
||||||
};
|
|
||||||
self.leaf.assign_targets(&mut pw,&self.leaf_targets,&leaf_in)?;
|
|
||||||
let proof = self.leaf_circ_data.prove(pw).unwrap();
|
let proof = self.leaf_circ_data.prove(pw).unwrap();
|
||||||
leaf_proofs.push(proof);
|
leaf_proofs.push(proof);
|
||||||
}
|
}
|
||||||
@ -122,15 +126,15 @@ impl<
|
|||||||
|
|
||||||
/// generates a proof - only one node
|
/// generates a proof - only one node
|
||||||
fn prove(
|
fn prove(
|
||||||
&mut self,
|
&self,
|
||||||
proofs_with_pi: &[ProofWithPublicInputs<F, C, D>],
|
proofs_with_pi: &[ProofWithPublicInputs<F, C, D>],
|
||||||
verifier_data: VerifierCircuitData<F, C, D>,
|
verifier_only_data: &VerifierOnlyCircuitData<C, D>,
|
||||||
) -> Result<(ProofWithPublicInputs<F, C, D>, VerifierCircuitData<F, C, D>)> where
|
) -> Result<(ProofWithPublicInputs<F, C, D>, VerifierOnlyCircuitData<C, D>)> where
|
||||||
<C as GenericConfig<D>>::Hasher: AlgebraicHasher<F>
|
<C as GenericConfig<D>>::Hasher: AlgebraicHasher<F>
|
||||||
{
|
{
|
||||||
|
|
||||||
if proofs_with_pi.len() == 1 {
|
if proofs_with_pi.len() == 1 {
|
||||||
return Ok((proofs_with_pi[0].clone(), verifier_data));
|
return Ok((proofs_with_pi[0].clone(), verifier_only_data.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut new_proofs = vec![];
|
let mut new_proofs = vec![];
|
||||||
@ -138,18 +142,102 @@ impl<
|
|||||||
for chunk in proofs_with_pi.chunks(2) {
|
for chunk in proofs_with_pi.chunks(2) {
|
||||||
|
|
||||||
let mut inner_pw = PartialWitness::new();
|
let mut inner_pw = PartialWitness::new();
|
||||||
let node_in = NodeInput{
|
|
||||||
node_proofs: [chunk[0].clone(), chunk[1].clone()],
|
self.node.assign_targets(
|
||||||
verifier_data: verifier_data.clone() ,
|
&mut inner_pw,
|
||||||
};
|
&self.node_targets,
|
||||||
self.node.assign_targets(&mut inner_pw,&self.node_targets,&node_in)?;
|
chunk,
|
||||||
|
verifier_only_data,
|
||||||
|
)?;
|
||||||
|
|
||||||
let proof = self.node_circ_data.prove(inner_pw)
|
let proof = self.node_circ_data.prove(inner_pw)
|
||||||
.map_err(|e| CircuitError::ProofGenerationError(e.to_string()))?;
|
.map_err(|e| CircuitError::ProofGenerationError(e.to_string()))?;
|
||||||
new_proofs.push(proof);
|
new_proofs.push(proof);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.prove(&new_proofs, self.node_circ_data.verifier_data())
|
self.prove(&new_proofs, &self.node_circ_data.verifier_only)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn verify_proof_and_public_input(
|
||||||
|
&self,
|
||||||
|
proof: ProofWithPublicInputs<F, C, D>,
|
||||||
|
inner_public_input: Vec<Vec<F>>,
|
||||||
|
inner_verifier_data: &VerifierCircuitData<F, C, D>) -> Result<()>
|
||||||
|
{
|
||||||
|
let public_input = proof.public_inputs.clone();
|
||||||
|
self.node_circ_data.verify(proof)
|
||||||
|
.map_err(|e| CircuitError::InvalidProofError(e.to_string()))?;
|
||||||
|
self.verify_public_input(public_input, inner_public_input, inner_verifier_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn verify_public_input(&self, public_input: Vec<F>, inner_public_input: Vec<Vec<F>>, inner_verifier_data: &VerifierCircuitData<F, C, D>) -> Result<()>{
|
||||||
|
assert_eq!(public_input.len(), 8);
|
||||||
|
|
||||||
|
let given_input_hash = &public_input[0..4];
|
||||||
|
let given_vd_hash = &public_input[4..8];
|
||||||
|
|
||||||
|
let inner_hash = Self::get_hash_of_verifier_data(&inner_verifier_data);
|
||||||
|
|
||||||
|
let leaf_hash = Self::get_hash_of_verifier_data(&self.leaf_circ_data.verifier_data());
|
||||||
|
|
||||||
|
let node_hash = Self::get_hash_of_verifier_data(&self.node_circ_data.verifier_data());
|
||||||
|
|
||||||
|
|
||||||
|
let mut pub_in_hashes = vec![];
|
||||||
|
let mut inner_vd_hashes = vec![];
|
||||||
|
for pub_in in inner_public_input{
|
||||||
|
let hash = H::hash_no_pad(&pub_in);
|
||||||
|
pub_in_hashes.push(hash);
|
||||||
|
inner_vd_hashes.push(inner_hash.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut level = 0;
|
||||||
|
while pub_in_hashes.len() > 1 {
|
||||||
|
let mut next_level_pi_hashes = Vec::new();
|
||||||
|
let mut next_level_vd_hashes = Vec::new();
|
||||||
|
for (pi_chunk, vd_chunk) in pub_in_hashes.chunks(2).zip(inner_vd_hashes.chunks(2)) {
|
||||||
|
// collect field elements
|
||||||
|
let pi_chunk_f: Vec<F> = pi_chunk.iter()
|
||||||
|
.flat_map(|h| h.elements.iter().cloned())
|
||||||
|
.collect();
|
||||||
|
let mut vd_chunk_f: Vec<F> = vd_chunk.iter()
|
||||||
|
.flat_map(|h| h.elements.iter().cloned())
|
||||||
|
.collect();
|
||||||
|
let hash_n = if level == 0 {leaf_hash} else{node_hash};
|
||||||
|
vd_chunk_f.extend_from_slice(&hash_n.elements);
|
||||||
|
|
||||||
|
// Compute Poseidon2 hash of the concatenated chunk
|
||||||
|
let pi_hash = H::hash_no_pad(&pi_chunk_f);
|
||||||
|
let vd_hash = H::hash_no_pad(&vd_chunk_f);
|
||||||
|
next_level_pi_hashes.push(pi_hash);
|
||||||
|
next_level_vd_hashes.push(vd_hash);
|
||||||
|
}
|
||||||
|
pub_in_hashes = next_level_pi_hashes;
|
||||||
|
inner_vd_hashes = next_level_vd_hashes;
|
||||||
|
level +=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check expected hash
|
||||||
|
let expected_pi_hash = pub_in_hashes[0];
|
||||||
|
let expected_vd_hash = inner_vd_hashes[0];
|
||||||
|
|
||||||
|
assert_eq!(given_input_hash, expected_pi_hash.elements);
|
||||||
|
assert_eq!(given_vd_hash, expected_vd_hash.elements);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// helper fn to generate hash of verifier data
|
||||||
|
fn get_hash_of_verifier_data(verifier_data: &VerifierCircuitData<F, C, D>) -> HashOut<F>{
|
||||||
|
let mut vd = vec![];
|
||||||
|
let digest: &HashOut<F> = &verifier_data.verifier_only.circuit_digest;
|
||||||
|
let caps = &verifier_data.verifier_only.constants_sigmas_cap;
|
||||||
|
vd.extend_from_slice(&digest.elements);
|
||||||
|
for i in 0..verifier_data.common.config.fri_config.num_cap_elements() {
|
||||||
|
let cap_hash = caps.0[i] as HashOut<F>;
|
||||||
|
vd.extend_from_slice(&cap_hash.elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
H::hash_no_pad(&vd)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::fs;
|
||||||
use plonky2::iop::witness::{PartialWitness};
|
use plonky2::iop::witness::{PartialWitness};
|
||||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||||
use plonky2::plonk::circuit_data::{CircuitConfig};
|
use plonky2::plonk::circuit_data::{CircuitConfig};
|
||||||
@ -40,9 +41,16 @@ mod tests {
|
|||||||
|
|
||||||
let mut tree = TreeRecursion::<F,D,C,HF>::build(inner_data.common.clone())?;
|
let mut tree = TreeRecursion::<F,D,C,HF>::build(inner_data.common.clone())?;
|
||||||
|
|
||||||
let root = tree.prove_tree(&proofs, inner_data.verifier_data())?;
|
let root = tree.prove_tree(&proofs, &inner_data.verifier_only)?;
|
||||||
|
println!("pub input size = {}", root.public_inputs.len());
|
||||||
|
|
||||||
|
let inner_pi: Vec<Vec<F>> = proofs.iter().map(|p| p.public_inputs.clone()).collect();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
tree.verify_proof_and_public_input(root,inner_pi,&inner_data.verifier_data()).is_ok(),
|
||||||
|
"proof verification failed"
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ fn bench_uniform_recursion<const N: usize,>(c: &mut Criterion) -> anyhow::Result
|
|||||||
// Proving Phase
|
// Proving Phase
|
||||||
group.bench_function("prove tree", |b| {
|
group.bench_function("prove tree", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
proof = Some(tree.prove_tree(&proofs, inner_data.verifier_data()).unwrap());
|
proof = Some(tree.prove_tree(&proofs, &inner_data.verifier_only).unwrap());
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -70,6 +70,7 @@ fn bench_uniform_recursion<const N: usize,>(c: &mut Criterion) -> anyhow::Result
|
|||||||
|
|
||||||
fn bench_uniform_tree_recursion(c: &mut Criterion){
|
fn bench_uniform_tree_recursion(c: &mut Criterion){
|
||||||
const N: usize = 2; // number of child nodes - binary here
|
const N: usize = 2; // number of child nodes - binary here
|
||||||
|
bench_uniform_recursion::<2>(c).expect("bench failed");
|
||||||
bench_uniform_recursion::<4>(c).expect("bench failed");
|
bench_uniform_recursion::<4>(c).expect("bench failed");
|
||||||
bench_uniform_recursion::<8>(c).expect("bench failed");
|
bench_uniform_recursion::<8>(c).expect("bench failed");
|
||||||
bench_uniform_recursion::<16>(c).expect("bench failed");
|
bench_uniform_recursion::<16>(c).expect("bench failed");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user