qp-plonky2 1.4.1

Recursive SNARKs based on PLONK and FRI
Documentation
//! Merkle proof path compression utilities.
//!
//! Re-exports path compression functions from core.

pub use qp_plonky2_core::hash::path_compression::{
    compress_merkle_proofs, decompress_merkle_proofs,
};

#[cfg(test)]
#[cfg(feature = "rand")]
mod tests {
    use rand::rngs::OsRng;
    use rand::Rng;

    use super::*;
    use crate::field::types::Sample;
    use crate::hash::merkle_tree::MerkleTree;
    use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};

    #[test]
    fn test_path_compression() {
        const D: usize = 2;
        type C = PoseidonGoldilocksConfig;
        type F = <C as GenericConfig<D>>::F;
        let h = 10;
        let cap_height = 3;
        let vs = (0..1 << h).map(|_| vec![F::rand()]).collect::<Vec<_>>();
        let mt = MerkleTree::<F, <C as GenericConfig<D>>::Hasher>::new(vs.clone(), cap_height);

        let mut rng = OsRng;
        let k = rng.gen_range(1..=1 << h);
        let indices = (0..k).map(|_| rng.gen_range(0..1 << h)).collect::<Vec<_>>();
        let proofs = indices.iter().map(|&i| mt.prove(i)).collect::<Vec<_>>();

        let compressed_proofs = compress_merkle_proofs(cap_height, &indices, &proofs);
        let decompressed_proofs = decompress_merkle_proofs(
            &indices.iter().map(|&i| vs[i].clone()).collect::<Vec<_>>(),
            &indices,
            &compressed_proofs,
            h,
            cap_height,
        );

        assert_eq!(proofs, decompressed_proofs);

        #[cfg(feature = "std")]
        {
            let compressed_proof_bytes = serde_cbor::to_vec(&compressed_proofs).unwrap();
            println!(
                "Compressed proof length: {} bytes",
                compressed_proof_bytes.len()
            );
            let proof_bytes = serde_cbor::to_vec(&proofs).unwrap();
            println!("Proof length: {} bytes", proof_bytes.len());
        }
    }
}