use bitvec::vec::BitVec;
use clap::Parser;
use rand::{distributions, Rng};
use rand_core::OsRng;
use seec_channel::sub_channel;
use std::time::Duration;
use tokio::time::Instant;
use zappot::base_ot::{Receiver, Sender};
use zappot::traits::{BaseROTReceiver, BaseROTSender};
use zappot::util::Block;
#[derive(Parser, Debug, Clone)]
struct Args {
#[clap(short, long, default_value_t = 128)]
num_ots: usize,
#[clap(short, long, default_value_t = 8066)]
port: u16,
}
async fn sender(args: Args) -> Vec<[Block; 2]> {
let mut rng = OsRng;
let mut sender = Sender::new();
let (mut base_sender, _, mut base_receiver, _) =
seec_channel::tcp::listen::<seec_channel::Sender<_>>(("127.0.0.1", args.port))
.await
.expect("Error listening for channel connection");
let (ch_sender, mut ch_receiver) = sub_channel(&mut base_sender, &mut base_receiver, 8)
.await
.expect("Establishing sub channel");
sender
.send_random(args.num_ots, &mut rng, &ch_sender, &mut ch_receiver)
.await
.expect("Failed to generate ROTs")
}
async fn receiver(args: Args) -> (Vec<Block>, BitVec) {
let mut rng = OsRng;
let mut receiver = Receiver::new();
let (mut base_sender, _, mut base_receiver, _) =
seec_channel::tcp::connect::<seec_channel::Sender<_>>(("127.0.0.1", args.port))
.await
.expect("Error listening for channel connection");
let (ch_sender, mut ch_receiver) = sub_channel(&mut base_sender, &mut base_receiver, 8)
.await
.expect("Establishing sub channel");
let choices: BitVec = rng
.sample_iter::<bool, _>(distributions::Standard)
.take(args.num_ots)
.collect();
let ots = receiver
.receive_random(&choices, &mut rng, &ch_sender, &mut ch_receiver)
.await
.expect("Failed to generate ROTs");
(ots, choices)
}
#[tokio::main]
async fn main() {
let args: Args = Args::parse();
let now = Instant::now();
let sender_fut = tokio::spawn(sender(args.clone()));
tokio::time::sleep(Duration::from_millis(50)).await;
let (receiver_ots, choices) = tokio::spawn(receiver(args.clone()))
.await
.expect("Error await receiver");
let sender_ots = sender_fut.await.expect("Error awaiting sender");
println!(
"Executed {} ots in {} ms",
args.num_ots,
now.elapsed().as_millis()
);
for ((recv, choice), [send1, send2]) in receiver_ots.into_iter().zip(choices).zip(sender_ots) {
let [chosen, not_chosen] = if choice {
[send2, send1]
} else {
[send1, send2]
};
assert_eq!(recv, chosen);
assert_ne!(recv, not_chosen);
}
}