Skip to content

Commit

Permalink
SealPIR rust wrapper v0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sga001 committed Jun 2, 2018
0 parents commit 6d0134c
Show file tree
Hide file tree
Showing 14 changed files with 2,954 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Cargo.lock
.clang-format
sealpir_bindings/bin/
sealpir_bindings/obj/
target/
deps/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "SealPIR"]
path = SealPIR
url = https://github.com/sga001/SealPIR.git
30 changes: 30 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "sealpir"
version = "0.1.0"
authors = ["Sebastian Angel <sebs@cs.utexas.edu>"]

[build-dependencies]
gcc = "0.3.54"

[dependencies]
libc = "0.2.42"
rand = "0.5.0"
serde = "1.0.65"
serde_derive = "1.0.65"

[dev-dependencies]
criterion = "0.2.3"
serde_bytes = "0.10.4"

[[bench]]
name = "pir"
harness = false

[profile.release]
opt-level = 3
debug = false
rpath = false
lto = true
debug-assertions = true
codegen-units = 1
panic = 'unwind'
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# SealPIR (Rust): Rust wrappers for SealPIR

SealPIR is a research library and should not be used in production systems. SealPIR allows a client to download an element from a database stored by a server without revealing which element was downloaded. SealPIR was introduced in our [paper](https://eprint.iacr.org/2017/1142.pdf).


SealPIR relies on SEAL. The rest of this README assumes that SEAL is installed in the folder deps/SEAL within this repository. See below for instructions on how to install SEAL.

# Compiling SEAL

SealPIR depends on SEAL v2.3.0-4 and a patch that exposes the substitution operator. You can get SEAL v2.3.0-4 from this [link](http://sealcrypto.org).

Once you have downloaded SEAL, apply the patch SEAL_v2.3.0-4.patch (available in this repository) to it. Here are the exact steps.

We assume that you are in the SEAL directory, and that you have copied the patch to this directory.

First, convert the SEAL directory into a git repo:

```sh
$ git init
$ git add .
$ git commit -m "SEAL v2.3.0-4"
```
Then, apply the patch:

```sh
$ git am SEAL_v2.3.0-4.patch
```

Finally, compile SEAL (NOTE: gcc-8 is not currently supported):

```sh
$ cd SEAL
$ ./configure CXXFLAGS="-O3 -march=native -fPIC"
$ make clean && make
```

# Compiling SealPIR-Rust

SealPIR's Rust wrapper works with [Rust](https://www.rust-lang.org/) nightly (we have tested with Rust 1.28.0). It also depends on the C++ version of SealPIR (included as a submodule) and SEAL (see above).

To compile SealPIR-Rust just do:

```sh
$ git submodule init
$ git submodule update
$ cargo build
```

# Reproducing the results in the paper

If you would like to reproduce the microbenchmarks found in the paper (Figure 9), simply run:

```sh
$ cargo bench [prefix of name of benchmark (or leave blank to run all)]
```

For example, to reproduce the SealPIR entries of the first row of Figure 9 (Query), simply
run:

```sh
$ cargo bench query
```

To reproduce a single data point, for example the Expand entry for SealPIR where n=262,144, run:

```sh
$ cargo bench expand_d2/262144
```

Note that the reply microbenchmark ("Answer" in Figure 9) already includes the cost of Expand (we subtract this cost in the paper).


You can find the code that runs these benchmarks (and their names) in ``benches/pir.rs``.

To reproduce latency and throughput results, check out the [pir-test](https://github.com/sga001/pir-test) repository (this also has examples on how to use SealPIR in a client-server networked application).
1,801 changes: 1,801 additions & 0 deletions SEAL_v2.3.0-4.patch

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions SealPIR
Submodule SealPIR added at d82128
161 changes: 161 additions & 0 deletions benches/pir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#![feature(custom_attribute, custom_derive, plugin)]

#[macro_use]
extern crate criterion;
extern crate rand;
extern crate sealpir;
extern crate serde;
#[macro_use]
extern crate serde_derive;

use criterion::Criterion;
use rand::ChaChaRng;
use rand::{RngCore, FromEntropy};
use sealpir::client::PirClient;
use sealpir::server::PirServer;
use std::time::Duration;

const SIZE: usize = 288;
const DIM: u32 = 2;
const LOGT: u32 = 23;
const POLY_DEGREE: u32 = 2048;
const NUMS: [u32; 3] = [1 << 16, 1 << 18, 1 << 20];

#[derive(Serialize, Clone)]
struct Element {
#[serde(serialize_with = "<[_]>::serialize")]
e: [u8; SIZE],
}

fn setup(c: &mut Criterion) {
c.bench_function_over_inputs(
&format!("setup_d{}", DIM),
|b, &&num| {
// setup
let mut rng = ChaChaRng::from_entropy();
let mut collection = vec![];
for _ in 0..num {
let mut x = [0u8; SIZE];
rng.fill_bytes(&mut x);
collection.push(x);
}
// measurement
b.iter(|| {
let mut server = PirServer::new(num, SIZE as u32, POLY_DEGREE, LOGT, DIM);
server.setup(&collection);
})
},
&NUMS,
);
}

fn query(c: &mut Criterion) {
c.bench_function_over_inputs(
&format!("query_d{}", DIM),
|b, &&num| {
// setup
let client = PirClient::new(num, SIZE as u32, POLY_DEGREE, LOGT, DIM);
// measurement
b.iter_with_setup(|| rand::random::<u32>() % num, |idx| client.gen_query(idx));
},
&NUMS,
);
}

fn expand(c: &mut Criterion) {
c.bench_function_over_inputs(
&format!("expand_d{}", DIM),
|b, &&num| {
// setup
let mut rng = ChaChaRng::from_entropy();
let mut collection = vec![];
for _ in 0..num {
let mut x = [0u8; SIZE];
rng.fill_bytes(&mut x);
collection.push(x);
}

let mut server = PirServer::new(num, SIZE as u32, POLY_DEGREE, LOGT, DIM);
let client = PirClient::new(num, SIZE as u32, POLY_DEGREE, LOGT, DIM);
let key = client.get_key();
server.setup(&collection);
server.set_galois_key(key, 0);

// measurement
b.iter_with_setup(
|| client.gen_query(rand::random::<u32>() % num),
|query| server.expand(&query, 0),
);
},
&NUMS,
);
}

fn reply(c: &mut Criterion) {
c.bench_function_over_inputs(
&format!("reply_d{}", DIM),
|b, &&num| {
// setup
let mut rng = ChaChaRng::from_entropy();
let mut collection = vec![];
for _ in 0..num {
let mut x = [0u8; SIZE];
rng.fill_bytes(&mut x);
collection.push(x);
}

let mut server = PirServer::new(num, SIZE as u32, POLY_DEGREE, LOGT, DIM);
let client = PirClient::new(num, SIZE as u32, POLY_DEGREE, LOGT, DIM);
let key = client.get_key();
server.setup(&collection);
server.set_galois_key(key, 0);

// measurement
b.iter_with_setup(
|| client.gen_query(rand::random::<u32>() % num),
|query| server.gen_reply(&query, 0),
);
},
&NUMS,
);
}

fn decode(c: &mut Criterion) {
c.bench_function_over_inputs(
&format!("decode_d{}", DIM),
|b, &&num| {
// setup
let mut rng = ChaChaRng::from_entropy();
let mut collection = vec![];
for _ in 0..num {
let mut x = [0u8; SIZE];
rng.fill_bytes(&mut x);
collection.push(x);
}

let mut server = PirServer::new(num, SIZE as u32, POLY_DEGREE, LOGT, DIM);
let client = PirClient::new(num, SIZE as u32, POLY_DEGREE, LOGT, DIM);
let key = client.get_key();
server.setup(&collection);
server.set_galois_key(key, 0);
let idx = rand::random::<u32>() % num;
let query = client.gen_query(idx);
let reply = server.gen_reply(&query, 0);

// measurement
b.iter(|| client.decode_reply::<Element>(idx, &reply));
},
&NUMS,
);
}

criterion_group! {
name = benches;
config = Criterion::default()
.sample_size(10)
.measurement_time(Duration::new(5, 0))
.without_plots();
targets = setup, query, expand, reply, decode
}

criterion_main!(benches);
26 changes: 26 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
extern crate gcc;
use std::env;

fn main() {
gcc::Build::new()
.file("SealPIR/pir.cpp")
.file("SealPIR/pir_server.cpp")
.file("SealPIR/pir_client.cpp")
.file("sealpir-bindings/pir_rust.cpp")
.include("sealpir-bindings/")
.include("SealPIR/")
.include("deps/SEAL/SEAL/")
.flag("-Wno-unknown-pragmas")
.flag("-Wno-sign-compare")
.flag("-Wno-unused-parameter")
.flag("-std=c++11")
.flag("-fopenmp")
.pic(true)
.cpp(true)
.compile("libsealpir.a");

let link_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

println!("cargo:rustc-link-search={}/deps/SEAL/bin/", link_dir);
println!("cargo:rustc-link-lib=static=seal");
}
Loading

0 comments on commit 6d0134c

Please sign in to comment.