Skip to content

Commit

Permalink
fix(mpz-ot): Ideal RCOT (#131)
Browse files Browse the repository at this point in the history
* delete obsolete module

* export test-utils and add ideal COT tests
  • Loading branch information
sinui0 authored May 13, 2024
1 parent 4064907 commit 94a8c3a
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 165 deletions.
3 changes: 2 additions & 1 deletion crates/mpz-ot-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ workspace = true
name = "mpz_ot_core"

[features]
default = ["rayon"]
default = ["rayon", "test-utils"]
rayon = ["dep:rayon", "itybity/rayon", "blake3/rayon"]
test-utils = []

[dependencies]
mpz-core.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions crates/mpz-ot-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ pub mod ferret;
pub mod ideal;
pub mod kos;
pub mod msgs;
#[cfg(test)]
pub(crate) mod test;
#[cfg(any(test, feature = "test-utils"))]
pub mod test;

/// An oblivious transfer identifier.
///
Expand Down
6 changes: 4 additions & 2 deletions crates/mpz-ot-core/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! OT test utilities.
use mpz_core::Block;

/// Asserts the correctness of correlated oblivious transfer.
pub(crate) fn assert_cot(delta: Block, choices: &[bool], msgs: &[Block], received: &[Block]) {
pub fn assert_cot(delta: Block, choices: &[bool], msgs: &[Block], received: &[Block]) {
assert!(choices.into_iter().zip(msgs.into_iter().zip(received)).all(
|(&choice, (&msg, &received))| {
if choice {
Expand All @@ -14,7 +16,7 @@ pub(crate) fn assert_cot(delta: Block, choices: &[bool], msgs: &[Block], receive
}

/// Asserts the correctness of random oblivious transfer.
pub(crate) fn assert_rot<T: Copy + PartialEq>(choices: &[bool], msgs: &[[T; 2]], received: &[T]) {
pub fn assert_rot<T: Copy + PartialEq>(choices: &[bool], msgs: &[[T; 2]], received: &[T]) {
assert!(choices.into_iter().zip(msgs.into_iter().zip(received)).all(
|(&choice, (&msg, &received))| {
if choice {
Expand Down
1 change: 1 addition & 0 deletions crates/mpz-ot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ cfg-if.workspace = true

[dev-dependencies]
mpz-common = { workspace = true, features = ["test-utils", "ideal"] }
mpz-ot-core = { workspace = true, features = ["test-utils"] }
rstest = { workspace = true }
criterion = { workspace = true, features = ["async_tokio"] }
tokio = { workspace = true, features = [
Expand Down
86 changes: 85 additions & 1 deletion crates/mpz-ot/src/ideal/cot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use mpz_ot_core::{
ideal::cot::IdealCOT, COTReceiverOutput, COTSenderOutput, RCOTReceiverOutput, RCOTSenderOutput,
};

use crate::{COTReceiver, COTSender, OTError, OTSetup, RandomCOTReceiver};
use crate::{COTReceiver, COTSender, OTError, OTSetup, RandomCOTReceiver, RandomCOTSender};

fn cot(
f: &mut IdealCOT,
Expand Down Expand Up @@ -70,6 +70,17 @@ impl<Ctx: Context> COTSender<Ctx, Block> for IdealCOTSender {
}
}

#[async_trait]
impl<Ctx: Context> RandomCOTSender<Ctx, Block> for IdealCOTSender {
async fn send_random_correlated(
&mut self,
ctx: &mut Ctx,
count: usize,
) -> Result<RCOTSenderOutput<Block>, OTError> {
Ok(self.0.call(ctx, count, rcot).await)
}
}

/// Ideal OT receiver.
#[derive(Debug, Clone)]
pub struct IdealCOTReceiver(Bob<IdealCOT>);
Expand Down Expand Up @@ -105,3 +116,76 @@ impl<Ctx: Context> RandomCOTReceiver<Ctx, bool, Block> for IdealCOTReceiver {
Ok(self.0.call(ctx, count, rcot).await)
}
}

#[cfg(test)]
mod tests {
use super::*;
use mpz_common::executor::test_st_executor;
use mpz_ot_core::test::assert_cot;
use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha12Rng;

#[tokio::test]
async fn test_ideal_cot() {
let mut rng = ChaCha12Rng::seed_from_u64(0);
let (mut ctx_a, mut ctx_b) = test_st_executor(8);
let (mut alice, mut bob) = ideal_cot();

let delta = alice.0.get_mut().delta();

let count = 10;
let choices = (0..count).map(|_| rng.gen()).collect::<Vec<bool>>();

let (
COTSenderOutput {
id: id_a,
msgs: sender_msgs,
},
COTReceiverOutput {
id: id_b,
msgs: receiver_msgs,
},
) = tokio::try_join!(
alice.send_correlated(&mut ctx_a, count),
bob.receive_correlated(&mut ctx_b, &choices)
)
.unwrap();

assert_eq!(id_a, id_b);
assert_eq!(count, sender_msgs.len());
assert_eq!(count, receiver_msgs.len());
assert_cot(delta, &choices, &sender_msgs, &receiver_msgs);
}

#[tokio::test]
async fn test_ideal_rcot() {
let (mut ctx_a, mut ctx_b) = test_st_executor(8);
let (mut alice, mut bob) = ideal_rcot();

let delta = alice.0.get_mut().delta();

let count = 10;

let (
RCOTSenderOutput {
id: id_a,
msgs: sender_msgs,
},
RCOTReceiverOutput {
id: id_b,
choices,
msgs: receiver_msgs,
},
) = tokio::try_join!(
alice.send_random_correlated(&mut ctx_a, count),
bob.receive_random_correlated(&mut ctx_b, count)
)
.unwrap();

assert_eq!(id_a, id_b);
assert_eq!(count, sender_msgs.len());
assert_eq!(count, receiver_msgs.len());
assert_eq!(count, choices.len());
assert_cot(delta, &choices, &sender_msgs, &receiver_msgs);
}
}
158 changes: 0 additions & 158 deletions crates/mpz-ot/src/ideal/rcot.rs

This file was deleted.

20 changes: 19 additions & 1 deletion crates/mpz-ot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use mpz_common::Context;

pub use mpz_ot_core::{
COTReceiverOutput, COTSenderOutput, OTReceiverOutput, OTSenderOutput, RCOTReceiverOutput,
ROTReceiverOutput, ROTSenderOutput, TransferId,
RCOTSenderOutput, ROTReceiverOutput, ROTSenderOutput, TransferId,
};

/// An oblivious transfer error.
Expand Down Expand Up @@ -96,6 +96,24 @@ pub trait RandomOTSender<Ctx, T> {
) -> Result<ROTSenderOutput<T>, OTError>;
}

/// A random correlated oblivious transfer sender.
#[async_trait]
pub trait RandomCOTSender<Ctx, T> {
/// Obliviously transfers the correlated messages to the receiver.
///
/// Returns the `0`-bit messages that were obliviously transferred.
///
/// # Arguments
///
/// * `ctx` - The thread context.
/// * `count` - The number of correlated messages to obliviously transfer.
async fn send_random_correlated(
&mut self,
ctx: &mut Ctx,
count: usize,
) -> Result<RCOTSenderOutput<T>, OTError>;
}

/// An oblivious transfer receiver.
#[async_trait]
pub trait OTReceiver<Ctx, T, U> {
Expand Down

0 comments on commit 94a8c3a

Please sign in to comment.