[−][src]Crate test_oblivc
Example Usage of the oblivc
crate
This crate uses the oblivc
crate to solve Yao's Millionaire's Problem.
We implement our solution in Obliv-C as a function millionaire
that reads both parties'
inputs, compares them, and sets the output to -1, 0, or 1 if party 1's input was less than,
equal to, or greater than party 2's.
Compilation
First, in build.rs
, we compile millionaire.oc
using the Obliv-C compiler.
This also tells Cargo to link the resulting objects after compiling our rust source code.
oblivc::compiler() .file("src/millionaire.oc") .include("src") .compile("millionaire");
Next, we generate Rust bindings for both the millionaire
function and the millionaire_args
struct defined in millionaire.h
.
oblivc::bindings() .header("src/millionaire.h") .generate().unwrap() .write_to_file(out_dir.join("millionaire.rs")).unwrap();
Note that for small projects, these bindings can also be generated by hand. Using bindgen
is just more convenient.
Calling Obliv-C from Rust
In our Rust source files, we first include the bindings generated by the build script.
include!(concat!(env!("OUT_DIR"), "/millionaire.rs"));
Now, for each party, we set up a millionaire_args
struct, as well as a
ProtocolDesc
describing our protocol. In this example, we let party 1 accept a TCP
connection using Obliv-C's native sockets.
let mut args = millionaire_args { input: 10, output: 0, }; let pd = oblivc::protocol_desc() .party(1) .accept("56734").unwrap();
Party 2 can then connect to the specified address:
let mut args = millionaire_args { input: 20, output: 0, }; let pd = oblivc::protocol_desc() .party(2) .connect("localhost", "67845").unwrap();
To execute the protocol, both parties call
unsafe { pd.exec_yao_protocol(millionaire, &mut args); }
Note that this function call is unsafe
, since there's no guarantee about the safety of the
Obliv-C source code we wrote. It is up to the user of the oblivc
crate to ensure their calls
to exec_yao_protocol
are safe.
Other Transports
Besides native sockets from Obliv-C's interface, any objects that implement Read
and
Write
can be used as transport for the protocol execution.
Examples using Rust's TcpStream
s and UnixStream
s can be found in the
tests
folder.
Structs
millionaire_args | Arguments to the Obliv-C function |
Functions
millionaire⚠ | The Obliv-C function that gets passed to |