From f06ed58f89671a4fef53175c108f7bb8122acde4 Mon Sep 17 00:00:00 2001 From: K Shiva Kiran Date: Sat, 13 Apr 2024 17:36:03 +0530 Subject: [PATCH] wip: better methods, added benches --- Cargo.toml | 9 ++++++- benches/bench.rs | 28 ++++++++++++++++++++++ examples/file.rs | 26 --------------------- input | Bin 102400 -> 0 bytes input1 | Bin 204800 -> 0 bytes src/algo.rs | 57 +++++++++++++++++++++------------------------ src/encoding.rs | 6 ++--- src/fbobj.rs | 13 ++++++----- src/fbobj/fb128.rs | 2 +- 9 files changed, 74 insertions(+), 67 deletions(-) create mode 100644 benches/bench.rs delete mode 100644 examples/file.rs delete mode 100644 input delete mode 100644 input1 diff --git a/Cargo.toml b/Cargo.toml index 981b941..020d650 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,11 @@ typenum = "1.17.0" rayon = "1.10.0" [lib] -doctest = false \ No newline at end of file +doctest = false + +[dev-dependencies] +criterion = "0.5.1" + +[[bench]] +name = "encrypt" +harness = false diff --git a/benches/bench.rs b/benches/bench.rs new file mode 100644 index 0000000..d4800ac --- /dev/null +++ b/benches/bench.rs @@ -0,0 +1,28 @@ +use criterion::*; +use false_bottom::{FB128, FBAlgo}; + +pub fn bench(c: &mut Criterion) { + let inp = vec![0_u8; 4096000]; + let mut fb = FB128::init(2, 2).unwrap(); + let mut group = c.benchmark_group("bench-group"); + let key = fb.add(&inp); + group.sample_size(21); + group.throughput(Throughput::Bytes(inp.len() as u64)); + group.bench_with_input( + BenchmarkId::new("4MB null bytes encryption", 4), &inp, + |b, inp| b.iter(|| { + fb.add(&inp) + }), + ); + group.bench_with_input( + BenchmarkId::new("4MB null bytes decryption", 4), &key, + |b, key| b.iter(|| { + fb.decrypt(&key) + }), + ); + + //c.bench_function("Encrypt 4MB", |b| b.iter(|| fb.add(&inp))); +} + +criterion_group!(benches, bench); +criterion_main!(benches); diff --git a/examples/file.rs b/examples/file.rs deleted file mode 100644 index 3e9ae0d..0000000 --- a/examples/file.rs +++ /dev/null @@ -1,26 +0,0 @@ -use false_bottom::{FB128, FBAlgo, Encode}; -use std::time::Instant; - -fn main() { - let inp = vec![0_u8; 1024000]; - println!("Input size: {} Bytes", inp.len()); - let mut fb = FB128::init(2, 2).unwrap(); - - println!("Encrypting..."); - let now = Instant::now(); - let key = fb.add(&inp); - let t_encr = now.elapsed().as_secs_f32(); - let encr = fb.to_bytes().0; - let r_encr = encr.len() as f32 / t_encr; - println!("Encryption: {t_encr:.2} @ {r_encr:.1} B/sec"); - - println!("Decrypting..."); - let now = Instant::now(); - let decr = fb.decrypt(&key).unwrap(); - let t_decr = now.elapsed().as_secs_f32(); - let r_decr = decr.len() as f32 / t_decr; - println!("Decryption: {t_decr:.2} @ {r_decr:.1} B/sec"); - let extra = encr.len() - inp.len(); - let percent = extra as f32/encr.len() as f32 * 100_f32; - println!("Extra Bytes: {extra} Bytes ({percent}%)"); -} diff --git a/input b/input deleted file mode 100644 index da1dfb90e7c41de55aeb63d311937cdac9edd929..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102400 zcmeIufdBvi0K=g9Qy=7oP+`D;0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfPs&J0gw*> A0RR91 diff --git a/input1 b/input1 deleted file mode 100644 index 52972ec9e05fbb995e2efd1ed651077d4cd226a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 204800 zcmeIu0Sy2E0K%a6Pi+qe5hx58Fkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj fFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*2A&26AT0m^ diff --git a/src/algo.rs b/src/algo.rs index 1b98abd..cce9910 100644 --- a/src/algo.rs +++ b/src/algo.rs @@ -1,15 +1,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later use crate::{FBError, FBKey, FBObj, FBObjTrait, FieldOps, Packing}; use crypto_bigint::{NonZero, RandomMod}; -use rand::{seq::index, Rng}; +use rand::{seq::index, rngs::ThreadRng, Rng}; use rayon::iter::*; use std::marker::Send; -use std::sync::RwLock; +use std::sync::Mutex; pub trait FBAlgo where Self: BlockOps + Sync + Send, - T: FieldOps + Packing + RandomMod + Send, + T: FieldOps + Packing + RandomMod + Send + Sync, { const MODULUS: NonZero; @@ -29,7 +29,7 @@ where let c_vec = (0..cipher_len) .map(|_| T::random_mod(&mut rng, &Self::MODULUS)) .collect(); - let c = RwLock::new(c_vec); + let c = Mutex::new(c_vec); Ok(FBObj { c, r }) } @@ -38,7 +38,10 @@ where fn add(&mut self, msg: &[u8]) -> FBKey { let indices = T::pack(msg) .into_par_iter() - .map(|msg_uint| self.add_block(&msg_uint)) + .map_init(|| rand::thread_rng(), |rng, index_row|{ + self.add_block(rng, &index_row) + }) + //.map(|msg_uint| self.add_block(&msg_uint)) .collect(); FBKey { indices } @@ -63,47 +66,40 @@ where pub trait BlockOps where Self: FBObjTrait, - T: FieldOps + RandomMod, + T: FieldOps + RandomMod + Send + Sync, { - fn add_block(&self, msg_uint: &T) -> Vec<(usize, usize)> { - let mut c_len; - { - c_len = self.cipher().read().unwrap().len(); - } + fn add_block(&self, rng: &mut ThreadRng, msg_uint: &T) -> Vec<(usize, usize)> { let r = self.keybase(); - let mut rng = rand::thread_rng(); + //let rng = &mut rand::thread_rng(); let n = rng.gen_range(2..=r.len()); - let mut c_i = index::sample(&mut rng, c_len, n-1).into_vec(); - let r_i = index::sample(&mut rng, r.len(), n).into_vec(); - let ri_last = *r_i.last() + let r_i = index::sample(rng, r.len(), n); + let ri_last = r_i.iter().last() .expect("r_i will contain at least 2 elements"); let ri_last_inv = r[ri_last].field_inv(); - let sum: T; + let c_i; + let c_len; { - let c = self.cipher().read().unwrap(); - sum = c_i.iter() + let mut c = self.cipher().lock().unwrap(); + c_i = index::sample(rng, c.len(), n-1); + let sum = c_i.iter() .zip( r_i.iter() ) - .map(|(&ci, &ri)| c[ci].field_mul(&r[ri]) ) + .map(|(ci, ri)| c[ci].field_mul(&r[ri]) ) .reduce(|acc, i| acc.field_add(&i)) .unwrap(); - } - let c_new_el = msg_uint.field_sub(&sum) - .field_mul(&ri_last_inv); - { - let mut c = self.cipher().write().unwrap(); + let c_new_el = msg_uint.field_sub(&sum) + .field_mul(&ri_last_inv); c.push(c_new_el); c_len = c.len(); } - c_i.push(c_len - 1); - let indices = c_i.into_iter() - .zip(r_i.into_iter()) + let indices = c_i.iter().chain([c_len - 1].into_iter()) + .zip(r_i.iter()) .collect(); indices } fn decrypt_block(&self, indices: &[(usize, usize)]) -> Result { - let (c, r) = (self.cipher().read().unwrap(), self.keybase()); + let (c, r) = (self.cipher().lock().unwrap(), self.keybase()); if indices.len() > r.len() { return Err(FBError::InvalidKey); } @@ -124,7 +120,8 @@ fn encrypt_u128() { use crypto_bigint::U128; let msg = U128::from_u32(100); let fb = FBObj::::init(18, 12).unwrap(); - let key = fb.add_block(&msg); + let rng = &mut rand::thread_rng(); + let key = fb.add_block(rng, &msg); let decrypted = fb.decrypt_block(&key).unwrap(); assert_eq!(msg, decrypted); } @@ -134,7 +131,7 @@ fn encrypt_bytes() { use crypto_bigint::U128; let input1 = vec![255_u8; 33]; let input2 = vec![0_u8; 102]; - let fb = FBObj::::init(21, 9).unwrap(); + let mut fb = FBObj::::init(21, 9).unwrap(); let key1 = fb.add(&input1); let key2 = fb.add(&input2); let decr1 = fb.decrypt(&key1).unwrap(); diff --git a/src/encoding.rs b/src/encoding.rs index b034353..17491b4 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -2,7 +2,7 @@ use crate::{FBError, FBObj, FBObjTrait}; use crypto_bigint::{ArrayEncoding, Bounded, generic_array::GenericArray}; use base64::{prelude::BASE64_STANDARD, Engine}; -use std::sync::RwLock; +use std::sync::Mutex; pub trait Encode where @@ -11,7 +11,7 @@ where { /// Returns the byte representation of the ciphertext and keybase. fn to_bytes(&self) -> (Vec, Vec) { - let c = self.cipher().read().unwrap() + let c = self.cipher().lock().unwrap() .iter() .flat_map(|bigint| bigint.to_le_byte_array()) .collect(); @@ -47,7 +47,7 @@ where if r.len() > c_vec.len() || r.len() < 2 { return Err(FBError::InvalidParams); } - let c = RwLock::new(c_vec); + let c = Mutex::new(c_vec); Ok(FBObj {c, r}) } diff --git a/src/fbobj.rs b/src/fbobj.rs index 0436afc..6a0757a 100644 --- a/src/fbobj.rs +++ b/src/fbobj.rs @@ -3,21 +3,22 @@ pub mod fb128; use crate::{BlockOps, Encode, FieldOps}; use crypto_bigint::{ArrayEncoding, Bounded, RandomMod}; -use std::sync::RwLock; +use std::sync::Mutex; +use std::marker::Sync; /// The False Bottom Object holds the ciphertext and the keybase. The provided type aliases can be used to pick a block size. pub struct FBObj { - pub(crate) c: RwLock>, + pub(crate) c: Mutex>, pub(crate) r: Vec, } pub trait FBObjTrait { - fn cipher(&self) -> &RwLock>; + fn cipher(&self) -> &Mutex>; fn keybase(&self) -> &Vec; } impl FBObjTrait for FBObj { - fn cipher(&self) -> &RwLock> { + fn cipher(&self) -> &Mutex> { &self.c } fn keybase(&self) -> &Vec { @@ -27,10 +28,10 @@ impl FBObjTrait for FBObj { impl BlockOps for FBObj where - T: FieldOps + RandomMod + T: FieldOps + RandomMod + Send + Sync {} impl Encode for FBObj where - T: ArrayEncoding + Bounded, + T: ArrayEncoding + Bounded {} diff --git a/src/fbobj/fb128.rs b/src/fbobj/fb128.rs index 15e23e1..d39b724 100644 --- a/src/fbobj/fb128.rs +++ b/src/fbobj/fb128.rs @@ -24,7 +24,7 @@ impl FieldOps for U128 { self.mul_mod_special(rhs, PRIME_POS) } fn field_inv(&self) -> Self { - self.inv_mod(&PRIME).0 + self.inv_odd_mod(&PRIME).0 } }