-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* update aes/block, add prg/ggm * add cr/ccr hashes * add reduce operation * add reduce to block * add gfmul/inner_product to block * add bench of reduce * add bench of aes/prg/ggm * minor * handling unsafe and documentation * handling unsafe and documentation * update minor changes * update minor changes * fmt * update comments * minor * minor * update sigma, add test
1 parent
ab4f98d
commit a036064
Showing
19 changed files
with
872 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
|
||
use mpz_core::{aes::AesEncryptor, block::Block}; | ||
|
||
fn criterion_benchmark(c: &mut Criterion) { | ||
let x = rand::random::<Block>(); | ||
let aes = AesEncryptor::new(x); | ||
let blk = rand::random::<Block>(); | ||
|
||
c.bench_function("aes::encrypt_block", move |bench| { | ||
bench.iter(|| { | ||
let z = aes.encrypt_block(black_box(blk)); | ||
black_box(z); | ||
}); | ||
}); | ||
|
||
c.bench_function("aes::encrypt_many_blocks::<8>", move |bench| { | ||
let key = rand::random::<Block>(); | ||
let aes = AesEncryptor::new(key); | ||
let blks = rand::random::<[Block; 8]>(); | ||
|
||
bench.iter(|| { | ||
let z = aes.encrypt_many_blocks(black_box(blks)); | ||
black_box(z); | ||
}); | ||
}); | ||
|
||
c.bench_function("aes::para_encrypt::<1,8>", move |bench| { | ||
let key = rand::random::<Block>(); | ||
let aes = AesEncryptor::new(key); | ||
let aes = [aes]; | ||
let mut blks = rand::random::<[Block; 8]>(); | ||
|
||
bench.iter(|| { | ||
let z = AesEncryptor::para_encrypt::<1, 8>(black_box(&aes), black_box(&mut blks)); | ||
black_box(z); | ||
}); | ||
}); | ||
} | ||
|
||
criterion_group!(benches, criterion_benchmark); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
use mpz_core::{block::Block, ggm_tree::GgmTree}; | ||
|
||
fn criterion_benchmark(c: &mut Criterion) { | ||
c.bench_function("ggm::gen::1K", move |bench| { | ||
let depth = 11; | ||
let ggm = GgmTree::new(depth); | ||
let mut tree = vec![Block::ZERO; 1 << (depth - 1)]; | ||
let mut k0 = vec![Block::ZERO; depth - 1]; | ||
let mut k1 = vec![Block::ZERO; depth - 1]; | ||
let seed = rand::random::<Block>(); | ||
bench.iter(|| { | ||
black_box(ggm.gen( | ||
black_box(seed), | ||
black_box(&mut tree), | ||
black_box(&mut k0), | ||
black_box(&mut k1), | ||
)); | ||
}); | ||
}); | ||
} | ||
|
||
criterion_group!(benches, criterion_benchmark); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
|
||
use mpz_core::{block::Block, prg::Prg}; | ||
use rand_core::RngCore; | ||
|
||
fn criterion_benchmark(c: &mut Criterion) { | ||
c.bench_function("Prg::byte", move |bench| { | ||
let mut prg = Prg::new(); | ||
let mut x = 0u8; | ||
bench.iter(|| { | ||
x = prg.random_byte(); | ||
black_box(x); | ||
}); | ||
}); | ||
|
||
c.bench_function("Prg::bytes", move |bench| { | ||
let mut prg = Prg::new(); | ||
let mut x = (0..16 * 1024) | ||
.map(|_| rand::random::<u8>()) | ||
.collect::<Vec<u8>>(); | ||
bench.iter(|| { | ||
prg.fill_bytes(black_box(&mut x)); | ||
}); | ||
}); | ||
|
||
c.bench_function("Prg::block", move |bench| { | ||
let mut prg = Prg::new(); | ||
let mut x = Block::ZERO; | ||
bench.iter(|| { | ||
x = prg.random_block(); | ||
black_box(x); | ||
}); | ||
}); | ||
|
||
c.bench_function("Prg::blocks", move |bench| { | ||
let mut prg = Prg::new(); | ||
let mut x = (0..16 * 1024) | ||
.map(|_| rand::random::<Block>()) | ||
.collect::<Vec<Block>>(); | ||
bench.iter(|| { | ||
prg.random_blocks(black_box(&mut x)); | ||
}); | ||
}); | ||
} | ||
|
||
criterion_group!(benches, criterion_benchmark); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
//! Implement GGM tree for OT. | ||
//! Implementation of GGM based on the procedure explained in the write-up | ||
//! (<https://eprint.iacr.org/2020/925.pdf>, Page 14) | ||
use crate::{tkprp::TwoKeyPrp, Block}; | ||
|
||
/// Struct of GGM | ||
pub struct GgmTree { | ||
tkprp: TwoKeyPrp, | ||
depth: usize, | ||
} | ||
|
||
impl GgmTree { | ||
///New GgmTree instance. | ||
#[inline(always)] | ||
pub fn new(depth: usize) -> Self { | ||
let tkprp = TwoKeyPrp::new([Block::ZERO, Block::from(1u128.to_le_bytes())]); | ||
Self { tkprp, depth } | ||
} | ||
|
||
/// Input: `seed`: a seed. | ||
/// Output: `tree`: a GGM (binary tree) `tree`, with size `2^{depth-1}` | ||
/// Output: `k0`: XORs of all the left-node values in each level, with size `depth-1`. | ||
/// Output: `k1`: XORs of all the right-node values in each level, with size `depth-1`. | ||
/// This implementation is adapted from EMP Toolkit. | ||
pub fn gen(&self, seed: Block, tree: &mut [Block], k0: &mut [Block], k1: &mut [Block]) { | ||
assert!(tree.len() == 1 << (self.depth - 1)); | ||
assert!(k0.len() == self.depth - 1); | ||
assert!(k1.len() == self.depth - 1); | ||
let mut buf = vec![Block::ZERO; 8]; | ||
self.tkprp.expand_1to2(tree, seed); | ||
k0[0] = tree[0]; | ||
k1[0] = tree[1]; | ||
|
||
self.tkprp.expand_2to4(&mut buf, tree); | ||
k0[1] = buf[0] ^ buf[2]; | ||
k1[1] = buf[1] ^ buf[3]; | ||
tree[0..4].copy_from_slice(&buf[0..4]); | ||
|
||
for h in 2..self.depth - 1 { | ||
k0[h] = Block::ZERO; | ||
k1[h] = Block::ZERO; | ||
let sz = 1 << h; | ||
for i in (0..=sz - 4).rev().step_by(4) { | ||
self.tkprp.expand_4to8(&mut buf, &tree[i..]); | ||
k0[h] ^= buf[0]; | ||
k0[h] ^= buf[2]; | ||
k0[h] ^= buf[4]; | ||
k0[h] ^= buf[6]; | ||
k1[h] ^= buf[1]; | ||
k1[h] ^= buf[3]; | ||
k1[h] ^= buf[5]; | ||
k1[h] ^= buf[7]; | ||
|
||
tree[2 * i..2 * i + 8].copy_from_slice(&buf); | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[test] | ||
fn ggm_test() { | ||
let depth = 3; | ||
let mut tree = vec![Block::ZERO; 1 << (depth - 1)]; | ||
let mut k0 = vec![Block::ZERO; depth - 1]; | ||
let mut k1 = vec![Block::ZERO; depth - 1]; | ||
|
||
let ggm = GgmTree::new(depth); | ||
|
||
ggm.gen(Block::ZERO, &mut tree, &mut k0, &mut k1); | ||
|
||
// Test vectors are from EMP Toolkit. | ||
assert_eq!( | ||
tree, | ||
[ | ||
Block::from((0x92A6DDEAA3E99F9BECB268BD9EF67C91 as u128).to_le_bytes()), | ||
Block::from((0x9E7E9C02ED1E62385EE8A9EDDC63A2B5 as u128).to_le_bytes()), | ||
Block::from((0xBD4B85E90AACBD106694537DB6251264 as u128).to_le_bytes()), | ||
Block::from((0x230485DC4360014833E07D8D914411A2 as u128).to_le_bytes()), | ||
] | ||
); | ||
|
||
assert_eq!( | ||
k0, | ||
[ | ||
Block::from((0x2E2B34CA59FA4C883B2C8AEFD44BE966 as u128).to_le_bytes()), | ||
Block::from((0x2FED5803A945228B8A263BC028D36EF5 as u128).to_le_bytes()), | ||
] | ||
); | ||
|
||
assert_eq!( | ||
k1, | ||
[ | ||
Block::from((0x7E46C568D1CD4972BB1A61F95DD80EDC as u128).to_le_bytes()), | ||
Block::from((0xBD7A19DEAE7E63706D08D4604D27B317 as u128).to_le_bytes()), | ||
] | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
//! Implement AES-based PRG. | ||
use crate::{aes::AesEncryptor, Block}; | ||
use rand::Rng; | ||
use rand_core::{ | ||
block::{BlockRng, BlockRngCore}, | ||
CryptoRng, RngCore, SeedableRng, | ||
}; | ||
/// Struct of PRG Core | ||
#[derive(Clone)] | ||
struct PrgCore { | ||
aes: AesEncryptor, | ||
state: u64, | ||
} | ||
|
||
// This implementation is somehow standard, and is adapted from Swanky. | ||
impl BlockRngCore for PrgCore { | ||
type Item = u32; | ||
type Results = [u32; 4 * AesEncryptor::AES_BLOCK_COUNT]; | ||
|
||
// Compute [AES(state)..AES(state+8)] | ||
#[inline(always)] | ||
fn generate(&mut self, results: &mut Self::Results) { | ||
let states = [0; AesEncryptor::AES_BLOCK_COUNT].map( | ||
#[inline(always)] | ||
|_| { | ||
let x = self.state; | ||
self.state += 1; | ||
Block::from(bytemuck::cast::<_, [u8; 16]>([x, 0u64])) | ||
}, | ||
); | ||
*results = bytemuck::cast(self.aes.encrypt_many_blocks(states)) | ||
} | ||
} | ||
|
||
impl SeedableRng for PrgCore { | ||
type Seed = Block; | ||
|
||
#[inline(always)] | ||
fn from_seed(seed: Self::Seed) -> Self { | ||
let aes = AesEncryptor::new(seed); | ||
Self { aes, state: 0u64 } | ||
} | ||
} | ||
|
||
impl CryptoRng for PrgCore {} | ||
|
||
/// Struct of PRG | ||
#[derive(Clone)] | ||
pub struct Prg(BlockRng<PrgCore>); | ||
|
||
impl RngCore for Prg { | ||
#[inline(always)] | ||
fn next_u32(&mut self) -> u32 { | ||
self.0.next_u32() | ||
} | ||
|
||
#[inline(always)] | ||
fn next_u64(&mut self) -> u64 { | ||
self.0.next_u64() | ||
} | ||
|
||
#[inline(always)] | ||
fn fill_bytes(&mut self, dest: &mut [u8]) { | ||
self.0.fill_bytes(dest) | ||
} | ||
|
||
#[inline(always)] | ||
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { | ||
self.0.try_fill_bytes(dest) | ||
} | ||
} | ||
|
||
impl SeedableRng for Prg { | ||
type Seed = Block; | ||
|
||
#[inline(always)] | ||
fn from_seed(seed: Self::Seed) -> Self { | ||
Prg(BlockRng::<PrgCore>::from_seed(seed)) | ||
} | ||
|
||
#[inline(always)] | ||
fn from_rng<R: RngCore>(rng: R) -> Result<Self, rand_core::Error> { | ||
BlockRng::<PrgCore>::from_rng(rng).map(Prg) | ||
} | ||
} | ||
|
||
impl CryptoRng for Prg {} | ||
|
||
impl Prg { | ||
/// New Prg with random seed. | ||
#[inline(always)] | ||
pub fn new() -> Self { | ||
let seed = rand::random::<Block>(); | ||
Prg::from_seed(seed) | ||
} | ||
|
||
/// Generate a random bool value. | ||
#[inline(always)] | ||
pub fn random_bool(&mut self) -> bool { | ||
self.gen() | ||
} | ||
|
||
/// Fill a bool slice with random bool values. | ||
#[inline(always)] | ||
pub fn random_bools(&mut self, buf: &mut [bool]) { | ||
self.fill(buf); | ||
} | ||
|
||
/// Generate a random byte value. | ||
#[inline(always)] | ||
pub fn random_byte(&mut self) -> u8 { | ||
self.gen() | ||
} | ||
|
||
/// Fill a byte slice with random values. | ||
#[inline(always)] | ||
pub fn random_bytes(&mut self, buf: &mut [u8]) { | ||
self.fill_bytes(buf); | ||
} | ||
|
||
/// Generate a random block. | ||
#[inline(always)] | ||
pub fn random_block(&mut self) -> Block { | ||
self.gen() | ||
} | ||
|
||
/// Fill a block slice with random block values. | ||
#[inline(always)] | ||
pub fn random_blocks(&mut self, buf: &mut [Block]) { | ||
let bytes: &mut [u8] = bytemuck::cast_slice_mut(buf); | ||
self.fill_bytes(bytes); | ||
} | ||
} | ||
|
||
impl Default for Prg { | ||
#[inline(always)] | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} | ||
|
||
#[test] | ||
fn prg_test() { | ||
let mut prg = Prg::new(); | ||
let mut x = vec![Block::ZERO; 2]; | ||
prg.random_blocks(&mut x); | ||
assert_ne!(x[0], x[1]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
//! Implement the two-key PRG as G(k) = PRF_seed0(k)\xor k || PRF_seed1(k)\xor k | ||
//! Refer to (<https://www.usenix.org/system/files/conference/nsdi17/nsdi17-wang-frank.pdf>, Page 8) | ||
use crate::{aes::AesEncryptor, Block}; | ||
|
||
/// Struct of two-key prp. | ||
/// This implementation is adapted from EMP toolkit. | ||
pub struct TwoKeyPrp([AesEncryptor; 2]); | ||
|
||
impl TwoKeyPrp { | ||
/// New an instance of TwoKeyPrp | ||
#[inline(always)] | ||
pub fn new(seeds: [Block; 2]) -> Self { | ||
Self([AesEncryptor::new(seeds[0]), AesEncryptor::new(seeds[1])]) | ||
} | ||
|
||
/// expand 1 to 2 | ||
#[inline(always)] | ||
pub fn expand_1to2(&self, children: &mut [Block], parent: Block) { | ||
children[0] = parent; | ||
children[1] = parent; | ||
AesEncryptor::para_encrypt::<2, 1>(&self.0, children); | ||
children[0] ^= parent; | ||
children[1] ^= parent; | ||
} | ||
|
||
/// expand 2 to 4 | ||
// p[0] p[1] | ||
// c[0] c[1] c[2] c[3] | ||
// t[0] t[2] t[1] t[3] | ||
#[inline(always)] | ||
pub fn expand_2to4(&self, children: &mut [Block], parent: &[Block]) { | ||
let mut tmp = [Block::ZERO; 4]; | ||
children[3] = parent[1]; | ||
children[2] = parent[1]; | ||
children[1] = parent[0]; | ||
children[0] = parent[0]; | ||
|
||
tmp[3] = parent[1]; | ||
tmp[1] = parent[1]; | ||
tmp[2] = parent[0]; | ||
tmp[0] = parent[0]; | ||
|
||
AesEncryptor::para_encrypt::<2, 2>(&self.0, &mut tmp); | ||
|
||
children[3] ^= tmp[3]; | ||
children[2] ^= tmp[1]; | ||
children[1] ^= tmp[2]; | ||
children[0] ^= tmp[0]; | ||
} | ||
|
||
/// expand 4 to 8 | ||
// p[0] p[1] p[2] p[3] | ||
// c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] | ||
// t[0] t[4] t[1] t[5] t[2] t[6] t[3] t[7] | ||
#[inline(always)] | ||
pub fn expand_4to8(&self, children: &mut [Block], parent: &[Block]) { | ||
let mut tmp = [Block::ZERO; 8]; | ||
children[7] = parent[3]; | ||
children[6] = parent[3]; | ||
children[5] = parent[2]; | ||
children[4] = parent[2]; | ||
children[3] = parent[1]; | ||
children[2] = parent[1]; | ||
children[1] = parent[0]; | ||
children[0] = parent[0]; | ||
|
||
tmp[7] = parent[3]; | ||
tmp[3] = parent[3]; | ||
tmp[6] = parent[2]; | ||
tmp[2] = parent[2]; | ||
tmp[5] = parent[1]; | ||
tmp[1] = parent[1]; | ||
tmp[4] = parent[0]; | ||
tmp[0] = parent[0]; | ||
|
||
AesEncryptor::para_encrypt::<2, 4>(&self.0, &mut tmp); | ||
|
||
children[7] ^= tmp[7]; | ||
children[6] ^= tmp[3]; | ||
children[5] ^= tmp[6]; | ||
children[4] ^= tmp[2]; | ||
children[3] ^= tmp[5]; | ||
children[2] ^= tmp[1]; | ||
children[1] ^= tmp[4]; | ||
children[0] ^= tmp[0]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters