use rand::rngs::ThreadRng; use rand::RngCore; use std::sync::mpsc::*; use std::thread::*; use crate::params; use crate::VecData; enum Command { PreProc(usize), PreProcResp(Vec), } enum Response { PubParams(Vec), PreProcMsg(Vec), } pub struct Client { r: usize, thread_handle: JoinHandle<()>, incoming_cmd: SyncSender, outgoing_resp: Receiver, } impl Client { pub fn new(r: usize) -> (Self, Vec) { let (incoming_cmd, incoming_cmd_recv) = sync_channel(0); let (outgoing_resp_send, outgoing_resp) = sync_channel(0); let thread_handle = spawn(move || { let spiral_params = params::get_spiral_params(r); let mut clientrng = rand::thread_rng(); let mut spiral_client = spiral_rs::client::Client::init(&spiral_params, &mut clientrng); // The first communication is the pub_params let pub_params = spiral_client.generate_keys().serialize(); outgoing_resp_send .send(Response::PubParams(pub_params)) .unwrap(); // Wait for commands loop { println!("Client waiting"); match incoming_cmd_recv.recv() { Err(_) => break, _ => panic!("Received something unexpected"), } } println!("Client ending"); }); let pub_params = match outgoing_resp.recv() { Ok(Response::PubParams(x)) => x, _ => panic!("Received something unexpected"), }; ( Client { r, thread_handle, incoming_cmd, outgoing_resp, }, pub_params, ) } } #[repr(C)] pub struct ClientNewRet { client: *mut Client, pub_params: VecData, } #[no_mangle] pub extern "C" fn spir_client_new(r: u8) -> ClientNewRet { let (client, pub_params) = Client::new(r as usize); let vecdata = VecData { data: pub_params.as_ptr(), len: pub_params.len(), cap: pub_params.capacity(), }; std::mem::forget(pub_params); ClientNewRet { client: Box::into_raw(Box::new(client)), pub_params: vecdata, } } #[no_mangle] pub extern "C" fn spir_client_free(client: *mut Client) { if client.is_null() { return; } unsafe { Box::from_raw(client); } }