diff --git a/Cargo.lock b/Cargo.lock index c8b9f1e..bfa2718 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,9 +2,15 @@ name = "mpc" version = "0.0.1" dependencies = [ + "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "snark 0.0.1", ] +[[package]] +name = "crossbeam" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "gcc" version = "0.3.32" @@ -30,6 +36,7 @@ dependencies = [ ] [metadata] +"checksum crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "fb974f835e90390c5f9dfac00f05b06dc117299f5ea4e85fbc7bb443af4911cc" "checksum gcc 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "dcb000abd6df9df4c637f75190297ebe56c1d7e66b56bbf3b4aa7aece15f61a2" "checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" "checksum libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "39dfaaa0f4da0f1a06876c5d94329d739ad0150868069cc235f1ddf80a0480e7" diff --git a/Cargo.toml b/Cargo.toml index 791b356..2548289 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ readme = "README.md" [dependencies] snark = { path = "./snark/" } +crossbeam = "0.2.9" diff --git a/snark/src/lib.rs b/snark/src/lib.rs index a4d6326..cb0b7aa 100644 --- a/snark/src/lib.rs +++ b/snark/src/lib.rs @@ -156,7 +156,7 @@ pub fn pairing(p: &Ga, q: &Gb) -> Gt where Ga: Pairing unsafe { libsnarkwrap_pairing(p.g1(q), p.g2(q)) } } -pub trait Group: Sized + +pub trait Group: Sized + Send + Copy + Clone + Mul + diff --git a/src/lagrange.rs b/src/lagrange.rs index a4c10fe..b59fa2b 100644 --- a/src/lagrange.rs +++ b/src/lagrange.rs @@ -1,16 +1,28 @@ use snark::{Group, Fr}; +use crossbeam; pub fn lagrange_coeffs(v: &[G], omega: Fr, d: usize) -> Vec { + const THREADS: usize = 8; + let overd = Fr::from_str(&format!("{}", d)).inverse(); - fft(v, omega) - .into_iter() - .rev() // coefficients are in reverse - .map(|e| e * overd) // divide by d - .collect::>() + let mut tmp = fft(v, omega, THREADS); + tmp.reverse(); // coefficients are in reverse + + crossbeam::scope(|scope| { + for i in tmp.chunks_mut(d / THREADS) { + scope.spawn(move || { + for i in i { + *i = *i * overd; + } + }); + } + }); + + tmp } -fn fft(v: &[G], omega: Fr) -> Vec +fn fft(v: &[G], omega: Fr, threads: usize) -> Vec { if v.len() == 2 { vec![ @@ -31,8 +43,25 @@ fn fft(v: &[G], omega: Fr) -> Vec } let o2 = omega * omega; - let evens = fft(&evens, o2); - let odds = fft(&odds, o2); + let (evens, odds) = if threads < 2 { + (fft(&evens, o2, 1), fft(&odds, o2, 1)) + } else { + use std::sync::mpsc::channel; + use std::thread; + + let (tx_evens, rx_evens) = channel(); + let (tx_odds, rx_odds) = channel(); + + thread::spawn(move || { + tx_evens.send(fft(&evens, o2, threads/2)).unwrap(); + }); + + thread::spawn(move || { + tx_odds.send(fft(&odds, o2, threads/2)).unwrap(); + }); + + (rx_evens.recv().unwrap(), rx_odds.recv().unwrap()) + }; let mut acc = omega; let mut res = Vec::with_capacity(v.len()); diff --git a/src/main.rs b/src/main.rs index 28536fc..db27492 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ extern crate snark; +extern crate crossbeam; mod util; mod lagrange;