use std::marker::PhantomData;
use crate::drgraph::Graph;
use crate::hasher::Hasher;
use crate::layered_drgporep::Layers;
use crate::parameter_cache::ParameterSetMetadata;
use crate::zigzag_graph::{ZigZag, ZigZagBucketGraph};
#[derive(Debug)]
pub struct ZigZagDrgPoRep<'a, H: 'a + Hasher> {
_a: PhantomData<&'a H>,
}
impl<'a, H: 'static + Hasher> Layers for ZigZagDrgPoRep<'a, H> where {
type Hasher = <ZigZagBucketGraph<H> as ZigZag>::BaseHasher;
type Graph = ZigZagBucketGraph<Self::Hasher>;
fn transform(graph: &Self::Graph) -> Self::Graph {
zigzag::<Self::Hasher, Self::Graph>(graph)
}
fn invert_transform(graph: &Self::Graph) -> Self::Graph {
zigzag::<Self::Hasher, Self::Graph>(graph)
}
}
fn zigzag<H, Z>(graph: &Z) -> Z
where
H: Hasher,
Z: ZigZag + Graph<H> + ParameterSetMetadata,
{
graph.zigzag()
}
#[cfg(test)]
mod tests {
use super::*;
use paired::bls12_381::Bls12;
use rand::{Rng, SeedableRng, XorShiftRng};
use crate::drgporep;
use crate::drgraph::new_seed;
use crate::fr32::fr_into_bytes;
use crate::hasher::{Blake2sHasher, PedersenHasher, Sha256Hasher};
use crate::layered_drgporep::{
LayerChallenges, PrivateInputs, PublicInputs, PublicParams, SetupParams,
};
use crate::porep::PoRep;
use crate::proof::ProofScheme;
const DEFAULT_ZIGZAG_LAYERS: usize = 10;
#[test]
fn extract_all_pedersen() {
test_extract_all::<PedersenHasher>();
}
#[test]
fn extract_all_sha256() {
test_extract_all::<Sha256Hasher>();
}
#[test]
fn extract_all_blake2s() {
test_extract_all::<Blake2sHasher>();
}
fn test_extract_all<H: 'static + Hasher>() {
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
let sloth_iter = 1;
let replica_id: H::Domain = rng.gen();
let data = vec![2u8; 32 * 3];
let challenges = LayerChallenges::new_fixed(DEFAULT_ZIGZAG_LAYERS, 5);
let mut data_copy = data.clone();
let sp = SetupParams {
drg: drgporep::DrgParams {
nodes: data.len() / 32,
degree: 5,
expansion_degree: 8,
seed: new_seed(),
},
sloth_iter,
layer_challenges: challenges.clone(),
};
let mut pp = ZigZagDrgPoRep::<H>::setup(&sp).expect("setup failed");
for _ in 0..pp.layer_challenges.layers() {
pp.graph = zigzag(&pp.graph);
}
ZigZagDrgPoRep::<H>::replicate(&pp, &replica_id, data_copy.as_mut_slice(), None)
.expect("replication failed");
let transformed_params = PublicParams::new(pp.graph, pp.sloth_iter, challenges.clone());
assert_ne!(data, data_copy);
let decoded_data = ZigZagDrgPoRep::<H>::extract_all(
&transformed_params,
&replica_id,
data_copy.as_mut_slice(),
)
.expect("failed to extract data");
assert_eq!(data, decoded_data);
}
fn prove_verify_fixed(n: usize, i: usize) {
let challenges = LayerChallenges::new_fixed(DEFAULT_ZIGZAG_LAYERS, 5);
test_prove_verify::<PedersenHasher>(n, i, challenges.clone());
test_prove_verify::<Sha256Hasher>(n, i, challenges.clone());
test_prove_verify::<Blake2sHasher>(n, i, challenges.clone());
}
fn prove_verify_tapered(n: usize, i: usize) {
let challenges = LayerChallenges::new_tapered(5, 10, 5, 0.9);
test_prove_verify::<PedersenHasher>(n, i, challenges.clone());
test_prove_verify::<Sha256Hasher>(n, i, challenges.clone());
test_prove_verify::<Blake2sHasher>(n, i, challenges.clone());
}
fn test_prove_verify<H: 'static + Hasher>(n: usize, i: usize, challenges: LayerChallenges) {
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
let degree = 1 + i;
let expansion_degree = i;
let sloth_iter = 1;
let replica_id: H::Domain = rng.gen();
let data: Vec<u8> = (0..n)
.flat_map(|_| fr_into_bytes::<Bls12>(&rng.gen()))
.collect();
let mut data_copy = data.clone();
let partitions = 2;
let sp = SetupParams {
drg: drgporep::DrgParams {
nodes: n,
degree,
expansion_degree,
seed: new_seed(),
},
sloth_iter,
layer_challenges: challenges.clone(),
};
let pp = ZigZagDrgPoRep::<H>::setup(&sp).expect("setup failed");
let (tau, aux) =
ZigZagDrgPoRep::<H>::replicate(&pp, &replica_id, data_copy.as_mut_slice(), None)
.expect("replication failed");
assert_ne!(data, data_copy);
let pub_inputs = PublicInputs::<H::Domain> {
replica_id,
seed: None,
tau: Some(tau.simplify().into()),
comm_r_star: tau.comm_r_star,
k: None,
};
let priv_inputs = PrivateInputs {
aux,
tau: tau.layer_taus,
};
let all_partition_proofs =
&ZigZagDrgPoRep::<H>::prove_all_partitions(&pp, &pub_inputs, &priv_inputs, partitions)
.expect("failed to generate partition proofs");
let proofs_are_valid =
ZigZagDrgPoRep::<H>::verify_all_partitions(&pp, &pub_inputs, all_partition_proofs)
.expect("failed to verify partition proofs");
assert!(proofs_are_valid);
}
table_tests! {
prove_verify_fixed{
prove_verify_fixed_32_5_1(5, 1);
prove_verify_fixed_32_5_2(5, 2);
prove_verify_fixed_32_5_3(5, 3);
}
}
table_tests! {
prove_verify_tapered{
prove_verify_tapered_32_5_1(5, 1);
prove_verify_tapered_32_5_2(5, 2);
prove_verify_tapered_32_5_3(5, 3);
}
}
#[test]
fn setup_terminates() {
let degree = 5;
let expansion_degree = 8;
let nodes = 1024 * 1024 * 32 * 8;
let sloth_iter = 0;
let layer_challenges = LayerChallenges::new_tapered(10, 333, 7, 0.3);
let sp = SetupParams {
drg: drgporep::DrgParams {
nodes,
degree,
expansion_degree,
seed: new_seed(),
},
sloth_iter,
layer_challenges: layer_challenges.clone(),
};
let _pp = ZigZagDrgPoRep::<PedersenHasher>::setup(&sp).expect("setup failed");
}
}