[][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 TcpStreams and UnixStreams can be found in the tests folder.

Structs

millionaire_args

Arguments to the Obliv-C function millionnaire.

Functions

millionaire

The Obliv-C function that gets passed to oblivc::ProtocolDesc::exec_yao_protocol.