false_bottom/
falsebottom.rs

1use crate::{FbError, FbKey, FbObj, PrimeField, Packing};
2use crypto_bigint::{ArrayEncoding, NonZero, RandomMod, Uint};
3use std::sync::RwLock;
4use rayon::iter::*;
5
6/// The main interface to the False Bottom algorithm.
7pub trait FalseBottom {
8	/// Creates a new `FbObj`.
9	/// The keybase and ciphertext are initialized from random values.  
10	/// Bounds: `2 <= keybase_len <= cipher_len`
11	/// # Panics
12	/// If Parameters are out of bounds.
13	fn init(cipher_len: usize, keybase_len: usize) -> Self;
14
15	/// Adds the provided message to the ciphertext.
16	fn add(&mut self, msg: &[u8]) -> FbKey;
17
18	/// Decrypts the message that corresponds to the provided key.
19	/// # Errors
20	/// [InvalidKey](FbError::InvalidKey)
21	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(|index_row| self.add_block(&mut rand::thread_rng(), &index_row))
49			.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}