client.rs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. use rand::rngs::ThreadRng;
  2. use rand::RngCore;
  3. use std::collections::VecDeque;
  4. use std::mem;
  5. use std::os::raw::c_uchar;
  6. use std::sync::mpsc::*;
  7. use std::thread::*;
  8. use aes::Block;
  9. use rayon::prelude::*;
  10. use subtle::Choice;
  11. use curve25519_dalek::ristretto::RistrettoPoint;
  12. use curve25519_dalek::scalar::Scalar;
  13. use crate::ot::*;
  14. use crate::params;
  15. use crate::to_vecdata;
  16. use crate::DbEntry;
  17. use crate::PreProcSingleMsg;
  18. use crate::PreProcSingleRespMsg;
  19. use crate::VecData;
  20. enum Command {
  21. PreProc(usize),
  22. PreProcFinish(Vec<PreProcSingleRespMsg>),
  23. }
  24. enum Response {
  25. PubParams(Vec<u8>),
  26. PreProcMsg(Vec<u8>),
  27. PreProcDone,
  28. }
  29. // The internal client state for a single outstanding preprocess query
  30. struct PreProcOutSingleState {
  31. rand_idx: usize,
  32. ot_state: Vec<(Choice, Scalar)>,
  33. }
  34. // The internal client state for a single preprocess ready to be used
  35. struct PreProcSingleState {
  36. rand_idx: usize,
  37. ot_key: Block,
  38. }
  39. pub struct Client {
  40. r: usize,
  41. thread_handle: JoinHandle<()>,
  42. incoming_cmd: SyncSender<Command>,
  43. outgoing_resp: Receiver<Response>,
  44. }
  45. impl Client {
  46. pub fn new(r: usize) -> (Self, Vec<u8>) {
  47. let (incoming_cmd, incoming_cmd_recv) = sync_channel(0);
  48. let (outgoing_resp_send, outgoing_resp) = sync_channel(0);
  49. let thread_handle = spawn(move || {
  50. let spiral_params = params::get_spiral_params(r);
  51. let mut clientrng = rand::thread_rng();
  52. let mut rng = rand::thread_rng();
  53. let mut spiral_client = spiral_rs::client::Client::init(&spiral_params, &mut clientrng);
  54. let num_records = 1 << r;
  55. let num_records_mask = num_records - 1;
  56. let spiral_blocking_factor = spiral_params.db_item_size / mem::size_of::<DbEntry>();
  57. // The first communication is the pub_params
  58. let pub_params = spiral_client.generate_keys().serialize();
  59. outgoing_resp_send
  60. .send(Response::PubParams(pub_params))
  61. .unwrap();
  62. // State for outstanding preprocessing queries
  63. let mut preproc_out_state: Vec<PreProcOutSingleState> = Vec::new();
  64. // State for preprocessing queries ready to be used
  65. let mut preproc_state: VecDeque<PreProcSingleState> = VecDeque::new();
  66. // Wait for commands
  67. loop {
  68. match incoming_cmd_recv.recv() {
  69. Err(_) => break,
  70. Ok(Command::PreProc(num_preproc)) => {
  71. // Ensure we don't already have outstanding
  72. // preprocessing state
  73. assert!(preproc_out_state.len() == 0);
  74. let mut preproc_msg: Vec<PreProcSingleMsg> = Vec::new();
  75. for _ in 0..num_preproc {
  76. let rand_idx = (rng.next_u64() as usize) & num_records_mask;
  77. let rand_pir_idx = rand_idx / spiral_blocking_factor;
  78. let spc_query = spiral_client.generate_query(rand_pir_idx).serialize();
  79. let (ot_state, ot_query) = otkey_request(rand_idx, r);
  80. preproc_out_state.push(PreProcOutSingleState { rand_idx, ot_state });
  81. preproc_msg.push(PreProcSingleMsg {
  82. ot_query,
  83. spc_query,
  84. });
  85. }
  86. let ret: Vec<u8> = bincode::serialize(&preproc_msg).unwrap();
  87. outgoing_resp_send.send(Response::PreProcMsg(ret)).unwrap();
  88. }
  89. Ok(Command::PreProcFinish(srvresp)) => {
  90. let num_preproc = srvresp.len();
  91. assert!(preproc_out_state.len() == num_preproc);
  92. let mut newstate: VecDeque<PreProcSingleState> = preproc_out_state
  93. .into_par_iter()
  94. .zip(srvresp)
  95. .map(|(c, s)| {
  96. let ot_key = otkey_receive(c.ot_state, &s.ot_resp);
  97. PreProcSingleState {
  98. rand_idx: c.rand_idx,
  99. ot_key,
  100. }
  101. })
  102. .collect();
  103. preproc_state.append(&mut newstate);
  104. preproc_out_state = Vec::new();
  105. outgoing_resp_send.send(Response::PreProcDone).unwrap();
  106. }
  107. _ => panic!("Received something unexpected in client loop"),
  108. }
  109. }
  110. });
  111. let pub_params = match outgoing_resp.recv() {
  112. Ok(Response::PubParams(x)) => x,
  113. _ => panic!("Received something unexpected in client new"),
  114. };
  115. (
  116. Client {
  117. r,
  118. thread_handle,
  119. incoming_cmd,
  120. outgoing_resp,
  121. },
  122. pub_params,
  123. )
  124. }
  125. pub fn preproc_PIRs(&self, num_preproc: usize) -> Vec<u8> {
  126. self.incoming_cmd
  127. .send(Command::PreProc(num_preproc))
  128. .unwrap();
  129. let ret = match self.outgoing_resp.recv() {
  130. Ok(Response::PreProcMsg(x)) => x,
  131. _ => panic!("Received something unexpected in preproc_PIRs"),
  132. };
  133. ret
  134. }
  135. pub fn preproc_finish(&self, msg: &[u8]) {
  136. self.incoming_cmd
  137. .send(Command::PreProcFinish(bincode::deserialize(msg).unwrap()))
  138. .unwrap();
  139. match self.outgoing_resp.recv() {
  140. Ok(Response::PreProcDone) => (),
  141. _ => panic!("Received something unexpected in preproc_finish"),
  142. }
  143. }
  144. }
  145. #[repr(C)]
  146. pub struct ClientNewRet {
  147. client: *mut Client,
  148. pub_params: VecData,
  149. }
  150. #[no_mangle]
  151. pub extern "C" fn spir_client_new(r: u8) -> ClientNewRet {
  152. let (client, pub_params) = Client::new(r as usize);
  153. ClientNewRet {
  154. client: Box::into_raw(Box::new(client)),
  155. pub_params: to_vecdata(pub_params),
  156. }
  157. }
  158. #[no_mangle]
  159. pub extern "C" fn spir_client_free(client: *mut Client) {
  160. if client.is_null() {
  161. return;
  162. }
  163. unsafe {
  164. Box::from_raw(client);
  165. }
  166. }
  167. #[no_mangle]
  168. pub extern "C" fn spir_client_preproc_PIRs(clientptr: *mut Client, num_preproc: u32) -> VecData {
  169. let client = unsafe {
  170. assert!(!clientptr.is_null());
  171. &mut *clientptr
  172. };
  173. let retvec = client.preproc_PIRs(num_preproc as usize);
  174. to_vecdata(retvec)
  175. }
  176. #[no_mangle]
  177. pub extern "C" fn spir_client_preproc_finish(
  178. clientptr: *mut Client,
  179. msgdata: *const c_uchar,
  180. msglen: usize,
  181. ) {
  182. let client = unsafe {
  183. assert!(!clientptr.is_null());
  184. &mut *clientptr
  185. };
  186. let msg_slice = unsafe {
  187. assert!(!msgdata.is_null());
  188. std::slice::from_raw_parts(msgdata, msglen)
  189. };
  190. client.preproc_finish(&msg_slice);
  191. }