|
@@ -8,10 +8,14 @@ use rayon::prelude::*;
|
|
|
use spiral_rs::client::PublicParameters;
|
|
|
use spiral_rs::client::Query;
|
|
|
use spiral_rs::params::Params;
|
|
|
+use spiral_rs::server::process_query;
|
|
|
|
|
|
+use crate::encdb_xor_keys;
|
|
|
+use crate::load_db_from_slice_mt;
|
|
|
use crate::ot::*;
|
|
|
use crate::params;
|
|
|
use crate::to_vecdata;
|
|
|
+use crate::DbEntry;
|
|
|
use crate::PreProcSingleMsg;
|
|
|
use crate::PreProcSingleRespMsg;
|
|
|
use crate::VecData;
|
|
@@ -19,10 +23,12 @@ use crate::VecData;
|
|
|
enum Command {
|
|
|
PubParams(Vec<u8>),
|
|
|
PreProcMsg(Vec<PreProcSingleMsg>),
|
|
|
+ QueryMsg(usize, usize, usize, DbEntry),
|
|
|
}
|
|
|
|
|
|
enum Response {
|
|
|
PreProcResp(Vec<u8>),
|
|
|
+ QueryResp(Vec<u8>),
|
|
|
}
|
|
|
|
|
|
// The internal client state for a single preprocess query
|
|
@@ -45,6 +51,8 @@ impl Server {
|
|
|
let thread_handle = spawn(move || {
|
|
|
let spiral_params = params::get_spiral_params(r);
|
|
|
let pub_params = PublicParameters::deserialize(&spiral_params, &pub_params);
|
|
|
+ let num_records = 1 << r;
|
|
|
+ let num_records_mask = num_records - 1;
|
|
|
|
|
|
// State for preprocessing queries
|
|
|
let mut preproc_state: VecDeque<PreProcSingleState> = VecDeque::new();
|
|
@@ -75,6 +83,41 @@ impl Server {
|
|
|
let ret: Vec<u8> = bincode::serialize(&resp_msg).unwrap();
|
|
|
outgoing_resp_send.send(Response::PreProcResp(ret)).unwrap();
|
|
|
}
|
|
|
+ Ok(Command::QueryMsg(offset, db, rot, blind)) => {
|
|
|
+ // Panic if there's no preprocess state
|
|
|
+ // available
|
|
|
+ let nextstate = preproc_state.pop_front().unwrap();
|
|
|
+ // Encrypt the database with the keys, rotating
|
|
|
+ // and blinding in the process. It is safe to
|
|
|
+ // construct a slice out of the const pointer we
|
|
|
+ // were handed because that pointer will stay
|
|
|
+ // valid until we return something back to the
|
|
|
+ // caller.
|
|
|
+ let totoffset = (offset + rot) & num_records_mask;
|
|
|
+ let num_threads = rayon::current_num_threads();
|
|
|
+ let encdb = unsafe {
|
|
|
+ let dbslice =
|
|
|
+ std::slice::from_raw_parts(db as *const DbEntry, num_records);
|
|
|
+ encdb_xor_keys(
|
|
|
+ &dbslice,
|
|
|
+ &nextstate.db_keys,
|
|
|
+ r,
|
|
|
+ totoffset,
|
|
|
+ blind,
|
|
|
+ num_threads,
|
|
|
+ )
|
|
|
+ };
|
|
|
+ // Load the encrypted db into Spiral
|
|
|
+ let sps_db = load_db_from_slice_mt(&spiral_params, &encdb, num_threads);
|
|
|
+ // Process the query
|
|
|
+ let resp = process_query(
|
|
|
+ &spiral_params,
|
|
|
+ &pub_params,
|
|
|
+ &nextstate.query,
|
|
|
+ sps_db.as_slice(),
|
|
|
+ );
|
|
|
+ outgoing_resp_send.send(Response::QueryResp(resp)).unwrap();
|
|
|
+ }
|
|
|
_ => panic!("Received something unexpected"),
|
|
|
}
|
|
|
}
|
|
@@ -97,6 +140,24 @@ impl Server {
|
|
|
};
|
|
|
ret
|
|
|
}
|
|
|
+
|
|
|
+ pub fn query_process(
|
|
|
+ &self,
|
|
|
+ msg: &[u8],
|
|
|
+ db: *const DbEntry,
|
|
|
+ rot: usize,
|
|
|
+ blind: DbEntry,
|
|
|
+ ) -> Vec<u8> {
|
|
|
+ let offset = usize::from_le_bytes(msg.try_into().unwrap());
|
|
|
+ self.incoming_cmd
|
|
|
+ .send(Command::QueryMsg(offset, db as usize, rot, blind))
|
|
|
+ .unwrap();
|
|
|
+ let ret = match self.outgoing_resp.recv() {
|
|
|
+ Ok(Response::QueryResp(x)) => x,
|
|
|
+ _ => panic!("Received something unexpected in query_process"),
|
|
|
+ };
|
|
|
+ ret
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#[no_mangle]
|
|
@@ -142,3 +203,24 @@ pub extern "C" fn spir_server_preproc_process(
|
|
|
let retvec = server.preproc_process(&msg_slice);
|
|
|
to_vecdata(retvec)
|
|
|
}
|
|
|
+
|
|
|
+#[no_mangle]
|
|
|
+pub extern "C" fn spir_server_query_process(
|
|
|
+ serverptr: *mut Server,
|
|
|
+ msgdata: *const c_uchar,
|
|
|
+ msglen: usize,
|
|
|
+ db: *const DbEntry,
|
|
|
+ rot: usize,
|
|
|
+ blind: DbEntry,
|
|
|
+) -> VecData {
|
|
|
+ let server = unsafe {
|
|
|
+ assert!(!serverptr.is_null());
|
|
|
+ &mut *serverptr
|
|
|
+ };
|
|
|
+ let msg_slice = unsafe {
|
|
|
+ assert!(!msgdata.is_null());
|
|
|
+ std::slice::from_raw_parts(msgdata, msglen)
|
|
|
+ };
|
|
|
+ let retvec = server.query_process(&msg_slice, db, rot, blind);
|
|
|
+ to_vecdata(retvec)
|
|
|
+}
|