From 778a045be60cfb98dc34df718c62e6511cf60314 Mon Sep 17 00:00:00 2001 From: K Shiva Kiran Date: Tue, 26 Mar 2024 12:16:32 +0530 Subject: [PATCH] Working on Traits --- examples/encryption.rs | 5 +- examples/export.rs | 6 +- src/crypt.rs | 130 ----------------------------- src/crypt/fb128.rs | 53 ------------ src/encoding.rs | 70 +++------------- src/false_bottom.rs | 169 ++++++++++++++++++++++++-------------- src/false_bottom/fb128.rs | 126 ++++++++++++++++++++++++++++ src/key.rs | 31 +++++++ src/lib.rs | 8 +- src/pack.rs | 58 +------------ 10 files changed, 290 insertions(+), 366 deletions(-) delete mode 100644 src/crypt.rs delete mode 100644 src/crypt/fb128.rs create mode 100644 src/false_bottom/fb128.rs create mode 100644 src/key.rs diff --git a/examples/encryption.rs b/examples/encryption.rs index dff3672..0306050 100644 --- a/examples/encryption.rs +++ b/examples/encryption.rs @@ -1,5 +1,4 @@ - -use false_bottom::FBCrypt; +use false_bottom::{FB128, FalseBottom}; fn main() { // Input messages @@ -8,7 +7,7 @@ fn main() { let real_msg2 = "Please meet me at the Paradise hotel at 5:30 PM"; // Cipher initialization - let mut fb = FBCrypt::init(18, 12).unwrap(); + let mut fb = FB128::init(18, 12).unwrap(); // Encryption let real_key1 = fb.add(&real_msg1.as_bytes()); diff --git a/examples/export.rs b/examples/export.rs index 497b14c..b0863b5 100644 --- a/examples/export.rs +++ b/examples/export.rs @@ -1,8 +1,8 @@ -use false_bottom::{FBCrypt, FBKey}; +use false_bottom::{FBObj, FBKey}; fn main() { // Cipher Initialization - let mut fb = FBCrypt::init(18, 9).unwrap(); + let mut fb = FBObj::init(18, 9).unwrap(); // Encryption let msg1 = "This is a message"; @@ -16,7 +16,7 @@ fn main() { let key2_exp = key2.export(); // Import - let fb_new = FBCrypt::import(&cipher, &keybase).unwrap(); + let fb_new = FBObj::import(&cipher, &keybase).unwrap(); let key1_imp = FBKey::import(&key1_exp).unwrap(); let key2_imp = FBKey::import(&key2_exp).unwrap(); diff --git a/src/crypt.rs b/src/crypt.rs deleted file mode 100644 index adc360e..0000000 --- a/src/crypt.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crypto_bigint::{U128, Limb, RandomMod, NonZero, Encoding}; -use crate::{FBError, FBKey, pack::Packing}; -use rand::{Rng, prelude::IteratorRandom}; -mod fb128; - -pub trait FB: FBBlock -where - T: RandomMod + SpecialMod + InvMod + Encoding + std::cmp::PartialOrd + Packing -{ - const MODULUS: NonZero; - - fn init(n: usize, k: usize) -> Result, FBError> - where - T: RandomMod - { - if n < k || k < 2 { - return Err(FBError::InvalidParams); - } - let mut rng = rand::thread_rng(); - let r = (0..k) - .map(|_| T::random_mod(&mut rng, &Self::MODULUS)) - .collect(); - let c = (0..n) - .map(|_| T::random_mod(&mut rng, &Self::MODULUS)) - .collect(); - - Ok(FBStruct { c, r }) - } - - fn add(&mut self, msg: &[u8]) -> FBKey { - let indices = T::pack(msg).into_iter() - .map(|msg_uint| self.add_u128(&msg_uint)) - .collect(); - - FBKey { indices } - } - - fn decrypt(&self, key: &FBKey) -> Result, FBError> { - let decr = key.indices.iter() - .map(|index_row| self.decrypt_u128(&index_row)) - .collect::, _>>()?; - let msg = T::unpack(&decr)?; - - Ok(msg) - } -} - -trait SpecialMod { - fn mul_mod_special(&self, rhs: &Self, c: Limb) -> Self; - fn add_mod_special(&self, rhs: &Self, c: Limb) -> Self; - fn sub_mod_special(&self, rhs: &Self, c: Limb) -> Self; -} - -use crypto_bigint::CtChoice; -trait InvMod { - fn inv_mod(&self, modulus: &Self) -> (Self, CtChoice) - where Self: Sized; -} - -impl SpecialMod for U128 { - fn mul_mod_special(&self, rhs: &Self, c: Limb) -> Self {self.mul_mod_special(rhs, c)} - fn add_mod_special(&self, rhs: &Self, c: Limb) -> Self {self.add_mod_special(rhs, c)} - fn sub_mod_special(&self, rhs: &Self, c: Limb) -> Self {self.sub_mod_special(rhs, c)} -} - -impl InvMod for U128 { - fn inv_mod(&self, modulus: &Self) -> (Self, CtChoice) { - self.inv_mod(modulus) - } -} - -trait FBBlock -where - T: RandomMod + SpecialMod + InvMod -{ - const P: T; - const P_POS: Limb; - - fn cipher(&self) -> &Vec; - fn cipher_mut(&mut self) -> &mut Vec; - fn keybase(&self) -> &Vec; - - fn add_u128(&mut self, msg_uint: &T) -> Vec<(usize, usize)> { - let c = self.cipher(); - let r = self.keybase(); - let mut rng = rand::thread_rng(); - let n = rng.gen_range(2..=r.len()); - let mut c_i = (0..c.len()).choose_multiple(&mut rng, n - 1); - let r_i = (0..r.len()).choose_multiple(&mut rng, n); - let mut sum = T::ZERO; - for (&ci, &ri) in c_i.iter().zip(r_i.iter()) { - sum = sum.add_mod_special( - &c[ci].mul_mod_special(&r[ri], Self::P_POS), - Self::P_POS); - } - let ri_last = *r_i.last().expect("r_i will contain at least 2 elements"); - let mod_inv = r[ri_last].inv_mod(&Self::P).0; - let c_new_el = msg_uint.sub_mod_special(&sum, Self::P_POS) - .mul_mod_special(&mod_inv, Self::P_POS); - let c = self.cipher_mut(); - c.push(c_new_el); - c_i.push(c.len() - 1); - let indices = c_i.into_iter() - .zip(r_i.into_iter()) - .collect(); - - indices - } - - fn decrypt_u128(&self, indices: &[(usize, usize)]) -> Result { - let (r, c) = (self.keybase(), self.cipher()); - if indices.len() > r.len() { - return Err(FBError::InvalidKey); - } - let mut msg = T::ZERO; - for &(ci, ri) in indices { - let c_el = c.get(ci).ok_or(FBError::InvalidKey)?; - let r_el = r.get(ri).ok_or(FBError::InvalidKey)?; - msg = msg.add_mod_special( - &c_el.mul_mod_special(&r_el, Self::P_POS), - Self::P_POS); - } - - Ok(msg) - } -} -pub struct FBStruct { - pub(crate) c: Vec, - pub(crate) r: Vec, -} diff --git a/src/crypt/fb128.rs b/src/crypt/fb128.rs deleted file mode 100644 index fcdb45f..0000000 --- a/src/crypt/fb128.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crypto_bigint::{U128, Limb, NonZero}; -use crate::{ - crypt::{FB, FBStruct, FBBlock}, - pack::Packing, -}; - -impl FB for FBStruct { - const MODULUS: NonZero = NonZero::::const_new(Self::P).0; -} - -impl FBBlock for FBStruct { - const P: U128 = U128::MAX.wrapping_sub(&U128::from_u8(159 - 1)); - const P_POS: Limb = Limb::from_u8(159); - - fn cipher(&self) -> &Vec { - &self.c - } - - fn cipher_mut(&mut self) -> &mut Vec { - &mut self.c - } - - fn keybase(&self) -> &Vec { - &self.r - } -} - -impl Packing for U128 { - const P_MINUS_ONE: U128 = U128::MAX.wrapping_sub(&U128::from_u8(159)); - const BYTES: usize = 16; -} - -#[test] -fn encrypt_u128() { - let msg = U128::from_u32(100); - let mut fb = FBStruct::init(20, 12).unwrap(); - let key = fb.add_u128(&msg); - let decrypted = fb.decrypt_u128(&key).unwrap(); - assert_eq!(msg, decrypted); -} - -#[test] -fn encrypt_bytes() { - let input1 = vec![255_u8; 150]; - let input2 = vec![0_u8; 102]; - let mut fb = FBStruct::init(21, 12).unwrap(); - let key1 = fb.add(&input1); - let key2 = fb.add(&input2); - let decr1 = fb.decrypt(&key1).unwrap(); - let decr2 = fb.decrypt(&key2).unwrap(); - assert_eq!(input1, decr1); - assert_eq!(input2, decr2); -} diff --git a/src/encoding.rs b/src/encoding.rs index 2bdddef..6796b36 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -1,60 +1,14 @@ -use base64::prelude::{BASE64_STANDARD, Engine}; -use bincode::{Options, DefaultOptions}; -use crypto_bigint::{U128, Encoding}; -use crate::{FBCrypt, FBKey, errors::FBError}; +use crypto_bigint::Encoding; +use crate::FBError; -impl FBCrypt { - - pub fn export(&self) -> (String, String) { - let c_bytes: Vec = self.c.iter() - .flat_map(|bigint| bigint.to_le_bytes()) - .collect(); - let r_bytes: Vec = self.r.iter() - .flat_map(|bigint| bigint.to_le_bytes()) - .collect(); - - (BASE64_STANDARD.encode(c_bytes), BASE64_STANDARD.encode(r_bytes)) - } - - pub fn import(cipher: &str, keybase: &str) -> Result { - let c_bytes = BASE64_STANDARD.decode(cipher) - .map_err(|_| FBError::DecodeError)?; - let c: Vec = c_bytes.chunks_exact(16) - .map(|chunk| U128::from_le_bytes(chunk.try_into().unwrap())) - .collect(); - let r_bytes = BASE64_STANDARD.decode(keybase) - .map_err(|_| FBError::DecodeError)?; - let r: Vec = r_bytes.chunks_exact(16) - .map(|chunk| U128::from_le_bytes(chunk.try_into().unwrap())) - .collect(); - if c.len() < r.len() || r.len() < 2 { - return Err(FBError::InvalidParams); - } - - Ok(FBCrypt {c, r}) - } -} - -impl FBKey { - - pub fn export(&self) -> String { - let binc = DefaultOptions::new(); - let indice_bytes = binc.serialize(&self.indices) - .unwrap(); - - BASE64_STANDARD.encode(&indice_bytes) - } - - pub fn import(key_str: &str) -> Result { - let binc = DefaultOptions::new(); - let indice_bytes = BASE64_STANDARD.decode(key_str) - .map_err(|_| FBError::DecodeError)?; - let indices: Vec<_> = binc.deserialize(&indice_bytes) - .map_err(|_| FBError::DecodeError)?; - if indices.len() < 2 { - return Err(FBError::DecodeError); - } - - Ok (FBKey {indices}) - } +pub trait Encode +where + T: Encoding +{ + const BYTES: usize; + + fn export(&self) -> (String, String); + fn import(cipher: &str, keybase: &str) -> Result + where + Self: Sized; } diff --git a/src/false_bottom.rs b/src/false_bottom.rs index d808812..f2a03ef 100644 --- a/src/false_bottom.rs +++ b/src/false_bottom.rs @@ -1,71 +1,96 @@ -use crypto_bigint::{U128, Limb, RandomMod, NonZero}; -use rand::{seq::IteratorRandom, Rng}; -use crate::{errors::FBError, packing}; +pub mod fb128; -pub struct FBCrypt { - pub(crate) c: Vec, // Ciphertext - pub(crate) r: Vec, // Keybase +use crypto_bigint::{Limb, RandomMod, NonZero, Encoding}; +use base64::prelude::{BASE64_STANDARD, Engine}; +use crate::{FBError, Packing, FBKey, Encode}; +use rand::{Rng, prelude::IteratorRandom}; +use std::cmp::PartialOrd; + +pub struct FBObj { + pub(crate) c: Vec, + pub(crate) r: Vec, } -pub struct FBKey { - // 2D Vec containing (cipher_index, keybase_index) pairs - pub(crate) indices: Vec>, -} +pub trait FalseBottom: FBBlockOperations +where + T: RandomMod + ModPrime + Encoding + PartialOrd + Packing +{ + const MODULUS: NonZero; -// Value and position of the Prime used (2^128 - 159) -const P: U128 = U128::MAX.wrapping_sub(&U128::from_u8(159 - 1)); -const P_POS: Limb = Limb::from_u8(159); - -impl FBCrypt { - pub fn init(n: usize, k: usize) -> Result { + fn init(n: usize, k: usize) -> Result, FBError> + where + T: RandomMod + { if n < k || k < 2 { return Err(FBError::InvalidParams); } - const MODULUS: NonZero = NonZero::::const_new(P).0; let mut rng = rand::thread_rng(); let r = (0..k) - .map(|_| U128::random_mod(&mut rng, &MODULUS)) + .map(|_| T::random_mod(&mut rng, &Self::MODULUS)) .collect(); let c = (0..n) - .map(|_| U128::random_mod(&mut rng, &MODULUS)) + .map(|_| T::random_mod(&mut rng, &Self::MODULUS)) .collect(); - Ok(FBCrypt { c, r }) + Ok(FBObj { c, r }) } - - pub fn add(&mut self, msg: &[u8]) -> FBKey { - let indices = packing::pack(msg).into_iter() + + fn add(&mut self, msg: &[u8]) -> FBKey { + let indices = T::pack(msg).into_iter() .map(|msg_uint| self.add_u128(&msg_uint)) .collect(); FBKey { indices } } - pub fn decrypt(&self, key: &FBKey) -> Result, FBError> { + fn decrypt(&self, key: &FBKey) -> Result, FBError> { let decr = key.indices.iter() .map(|index_row| self.decrypt_u128(&index_row)) .collect::, _>>()?; - let msg = packing::unpack(&decr)?; + let msg = T::unpack(&decr)?; Ok(msg) } +} - fn add_u128(&mut self, msg_uint: &U128) -> Vec<(usize, usize)> { - let (r, c) = (&self.r, &mut self.c); +pub trait ModPrime { + const PRIME_POS: Limb; + const PRIME: T; + fn mul_mod_prime(&self, rhs: &Self) -> Self; + fn add_mod_prime(&self, rhs: &Self) -> Self; + fn sub_mod_prime(&self, rhs: &Self) -> Self; + fn inv_mod_prime(&self) -> Self; +} + + +pub trait FBBlockOperations +where + T: RandomMod + ModPrime +{ + const P: T; + const P_POS: Limb; + + fn cipher(&self) -> &Vec; + fn cipher_mut(&mut self) -> &mut Vec; + fn keybase(&self) -> &Vec; + + fn add_u128(&mut self, msg_uint: &T) -> Vec<(usize, usize)> { + let c = self.cipher(); + let r = self.keybase(); let mut rng = rand::thread_rng(); let n = rng.gen_range(2..=r.len()); let mut c_i = (0..c.len()).choose_multiple(&mut rng, n - 1); let r_i = (0..r.len()).choose_multiple(&mut rng, n); - let mut sum = U128::ZERO; - for (&ci, &ri) in c_i.iter().zip(r_i.iter()) { - sum = sum.add_mod_special( - &c[ci].mul_mod_special(&r[ri], P_POS), - P_POS); + let mut sum = T::ZERO; + for (&ci, &ri) in c_i.iter().zip( r_i.iter() ) { + sum = sum.add_mod_prime( &c[ci].mul_mod_prime(&r[ri]) ); } - let ri_last = *r_i.last().expect("r_i will contain at least 2 elements"); - let mod_inv = r[ri_last].inv_mod(&P).0; - let c_new_el = msg_uint.sub_mod_special(&sum, P_POS) - .mul_mod_special(&mod_inv, P_POS); + let ri_last = *r_i.last() + .expect("r_i will contain at least 2 elements"); + let mod_inv = r[ri_last].inv_mod_prime(); + let c_new_el = msg_uint.sub_mod_prime(&sum) + .mul_mod_prime(&mod_inv); + let c = self.cipher_mut(); c.push(c_new_el); c_i.push(c.len() - 1); let indices = c_i.into_iter() @@ -75,41 +100,59 @@ impl FBCrypt { indices } - fn decrypt_u128(&self, indices: &[(usize, usize)]) -> Result { - if indices.len() > self.r.len() { + fn decrypt_u128(&self, indices: &[(usize, usize)]) -> Result { + let (r, c) = (self.keybase(), self.cipher()); + if indices.len() > r.len() { return Err(FBError::InvalidKey); } - let mut msg = U128::ZERO; + let mut msg = T::ZERO; for &(ci, ri) in indices { - let c_el = self.c.get(ci).ok_or(FBError::InvalidKey)?; - let r_el = self.r.get(ri).ok_or(FBError::InvalidKey)?; - msg = msg.add_mod_special( - &c_el.mul_mod_special(&r_el, P_POS), - P_POS); + let c_el = c.get(ci).ok_or(FBError::InvalidKey)?; + let r_el = r.get(ri).ok_or(FBError::InvalidKey)?; + msg = msg.add_mod_prime(&c_el.mul_mod_prime(&r_el)); } Ok(msg) } } -#[test] -fn encrypt_u128() { - let msg = U128::from_u32(100); - let mut fb = FBCrypt::init(20, 12).unwrap(); - let key = fb.add_u128(&msg); - let decrypted = fb.decrypt_u128(&key).unwrap(); - assert_eq!(msg, decrypted); -} +impl Encode for FBObj +where + T: Encoding + crypto_bigint::Bounded, +::Repr: Iterator + for <'a> From<&'a [u8]>, +Vec: FromIterator<<::Repr as Iterator>::Item> +{ + const BYTES: usize = T::BYTES; -#[test] -fn encrypt_bytes() { - let input1 = vec![255_u8; 150]; - let input2 = vec![0_u8; 102]; - let mut fb = FBCrypt::init(21, 12).unwrap(); - let key1 = fb.add(&input1); - let key2 = fb.add(&input2); - let decr1 = fb.decrypt(&key1).unwrap(); - let decr2 = fb.decrypt(&key2).unwrap(); - assert_eq!(input1, decr1); - assert_eq!(input2, decr2); + fn export(&self) -> (String, String) { + let c_bytes: Vec = self.c.iter() + .flat_map(|bigint| bigint.to_le_bytes()) + .collect(); + let r_bytes: Vec = self.r.iter() + .flat_map(|bigint| bigint.to_le_bytes()) + .collect(); + + (BASE64_STANDARD.encode(c_bytes), BASE64_STANDARD.encode(r_bytes)) + } + + fn import(cipher: &str, keybase: &str) -> Result + where + Self: Sized + { + let c_bytes = BASE64_STANDARD.decode(cipher) + .map_err(|_| FBError::DecodeError)?; + let c: Vec = c_bytes.chunks_exact(Self::BYTES) + .map(|chunk| T::from_le_bytes(chunk.try_into().unwrap())) + .collect(); + let r_bytes = BASE64_STANDARD.decode(keybase) + .map_err(|_| FBError::DecodeError)?; + let r: Vec = r_bytes.chunks_exact(Self::BYTES) + .map(|chunk| T::from_le_bytes(chunk.try_into().unwrap())) + .collect(); + if c.len() < r.len() || r.len() < 2 { + return Err(FBError::InvalidParams); + } + + Ok(Self {c, r}) + } } diff --git a/src/false_bottom/fb128.rs b/src/false_bottom/fb128.rs new file mode 100644 index 0000000..8721ea7 --- /dev/null +++ b/src/false_bottom/fb128.rs @@ -0,0 +1,126 @@ +use crypto_bigint::{U128, Limb, NonZero, Encoding}; +use crate::{ + false_bottom::{FalseBottom, ModPrime, FBBlockOperations, FBObj}, + pack::Packing, FBError, +}; + +pub type FB128 = FBObj; + +impl FalseBottom for FBObj { + const MODULUS: NonZero = NonZero::::const_new(Self::P).0; +} + +impl FBBlockOperations for FBObj { + const P: U128 = U128::MAX.wrapping_sub(&U128::from_u8(159 - 1)); + const P_POS: Limb = Limb::from_u8(159); + + fn cipher(&self) -> &Vec { + &self.c + } + + fn cipher_mut(&mut self) -> &mut Vec { + &mut self.c + } + + fn keybase(&self) -> &Vec { + &self.r + } +} + +impl ModPrime for U128 { + const PRIME_POS: Limb = Limb::from_u32(159); + const PRIME: U128 = U128::MAX.wrapping_sub(&U128::from_u8(159 - 1)); + + fn mul_mod_prime(&self, rhs: &Self) -> Self { + self.mul_mod_special(rhs, Self::PRIME_POS) + } + fn add_mod_prime(&self, rhs: &Self) -> Self { + self.add_mod_special(rhs, Self::PRIME_POS) + } + fn sub_mod_prime(&self, rhs: &Self) -> Self { + self.sub_mod_special(rhs, Self::PRIME_POS) + } + fn inv_mod_prime(&self) -> Self { + self.inv_mod(&Self::PRIME).0 + } +} + +impl Packing for U128 { + const P_MINUS_ONE: U128 = U128::MAX.wrapping_sub(&U128::from_u8(159)); + + fn pack(inp: &[u8]) -> Vec { + let mut out = Vec::with_capacity(inp.len()/16 + 2); + inp.chunks(16) + .for_each(|inp_chunk| { + let mut out_chunk = [0_u8; 16]; + out_chunk[..inp_chunk.len()].copy_from_slice(inp_chunk); + let mut out_uint = U128::from_le_bytes(out_chunk); + if out_uint >= Self::P_MINUS_ONE { + out.push(Self::P_MINUS_ONE); + out_uint = out_uint.wrapping_sub(&U128::from_u16(3000)); + } + out.push(out_uint); + }); + let inp_chunk_last = inp.chunks_exact(16) + .remainder(); + let mut pad_chunk: [u8; 16] = [16; 16]; + if inp_chunk_last.len() > 0 { + pad_chunk[15] += 16 - inp_chunk_last.len() as u8; + } + out.push(U128::from_le_bytes(pad_chunk)); + out.shrink_to_fit(); + + out + } + + fn unpack(inp: &[U128]) -> Result, FBError> { + let pad_len = inp.last() + .ok_or(FBError::InvalidKey)? + .to_le_bytes()[15] as usize; + if pad_len > 31 { + return Err(FBError::InvalidKey); + } + let mut out = Vec::with_capacity(inp.len()*16); + let mut add_3k = false; + for i in inp { + if add_3k { + let orig = i.wrapping_add(&U128::from_u16(3000)); + out.extend(orig.to_le_bytes().into_iter()); + add_3k = false; + } else if *i == Self::P_MINUS_ONE { + add_3k = true; + } else { + out.extend(i.to_le_bytes().into_iter()); + } + } + let trunc_len = out.len().checked_sub(pad_len) + .ok_or(FBError::InvalidKey)?; + out.truncate(trunc_len); + out.shrink_to_fit(); + + Ok(out) + } + +} + +#[test] +fn encrypt_u128() { + let msg = U128::from_u32(100); + let mut fb = FBObj::init(20, 12).unwrap(); + let key = fb.add_u128(&msg); + let decrypted = fb.decrypt_u128(&key).unwrap(); + assert_eq!(msg, decrypted); +} + +#[test] +fn encrypt_bytes() { + let input1 = vec![255_u8; 150]; + let input2 = vec![0_u8; 102]; + let mut fb = FBObj::init(21, 12).unwrap(); + let key1 = fb.add(&input1); + let key2 = fb.add(&input2); + let decr1 = fb.decrypt(&key1).unwrap(); + let decr2 = fb.decrypt(&key2).unwrap(); + assert_eq!(input1, decr1); + assert_eq!(input2, decr2); +} diff --git a/src/key.rs b/src/key.rs new file mode 100644 index 0000000..cd5caaf --- /dev/null +++ b/src/key.rs @@ -0,0 +1,31 @@ +use crate::FBError; +use base64::prelude::{BASE64_STANDARD, Engine}; +use bincode::{Options, DefaultOptions}; + +pub struct FBKey { + pub(crate) indices: Vec>, +} + +impl FBKey { + + pub fn export(&self) -> String { + let binc = DefaultOptions::new(); + let indice_bytes = binc.serialize(&self.indices) + .unwrap(); + + BASE64_STANDARD.encode(&indice_bytes) + } + + pub fn import(key_str: &str) -> Result { + let binc = DefaultOptions::new(); + let indice_bytes = BASE64_STANDARD.decode(key_str) + .map_err(|_| FBError::DecodeError)?; + let indices: Vec<_> = binc.deserialize(&indice_bytes) + .map_err(|_| FBError::DecodeError)?; + if indices.len() < 2 { + return Err(FBError::DecodeError); + } + + Ok (FBKey {indices}) + } +} diff --git a/src/lib.rs b/src/lib.rs index 1148ad9..00e4259 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,15 @@ mod encoding; mod errors; mod false_bottom; +mod key; mod packing; mod pack; -mod crypt; pub use crate::{ errors::FBError, - false_bottom::{FBCrypt, FBKey}, + false_bottom::fb128::FB128, + key::FBKey, + encoding::Encode, }; + +pub(crate) use crate::pack::Packing; diff --git a/src/pack.rs b/src/pack.rs index 7575f98..5120592 100644 --- a/src/pack.rs +++ b/src/pack.rs @@ -1,4 +1,5 @@ use crypto_bigint::{Encoding}; +use std::cmp::PartialOrd; use crate::FBError; /* PACKING SCHEME @@ -11,61 +12,10 @@ use crate::FBError; pub(crate) trait Packing where - T: Encoding + std::cmp::PartialOrd + T: Encoding + PartialOrd { const P_MINUS_ONE: T; - const BYTES: usize; - fn pack(inp: &[u8]) -> Vec { - let mut out = Vec::with_capacity(inp.len()/Self::BYTES + 2); - inp.chunks(Self::BYTES) - .for_each(|inp_chunk| { - let mut out_chunk = [0_u8; Self::BYTES]; - out_chunk[..inp_chunk.len()].copy_from_slice(inp_chunk); - let mut out_uint = T::from_le_bytes(out_chunk); - if out_uint >= Self::P_MINUS_ONE { - out.push(Self::P_MINUS_ONE); - out_uint = out_uint.wrapping_sub(&T::from_u16(3000)); - } - out.push(out_uint); - }); - let inp_chunk_last = inp.chunks_exact(Self::BYTES) - .remainder(); - let mut pad_chunk = [Self::BYTES as u8; Self::BYTES]; - if inp_chunk_last.len() > 0 { - pad_chunk[Self::BYTES as u8 - 1] += Self::BYTES as u8 - inp_chunk_last.len() as u8; - } - out.push(T::from_le_bytes(pad_chunk)); - out.shrink_to_fit(); - - out - } - - fn unpack(inp: &[T]) -> Result, FBError> { - let pad_len = inp.last() - .ok_or(FBError::InvalidKey)? - .to_le_bytes()[15] as usize; - if pad_len > 31 { - return Err(FBError::InvalidKey); - } - let mut out = Vec::with_capacity(inp.len()*16); - let mut add_3k = false; - for i in inp { - if add_3k { - let orig = i.wrapping_add(&T::from_u16(3000)); - out.extend(orig.to_le_bytes().into_iter()); - add_3k = false; - } else if *i == Self::P_MINUS_ONE { - add_3k = true; - } else { - out.extend(i.to_le_bytes().into_iter()); - } - } - let trunc_len = out.len().checked_sub(pad_len) - .ok_or(FBError::InvalidKey)?; - out.truncate(trunc_len); - out.shrink_to_fit(); - - Ok(out) - } + fn pack(inp: &[u8]) -> Vec; + fn unpack(inp: &[T]) -> Result, FBError>; }