use super::crypto::*;
use super::dleq;
type Challenge<C> = Scalar<C>;
#[derive(Clone)]
pub struct Proof<C: EcOperation> {
c: Challenge<C>,
zs: Vec<Scalar<C>>,
}
const DOMAIN_SEP: &[u8] = b"pvss-pdleq-v1:sha2-256:";
impl<C: EcOperation> Proof<C> {
pub fn create(params: &[(Scalar<C>, &Scalar<C>, dleq::DLEQ<'_, C>)]) -> Proof<C> {
let mut zs = Vec::with_capacity(params.len());
let mut hasher = PointHasher::new_sep(DOMAIN_SEP);
for param in params.iter() {
let &(ref w, _, ref dleq) = param;
hasher = hasher
.update(&dleq.g1)
.update(&dleq.g2)
.update(&dleq.h1)
.update(&dleq.h2)
.update(&dleq.g1.mul(&w))
.update(&dleq.g2.mul(&w));
}
let c = hasher.finalize();
for (w, a, _) in params.iter() {
let z = w + &(*a * &c);
zs.push(z);
}
Proof { c, zs }
}
pub fn verify(&self, dleqs: &[dleq::DLEQ<'_, C>]) -> bool {
if dleqs.len() != self.zs.len() {
return false;
};
let mut hasher = PointHasher::new_sep(DOMAIN_SEP);
for (i, z) in self.zs.iter().enumerate() {
let dleq = &dleqs[i];
let r1 = dleq.g1.mul(z);
let r2 = dleq.g2.mul(z);
let a1 = r1 - dleq.h1.mul(&self.c);
let a2 = r2 - dleq.h2.mul(&self.c);
hasher = hasher
.update(&dleq.g1)
.update(&dleq.g2)
.update(&dleq.h1)
.update(&dleq.h2)
.update(&a1)
.update(&a2);
}
let c = hasher.finalize();
self.c == c
}
}