use cyber_hemera::hash as hemera_hash;
use nebu::Goldilocks;
use zheng::ccs::{universal_ccs, universal_witness};
use zheng::types::{Accumulator, CCSInstance, CCSWitness, Proof, ProofGroup, Statement, TraceProof};
use zheng::{ProofParams, verify};
const ADD: u64 = 5;
pub(crate) fn instance() -> &'static CCSInstance {
universal_ccs()
}
pub(crate) fn blank_acc() -> Accumulator {
Accumulator::blank(instance())
}
pub(crate) fn add_step(material: &[u8]) -> CCSWitness {
let h = hemera_hash(material);
let bytes = h.as_bytes();
let a = Goldilocks::new(u64::from_le_bytes(bytes[0..8].try_into().unwrap_or([0u8; 8])));
let b = Goldilocks::new(u64::from_le_bytes(bytes[8..16].try_into().unwrap_or([0u8; 8])));
let mut regs_t = [Goldilocks::ZERO; 16];
regs_t[0] = Goldilocks::new(ADD);
regs_t[4] = a;
regs_t[5] = b;
regs_t[6] = a + b;
universal_witness(®s_t, &[Goldilocks::ZERO; 16], None)
}
pub(crate) fn verify_group(acc: &Accumulator, proof: &Proof, statement: &Statement) -> bool {
if acc.step_count() == 0 {
return false;
}
let trace_proof = TraceProof {
universal: ProofGroup { proof: proof.clone(), accumulator: acc.clone() },
binding: None,
};
verify(&trace_proof, statement, &ProofParams::default()).is_ok()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn add_step_satisfies_the_universal_instance() {
assert!(instance().is_satisfied_by(&add_step(b"material")));
}
#[test]
fn different_material_gives_different_rows() {
assert_ne!(add_step(b"a").z, add_step(b"b").z);
}
}