false_bottom/
falsebottom.rs1use crate::{FbError, FbKey, FbObj, PrimeField, Packing};
2use crypto_bigint::{ArrayEncoding, NonZero, RandomMod, Uint};
3use std::sync::RwLock;
4use rayon::iter::*;
5
6pub trait FalseBottom {
8 fn init(cipher_len: usize, keybase_len: usize) -> Self;
14
15 fn add(&mut self, msg: &[u8]) -> FbKey;
17
18 fn decrypt(&self, key: &FbKey) -> Result<Vec<u8>, FbError>;
22}
23
24impl<const LIMBS: usize> FalseBottom for FbObj<Uint<LIMBS>>
25where
26 Uint<LIMBS>: ArrayEncoding + PrimeField
27{
28 fn init(cipher_len: usize, keybase_len: usize) -> FbObj<Uint<LIMBS>> {
29 let modulus = NonZero::<Uint<LIMBS>>::new(Uint::<LIMBS>::PRIME).unwrap();
30 if cipher_len < keybase_len || keybase_len < 2 {
31 panic!("Valid bounds are: 2 <= keybase_len <= cipher_len");
32 }
33 let mut rng = rand::thread_rng();
34 let r = (0..keybase_len)
35 .map(|_| Uint::<LIMBS>::random_mod(&mut rng, &modulus))
36 .collect();
37 let c_vec = (0..cipher_len)
38 .map(|_| Uint::<LIMBS>::random_mod(&mut rng, &modulus))
39 .collect();
40 let c = RwLock::new(c_vec);
41
42 FbObj {c, r}
43 }
44
45 fn add(&mut self, msg: &[u8]) -> FbKey {
46 let indices = Uint::<LIMBS>::pack(msg)
47 .into_par_iter()
48 .map_init(
50 || rand::thread_rng(),
51 |rng, index_row| self.add_block(rng, &index_row),
52 )
53 .collect();
54
55 FbKey(indices)
56 }
57
58 fn decrypt(&self, key: &FbKey) -> Result<Vec<u8>, FbError> {
59 let decr = key.0.iter()
60 .map(|index_row| self.decrypt_block(&index_row))
61 .collect::<Result<Vec<_>, _>>()?;
62 let msg = Uint::<LIMBS>::unpack(decr)?;
63
64 Ok(msg)
65 }
66}