Skip to content

Commit

Permalink
WIP: Adapting mpz-ole to new OT traits...
Browse files Browse the repository at this point in the history
  • Loading branch information
th4s committed Mar 7, 2024
1 parent 0aa9250 commit ca1e22d
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 217 deletions.
63 changes: 12 additions & 51 deletions ole/mpz-ole/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
#![deny(clippy::all)]

use async_trait::async_trait;
use mpz_core::ProtocolMessage;
use mpz_ole_core::OLECoreError;
use mpz_ot::OTError;
use mpz_share_conversion_core::fields::Field;
use msg::{OLEeMessageError, ROLEeMessageError};
use std::{error::Error, fmt::Debug};
use utils_aio::{sink::IoSink, stream::IoStream};

pub mod ideal;
pub mod msg;
Expand All @@ -32,14 +30,14 @@ pub enum OLEError {
Message(Box<dyn Error + Send + 'static>),
}

impl<T: Debug + Send + 'static, F: Field> From<OLEeMessageError<T, F>> for OLEError {
fn from(value: OLEeMessageError<T, F>) -> Self {
impl<F: Field> From<OLEeMessageError<F>> for OLEError {
fn from(value: OLEeMessageError<F>) -> Self {
OLEError::Message(Box::new(value) as Box<dyn Error + Send + 'static>)
}
}

impl<T: Debug + Send + 'static, F: Field> From<ROLEeMessageError<T, F>> for OLEError {
fn from(value: ROLEeMessageError<T, F>) -> Self {
impl<F: Field> From<ROLEeMessageError<F>> for OLEError {
fn from(value: ROLEeMessageError<F>) -> Self {
OLEError::Message(Box::new(value) as Box<dyn Error + Send + 'static>)
}
}
Expand All @@ -50,103 +48,66 @@ impl<T: Debug + Send + 'static, F: Field> From<ROLEeMessageError<T, F>> for OLEE
/// which depend on the inputs of [`OLEeProvide`]. The evaluator can introduce additive errors to
/// the evaluation.
#[async_trait]
pub trait OLEeEvaluate<F: Field>: ProtocolMessage {
pub trait OLEeEvaluate<F: Field> {
/// Evaluates linear functions at specific points obliviously.
///
/// The functions being evaluated are outputs_k = inputs_k * provider-factors_k +
/// provider-offsets_k. Returns the outputs of the functions.
///
/// # Arguments
///
/// * `sink` - The IO sink to the provider.
/// * `stream` - The IO stream from the provider.
/// * `inputs` - The points where to evaluate the functions.
async fn evaluate<
Si: IoSink<Self::Msg> + Send + Unpin,
St: IoStream<Self::Msg> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
inputs: Vec<F>,
) -> Result<Vec<F>, OLEError>;
async fn evaluate(&mut self, inputs: Vec<F>) -> Result<Vec<F>, OLEError>;
}

/// An OLE with errors provider.
///
/// The provider determines with his inputs which linear functions are to be evaluated by
/// [`OLEeEvaluate`]. The provider can introduce additive errors to the evaluation.
#[async_trait]
pub trait OLEeProvide<F: Field>: ProtocolMessage {
pub trait OLEeProvide<F: Field> {
/// Provides the linear functions which are to be evaluated obliviously.
///
/// The functions being evaluated are evaluator-outputs_k = evaluator-inputs_k * factors_k +
/// offsets_k. Returns the offsets of the functions.
///
/// # Arguments
///
/// * `sink` - The IO sink to the evaluator.
/// * `stream` - The IO stream from the evaluator.
/// * `factors` - Provides the slopes for the linear functions.
async fn provide<Si: IoSink<Self::Msg> + Send + Unpin, St: IoStream<Self::Msg> + Send + Unpin>(
&mut self,
sink: &mut Si,
stream: &mut St,
factors: Vec<F>,
) -> Result<Vec<F>, OLEError>;
async fn provide(&mut self, factors: Vec<F>) -> Result<Vec<F>, OLEError>;
}

/// A random OLE with errors (ROLEe) evaluator.
///
/// The evaluator obliviously evaluates random linear functions at random values. The evaluator
/// can introduce additive errors to the evaluation.
#[async_trait]
pub trait RandomOLEeEvaluate<F: Field>: ProtocolMessage {
pub trait RandomOLEeEvaluate<F: Field> {
/// Evaluates random linear functions at random points obliviously.
///
/// The function being evaluated is outputs_k = random-inputs_k * random-factors_k +
/// random-offsets_k. Returns (random-inputs, outputs).
///
/// # Arguments
///
/// * `sink` - The IO sink to the provider.
/// * `stream` - The IO stream from the provider.
/// * `count` - The number of functions to evaluate.
async fn evaluate_random<
Si: IoSink<Self::Msg> + Send + Unpin,
St: IoStream<Self::Msg> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
count: usize,
) -> Result<(Vec<F>, Vec<F>), OLEError>;
async fn evaluate_random(&mut self, count: usize) -> Result<(Vec<F>, Vec<F>), OLEError>;
}

/// A random OLE with errors (ROLEe) provider.
///
/// The provider receives random linear functions. The provider can introduce additive errors to the evaluation.
#[async_trait]
pub trait RandomOLEeProvide<F: Field>: ProtocolMessage {
pub trait RandomOLEeProvide<F: Field> {
/// Provides the random functions which are to be evaluated obliviously.
///
/// The function being evaluated is evaluator-outputs_k = random-inputs_k * random-factors_k +
/// random-offsets_k. Returns (random-factors, random-offsets).
///
/// # Arguments
///
/// * `sink` - The IO sink to the evaluator.
/// * `stream` - The IO stream from the evaluator.
/// * `count` - The number of functions to provide.
async fn provide_random<
Si: IoSink<Self::Msg> + Send + Unpin,
St: IoStream<Self::Msg> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
count: usize,
) -> Result<(Vec<F>, Vec<F>), OLEError>;
async fn provide_random(&mut self, count: usize) -> Result<(Vec<F>, Vec<F>), OLEError>;
}

/// Workaround because of feature `generic_const_exprs` not available in stable.
Expand Down
16 changes: 6 additions & 10 deletions ole/mpz-ole/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, EnumTryAsInner, Serialize, Deserialize)]
#[derive_err(Debug)]
/// A message type for ROLEe protocols.
pub enum ROLEeMessage<T, F: Field> {
/// Messages of the random OT protocol.
RandomOTMessage(T),
pub enum ROLEeMessage<F: Field> {
/// Random field elements sent by the provider.
///
/// These are u_i and e_k.
Expand All @@ -20,26 +18,24 @@ pub enum ROLEeMessage<T, F: Field> {
RandomEvaluatorMsg(Vec<F>),
}

impl<T, F: Field> From<ROLEeMessageError<T, F>> for std::io::Error {
fn from(err: ROLEeMessageError<T, F>) -> Self {
impl<F: Field> From<ROLEeMessageError<F>> for std::io::Error {
fn from(err: ROLEeMessageError<F>) -> Self {
std::io::Error::new(std::io::ErrorKind::InvalidData, err.to_string())
}
}

#[derive(Debug, Clone, EnumTryAsInner, Serialize, Deserialize)]
#[derive_err(Debug)]
/// A message type for OLEe protocols.
pub enum OLEeMessage<T, F: Field> {
/// Messages of the underlying ROLEe protocol.
ROLEeMessage(T),
pub enum OLEeMessage<F: Field> {
/// Field elements sent by the provider.
ProviderDerand(Vec<F>),
/// Field elements sent by the evaluator.
EvaluatorDerand(Vec<F>),
}

impl<T, F: Field> From<OLEeMessageError<T, F>> for std::io::Error {
fn from(err: OLEeMessageError<T, F>) -> Self {
impl<F: Field> From<OLEeMessageError<F>> for std::io::Error {
fn from(err: OLEeMessageError<F>) -> Self {
std::io::Error::new(std::io::ErrorKind::InvalidData, err.to_string())
}
}
32 changes: 3 additions & 29 deletions ole/mpz-ole/src/ole/role/evaluator.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
use crate::{
msg::OLEeMessage,
ole::role::{into_role_sink, into_role_stream},
Check, OLEError, OLEeEvaluate, RandomOLEeEvaluate,
};
use crate::{msg::OLEeMessage, Check, OLEError, OLEeEvaluate, RandomOLEeEvaluate};
use async_trait::async_trait;
use futures::SinkExt;
use mpz_core::ProtocolMessage;
use mpz_ole_core::ole::role::OLEeEvaluator as OLEeCoreEvaluator;
use mpz_share_conversion_core::Field;
use utils_aio::{
Expand All @@ -32,34 +27,13 @@ impl<const N: usize, T: RandomOLEeEvaluate<F>, F: Field> OLEeEvaluator<N, T, F>
}
}

impl<const N: usize, T: RandomOLEeEvaluate<F>, F: Field> ProtocolMessage
for OLEeEvaluator<N, T, F>
{
type Msg = OLEeMessage<T::Msg, F>;
}

#[async_trait]
impl<const N: usize, T, F: Field> OLEeEvaluate<F> for OLEeEvaluator<N, T, F>
where
T: RandomOLEeEvaluate<F> + Send,
{
async fn evaluate<
Si: IoSink<Self::Msg> + Send + Unpin,
St: IoStream<Self::Msg> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
inputs: Vec<F>,
) -> Result<Vec<F>, OLEError> {
let (bk_dash, yk_dash) = self
.role_evaluator
.evaluate_random(
&mut into_role_sink(sink),
&mut into_role_stream(stream),
inputs.len(),
)
.await?;
async fn evaluate(&mut self, inputs: Vec<F>) -> Result<Vec<F>, OLEError> {
let (bk_dash, yk_dash) = self.role_evaluator.evaluate_random(inputs.len()).await?;

let vk: Vec<F> = self.ole_core.create_mask(&bk_dash, &inputs)?;

Expand Down
24 changes: 0 additions & 24 deletions ole/mpz-ole/src/ole/role/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,6 @@ mod provider;
pub use evaluator::OLEeEvaluator;
pub use provider::OLEeProvider;

use crate::msg::OLEeMessage;
use futures::{SinkExt, StreamExt};
use mpz_share_conversion_core::Field;
use utils_aio::{sink::IoSink, stream::IoStream};

/// Converts a sink of OLEe messages into a sink of ROLEe messsages.
fn into_role_sink<'a, Si: IoSink<OLEeMessage<T, F>> + Send + Unpin, T: Send + 'a, F: Field>(
sink: &'a mut Si,
) -> impl IoSink<T> + Send + Unpin + 'a {
Box::pin(SinkExt::with(sink, |msg| async move {
Ok(OLEeMessage::ROLEeMessage(msg))
}))
}

/// Converts a stream of OLEe messages into a stream of ROLEe messsages.
fn into_role_stream<'a, St: IoStream<OLEeMessage<T, F>> + Send + Unpin, T: Send + 'a, F: Field>(
stream: &'a mut St,
) -> impl IoStream<T> + Send + Unpin + 'a {
StreamExt::map(stream, |msg| match msg {
Ok(msg) => msg.try_into_rol_ee_message().map_err(From::from),
Err(err) => Err(err),
})
}

#[cfg(test)]
mod tests {
use super::{OLEeEvaluator, OLEeProvider};
Expand Down
30 changes: 3 additions & 27 deletions ole/mpz-ole/src/ole/role/provider.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
use crate::{
msg::OLEeMessage,
ole::role::{into_role_sink, into_role_stream},
Check, OLEError, OLEeProvide, RandomOLEeProvide,
};
use crate::{msg::OLEeMessage, Check, OLEError, OLEeProvide, RandomOLEeProvide};
use async_trait::async_trait;
use futures::SinkExt;
use mpz_core::ProtocolMessage;
use mpz_ole_core::ole::role::OLEeProvider as OLEeCoreProvider;
use mpz_share_conversion_core::Field;
use utils_aio::{
Expand All @@ -32,33 +27,14 @@ impl<const N: usize, T: RandomOLEeProvide<F>, F: Field> OLEeProvider<N, T, F> {
}
}

impl<const N: usize, T: RandomOLEeProvide<F>, F: Field> ProtocolMessage for OLEeProvider<N, T, F> {
type Msg = OLEeMessage<T::Msg, F>;
}

#[async_trait]
impl<const N: usize, T, F: Field> OLEeProvide<F> for OLEeProvider<N, T, F>
where
T: RandomOLEeProvide<F> + Send,
Self: Send,
{
async fn provide<
Si: IoSink<Self::Msg> + Send + Unpin,
St: IoStream<Self::Msg> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
factors: Vec<F>,
) -> Result<Vec<F>, OLEError> {
let (ak_dash, xk_dash) = self
.role_provider
.provide_random(
&mut into_role_sink(sink),
&mut into_role_stream(stream),
factors.len(),
)
.await?;
async fn provide(&mut self, factors: Vec<F>) -> Result<Vec<F>, OLEError> {
let (ak_dash, xk_dash) = self.role_provider.provide_random(factors.len()).await?;

let uk: Vec<F> = self.ole_core.create_mask(&ak_dash, &factors)?;

Expand Down
29 changes: 3 additions & 26 deletions ole/mpz-ole/src/role/rot/evaluator.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
use crate::{
msg::ROLEeMessage,
role::rot::{into_rot_sink, into_rot_stream},
Check, OLEError, RandomOLEeEvaluate,
};
use crate::{msg::ROLEeMessage, Check, OLEError, RandomOLEeEvaluate};
use async_trait::async_trait;
use futures::SinkExt;
use mpz_core::ProtocolMessage;
use mpz_ole_core::role::ot::ROLEeEvaluator as ROLEeCoreEvaluator;
use mpz_ot::RandomOTReceiver;
use mpz_share_conversion_core::Field;
Expand Down Expand Up @@ -33,34 +28,16 @@ impl<const N: usize, T: RandomOTReceiver<bool, [u8; N]>, F: Field> ROLEeEvaluato
}
}

impl<const N: usize, T: RandomOTReceiver<bool, [u8; N]>, F: Field> ProtocolMessage
for ROLEeEvaluator<N, T, F>
{
type Msg = ROLEeMessage<T::Msg, F>;
}

#[async_trait]
impl<const N: usize, T, F: Field> RandomOLEeEvaluate<F> for ROLEeEvaluator<N, T, F>
where
T: RandomOTReceiver<bool, [u8; N]> + Send,
Self: Send,
{
async fn evaluate_random<
Si: IoSink<Self::Msg> + Send + Unpin,
St: IoStream<Self::Msg> + Send + Unpin,
>(
&mut self,
sink: &mut Si,
stream: &mut St,
count: usize,
) -> Result<(Vec<F>, Vec<F>), OLEError> {
async fn evaluate_random(&mut self, count: usize) -> Result<(Vec<F>, Vec<F>), OLEError> {
let (fi, tfi): (Vec<bool>, Vec<[u8; N]>) = self
.rot_receiver
.receive_random(
&mut into_rot_sink(sink),
&mut into_rot_stream(stream),
count * F::BIT_SIZE as usize,
)
.receive_random(count * F::BIT_SIZE as usize)
.await?;

let (ui, ek): (Vec<F>, Vec<F>) =
Expand Down
24 changes: 0 additions & 24 deletions ole/mpz-ole/src/role/rot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,6 @@ mod provider;
pub use evaluator::ROLEeEvaluator;
pub use provider::ROLEeProvider;

use crate::msg::ROLEeMessage;
use futures::{SinkExt, StreamExt};
use mpz_share_conversion_core::Field;
use utils_aio::{sink::IoSink, stream::IoStream};

/// Converts a sink of ROLE messages into a sink of random OT messages.
fn into_rot_sink<'a, Si: IoSink<ROLEeMessage<T, F>> + Send + Unpin, T: Send + 'a, F: Field>(
sink: &'a mut Si,
) -> impl IoSink<T> + Send + Unpin + 'a {
Box::pin(SinkExt::with(sink, |msg| async move {
Ok(ROLEeMessage::RandomOTMessage(msg))
}))
}

/// Converts a stream of ROLE messages into a stream of random OT messages.
fn into_rot_stream<'a, St: IoStream<ROLEeMessage<T, F>> + Send + Unpin, T: Send + 'a, F: Field>(
stream: &'a mut St,
) -> impl IoStream<T> + Send + Unpin + 'a {
StreamExt::map(stream, |msg| match msg {
Ok(msg) => msg.try_into_random_ot_message().map_err(From::from),
Err(err) => Err(err),
})
}

#[cfg(test)]
mod tests {
use super::{ROLEeEvaluator, ROLEeProvider};
Expand Down
Loading

0 comments on commit ca1e22d

Please sign in to comment.