Skip to content

Commit

Permalink
Split PRG impl as feature prg
Browse files Browse the repository at this point in the history
  • Loading branch information
myl7 committed Jul 12, 2023
1 parent 4e9c48a commit e16a9ed
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 66 deletions.
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ license = "Apache-2.0"
keywords = ["crypto", "dpf", "fss", "dcf", "dist-comparison-fn"]
categories = ["cryptography"]

[features]
prg = ["aes"]

[dependencies]
bitvec = "1.0.1"
aes = "0.8.3"
aes = { version = "0.8.3", optional = true }

[dev-dependencies]
rand = { version = "0.8.5", features = ["std", "std_rng"] }
75 changes: 10 additions & 65 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@

//! See [`Dcf`]
use aes::cipher::generic_array::GenericArray;
use aes::cipher::{BlockEncrypt, KeyInit};
use aes::Aes256;
#[cfg(feature = "prg")]
pub mod prg;

pub(crate) mod utils;

use bitvec::prelude::*;

use crate::utils::{xor, xor_inplace};

/// API of Distributed comparison function.
///
/// See [`CmpFn`] for `N` and `LAMBDA`.
Expand Down Expand Up @@ -219,73 +223,14 @@ pub enum BoundState {
GtBeta,
}

/// Matyas-Meyer-Oseas one-way compression function with AES256 and precreated keys as an implementation of [`Prg`].
pub struct Aes256MatyasMeyerOseasPrg {
ciphers: [Aes256; 5],
}

impl Aes256MatyasMeyerOseasPrg {
pub fn new(keys: [&[u8; 32]; 5]) -> Self {
let ciphers = std::array::from_fn(|i| {
let key_block = GenericArray::from_slice(keys[i]);
Aes256::new(key_block)
});
Self { ciphers }
}
}

impl Prg<16> for Aes256MatyasMeyerOseasPrg {
fn gen(&self, seed: &[u8; 16]) -> [([u8; 16], [u8; 16], bool); 2] {
let rand_blocks: Vec<[u8; 16]> = self
.ciphers
.iter()
.map(|cipher| {
let mut block = GenericArray::clone_from_slice(seed);
cipher.encrypt_block(&mut block);
xor_inplace(&mut block.into(), &[seed]);
block.into()
})
.collect();
assert_eq!(rand_blocks.len(), 5);
[
(
rand_blocks[0],
rand_blocks[1],
rand_blocks[4].view_bits::<Lsb0>()[0],
),
(
rand_blocks[2],
rand_blocks[3],
rand_blocks[4].view_bits::<Lsb0>()[1],
),
]
}
}

fn xor<const LAMBDA: usize>(xs: &[&[u8; LAMBDA]]) -> [u8; LAMBDA] {
let mut res = [0; LAMBDA];
for i in 0..LAMBDA {
for x in xs {
res[i] ^= x[i];
}
}
res
}

fn xor_inplace<const LAMBDA: usize>(lhs: &mut [u8; LAMBDA], rhss: &[&[u8; LAMBDA]]) {
for i in 0..LAMBDA {
for rhs in rhss {
lhs[i] ^= rhs[i];
}
}
}

#[cfg(test)]
#[cfg(all(test, feature = "prg"))]
mod tests {
use super::*;

use rand::{thread_rng, Rng};

use crate::prg::Aes256MatyasMeyerOseasPrg;

const KEYS: [&[u8; 32]; 5] = [
b"j9\x1b_\xb3X\xf33\xacW\x15\x1b\x0812K\xb3I\xb9\x90r\x1cN\xb5\xee9W\xd3\xbb@\xc6d",
b"\x9b\x15\xc8\x0f\xb7\xbc!q\x9e\x89\xb8\xf7\x0e\xa0S\x9dN\xfa\x0c;\x16\xe4\x98\x82b\xfcdy\xb5\x8c{\xc2",
Expand Down
55 changes: 55 additions & 0 deletions src/prg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (C) myl7
// SPDX-License-Identifier: Apache-2.0

//! [`crate::Prg`] implementations
use aes::cipher::generic_array::GenericArray;
use aes::cipher::{BlockEncrypt, KeyInit};
use aes::Aes256;
use bitvec::prelude::*;

use crate::utils::xor_inplace;
use crate::Prg;

/// Matyas-Meyer-Oseas one-way compression function with AES256 and precreated keys as an implementation of [`Prg`].
pub struct Aes256MatyasMeyerOseasPrg {
ciphers: [Aes256; 5],
}

impl Aes256MatyasMeyerOseasPrg {
pub fn new(keys: [&[u8; 32]; 5]) -> Self {
let ciphers = std::array::from_fn(|i| {
let key_block = GenericArray::from_slice(keys[i]);
Aes256::new(key_block)
});
Self { ciphers }
}
}

impl Prg<16> for Aes256MatyasMeyerOseasPrg {
fn gen(&self, seed: &[u8; 16]) -> [([u8; 16], [u8; 16], bool); 2] {
let rand_blocks: Vec<[u8; 16]> = self
.ciphers
.iter()
.map(|cipher| {
let mut block = GenericArray::clone_from_slice(seed);
cipher.encrypt_block(&mut block);
xor_inplace(&mut block.into(), &[seed]);
block.into()
})
.collect();
assert_eq!(rand_blocks.len(), 5);
[
(
rand_blocks[0],
rand_blocks[1],
rand_blocks[4].view_bits::<Lsb0>()[0],
),
(
rand_blocks[2],
rand_blocks[3],
rand_blocks[4].view_bits::<Lsb0>()[1],
),
]
}
}
20 changes: 20 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) myl7
// SPDX-License-Identifier: Apache-2.0

pub fn xor<const LAMBDA: usize>(xs: &[&[u8; LAMBDA]]) -> [u8; LAMBDA] {
let mut res = [0; LAMBDA];
for i in 0..LAMBDA {
for x in xs {
res[i] ^= x[i];
}
}
res
}

pub fn xor_inplace<const LAMBDA: usize>(lhs: &mut [u8; LAMBDA], rhss: &[&[u8; LAMBDA]]) {
for i in 0..LAMBDA {
for rhs in rhss {
lhs[i] ^= rhs[i];
}
}
}

0 comments on commit e16a9ed

Please sign in to comment.