mirror of https://github.com/zcash/mpc.git
Make FFT and division by d parallel.
This commit is contained in:
parent
ac39f38e90
commit
4ad19126df
|
@ -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"
|
||||
|
|
|
@ -11,3 +11,4 @@ readme = "README.md"
|
|||
|
||||
[dependencies]
|
||||
snark = { path = "./snark/" }
|
||||
crossbeam = "0.2.9"
|
||||
|
|
|
@ -156,7 +156,7 @@ pub fn pairing<Ga: Group, Gb: Group>(p: &Ga, q: &Gb) -> Gt where Ga: Pairing<Gb>
|
|||
unsafe { libsnarkwrap_pairing(p.g1(q), p.g2(q)) }
|
||||
}
|
||||
|
||||
pub trait Group: Sized +
|
||||
pub trait Group: Sized + Send +
|
||||
Copy +
|
||||
Clone +
|
||||
Mul<Fr, Output=Self> +
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
use snark::{Group, Fr};
|
||||
use crossbeam;
|
||||
|
||||
pub fn lagrange_coeffs<G: Group>(v: &[G], omega: Fr, d: usize) -> Vec<G>
|
||||
{
|
||||
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::<Vec<_>>()
|
||||
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<G: Group>(v: &[G], omega: Fr) -> Vec<G>
|
||||
fn fft<G: Group>(v: &[G], omega: Fr, threads: usize) -> Vec<G>
|
||||
{
|
||||
if v.len() == 2 {
|
||||
vec![
|
||||
|
@ -31,8 +43,25 @@ fn fft<G: Group>(v: &[G], omega: Fr) -> Vec<G>
|
|||
}
|
||||
|
||||
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());
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extern crate snark;
|
||||
extern crate crossbeam;
|
||||
|
||||
mod util;
|
||||
mod lagrange;
|
||||
|
|
Loading…
Reference in New Issue