working on export
This commit is contained in:
parent
d33b8f534d
commit
1ff02271ad
|
@ -4,20 +4,23 @@ fn main() {
|
||||||
let real_msg = "The troops are headed due north";
|
let real_msg = "The troops are headed due north";
|
||||||
let fake_msg = "The troops are headed due south";
|
let fake_msg = "The troops are headed due south";
|
||||||
|
|
||||||
let mut fb = FBCrypt::init(12, 12).unwrap();
|
let mut fb = FBCrypt::init(18, 12).unwrap();
|
||||||
|
|
||||||
let real_key = fb.add(&real_msg.as_bytes()).unwrap();
|
let real_key = fb.add(&real_msg.as_bytes()).unwrap();
|
||||||
let fake_key = fb.add(&fake_msg.as_bytes()).unwrap();
|
let fake_key = fb.add(&fake_msg.as_bytes()).unwrap();
|
||||||
|
|
||||||
let real_decr = fb.decrypt(&real_key).unwrap();
|
let cipher = fb.export().unwrap();
|
||||||
let fake_decr = fb.decrypt(&fake_key).unwrap();
|
let mut fb_new = FBCrypt::import(&cipher).unwrap();
|
||||||
|
|
||||||
|
let real_decr = fb_new.decrypt(&real_key).unwrap();
|
||||||
|
let fake_decr = fb_new.decrypt(&fake_key).unwrap();
|
||||||
|
|
||||||
let real_str = String::from_utf8(real_decr).unwrap();
|
let real_str = String::from_utf8(real_decr).unwrap();
|
||||||
let fake_str = String::from_utf8(fake_decr).unwrap();
|
let fake_str = String::from_utf8(fake_decr).unwrap();
|
||||||
|
|
||||||
let cipher = fb.export();
|
|
||||||
println!("Cipher: {cipher}");
|
println!("Cipher: {cipher}");
|
||||||
println!("Decrypted Contents:");
|
println!("Decrypted Contents:");
|
||||||
println!("Real: {real_str}\nFake: {fake_str}");
|
println!("Real: {real_str}\nFake: {fake_str}");
|
||||||
assert_eq!(real_msg, real_str);
|
assert_eq!(real_msg, real_str);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,38 +5,36 @@ use crypto_bigint::{U128, Encoding};
|
||||||
// all 128 bit integers are within the prime field (i.e < 2^128 - 159)
|
// all 128 bit integers are within the prime field (i.e < 2^128 - 159)
|
||||||
// As of now, this is achieved by utilizing only 120 bits out of 128 bits
|
// As of now, this is achieved by utilizing only 120 bits out of 128 bits
|
||||||
|
|
||||||
impl FBCrypt {
|
pub(crate) fn msg_to_u128_blocks(inp: &[u8]) -> Result<Vec<U128>, FBError> {
|
||||||
pub(crate) fn to_u128_blocks(inp: &[u8]) -> Result<Vec<U128>, FBError> {
|
if inp.len() == 0 {
|
||||||
if inp.len() == 0 {
|
return Err(FBError::EmptyInput);
|
||||||
return Err(FBError::EmptyInput);
|
|
||||||
}
|
|
||||||
let mut out: Vec<U128> = inp.chunks_exact(15)
|
|
||||||
.map(|chunk| {
|
|
||||||
let mut padded_chunk = [0_u8; 16];
|
|
||||||
padded_chunk[..chunk.len()].copy_from_slice(chunk);
|
|
||||||
U128::from_le_bytes(padded_chunk)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let rem = inp.chunks_exact(15)
|
|
||||||
.remainder();
|
|
||||||
if rem.len() > 0 {
|
|
||||||
let mut rem_chunk: [u8; 16] = [0; 16];
|
|
||||||
rem_chunk[..rem.len()].copy_from_slice(rem);
|
|
||||||
rem_chunk[15] = 16 - rem.len() as u8;
|
|
||||||
out.push(U128::from_le_bytes(rem_chunk));
|
|
||||||
}
|
|
||||||
Ok(out)
|
|
||||||
}
|
}
|
||||||
|
let mut out: Vec<U128> = inp.chunks_exact(15)
|
||||||
pub(crate) fn to_bytes(inp: &[U128]) -> Result<Vec<u8>, FBError> {
|
.map(|chunk| {
|
||||||
if inp.len() == 0 {
|
let mut padded_chunk = [0_u8; 16];
|
||||||
return Err(FBError::EmptyInput)
|
padded_chunk[..15].copy_from_slice(chunk);
|
||||||
}
|
U128::from_le_bytes(padded_chunk)
|
||||||
let mut out: Vec<u8> = inp.iter()
|
})
|
||||||
.flat_map(|big_num| big_num.to_le_bytes()[..15].to_vec())
|
.collect();
|
||||||
.collect();
|
let rem = inp.chunks_exact(15)
|
||||||
let pad = inp.last().unwrap().to_le_bytes()[15];
|
.remainder();
|
||||||
out.truncate(out.len()+1-pad as usize);
|
if rem.len() > 0 {
|
||||||
Ok(out)
|
let mut rem_chunk: [u8; 16] = [0; 16];
|
||||||
|
rem_chunk[..rem.len()].copy_from_slice(rem);
|
||||||
|
rem_chunk[15] = 16 - rem.len() as u8;
|
||||||
|
out.push(U128::from_le_bytes(rem_chunk));
|
||||||
}
|
}
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn to_msg_bytes(inp: &[U128]) -> Result<Vec<u8>, FBError> {
|
||||||
|
if inp.len() == 0 {
|
||||||
|
return Err(FBError::EmptyInput)
|
||||||
|
}
|
||||||
|
let mut out: Vec<u8> = inp.iter()
|
||||||
|
.flat_map(|big_num| big_num.to_le_bytes()[..15].to_vec())
|
||||||
|
.collect();
|
||||||
|
let pad = inp.last().unwrap().to_le_bytes()[15];
|
||||||
|
out.truncate(out.len()+1-pad as usize);
|
||||||
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,41 @@
|
||||||
use base64::prelude::*;
|
use base64::prelude::*;
|
||||||
|
use crypto_bigint::{U128, Encoding};
|
||||||
use crate::{
|
use crate::{
|
||||||
FBCrypt,
|
FBCrypt,
|
||||||
errors::FBError,
|
errors::FBError,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl FBCrypt {
|
impl FBCrypt {
|
||||||
pub fn export(&self) -> String {
|
pub fn export(&self) -> Result<String, FBError> {
|
||||||
BASE64_STANDARD.encode(
|
let c_bytes: Vec<u8> = self.c.iter()
|
||||||
FBCrypt::to_bytes(&self.c).unwrap_or("".into())
|
.flat_map(|bigint| bigint.to_le_bytes().to_vec())
|
||||||
)
|
.collect();
|
||||||
|
let r_bytes: Vec<u8> = self.r.iter()
|
||||||
|
.flat_map(|bigint| bigint.to_le_bytes().to_vec())
|
||||||
|
.collect();
|
||||||
|
Ok(
|
||||||
|
BASE64_STANDARD.encode(c_bytes) + ":"
|
||||||
|
+ &BASE64_STANDARD.encode(r_bytes)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn import(c_str: &str, r_str: &str) -> Result<FBCrypt, FBError> {
|
pub fn import(string: &str) -> Result<FBCrypt, FBError> {
|
||||||
|
let (c_str, r_str) = string.split_once(':')
|
||||||
|
.ok_or_else(|| FBError::DecodeError)?;
|
||||||
let c_bytes = BASE64_STANDARD.decode(c_str)
|
let c_bytes = BASE64_STANDARD.decode(c_str)
|
||||||
.map_err(|_| FBError::DecodeError)?;
|
.map_err(|_| FBError::DecodeError)?;
|
||||||
let c = FBCrypt::to_u128_blocks(&c_bytes)?;
|
let c: Vec<U128> = c_bytes.chunks_exact(16)
|
||||||
|
.map(|chunk| U128::from_le_bytes(chunk.try_into().unwrap()))
|
||||||
|
.collect();
|
||||||
let r_bytes = BASE64_STANDARD.decode(r_str)
|
let r_bytes = BASE64_STANDARD.decode(r_str)
|
||||||
.map_err(|_| FBError::DecodeError)?;
|
.map_err(|_| FBError::DecodeError)?;
|
||||||
let r = FBCrypt::to_u128_blocks(&r_bytes)?;
|
let r: Vec<U128> = r_bytes.chunks_exact(16)
|
||||||
|
.map(|chunk| U128::from_le_bytes(chunk.try_into().unwrap()))
|
||||||
|
.collect();
|
||||||
Ok(FBCrypt {c, r})
|
Ok(FBCrypt {c, r})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FBKey {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
use rand::{Rng, seq::IteratorRandom};
|
use rand::{Rng, seq::IteratorRandom};
|
||||||
use crate::{errors::FBError};
|
use crate::{errors::FBError, convert::*};
|
||||||
use crypto_bigint::{U128, RandomMod, NonZero, rand_core::OsRng, Limb};
|
use crypto_bigint::{U128, RandomMod, NonZero, rand_core::OsRng, Limb};
|
||||||
|
|
||||||
pub struct FBCrypt {
|
pub struct FBCrypt {
|
||||||
pub(crate) r: Vec<U128>,
|
|
||||||
pub(crate) c: Vec<U128>,
|
pub(crate) c: Vec<U128>,
|
||||||
|
pub(crate) r: Vec<U128>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FBKey {
|
pub struct FBKey {
|
||||||
pub(crate) indices: Vec<(usize, usize)>,
|
pub(crate) r: Vec<U128>,
|
||||||
|
pub(crate) indices: Vec<Vec<(usize, usize)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prime number value
|
// Prime number value
|
||||||
|
@ -28,28 +29,31 @@ impl FBCrypt {
|
||||||
let c: Vec<U128> = (0..n)
|
let c: Vec<U128> = (0..n)
|
||||||
.map(|_| U128::random_mod(&mut OsRng, &MODULUS))
|
.map(|_| U128::random_mod(&mut OsRng, &MODULUS))
|
||||||
.collect();
|
.collect();
|
||||||
Ok(FBCrypt {r, c})
|
Ok(FBCrypt {c, r})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, m: &[u8]) -> Result<Vec<FBKey>, FBError> {
|
pub fn add(&mut self, m: &[u8]) -> Result<FBKey, FBError> {
|
||||||
let msg: Vec<U128> = FBCrypt::to_u128_blocks(m)?;
|
let msg: Vec<U128> = msg_to_u128_blocks(m)?;
|
||||||
let mut keys: Vec<FBKey> = Vec::new();
|
let mut key = FBKey {
|
||||||
|
r: self.r.clone(),
|
||||||
|
indices: Vec::new()
|
||||||
|
};
|
||||||
for m in msg {
|
for m in msg {
|
||||||
keys.push(self.add_u128(&m)?)
|
key.indices.push(self.add_u128(&m)?)
|
||||||
}
|
}
|
||||||
Ok(keys)
|
Ok(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decrypt(&mut self, keys: &[FBKey]) -> Result<Vec<u8>, FBError> {
|
pub fn decrypt(&mut self, key: &FBKey) -> Result<Vec<u8>, FBError> {
|
||||||
let mut decrypted: Vec<U128> = Vec::new();
|
let mut decrypted: Vec<U128> = Vec::new();
|
||||||
for key in keys {
|
for indices in &key.indices {
|
||||||
decrypted.push(self.decrypt_u128(&key)?)
|
decrypted.push(self.decrypt_u128(&indices)?)
|
||||||
}
|
}
|
||||||
let msg = FBCrypt::to_bytes(&decrypted)?;
|
let msg = to_msg_bytes(&decrypted)?;
|
||||||
Ok(msg)
|
Ok(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_u128(&mut self, m: &U128) -> Result<FBKey, FBError> {
|
fn add_u128(&mut self, m: &U128) -> Result<Vec<(usize, usize)>, FBError> {
|
||||||
if m.ge(&P) {
|
if m.ge(&P) {
|
||||||
return Err(FBError::IntegerTooLarge);
|
return Err(FBError::IntegerTooLarge);
|
||||||
}
|
}
|
||||||
|
@ -82,15 +86,15 @@ impl FBCrypt {
|
||||||
let indices: Vec<(usize, usize)> = c_i.into_iter()
|
let indices: Vec<(usize, usize)> = c_i.into_iter()
|
||||||
.zip(r_i.into_iter())
|
.zip(r_i.into_iter())
|
||||||
.collect();
|
.collect();
|
||||||
Ok(FBKey {indices})
|
Ok(indices)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt_u128(&self, key: &FBKey) -> Result<U128, FBError> {
|
fn decrypt_u128(&self, indices: &[(usize, usize)]) -> Result<U128, FBError> {
|
||||||
if key.indices.len() > self.c.len() {
|
if indices.len() > self.c.len() {
|
||||||
return Err(FBError::InvalidKey)
|
return Err(FBError::InvalidKey)
|
||||||
}
|
}
|
||||||
let mut m: U128 = U128::ZERO;
|
let mut m: U128 = U128::ZERO;
|
||||||
for &(ci, ri) in &key.indices {
|
for &(ci, ri) in indices {
|
||||||
m = m.add_mod(
|
m = m.add_mod(
|
||||||
&self.c[ci].mul_mod_special(&self.r[ri], P_POS),
|
&self.c[ci].mul_mod_special(&self.r[ri], P_POS),
|
||||||
&P);
|
&P);
|
||||||
|
@ -112,7 +116,7 @@ fn encrypt_u128() {
|
||||||
fn encrypt_bytes() {
|
fn encrypt_bytes() {
|
||||||
let input = vec![0xff; 150];
|
let input = vec![0xff; 150];
|
||||||
let mut fb = FBCrypt::init(21, 12).unwrap();
|
let mut fb = FBCrypt::init(21, 12).unwrap();
|
||||||
let keys = fb.add(&input).unwrap();
|
let key = fb.add(&input).unwrap();
|
||||||
let decrypted = fb.decrypt(&keys).unwrap();
|
let decrypted = fb.decrypt(&key).unwrap();
|
||||||
assert_eq!(input, decrypted);
|
assert_eq!(input, decrypted);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue