Skip to content

Commit

Permalink
OTSetup trait (#52)
Browse files Browse the repository at this point in the history
* add OTSetup trait and impl for CO

* implement OT setup

* add base OT setup into sender

* perform cointoss before base ot setup
  • Loading branch information
sinui0 committed Aug 30, 2023
1 parent 1e32eaa commit 1cae1bc
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 115 deletions.
2 changes: 1 addition & 1 deletion ot/mpz-ot/benches/ot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use futures_util::StreamExt;
use mpz_core::Block;
use mpz_ot::{
chou_orlandi::{Receiver, ReceiverConfig, Sender, SenderConfig},
OTReceiver, OTSender,
OTReceiver, OTSender, OTSetup,
};
use utils_aio::duplex::MemoryDuplex;

Expand Down
6 changes: 3 additions & 3 deletions ot/mpz-ot/src/chou_orlandi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! ```
//! use utils_aio::duplex::MemoryDuplex;
//! use mpz_ot::chou_orlandi::{Receiver, Sender, SenderConfig, ReceiverConfig};
//! use mpz_ot::{OTReceiver, OTSender};
//! use mpz_ot::{OTReceiver, OTSender, OTSetup};
//! use mpz_core::Block;
//! use futures::StreamExt;
//!
Expand Down Expand Up @@ -54,7 +54,7 @@
//! ```
//! use utils_aio::duplex::MemoryDuplex;
//! use mpz_ot::chou_orlandi::{Receiver, Sender, SenderConfig, ReceiverConfig};
//! use mpz_ot::{OTReceiver, OTSender, CommittedOTReceiver, VerifiableOTSender};
//! use mpz_ot::{OTReceiver, OTSender, CommittedOTReceiver, VerifiableOTSender, OTSetup};
//! use mpz_core::Block;
//! use futures::StreamExt;
//!
Expand Down Expand Up @@ -128,7 +128,7 @@ mod tests {
use rand_core::SeedableRng;
use utils_aio::{duplex::MemoryDuplex, sink::IoSink, stream::IoStream};

use crate::{CommittedOTReceiver, OTReceiver, OTSender, VerifiableOTSender};
use crate::{CommittedOTReceiver, OTReceiver, OTSender, OTSetup, VerifiableOTSender};

use super::*;
use rstest::*;
Expand Down
33 changes: 21 additions & 12 deletions ot/mpz-ot/src/chou_orlandi/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use utils_aio::{
stream::{ExpectStreamExt, IoStream},
};

use crate::{CommittedOTReceiver, OTError, OTReceiver};
use crate::{CommittedOTReceiver, OTError, OTReceiver, OTSetup};

use super::ReceiverError;

Expand Down Expand Up @@ -71,26 +71,31 @@ impl Receiver {
cointoss_payload: None,
}
}
}

/// Sets up the receiver.
///
/// # Arguments
///
/// * `sink` - The sink to send messages to the sender
/// * `stream` - The stream to receive messages from the sender
pub async fn setup<Si: IoSink<Message> + Send + Unpin, St: IoStream<Message> + Send + Unpin>(
#[async_trait]
impl OTSetup for Receiver {
async fn setup<Si: IoSink<Message> + Send + Unpin, St: IoStream<Message> + Send + Unpin>(
&mut self,
sink: &mut Si,
stream: &mut St,
) -> Result<(), ReceiverError> {
let (config, seed) = self.state.replace(State::Error).into_initialized()?;
) -> Result<(), OTError> {
if self.state.is_setup() {
return Ok(());
}

let (config, seed) = self
.state
.replace(State::Error)
.into_initialized()
.map_err(ReceiverError::from)?;

// If the receiver is committed, we generate the seed using a cointoss.
let receiver = if config.receiver_commit() {
if seed.is_some() {
return Err(ReceiverError::InvalidConfig(
"committed receiver seed must be generated using coin toss".to_string(),
));
))?;
}

let (seed, cointoss_payload) = execute_cointoss(sink, stream).await?;
Expand All @@ -102,7 +107,11 @@ impl Receiver {
ReceiverCore::new_with_seed(config, seed.unwrap_or_else(|| thread_rng().gen()))
};

let sender_setup = stream.expect_next().await?.into_sender_setup()?;
let sender_setup = stream
.expect_next()
.await?
.into_sender_setup()
.map_err(ReceiverError::from)?;

let receiver = Backend::spawn(move || receiver.setup(sender_setup)).await;

Expand Down
25 changes: 15 additions & 10 deletions ot/mpz-ot/src/chou_orlandi/sender.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{chou_orlandi::SenderError, OTError, OTSender, VerifiableOTSender};
use crate::{chou_orlandi::SenderError, OTError, OTSender, OTSetup, VerifiableOTSender};

use async_trait::async_trait;
use futures_util::SinkExt;
Expand Down Expand Up @@ -63,19 +63,24 @@ impl Sender {
cointoss_receiver: None,
}
}
}

/// Sets up the Sender.
///
/// # Arguments
///
/// * `sink` - The sink to send messages to the receiver
/// * `stream` - The stream to receive messages from the receiver
pub async fn setup<Si: IoSink<Message> + Send + Unpin, St: IoStream<Message> + Send + Unpin>(
#[async_trait]
impl OTSetup for Sender {
async fn setup<Si: IoSink<Message> + Send + Unpin, St: IoStream<Message> + Send + Unpin>(
&mut self,
sink: &mut Si,
stream: &mut St,
) -> Result<(), SenderError> {
let sender = self.state.replace(State::Error).into_initialized()?;
) -> Result<(), OTError> {
if self.state.is_setup() {
return Ok(());
}

let sender = self
.state
.replace(State::Error)
.into_initialized()
.map_err(SenderError::from)?;

// If the receiver is committed, we run the cointoss protocol
if sender.config().receiver_commit() {
Expand Down
2 changes: 1 addition & 1 deletion ot/mpz-ot/src/kos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ mod tests {

use crate::{
mock::{mock_ot_pair, MockOTReceiver, MockOTSender},
CommittedOTSender, OTReceiver, OTSender, VerifiableOTReceiver,
CommittedOTSender, OTReceiver, OTSender, OTSetup, VerifiableOTReceiver,
};

#[fixture]
Expand Down
113 changes: 65 additions & 48 deletions ot/mpz-ot/src/kos/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use utils_aio::{
stream::{ExpectStreamExt, IoStream},
};

use crate::{OTError, OTReceiver, OTSender, VerifiableOTReceiver, VerifiableOTSender};
use crate::{OTError, OTReceiver, OTSender, OTSetup, VerifiableOTReceiver, VerifiableOTSender};

use super::{into_base_sink, into_base_stream, ReceiverError, ReceiverVerifyError};

Expand Down Expand Up @@ -65,53 +65,6 @@ where
Ok(self.state.as_extension()?.remaining())
}

/// Performs the base OT setup.
///
/// # Arguments
///
/// * `sink` - The sink to send messages to the base OT receiver
/// * `stream` - The stream to receive messages from the base OT receiver
pub async fn setup<
Si: IoSink<Message<BaseOT::Msg>> + Send + Unpin,
St: IoStream<Message<BaseOT::Msg>> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
) -> Result<(), ReceiverError> {
let ext_receiver = self.state.replace(State::Error).into_initialized()?;

// If the sender is committed, we run a cointoss
if ext_receiver.config().sender_commit() {
let commitment = stream.expect_next().await?.into_cointoss_commit()?;

let (cointoss_receiver, payload) =
cointoss::Receiver::new(vec![thread_rng().gen()]).reveal(commitment)?;

sink.send(Message::CointossReceiverPayload(payload)).await?;

self.cointoss_receiver = Some(cointoss_receiver);
}

let mut rng = thread_rng();
let seeds: [[Block; 2]; CSP] = std::array::from_fn(|_| [rng.gen(), rng.gen()]);

// Send seeds to sender
self.base
.send(
&mut into_base_sink(sink),
&mut into_base_stream(stream),
&seeds,
)
.await?;

let ext_receiver = ext_receiver.setup(seeds);

self.state = State::Extension(Box::new(ext_receiver));

Ok(())
}

/// Performs OT extension.
///
/// # Arguments
Expand Down Expand Up @@ -188,6 +141,70 @@ where
type Msg = Message<BaseOT::Msg>;
}

#[async_trait]
impl<BaseOT> OTSetup for Receiver<BaseOT>
where
BaseOT: OTSetup + OTSender<[Block; 2]> + Send,
{
async fn setup<
Si: IoSink<Message<BaseOT::Msg>> + Send + Unpin,
St: IoStream<Message<BaseOT::Msg>> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
) -> Result<(), OTError> {
if self.state.is_extension() {
return Ok(());
}

let ext_receiver = self
.state
.replace(State::Error)
.into_initialized()
.map_err(ReceiverError::from)?;

// If the sender is committed, we run a cointoss
if ext_receiver.config().sender_commit() {
let commitment = stream
.expect_next()
.await?
.into_cointoss_commit()
.map_err(ReceiverError::from)?;

let (cointoss_receiver, payload) = cointoss::Receiver::new(vec![thread_rng().gen()])
.reveal(commitment)
.map_err(ReceiverError::from)?;

sink.send(Message::CointossReceiverPayload(payload)).await?;

self.cointoss_receiver = Some(cointoss_receiver);
}

// Set up base OT if not already done
self.base
.setup(&mut into_base_sink(sink), &mut into_base_stream(stream))
.await?;

let seeds: [[Block; 2]; CSP] = std::array::from_fn(|_| thread_rng().gen());

// Send seeds to sender
self.base
.send(
&mut into_base_sink(sink),
&mut into_base_stream(stream),
&seeds,
)
.await?;

let ext_receiver = ext_receiver.setup(seeds);

self.state = State::Extension(Box::new(ext_receiver));

Ok(())
}
}

#[async_trait]
impl<BaseOT> OTReceiver<bool, Block> for Receiver<BaseOT>
where
Expand Down
97 changes: 59 additions & 38 deletions ot/mpz-ot/src/kos/sender.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
kos::SenderError, CommittedOTReceiver, CommittedOTSender, OTError, OTReceiver, OTSender,
OTSetup,
};

use async_trait::async_trait;
Expand Down Expand Up @@ -65,44 +66,6 @@ where
Ok(self.state.as_extension()?.remaining())
}

/// Performs the base OT setup using a random delta.
///
/// # Arguments
///
/// * `sink` - The sink to send messages to the base OT sender
/// * `stream` - The stream to receive messages from the base OT sender
pub async fn setup<
Si: IoSink<Message<BaseOT::Msg>> + Send + Unpin,
St: IoStream<Message<BaseOT::Msg>> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
) -> Result<(), SenderError> {
// If the sender is committed, we sample delta using a cointoss.
let delta = if self.state.as_initialized()?.config().sender_commit() {
let (cointoss_sender, commitment) =
cointoss::Sender::new(vec![thread_rng().gen()]).send();

sink.send(Message::CointossCommit(commitment)).await?;
let payload = stream
.expect_next()
.await?
.into_cointoss_receiver_payload()?;

let (seeds, payload) = cointoss_sender.finalize(payload)?;

// Store the payload to reveal to the receiver later.
self.cointoss_payload = Some(payload);

seeds[0]
} else {
Block::random(&mut thread_rng())
};

self._setup_with_delta(sink, stream, delta).await
}

/// Performs the base OT setup with the provided delta.
///
/// # Arguments
Expand Down Expand Up @@ -233,6 +196,64 @@ where
type Msg = Message<BaseOT::Msg>;
}

#[async_trait]
impl<BaseOT> OTSetup for Sender<BaseOT>
where
BaseOT: OTSetup + OTReceiver<bool, Block> + Send,
{
async fn setup<
Si: IoSink<Message<BaseOT::Msg>> + Send + Unpin,
St: IoStream<Message<BaseOT::Msg>> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
) -> Result<(), OTError> {
if self.state.is_extension() {
return Ok(());
}

// If the sender is committed, we sample delta using a cointoss.
let delta = if self
.state
.as_initialized()
.map_err(SenderError::from)?
.config()
.sender_commit()
{
let (cointoss_sender, commitment) =
cointoss::Sender::new(vec![thread_rng().gen()]).send();

sink.send(Message::CointossCommit(commitment)).await?;
let payload = stream
.expect_next()
.await?
.into_cointoss_receiver_payload()
.map_err(SenderError::from)?;

let (seeds, payload) = cointoss_sender
.finalize(payload)
.map_err(SenderError::from)?;

// Store the payload to reveal to the receiver later.
self.cointoss_payload = Some(payload);

seeds[0]
} else {
Block::random(&mut thread_rng())
};

// Set up base OT if not already done
self.base
.setup(&mut into_base_sink(sink), &mut into_base_stream(stream))
.await?;

self._setup_with_delta(sink, stream, delta)
.await
.map_err(OTError::from)
}
}

#[async_trait]
impl<BaseOT> OTSender<[Block; 2]> for Sender<BaseOT>
where
Expand Down
Loading

0 comments on commit 1cae1bc

Please sign in to comment.