From 278445a559092dbc630c8ab52c47d9645279a4f2 Mon Sep 17 00:00:00 2001 From: Mikkel Wienberg Madsen Date: Wed, 12 Jun 2024 13:31:24 +0200 Subject: [PATCH] Use file descriptors instead of paths --- Cargo.lock | 62 +++++++++++++++++++++++++++++-- Cargo.toml | 3 +- src/schemes/spdz.rs | 16 ++++---- src/schemes/spdz/preprocessing.rs | 25 +++++-------- wecare/Cargo.lock | 62 +++++++++++++++++++++++++++++-- wecare/Cargo.toml | 3 ++ wecare/src/lib.rs | 44 ++++++++++++++-------- 7 files changed, 167 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a41dc1..ba79eed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,6 +157,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "bitvec" version = "1.0.1" @@ -219,6 +225,7 @@ dependencies = [ "rayon", "serde", "sha2", + "tempfile", "thiserror", "tokio", "tokio-test", @@ -366,6 +373,16 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -375,6 +392,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + [[package]] name = "ff" version = "0.13.0" @@ -495,7 +518,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -633,9 +656,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -652,6 +675,12 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "lock_api" version = "0.4.11" @@ -939,7 +968,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1007,6 +1036,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "rustversion" version = "1.0.15" @@ -1145,6 +1187,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand 2.1.0", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "thiserror" version = "1.0.58" diff --git a/Cargo.toml b/Cargo.toml index 6f643de..8cc7702 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ fixed = "2.0.0-alpha.11" futures = "0.3.28" futures-concurrency = "7.6.0" group = "0.13.0" -itertools = "0.12" +itertools = "0.13" num-traits = "0.2.16" overload = "0.1.1" rand = "0.8.5" @@ -30,6 +30,7 @@ tokio-util = { version = "0.7.9", features = ["io", "net", "io-util", "codec", " tracing = "0.1.40" [dev-dependencies] +tempfile = "3.10.1" tokio-test = "0.4.4" curve25519-dalek = { version = "4.1.1", features = ["group", "serde"] } sha2 = "0.10.8" diff --git a/src/schemes/spdz.rs b/src/schemes/spdz.rs index ebd4073..09c3fd7 100644 --- a/src/schemes/spdz.rs +++ b/src/schemes/spdz.rs @@ -377,7 +377,7 @@ fn power>(base: F, ex #[cfg(test)] mod test { - use std::path::Path; + use std::io::Seek; use ff::Field; use rand::thread_rng; use rand::SeedableRng; @@ -1410,21 +1410,23 @@ mod test { fn test_dealer_writing_to_file() { // preprosessing by dealer type F = Element32; - let file_names = vec![ - Path::new("/tmp/context2.bin"), - Path::new("/tmp/context1.bin"), + let mut files = [ + tempfile::tempfile().unwrap(), + tempfile::tempfile().unwrap(), ]; let known_to_each = vec![1, 2]; let number_of_triplets = 2; preprocessing::write_preproc_to_file( - &file_names, + &mut files, known_to_each, number_of_triplets, F::from_u128(0u128), ) .unwrap(); - let p1_context: SpdzContext = preprocessing::read_preproc_from_file(file_names[0]); - let p2_context: SpdzContext = preprocessing::read_preproc_from_file(file_names[1]); + files[0].rewind().unwrap(); + files[1].rewind().unwrap(); + let p1_context: SpdzContext = preprocessing::read_preproc_from_file(&mut files[0]); + let p2_context: SpdzContext = preprocessing::read_preproc_from_file(&mut files[1]); // unpacking let p1_params = p1_context.params; let p2_params = p2_context.params; diff --git a/src/schemes/spdz/preprocessing.rs b/src/schemes/spdz/preprocessing.rs index 575ecc8..79f4cca 100644 --- a/src/schemes/spdz/preprocessing.rs +++ b/src/schemes/spdz/preprocessing.rs @@ -8,8 +8,7 @@ use std::{ error::Error, fmt, fs::File, - io::{self, Read, Write}, - path::Path, + io::{self, Write}, }; #[derive(Debug, Clone, PartialEq)] pub enum MissingPreProcErrorType { @@ -89,37 +88,31 @@ pub struct SecretValues { pub mac_key: F, } pub fn write_preproc_to_file( - file_names: &[&Path], + files: &mut [File], known_to_each: Vec, number_of_triplets: usize, _: F, ) -> Result<(), Box> { - let number_of_parties = file_names.len(); + let number_of_parties = files.len(); assert!(number_of_parties == known_to_each.len()); let rng = rand_chacha::ChaCha20Rng::from_entropy(); // Notice here that the secret values are not written to the file, No party is allowed to know the value. let (contexts, _): (Vec>, _) = dealer_prepross(rng, known_to_each, number_of_triplets, number_of_parties); - let names_and_contexts = file_names.iter().zip(contexts); - for (name, context) in names_and_contexts { + let names_and_contexts = files.iter_mut().zip(contexts); + for (file, context) in names_and_contexts { let data: Vec = bincode::serialize(&context)?; - let mut file = File::create(name)?; file.write_all(&data)?; - file.sync_all()?; } Ok(()) } pub fn read_preproc_from_file( - file_name: &Path, + file: &mut File, ) -> SpdzContext { // TODO: return Result instead. - let mut data = Vec::new(); - let mut file = File::open(file_name).expect("open file"); - file.read_to_end(&mut data).expect("read to end"); - let new_context: SpdzContext = bincode::deserialize(&data).expect("deserialize"); - new_context + bincode::deserialize_from(file).unwrap() } @@ -259,8 +252,8 @@ impl SpdzContext generate_empty_context(number_of_parties, mac_key_share, who_am_i) } - pub fn from_file(path: &Path) -> Result { - Ok(read_preproc_from_file(path)) + pub fn from_file(mut file: File) -> Result { + Ok(read_preproc_from_file(&mut file)) } } diff --git a/wecare/Cargo.lock b/wecare/Cargo.lock index daea2dc..e1bfd88 100644 --- a/wecare/Cargo.lock +++ b/wecare/Cargo.lock @@ -135,6 +135,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "bitvec" version = "1.0.1" @@ -341,6 +347,16 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -350,6 +366,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + [[package]] name = "ff" version = "0.13.0" @@ -470,7 +492,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -608,9 +630,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -627,6 +649,12 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "lock_api" version = "0.4.11" @@ -914,7 +942,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -982,6 +1010,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "rustversion" version = "1.0.16" @@ -1109,6 +1150,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand 2.1.0", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "thiserror" version = "1.0.58" @@ -1292,6 +1345,7 @@ dependencies = [ "curve25519-dalek", "fixed", "rand", + "tempfile", "tokio", ] diff --git a/wecare/Cargo.toml b/wecare/Cargo.toml index 05a4f14..72eefe0 100644 --- a/wecare/Cargo.toml +++ b/wecare/Cargo.toml @@ -11,3 +11,6 @@ tokio = { version = "1.33.0", features = ["full"] } curve25519-dalek = { version = "4.1.1", features = ["group", "serde"] } rand = "0.8.5" fixed = "2.0.0-alpha.11" + +[dev-dependencies] +tempfile = "3.10.1" diff --git a/wecare/src/lib.rs b/wecare/src/lib.rs index a1323a5..360a5e1 100644 --- a/wecare/src/lib.rs +++ b/wecare/src/lib.rs @@ -1,6 +1,5 @@ -use std::{net::SocketAddr, time::Duration}; +use std::{fs::File, net::SocketAddr, time::Duration}; use caring::{net::network::TcpNetwork, schemes::spdz::{self, preprocessing}}; -use std::path::Path; pub struct AdderEngine { network: TcpNetwork, @@ -123,7 +122,7 @@ impl std::fmt::Display for MpcError { impl std::error::Error for MpcError {} //pub fn setup_engine(my_addr: &str, others: &[impl AsRef], file_name: String) -> Result, MpcError> { -pub fn setup_engine(my_addr: &str, others: &[impl AsRef], file_name: &Path) -> Result { +pub fn setup_engine(my_addr: &str, others: &[impl AsRef], mut file: File) -> Result { let my_addr: SocketAddr = my_addr.parse().unwrap(); let others: Vec = others.iter().map(|s| s.as_ref().parse().unwrap()).collect(); @@ -134,7 +133,7 @@ pub fn setup_engine(my_addr: &str, others: &[impl AsRef], file_name: &Path) .unwrap(); let network = TcpNetwork::connect(my_addr, &others); let network = runtime.block_on(network).map_err(|_| MpcError("Failed to setup network"))?; - let mut context = preprocessing::read_preproc_from_file(file_name); + let mut context = preprocessing::read_preproc_from_file(&mut file); // Notice: This is a hack and only works as long as the parties share the same number of elements. // To make a propper solotion, the id must be known befor the preprocessing is made. // To ensure that the right number of elements are made for each party. @@ -148,13 +147,13 @@ pub fn setup_engine(my_addr: &str, others: &[impl AsRef], file_name: &Path) Ok(engine) } -pub fn do_preproc(filenames: &[&Path], number_of_shares: Vec){ - assert_eq!(filenames.len(), number_of_shares.len()); +pub fn do_preproc(files: &mut [File], number_of_shares: Vec){ + assert_eq!(files.len(), number_of_shares.len()); let known_to_each = vec![number_of_shares[0], number_of_shares[1]]; let number_of_triplets = 0; let num = to_offset(0.0); preprocessing::write_preproc_to_file( - filenames, + files, known_to_each, number_of_triplets, curve25519_dalek::Scalar::from(num), @@ -163,7 +162,7 @@ pub fn do_preproc(filenames: &[&Path], number_of_shares: Vec){ #[cfg(test)] mod test { - use std::time::Duration; + use std::{io::Seek, time::Duration}; use super::*; @@ -183,10 +182,16 @@ mod test { #[test] fn sunshine() { use std::thread; - do_preproc(&[Path::new("/tmp/context1.bin"), Path::new("/tmp/context2.bin")], vec![1,1]); - let t1 = thread::spawn(|| { + let ctx1 = tempfile::tempfile().unwrap(); + let ctx2 = tempfile::tempfile().unwrap(); + let mut files = [ctx1, ctx2]; + do_preproc(&mut files, vec![1,1]); + let [mut ctx1, mut ctx2] = files; + ctx1.rewind().unwrap(); + ctx2.rewind().unwrap(); + let t1 = thread::spawn(move || { println!("[1] Setting up..."); - let mut engine = setup_engine("127.0.0.1:1234", &["127.0.0.1:1235"], Path::new("/tmp/context1.bin") ).unwrap(); + let mut engine = setup_engine("127.0.0.1:1234", &["127.0.0.1:1235"], ctx1 ).unwrap(); println!("[1] Ready"); let res = mpc_sum(&mut engine, &[32.0]).unwrap(); println!("[1] Done"); @@ -194,9 +199,9 @@ mod test { res }); std::thread::sleep(Duration::from_millis(50)); - let t2 = thread::spawn(|| { + let t2 = thread::spawn(move || { println!("[2] Setting up..."); - let mut engine = setup_engine("127.0.0.1:1235", &["127.0.0.1:1234"], Path::new("/tmp/context2.bin") ).unwrap(); + let mut engine = setup_engine("127.0.0.1:1235", &["127.0.0.1:1234"], ctx2 ).unwrap(); println!("[2] Ready"); let res = mpc_sum(&mut engine, &[32.0]).unwrap(); println!("[2] Done"); @@ -212,10 +217,17 @@ mod test { #[test] fn sunshine_for_two() { use std::thread; - do_preproc(&[Path::new("/tmp/context3.bin"), Path::new("/tmp/context4.bin")], vec![2,2]); + + let ctx1 = tempfile::tempfile().unwrap(); + let ctx2 = tempfile::tempfile().unwrap(); + let mut files = [ctx1, ctx2]; + do_preproc(&mut files, vec![2,2]); + let [mut ctx1, mut ctx2] = files; + ctx1.rewind().unwrap(); + ctx2.rewind().unwrap(); let t1 = thread::spawn(|| { println!("[1] Setting up..."); - let mut engine = setup_engine("127.0.0.1:2234", &["127.0.0.1:2235"], Path::new("/tmp/context3.bin") ).unwrap(); + let mut engine = setup_engine("127.0.0.1:2234", &["127.0.0.1:2235"], ctx1 ).unwrap(); println!("[1] Ready"); let res = mpc_sum(&mut engine, &[32.0, 11.9]).unwrap(); println!("[1] Done"); @@ -225,7 +237,7 @@ mod test { std::thread::sleep(Duration::from_millis(50)); let t2 = thread::spawn(|| { println!("[2] Setting up..."); - let mut engine = setup_engine("127.0.0.1:2235", &["127.0.0.1:2234"], Path::new("/tmp/context4.bin") ).unwrap(); + let mut engine = setup_engine("127.0.0.1:2235", &["127.0.0.1:2234"], ctx2 ).unwrap(); println!("[2] Ready"); let res = mpc_sum(&mut engine, &[32.0, 24.1]).unwrap(); println!("[2] Done");