1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#![doc(html_root_url = "https://schoppmp.github.io/doc/oblivc-rust/")]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

extern crate libgcrypt_sys;
extern crate libgpg_error_sys;

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

#[cfg(test)]
mod test {
    use super::*;
    use std::os::raw::{c_int, c_void};
    use std::ffi::CString;
    use std::thread;
    use std::time::Duration;

    #[repr(C)]
    struct TestMillionaireArgs {
        input: c_int,
        output: i8,
    }
    #[link(name = "test_oblivc", kind = "static")]
    extern "C" {
        fn millionaire(arg: *mut c_void);
    }

    #[test]
    fn test_millionaire() {
        // spawn two threads, one for the server and one for the client
        let handles: Vec<_> = (1..3)
            .map(|party| {
                thread::spawn(move || {
                    let mut args = TestMillionaireArgs {
                        input: (10000 + 100 * party) as c_int,
                        output: 0i8,
                    };
                    let host = CString::new("localhost").unwrap();
                    let port = CString::new("34512").unwrap();
                    unsafe {
                        // allocate a ProtocolDesc
                        let mut pd: ProtocolDesc = std::mem::zeroed();
                        // connect
                        setCurrentParty(&mut pd, party);
                        if party == 1 {
                            assert_eq!(protocolAcceptTcp2P(&mut pd, port.as_ptr()), 0);
                        } else {
                            while protocolConnectTcp2P(&mut pd, host.as_ptr(), port.as_ptr()) != 0 {
                                thread::sleep(Duration::from_millis(100));
                            }
                        }
                        // run millionnaire's problem
                        execYaoProtocol(
                            &mut pd,
                            Some(millionaire),
                            &mut args as *mut _ as *mut c_void,
                        );
                        cleanupProtocol(&mut pd);
                    }
                    // party 1 input < party 2 input
                    assert!(args.output < 0);
                })
            })
            .collect();
        for handle in handles {
            handle.join().unwrap();
        }
    }
}