pythnet_sdk/accumulators/
mul.rs1use crate::{
4 accumulators::Accumulator,
5 hashers::{prime::PrimeHasher, Hasher},
6};
7
8pub struct MulAccumulator<H: Hasher> {
16 pub accumulator: H::Hash,
17 pub items: Vec<H::Hash>,
18}
19
20impl<'a> Accumulator<'a> for MulAccumulator<PrimeHasher> {
21 type Proof = <PrimeHasher as Hasher>::Hash;
22
23 fn prove(&self, item: &[u8]) -> Option<Self::Proof> {
24 let bytes = u128::from_be_bytes(PrimeHasher::hashv(&[item]));
25 let acc = u128::from_be_bytes(self.accumulator);
26 Some((acc / bytes).to_be_bytes())
27 }
28
29 fn check(&self, proof: Self::Proof, item: &[u8]) -> bool {
30 let bytes = u128::from_be_bytes(PrimeHasher::hashv(&[item]));
31 let proof = u128::from_be_bytes(proof);
32 proof * bytes == u128::from_be_bytes(self.accumulator)
33 }
34
35 fn from_set(items: impl Iterator<Item = &'a [u8]>) -> Option<Self> {
36 let primes: Vec<[u8; 16]> = items.map(|i| PrimeHasher::hashv(&[i])).collect();
37 Some(Self {
38 items: primes.clone(),
39 accumulator: primes.into_iter().reduce(|acc, v| {
40 u128::to_be_bytes(u128::from_be_bytes(acc) * u128::from_be_bytes(v))
41 })?,
42 })
43 }
44}
45
46#[cfg(test)]
47mod test {
48 use {super::*, std::collections::HashSet};
49
50 #[test]
51 fn test_membership() {
52 let mut set: HashSet<&[u8]> = HashSet::new();
53
54 let item_a = 33usize.to_be_bytes();
57 let item_b = 54usize.to_be_bytes();
58 let item_c = 2usize.to_be_bytes();
59 let item_d = 88usize.to_be_bytes();
60
61 set.insert(&item_a);
63 set.insert(&item_b);
64 set.insert(&item_c);
65
66 println!();
67
68 {
70 let accumulator = MulAccumulator::<PrimeHasher>::from_set(set.into_iter()).unwrap();
71 let proof = accumulator.prove(&item_a).unwrap();
72 assert!(accumulator.check(proof, &item_a));
73 assert!(!accumulator.check(proof, &item_d));
74 }
75 }
76}