wip: better methods, added benches
This commit is contained in:
parent
c36aa12756
commit
f06ed58f89
|
@ -17,4 +17,11 @@ typenum = "1.17.0"
|
|||
rayon = "1.10.0"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
doctest = false
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.5.1"
|
||||
|
||||
[[bench]]
|
||||
name = "encrypt"
|
||||
harness = false
|
||||
|
|
|
@ -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);
|
|
@ -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}%)");
|
||||
}
|
57
src/algo.rs
57
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<T>
|
||||
where
|
||||
Self: BlockOps<T> + Sync + Send,
|
||||
T: FieldOps + Packing + RandomMod + Send,
|
||||
T: FieldOps + Packing + RandomMod + Send + Sync,
|
||||
{
|
||||
const MODULUS: NonZero<T>;
|
||||
|
||||
|
@ -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<T>
|
||||
where
|
||||
Self: FBObjTrait<T>,
|
||||
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<T, FBError> {
|
||||
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::<U128>::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::<U128>::init(21, 9).unwrap();
|
||||
let mut fb = FBObj::<U128>::init(21, 9).unwrap();
|
||||
let key1 = fb.add(&input1);
|
||||
let key2 = fb.add(&input2);
|
||||
let decr1 = fb.decrypt(&key1).unwrap();
|
||||
|
|
|
@ -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<T>
|
||||
where
|
||||
|
@ -11,7 +11,7 @@ where
|
|||
{
|
||||
/// Returns the byte representation of the ciphertext and keybase.
|
||||
fn to_bytes(&self) -> (Vec<u8>, Vec<u8>) {
|
||||
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})
|
||||
}
|
||||
|
|
13
src/fbobj.rs
13
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<T> {
|
||||
pub(crate) c: RwLock<Vec<T>>,
|
||||
pub(crate) c: Mutex<Vec<T>>,
|
||||
pub(crate) r: Vec<T>,
|
||||
}
|
||||
|
||||
pub trait FBObjTrait<T> {
|
||||
fn cipher(&self) -> &RwLock<Vec<T>>;
|
||||
fn cipher(&self) -> &Mutex<Vec<T>>;
|
||||
fn keybase(&self) -> &Vec<T>;
|
||||
}
|
||||
|
||||
impl<T> FBObjTrait<T> for FBObj<T> {
|
||||
fn cipher(&self) -> &RwLock<Vec<T>> {
|
||||
fn cipher(&self) -> &Mutex<Vec<T>> {
|
||||
&self.c
|
||||
}
|
||||
fn keybase(&self) -> &Vec<T> {
|
||||
|
@ -27,10 +28,10 @@ impl<T> FBObjTrait<T> for FBObj<T> {
|
|||
|
||||
impl<T> BlockOps<T> for FBObj<T>
|
||||
where
|
||||
T: FieldOps + RandomMod
|
||||
T: FieldOps + RandomMod + Send + Sync
|
||||
{}
|
||||
|
||||
impl<T> Encode<T> for FBObj<T>
|
||||
where
|
||||
T: ArrayEncoding + Bounded,
|
||||
T: ArrayEncoding + Bounded
|
||||
{}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue