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