Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ferret with io #171

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/mpz-common/src/ideal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct Buffer {
}

/// The ideal functionality from the perspective of Alice.
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Alice<F> {
f: Arc<Mutex<F>>,
buffer: Arc<Mutex<Buffer>>,
Expand All @@ -35,7 +35,7 @@ impl<F> Clone for Alice<F> {

impl<F> Alice<F> {
/// Returns a lock to the ideal functionality.
pub fn get_mut(&mut self) -> MutexGuard<'_, F> {
pub fn lock(&self) -> MutexGuard<'_, F> {
self.f.lock().unwrap()
}

Expand Down Expand Up @@ -79,7 +79,7 @@ impl<F> Alice<F> {
}

/// The ideal functionality from the perspective of Bob.
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Bob<F> {
f: Arc<Mutex<F>>,
buffer: Arc<Mutex<Buffer>>,
Expand All @@ -96,7 +96,7 @@ impl<F> Clone for Bob<F> {

impl<F> Bob<F> {
/// Returns a lock to the ideal functionality.
pub fn get_mut(&mut self) -> MutexGuard<'_, F> {
pub fn lock(&self) -> MutexGuard<'_, F> {
self.f.lock().unwrap()
}

Expand Down
52 changes: 27 additions & 25 deletions crates/mpz-core/src/ggm_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,35 @@ impl GgmTree {
assert_eq!(k0.len(), self.depth);
assert_eq!(k1.len(), self.depth);
let mut buf = [Block::ZERO; 8];
self.tkprp.expand_1to2(tree, seed);
k0[0] = tree[0];
k1[0] = tree[1];
if self.depth > 1 {
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 {
k0[h] = Block::ZERO;
k1[h] = Block::ZERO;

// How many nodes there are in this layer
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];
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]);

tree[2 * i..2 * i + 8].copy_from_slice(&buf);
for h in 2..self.depth {
k0[h] = Block::ZERO;
k1[h] = Block::ZERO;

// How many nodes there are in this layer
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);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/mpz-ot-core/src/chou_orlandi/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl Receiver<state::Setup> {
let SenderPayload { id, payload } = payload;

// Check that the transfer id matches
let expected_id = current_id.next();
let expected_id = current_id.next_id();
if id != expected_id {
return Err(ReceiverError::IdMismatch(expected_id, id));
}
Expand Down
2 changes: 1 addition & 1 deletion crates/mpz-ot-core/src/chou_orlandi/sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl Sender<state::Setup> {
} = receiver_payload;

// Check that the transfer id matches
let expected_id = current_id.next();
let expected_id = current_id.next_id();
if id != expected_id {
return Err(SenderError::IdMismatch(expected_id, id));
}
Expand Down
68 changes: 27 additions & 41 deletions crates/mpz-ot-core/src/ferret/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
//! An implementation of the [`Ferret`](https://eprint.iacr.org/2020/924.pdf) protocol.

use mpz_core::lpn::LpnParameters;

pub mod cuckoo;
pub mod error;
pub mod mpcot;
Expand All @@ -19,44 +16,29 @@ pub const CUCKOO_HASH_NUM: usize = 3;
/// Trial numbers in Cuckoo hash insertion.
pub const CUCKOO_TRIAL_NUM: usize = 100;

/// LPN parameters with regular noise.
/// Derived from https://github.com/emp-toolkit/emp-ot/blob/master/emp-ot/ferret/constants.h
pub const LPN_PARAMETERS_REGULAR: LpnParameters = LpnParameters {
n: 10180608,
k: 124000,
t: 4971,
};

/// LPN parameters with uniform noise.
/// Derived from Table 2.
pub const LPN_PARAMETERS_UNIFORM: LpnParameters = LpnParameters {
n: 10616092,
k: 588160,
t: 1324,
};

/// The type of Lpn parameters.
#[derive(Debug)]
#[derive(Debug, Clone, Copy, Default)]
pub enum LpnType {
/// Uniform error distribution.
Uniform,
/// Regular error distribution.
#[default]
Regular,
}

#[cfg(test)]
mod tests {
use super::*;

use msgs::LpnMatrixSeed;
use receiver::Receiver;
use sender::Sender;

use crate::ideal::{cot::IdealCOT, mpcot::IdealMpcot};
use crate::test::assert_cot;
use crate::{MPCOTReceiverOutput, MPCOTSenderOutput, RCOTReceiverOutput, RCOTSenderOutput};
use crate::{
ideal::{cot::IdealCOT, mpcot::IdealMpcot},
test::assert_cot,
MPCOTReceiverOutput, MPCOTSenderOutput, RCOTReceiverOutput, RCOTSenderOutput,
};
use mpz_core::{lpn::LpnParameters, prg::Prg};
use rand::SeedableRng;

const LPN_PARAMETERS_TEST: LpnParameters = LpnParameters {
n: 9600,
Expand All @@ -66,7 +48,7 @@ mod tests {

#[test]
fn ferret_test() {
let mut prg = Prg::from_seed([1u8; 16].into());
let mut prg = Prg::new();
let delta = prg.random_block();
let mut ideal_cot = IdealCOT::default();
let mut ideal_mpcot = IdealMpcot::default();
Expand Down Expand Up @@ -101,18 +83,8 @@ mod tests {
)
.unwrap();

let LpnMatrixSeed {
seed: lpn_matrix_seed,
} = seed;

let mut sender = sender
.setup(
delta,
LPN_PARAMETERS_TEST,
LpnType::Regular,
lpn_matrix_seed,
&v,
)
.setup(delta, LPN_PARAMETERS_TEST, LpnType::Regular, seed, &v)
.unwrap();

// extend once
Expand All @@ -122,8 +94,15 @@ mod tests {
let (MPCOTSenderOutput { s, .. }, MPCOTReceiverOutput { r, .. }) =
ideal_mpcot.extend(&query.0, query.1);

let msgs = sender.extend(&s).unwrap();
let (choices, received) = receiver.extend(&r).unwrap();
sender.extend(s).unwrap();
receiver.extend(r).unwrap();

let RCOTSenderOutput { msgs, .. } = sender.consume(2).unwrap();
let RCOTReceiverOutput {
choices,
msgs: received,
..
} = receiver.consume(2).unwrap();

assert_cot(delta, &choices, &msgs, &received);

Expand All @@ -134,8 +113,15 @@ mod tests {
let (MPCOTSenderOutput { s, .. }, MPCOTReceiverOutput { r, .. }) =
ideal_mpcot.extend(&query.0, query.1);

let msgs = sender.extend(&s).unwrap();
let (choices, received) = receiver.extend(&r).unwrap();
sender.extend(s).unwrap();
receiver.extend(r).unwrap();

let RCOTSenderOutput { msgs, .. } = sender.consume(sender.remaining()).unwrap();
let RCOTReceiverOutput {
choices,
msgs: received,
..
} = receiver.consume(receiver.remaining()).unwrap();

assert_cot(delta, &choices, &msgs, &received);
}
Expand Down
5 changes: 2 additions & 3 deletions crates/mpz-ot-core/src/ferret/mpcot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ mod tests {
use crate::ideal::spcot::IdealSpcot;
use crate::{SPCOTReceiverOutput, SPCOTSenderOutput};
use mpz_core::prg::Prg;
use rand::SeedableRng;

#[test]
fn mpcot_general_test() {
let mut prg = Prg::from_seed([1u8; 16].into());
let mut prg = Prg::new();
let delta = prg.random_block();
let mut ideal_spcot = IdealSpcot::new_with_delta(delta);

Expand Down Expand Up @@ -96,7 +95,7 @@ mod tests {

#[test]
fn mpcot_regular_test() {
let mut prg = Prg::from_seed([2u8; 16].into());
let mut prg = Prg::new();
let delta = prg.random_block();
let mut ideal_spcot = IdealSpcot::new_with_delta(delta);

Expand Down
30 changes: 15 additions & 15 deletions crates/mpz-ot-core/src/ferret/mpcot/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ impl Receiver {
/// # Argument
///
/// * `hash_seed` - Random seed to generate hashes, will be sent to the sender.
pub fn setup(self, hash_seed: Block) -> (Receiver<state::PreExtension>, HashSeed) {
pub fn setup(self, hash_seed: Block) -> (Receiver<state::Extension>, HashSeed) {
let mut prg = Prg::from_seed(hash_seed);
let hashes = std::array::from_fn(|_| AesEncryptor::new(prg.random_block()));
let recv = Receiver {
state: state::PreExtension {
state: state::Extension {
counter: 0,
hashes: Arc::new(hashes),
},
Expand All @@ -48,7 +48,7 @@ impl Receiver {
}
}

impl Receiver<state::PreExtension> {
impl Receiver<state::Extension> {
/// Performs the hash procedure in MPCOT extension.
/// Outputs the length of each bucket plus 1.
///
Expand All @@ -63,7 +63,7 @@ impl Receiver<state::PreExtension> {
self,
alphas: &[u32],
n: u32,
) -> Result<(Receiver<state::Extension>, Vec<(usize, u32)>), ReceiverError> {
) -> Result<(Receiver<state::ExtensionInternal>, Vec<(usize, u32)>), ReceiverError> {
if alphas.len() as u32 > n {
return Err(ReceiverError::InvalidInput(
"length of alphas should not exceed n".to_string(),
Expand Down Expand Up @@ -104,7 +104,7 @@ impl Receiver<state::PreExtension> {
}

let receiver = Receiver {
state: state::Extension {
state: state::ExtensionInternal {
counter: self.state.counter,
m,
n,
Expand All @@ -117,7 +117,7 @@ impl Receiver<state::PreExtension> {
Ok((receiver, p))
}
}
impl Receiver<state::Extension> {
impl Receiver<state::ExtensionInternal> {
/// Performs MPCOT extension.
///
/// See Step 5 in Figure 7.
Expand All @@ -128,7 +128,7 @@ impl Receiver<state::Extension> {
pub fn extend(
self,
rt: &[Vec<Block>],
) -> Result<(Receiver<state::PreExtension>, Vec<Block>), ReceiverError> {
) -> Result<(Receiver<state::Extension>, Vec<Block>), ReceiverError> {
if rt.len() != self.state.m {
return Err(ReceiverError::InvalidInput(
"the length rt should be m".to_string(),
Expand Down Expand Up @@ -165,7 +165,7 @@ impl Receiver<state::Extension> {
}

let receiver = Receiver {
state: state::PreExtension {
state: state::Extension {
counter: self.state.counter + 1,
hashes: self.state.hashes,
},
Expand All @@ -182,8 +182,8 @@ pub mod state {
pub trait Sealed {}

impl Sealed for super::Initialized {}
impl Sealed for super::PreExtension {}
impl Sealed for super::Extension {}
impl Sealed for super::ExtensionInternal {}
}

/// The receiver's state.
Expand All @@ -200,20 +200,20 @@ pub mod state {
/// The receiver's state before extending.
///
/// In this state the receiver performs pre extension in MPCOT (potentially multiple times).
pub struct PreExtension {
pub struct Extension {
/// Current MPCOT counter
pub(super) counter: usize,
/// The hashes to generate Cuckoo hash table.
pub(super) hashes: Arc<[AesEncryptor; CUCKOO_HASH_NUM]>,
}

impl State for PreExtension {}
impl State for Extension {}

opaque_debug::implement!(PreExtension);
opaque_debug::implement!(Extension);
/// The receiver's state of extension.
///
/// In this state the receiver performs MPCOT extension (potentially multiple times).
pub struct Extension {
pub struct ExtensionInternal {
/// Current MPCOT counter
pub(super) counter: usize,
/// Current length of Cuckoo hash table, will possibly be changed in each extension.
Expand All @@ -228,7 +228,7 @@ pub mod state {
pub(super) buckets_length: Vec<usize>,
}

impl State for Extension {}
impl State for ExtensionInternal {}

opaque_debug::implement!(Extension);
opaque_debug::implement!(ExtensionInternal);
}
Loading
Loading