client.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. use rand::rngs::ThreadRng;
  2. use rand::RngCore;
  3. use std::mem;
  4. use std::sync::mpsc::*;
  5. use std::thread::*;
  6. use subtle::Choice;
  7. use curve25519_dalek::ristretto::RistrettoPoint;
  8. use curve25519_dalek::scalar::Scalar;
  9. use crate::ot::*;
  10. use crate::params;
  11. use crate::to_vecdata;
  12. use crate::DbEntry;
  13. use crate::PreProcSingleMsg;
  14. use crate::VecData;
  15. enum Command {
  16. PreProc(usize),
  17. PreProcResp(Vec<u8>),
  18. }
  19. enum Response {
  20. PubParams(Vec<u8>),
  21. PreProcMsg(Vec<u8>),
  22. }
  23. // The internal client state for a single preprocess query
  24. struct PreProcSingleState {
  25. rand_idx: usize,
  26. ot_state: Vec<(Choice, Scalar)>,
  27. }
  28. pub struct Client {
  29. r: usize,
  30. thread_handle: JoinHandle<()>,
  31. incoming_cmd: SyncSender<Command>,
  32. outgoing_resp: Receiver<Response>,
  33. }
  34. impl Client {
  35. pub fn new(r: usize) -> (Self, Vec<u8>) {
  36. let (incoming_cmd, incoming_cmd_recv) = sync_channel(0);
  37. let (outgoing_resp_send, outgoing_resp) = sync_channel(0);
  38. let thread_handle = spawn(move || {
  39. let spiral_params = params::get_spiral_params(r);
  40. let mut clientrng = rand::thread_rng();
  41. let mut rng = rand::thread_rng();
  42. let mut spiral_client = spiral_rs::client::Client::init(&spiral_params, &mut clientrng);
  43. let num_records = 1 << r;
  44. let num_records_mask = num_records - 1;
  45. let spiral_blocking_factor = spiral_params.db_item_size / mem::size_of::<DbEntry>();
  46. // The first communication is the pub_params
  47. let pub_params = spiral_client.generate_keys().serialize();
  48. outgoing_resp_send
  49. .send(Response::PubParams(pub_params))
  50. .unwrap();
  51. // State for preprocessing queries
  52. let mut preproc_state: Vec<PreProcSingleState> = Vec::new();
  53. // Wait for commands
  54. loop {
  55. match incoming_cmd_recv.recv() {
  56. Err(_) => break,
  57. Ok(Command::PreProc(num_preproc)) => {
  58. // Ensure we don't already have outstanding
  59. // preprocessing state
  60. assert!(preproc_state.len() == 0);
  61. let mut preproc_msg: Vec<PreProcSingleMsg> = Vec::new();
  62. for _ in 0..num_preproc {
  63. let rand_idx = (rng.next_u64() as usize) & num_records_mask;
  64. let rand_pir_idx = rand_idx / spiral_blocking_factor;
  65. let spc_query = spiral_client.generate_query(rand_pir_idx).serialize();
  66. let (ot_state, ot_query) = otkey_request(rand_idx, r);
  67. preproc_state.push(PreProcSingleState { rand_idx, ot_state });
  68. preproc_msg.push(PreProcSingleMsg {
  69. ot_query,
  70. spc_query,
  71. });
  72. }
  73. let ret: Vec<u8> = bincode::serialize(&preproc_msg).unwrap();
  74. outgoing_resp_send.send(Response::PreProcMsg(ret)).unwrap();
  75. }
  76. _ => panic!("Received something unexpected in client loop"),
  77. }
  78. }
  79. });
  80. let pub_params = match outgoing_resp.recv() {
  81. Ok(Response::PubParams(x)) => x,
  82. _ => panic!("Received something unexpected in client new"),
  83. };
  84. (
  85. Client {
  86. r,
  87. thread_handle,
  88. incoming_cmd,
  89. outgoing_resp,
  90. },
  91. pub_params,
  92. )
  93. }
  94. pub fn preproc_PIRs(&self, num_preproc: usize) -> Vec<u8> {
  95. self.incoming_cmd
  96. .send(Command::PreProc(num_preproc))
  97. .unwrap();
  98. let ret = match self.outgoing_resp.recv() {
  99. Ok(Response::PreProcMsg(x)) => x,
  100. _ => panic!("Received something unexpected in preproc_PIRs"),
  101. };
  102. ret
  103. }
  104. }
  105. #[repr(C)]
  106. pub struct ClientNewRet {
  107. client: *mut Client,
  108. pub_params: VecData,
  109. }
  110. #[no_mangle]
  111. pub extern "C" fn spir_client_new(r: u8) -> ClientNewRet {
  112. let (client, pub_params) = Client::new(r as usize);
  113. ClientNewRet {
  114. client: Box::into_raw(Box::new(client)),
  115. pub_params: to_vecdata(pub_params),
  116. }
  117. }
  118. #[no_mangle]
  119. pub extern "C" fn spir_client_free(client: *mut Client) {
  120. if client.is_null() {
  121. return;
  122. }
  123. unsafe {
  124. Box::from_raw(client);
  125. }
  126. }
  127. #[no_mangle]
  128. pub extern "C" fn spir_client_preproc_PIRs(clientptr: *mut Client, num_preproc: u32) -> VecData {
  129. let client = unsafe {
  130. assert!(!clientptr.is_null());
  131. &mut *clientptr
  132. };
  133. let retvec = client.preproc_PIRs(num_preproc as usize);
  134. to_vecdata(retvec)
  135. }