optimize Params<C>::read()

This commit is contained in:
spherel 2022-05-02 06:50:52 +00:00
parent 14263e9208
commit c1f77ad576
3 changed files with 85 additions and 8 deletions

View File

@ -1,6 +1,8 @@
//! This module provides common utilities, traits and structures for group,
//! field and polynomial arithmetic.
use std::io;
use super::multicore;
pub use ff::Field;
use group::{
@ -352,6 +354,42 @@ pub fn parallelize<T: Send, F: Fn(&mut [T], usize) + Send + Sync + Clone>(v: &mu
});
}
/// This simple utility function will parallelize an operation returning `io::Result` that is to be
/// performed over a mutable slice.
pub fn parallelize_is_ok<
T: Send,
F: Fn(&mut [T], usize) -> io::Result<()> + Send + Sync + Clone,
>(
v: &mut [T],
f: F,
) -> io::Result<()> {
let n = v.len();
let num_threads = multicore::current_num_threads();
let mut chunk = (n as usize) / num_threads;
if chunk < num_threads {
chunk = n as usize;
}
let mut is_ok = true;
multicore::scope(|scope| {
for (chunk_num, v) in v.chunks_mut(chunk).enumerate() {
let f = f.clone();
scope.spawn(move |_| {
let start = chunk_num * chunk;
is_ok = is_ok && f(v, start).is_ok();
});
}
});
match is_ok {
true => Ok(()),
false => Err(io::Error::new(
io::ErrorKind::Other,
"invalid point encoding in proof",
)),
}
}
fn log2_floor(num: usize) -> u32 {
assert!(num > 0);

View File

@ -11,6 +11,11 @@ pub(crate) trait CurveRead: CurveAffine {
Option::from(Self::from_bytes(&compressed))
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point encoding in proof"))
}
fn convert_from_bytes(compressed: Self::Repr) -> io::Result<Self> {
Option::from(Self::from_bytes(&compressed))
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point encoding in proof"))
}
}
impl<C: CurveAffine> CurveRead for C {}

View File

@ -5,7 +5,8 @@
use super::{Coeff, LagrangeCoeff, Polynomial, MSM};
use crate::arithmetic::{
best_fft, best_multiexp, parallelize, CurveAffine, CurveExt, Engine, FieldExt, Group,
best_fft, best_multiexp, parallelize, parallelize_is_ok, CurveAffine, CurveExt, Engine,
FieldExt, Group,
};
use crate::helpers::CurveRead;
@ -177,12 +178,45 @@ impl<C: CurveAffine> Params<C> {
let k = u32::from_le_bytes(k);
let n = 1 << k;
let g: Vec<C> = (0..n)
.map(|_| C::read(&mut reader))
.collect::<Result<_, _>>()?;
let g_lagrange: Vec<C> = (0..n)
.map(|_| C::read(&mut reader))
.collect::<Result<_, _>>()?;
let mut g_compressed: Vec<C::Repr> = vec![C::Repr::default(); n];
for i in 0..n {
reader.read_exact(g_compressed[i].as_mut())?;
}
let mut g_lagrange_compressed: Vec<C::Repr> = vec![C::Repr::default(); n];
for i in 0..n {
reader.read_exact(g_lagrange_compressed[i].as_mut())?;
}
let g: Vec<C> = {
let mut g = vec![C::default(); n];
parallelize_is_ok(&mut g, |g, chunks| {
for (i, g) in g.iter_mut().enumerate() {
let tmp = C::convert_from_bytes(g_compressed[chunks + i]);
*g = match tmp {
Ok(ele) => ele,
Err(e) => return Err(e),
}
}
Ok(())
})?;
g
};
let g_lagrange: Vec<C> = {
let mut g_lagrange = vec![C::default(); n];
parallelize_is_ok(&mut g_lagrange, |g_lagrange, chunks| {
for (i, g_lagrange) in g_lagrange.iter_mut().enumerate() {
let tmp = C::convert_from_bytes(g_lagrange_compressed[chunks + i]);
*g_lagrange = match tmp {
Ok(ele) => ele,
Err(e) => return Err(e),
}
}
Ok(())
})?;
g_lagrange
};
let mut additional_data_len = [0u8; 4];
reader.read_exact(&mut additional_data_len[..])?;
@ -193,7 +227,7 @@ impl<C: CurveAffine> Params<C> {
Ok(Params {
k,
n,
n: n as u64,
g,
g_lagrange,
additional_data,