|
@@ -16,6 +16,7 @@ use subtle::Choice;
|
|
|
use curve25519_dalek::ristretto::RistrettoPoint;
|
|
|
use curve25519_dalek::scalar::Scalar;
|
|
|
|
|
|
+use crate::dbentry_decrypt;
|
|
|
use crate::ot::*;
|
|
|
use crate::params;
|
|
|
use crate::to_vecdata;
|
|
@@ -28,6 +29,7 @@ enum Command {
|
|
|
PreProc(usize),
|
|
|
PreProcFinish(Vec<PreProcSingleRespMsg>),
|
|
|
Query(usize),
|
|
|
+ QueryFinish(Vec<u8>),
|
|
|
}
|
|
|
|
|
|
enum Response {
|
|
@@ -35,6 +37,7 @@ enum Response {
|
|
|
PreProcMsg(Vec<u8>),
|
|
|
PreProcDone,
|
|
|
QueryMsg(Vec<u8>),
|
|
|
+ QueryDone(DbEntry),
|
|
|
}
|
|
|
|
|
|
// The internal client state for a single outstanding preprocess query
|
|
@@ -129,7 +132,7 @@ impl Client {
|
|
|
// panic if there are no preproc states
|
|
|
// available
|
|
|
let nextstate = preproc_state.pop_front().unwrap();
|
|
|
- let offset = (num_records + nextstate.rand_idx - idx) & num_records_mask;
|
|
|
+ let offset = (num_records + idx - nextstate.rand_idx) & num_records_mask;
|
|
|
let mut querymsg: Vec<u8> = Vec::new();
|
|
|
querymsg.extend(offset.to_le_bytes());
|
|
|
query_state.push_back(nextstate);
|
|
@@ -137,6 +140,27 @@ impl Client {
|
|
|
.send(Response::QueryMsg(querymsg))
|
|
|
.unwrap();
|
|
|
}
|
|
|
+ Ok(Command::QueryFinish(msg)) => {
|
|
|
+ // panic if there is no outstanding state
|
|
|
+ let nextstate = query_state.pop_front().unwrap();
|
|
|
+ let encdbblock = spiral_client.decode_response(msg.as_slice());
|
|
|
+ // Extract the one encrypted DbEntry we were
|
|
|
+ // looking for (and the only one we are able to
|
|
|
+ // decrypt)
|
|
|
+ let entry_in_block = nextstate.rand_idx % spiral_blocking_factor;
|
|
|
+ let loc_in_block = entry_in_block * mem::size_of::<DbEntry>();
|
|
|
+ let loc_in_block_end = (entry_in_block + 1) * mem::size_of::<DbEntry>();
|
|
|
+ let encdbentry = DbEntry::from_le_bytes(
|
|
|
+ encdbblock[loc_in_block..loc_in_block_end]
|
|
|
+ .try_into()
|
|
|
+ .unwrap(),
|
|
|
+ );
|
|
|
+ let decdbentry =
|
|
|
+ dbentry_decrypt(&nextstate.ot_key, nextstate.rand_idx, encdbentry);
|
|
|
+ outgoing_resp_send
|
|
|
+ .send(Response::QueryDone(decdbentry))
|
|
|
+ .unwrap();
|
|
|
+ }
|
|
|
_ => panic!("Received something unexpected in client loop"),
|
|
|
}
|
|
|
}
|
|
@@ -161,11 +185,10 @@ impl Client {
|
|
|
self.incoming_cmd
|
|
|
.send(Command::PreProc(num_preproc))
|
|
|
.unwrap();
|
|
|
- let ret = match self.outgoing_resp.recv() {
|
|
|
+ match self.outgoing_resp.recv() {
|
|
|
Ok(Response::PreProcMsg(x)) => x,
|
|
|
_ => panic!("Received something unexpected in preproc"),
|
|
|
- };
|
|
|
- ret
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
pub fn preproc_finish(&self, msg: &[u8]) {
|
|
@@ -180,11 +203,20 @@ impl Client {
|
|
|
|
|
|
pub fn query(&self, idx: usize) -> Vec<u8> {
|
|
|
self.incoming_cmd.send(Command::Query(idx)).unwrap();
|
|
|
- let ret = match self.outgoing_resp.recv() {
|
|
|
+ match self.outgoing_resp.recv() {
|
|
|
Ok(Response::QueryMsg(x)) => x,
|
|
|
_ => panic!("Received something unexpected in preproc"),
|
|
|
- };
|
|
|
- ret
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn query_finish(&self, msg: &[u8]) -> DbEntry {
|
|
|
+ self.incoming_cmd
|
|
|
+ .send(Command::QueryFinish(msg.to_vec()))
|
|
|
+ .unwrap();
|
|
|
+ match self.outgoing_resp.recv() {
|
|
|
+ Ok(Response::QueryDone(entry)) => entry,
|
|
|
+ _ => panic!("Received something unexpected in preproc_finish"),
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -249,3 +281,20 @@ pub extern "C" fn spir_client_query(clientptr: *mut Client, idx: usize) -> VecDa
|
|
|
let retvec = client.query(idx);
|
|
|
to_vecdata(retvec)
|
|
|
}
|
|
|
+
|
|
|
+#[no_mangle]
|
|
|
+pub extern "C" fn spir_client_query_finish(
|
|
|
+ clientptr: *mut Client,
|
|
|
+ msgdata: *const c_uchar,
|
|
|
+ msglen: usize,
|
|
|
+) -> DbEntry {
|
|
|
+ let client = unsafe {
|
|
|
+ assert!(!clientptr.is_null());
|
|
|
+ &mut *clientptr
|
|
|
+ };
|
|
|
+ let msg_slice = unsafe {
|
|
|
+ assert!(!msgdata.is_null());
|
|
|
+ std::slice::from_raw_parts(msgdata, msglen)
|
|
|
+ };
|
|
|
+ client.query_finish(&msg_slice)
|
|
|
+}
|