use crate::pedersen::{PedersenCommitment, PedersenParams};
use curve25519_dalek::scalar::Scalar;
#[derive(Debug, Clone)]
pub struct HidingVerifier {
pub samples: usize,
}
impl HidingVerifier {
pub fn new(samples: usize) -> Self {
Self { samples }
}
pub fn test_unique_commitments(&self, params: &PedersenParams, value: u64) -> bool {
let scalar = Scalar::from(value);
let mut seen = std::collections::HashSet::new();
for _ in 0..self.samples {
let (comm, _) = PedersenCommitment::commit(params, &scalar);
let bytes = comm.compressed.to_bytes();
if seen.contains(&bytes) {
return false;
}
seen.insert(bytes);
}
seen.len() == self.samples
}
pub fn test_indistinguishability(
&self,
params: &PedersenParams,
value_a: u64,
value_b: u64,
) -> bool {
let scalar_a = Scalar::from(value_a);
let scalar_b = Scalar::from(value_b);
let mut set_a = std::collections::HashSet::new();
for _ in 0..self.samples {
let (comm, _) = PedersenCommitment::commit(params, &scalar_a);
set_a.insert(comm.compressed.to_bytes());
}
for _ in 0..self.samples {
let (comm, _) = PedersenCommitment::commit(params, &scalar_b);
if set_a.contains(&comm.compressed.to_bytes()) {
return false;
}
}
true
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unique_commitments() {
let params = PedersenParams::default();
let verifier = HidingVerifier::new(50);
assert!(verifier.test_unique_commitments(¶ms, 42));
}
#[test]
fn indistinguishability() {
let params = PedersenParams::default();
let verifier = HidingVerifier::new(50);
assert!(verifier.test_indistinguishability(¶ms, 0, 1));
}
#[test]
fn hiding_different_values() {
let params = PedersenParams::default();
let verifier = HidingVerifier::new(30);
assert!(verifier.test_indistinguishability(¶ms, 100, 200));
}
}