#![warn(clippy::unwrap_used)]
use std::{fmt::Debug, future::Future};
use cryprot_core::{Block, buf::Buf};
use cryprot_net::Connection;
use rand::{CryptoRng, Rng, distr, prelude::Distribution, rngs::StdRng};
use subtle::Choice;
pub mod adapter;
pub mod extension;
#[cfg(feature = "_ml-kem-base-ot")]
pub mod mlkem_ot;
pub mod noisy_vole;
pub mod phase;
pub mod silent_ot;
pub mod simplest_ot;
#[cfg(feature = "_ml-kem-base-ot")]
pub type BaseOt = mlkem_ot::MlKemOt;
#[cfg(not(feature = "_ml-kem-base-ot"))]
pub type BaseOt = simplest_ot::SimplestOt;
#[cfg(feature = "_ml-kem-base-ot")]
pub type BaseOtError = mlkem_ot::Error;
#[cfg(not(feature = "_ml-kem-base-ot"))]
pub type BaseOtError = simplest_ot::Error;
pub trait Connected {
fn connection(&mut self) -> &mut Connection;
}
impl<C: Connected> Connected for &mut C {
fn connection(&mut self) -> &mut Connection {
(*self).connection()
}
}
pub trait RotSender: Connected + Send {
type Error;
fn send(
&mut self,
count: usize,
) -> impl Future<Output = Result<Vec<[Block; 2]>, Self::Error>> + Send {
async move {
let mut ots = Vec::zeroed(count);
self.send_into(&mut ots).await?;
Ok(ots)
}
}
fn send_into(
&mut self,
ots: &mut impl Buf<[Block; 2]>,
) -> impl Future<Output = Result<(), Self::Error>> + Send;
}
pub trait RotReceiver: Connected + Send {
type Error;
fn receive(
&mut self,
choices: &[Choice],
) -> impl Future<Output = Result<Vec<Block>, Self::Error>> + Send {
async {
let mut ots = Vec::zeroed(choices.len());
self.receive_into(&mut ots, choices).await?;
Ok(ots)
}
}
fn receive_into(
&mut self,
ots: &mut impl Buf<Block>,
choices: &[Choice],
) -> impl Future<Output = Result<(), Self::Error>> + Send;
}
impl<S: RotSender> RotSender for &mut S {
type Error = S::Error;
fn send_into(
&mut self,
ots: &mut impl Buf<[Block; 2]>,
) -> impl Future<Output = Result<(), Self::Error>> + Send {
(*self).send_into(ots)
}
}
impl<R: RotReceiver> RotReceiver for &mut R {
type Error = R::Error;
fn receive_into(
&mut self,
ots: &mut impl Buf<Block>,
choices: &[Choice],
) -> impl Future<Output = Result<(), Self::Error>> + Send {
(*self).receive_into(ots, choices)
}
}
pub trait RandChoiceRotSender {}
pub trait RandChoiceRotReceiver: Connected + Send {
type Error;
fn rand_choice_receive(
&mut self,
count: usize,
) -> impl Future<Output = Result<(Vec<Block>, Vec<Choice>), Self::Error>> + Send {
async move {
let mut ots = Vec::zeroed(count);
let choices = self.rand_choice_receive_into(&mut ots).await?;
Ok((ots, choices))
}
}
fn rand_choice_receive_into(
&mut self,
ots: &mut impl Buf<Block>,
) -> impl Future<Output = Result<Vec<Choice>, Self::Error>> + Send;
}
impl<R: RotReceiver> RandChoiceRotReceiver for R {
type Error = R::Error;
async fn rand_choice_receive_into(
&mut self,
ots: &mut impl Buf<Block>,
) -> Result<Vec<Choice>, Self::Error> {
let choices = random_choices(ots.len(), &mut rand::make_rng::<StdRng>());
self.receive_into(ots, &choices).await?;
Ok(choices)
}
}
pub trait CotSender: Connected + Send {
type Error;
fn correlated_send<F>(
&mut self,
count: usize,
correlation: F,
) -> impl Future<Output = Result<Vec<Block>, Self::Error>> + Send
where
F: FnMut(usize) -> Block + Send,
{
async move {
let mut ots = Vec::zeroed(count);
self.correlated_send_into(&mut ots, correlation).await?;
Ok(ots)
}
}
fn correlated_send_into<B, F>(
&mut self,
ots: &mut B,
correlation: F,
) -> impl Future<Output = Result<(), Self::Error>> + Send
where
B: Buf<Block>,
F: FnMut(usize) -> Block + Send;
}
pub trait CotReceiver: Connected + Send {
type Error;
fn correlated_receive(
&mut self,
choices: &[Choice],
) -> impl Future<Output = Result<Vec<Block>, Self::Error>> + Send {
async {
let mut ots = Vec::zeroed(choices.len());
self.correlated_receive_into(&mut ots, choices).await?;
Ok(ots)
}
}
fn correlated_receive_into<B>(
&mut self,
ots: &mut B,
choices: &[Choice],
) -> impl Future<Output = Result<(), Self::Error>> + Send
where
B: Buf<Block>;
}
pub trait SemiHonest {}
pub trait Malicious: SemiHonest {}
pub trait Security: Send + Sync + Debug + Copy + Clone + private::Sealed {
const MALICIOUS_SECURITY: bool;
}
#[derive(Copy, Clone, Debug)]
pub struct SemiHonestMarker;
impl Security for SemiHonestMarker {
const MALICIOUS_SECURITY: bool = false;
}
#[derive(Copy, Clone, Debug)]
pub struct MaliciousMarker;
impl Security for MaliciousMarker {
const MALICIOUS_SECURITY: bool = true;
}
mod private {
pub trait Sealed {}
impl Sealed for super::SemiHonestMarker {}
impl Sealed for super::MaliciousMarker {}
}
pub fn random_choices<RNG: Rng + CryptoRng>(count: usize, rng: &mut RNG) -> Vec<Choice> {
let uniform = distr::Uniform::new(0, 2).expect("correct range");
uniform
.sample_iter(rng)
.take(count)
.map(Choice::from)
.collect()
}