use crate::utils::test_utils::fan_in_inboxes;
use ark_ff::PrimeField;
use ark_std::rand::Rng;
use ark_std::test_rng;
use num_integer::binomial;
use std::sync::Arc;
use stoffelcrypto::common::{SecretSharingScheme, RBC};
use stoffelcrypto::honeybadger::fpmul::truncpr::TruncPrNode;
use stoffelcrypto::honeybadger::robust_interpolate::robust_interpolate::RobustShare;
use stoffelcrypto::honeybadger::{SessionId, WrappedMessage};
use stoffelmpc_network::fake_network::{FakeNetwork, SenderId};
use tokio::sync::mpsc::Receiver;
use tokio::task::JoinSet;
use tracing::{error, warn};
pub async fn spawn_receiver_tasks<F, R>(
num_parties: usize,
mut receivers: Vec<Vec<Receiver<Vec<u8>>>>,
nodes: Vec<TruncPrNode<F, R>>,
network: Vec<Arc<FakeNetwork>>,
) -> JoinSet<()>
where
F: PrimeField,
R: RBC<Id = SessionId> + Clone + 'static,
{
let mut set = JoinSet::new();
for i in 0..num_parties {
let mut node = nodes[i].clone();
let receiver = receivers.remove(0);
let net = network[i].clone();
let inbox: Vec<(SenderId, Receiver<Vec<u8>>)> = receiver
.into_iter() .enumerate()
.map(|(i, r)| (SenderId::Node(i), r))
.collect();
let mut merge_rx = fan_in_inboxes(inbox);
set.spawn(async move {
while let Some((_, bytes)) = merge_rx.recv().await {
let wrapped: WrappedMessage = bincode::deserialize(&bytes).unwrap();
match wrapped {
WrappedMessage::Rbc(msg) => match node.rbc.process(msg, net.clone()).await {
Ok(()) => {
node.drain_rbc_output().await.unwrap();
}
Err(e) => warn!("Error processing RBC message: {:?}", e),
},
message => {
error!("Unexpected message type: {:?}", message)
}
}
}
});
}
set
}
pub fn generate_random_shared_bits<F>(
num_parties: usize,
threshold: usize,
m: usize,
) -> Vec<Vec<RobustShare<F>>>
where
F: PrimeField,
{
let mut shares_bit_all_parties: Vec<Vec<RobustShare<F>>> = vec![vec![]; num_parties];
let mut rng = test_rng();
for _ in 0..m {
let random_bit = F::from(rng.gen::<u32>() & 1);
let shares_bit =
RobustShare::compute_shares(random_bit, num_parties, threshold, None, &mut rng)
.unwrap();
for party_id in 0..num_parties {
shares_bit_all_parties[party_id].push(shares_bit[party_id].clone());
}
}
shares_bit_all_parties
}
pub fn generate_random_shared_int<F>(
num_parties: usize,
threshold: usize,
k: u64,
) -> Vec<RobustShare<F>>
where
F: PrimeField,
{
let bin_coeff = binomial(num_parties, threshold);
let mut rng = test_rng();
let mut rand_value = F::zero();
for _ in 0..bin_coeff {
let rand_int: u64 = rng.gen_range(0..(1 << k));
rand_value = rand_value + F::from(rand_int);
}
let shares =
RobustShare::compute_shares(rand_value, num_parties, threshold, None, &mut rng).unwrap();
shares
}
pub fn generate_input_integer_z_k<F>(
num_parties: usize,
threshold: usize,
k: usize,
) -> (u32, Vec<RobustShare<F>>)
where
F: PrimeField,
{
let mut rng = test_rng();
let rand_int = rng.gen_range(0..((1 << (k - 1)) - 1));
let rand_int_field = F::from(rand_int as u32);
let shares =
RobustShare::compute_shares(rand_int_field, num_parties, threshold, None, &mut rng)
.unwrap();
(rand_int, shares)
}