Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Further summonerd parallelization #3272

Merged
merged 3 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions crates/bin/pcli/src/command/ceremony.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,12 @@ pub enum CeremonyCmd {
Contribute {
#[clap(long)]
phase: u8,
#[clap(long, default_value="https://summoning-dev.penumbra.zone")]
#[clap(long, default_value = "https://summoning-dev.penumbra.zone")]
coordinator_url: Url,
#[clap(long, default_value="penumbra1zjd6p7d6xta200mzcxtcudqthe4yfsnm6cw7wpr6tdecj6gsdpjmjld6vezu7rdj3kr8u9rl9pkhgst99sxy8wlvl8wqsst0wjhy0wewsczx9d6ys96z84rhewdwrm537y6wwz")]
#[clap(
long,
default_value = "penumbra1zjd6p7d6xta200mzcxtcudqthe4yfsnm6cw7wpr6tdecj6gsdpjmjld6vezu7rdj3kr8u9rl9pkhgst99sxy8wlvl8wqsst0wjhy0wewsczx9d6ys96z84rhewdwrm537y6wwz"
)]
coordinator_address: Address,
#[clap(long)]
bid: String,
Expand Down
28 changes: 22 additions & 6 deletions crates/crypto/proof-setup/src/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::single::{
use anyhow::{anyhow, Result};
use ark_groth16::ProvingKey;
use ark_relations::r1cs::ConstraintMatrices;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate};
use decaf377::Bls12_377;
use penumbra_dex::{swap::proof::SwapCircuit, swap_claim::proof::SwapClaimCircuit};
use penumbra_governance::DelegatorVoteCircuit;
Expand All @@ -30,18 +30,28 @@ use rand_core::OsRng;

// Some helper functions since we have to use these seventeen billion times

const SERIALIZATION_COMPRESSION: Compress = Compress::No;

fn to_bytes<T: CanonicalSerialize>(t: &T) -> Result<Vec<u8>> {
let mut out = Vec::new();
t.serialize_uncompressed(&mut out)?;
t.serialize_with_mode(&mut out, SERIALIZATION_COMPRESSION)?;
Ok(out)
}

fn from_bytes<T: CanonicalDeserialize>(data: &[u8]) -> Result<T> {
Ok(T::deserialize_uncompressed(data)?)
Ok(T::deserialize_with_mode(
data,
SERIALIZATION_COMPRESSION,
Validate::Yes,
)?)
}

fn from_bytes_unchecked<T: CanonicalDeserialize>(data: &[u8]) -> Result<T> {
Ok(T::deserialize_uncompressed_unchecked(data)?)
Ok(T::deserialize_with_mode(
data,
SERIALIZATION_COMPRESSION,
Validate::No,
)?)
}

pub const NUM_CIRCUITS: usize = 7;
Expand Down Expand Up @@ -239,7 +249,10 @@ impl TryFrom<pb::participate_request::Contribution> for Phase2RawCeremonyContrib
let out = transform_parallel(data, |(parent_hash, updated, update_proof)| {
Ok::<_, anyhow::Error>(Phase2RawContribution {
parent: ContributionHash::try_from(parent_hash.as_slice())?,
new_elements: from_bytes::<Phase2RawCRSElements>(updated.as_slice())?,
new_elements: Phase2RawCRSElements::checked_deserialize_parallel(
SERIALIZATION_COMPRESSION,
updated.as_slice(),
)?,
linking_proof: from_bytes::<DLogProof>(update_proof.as_slice())?,
})
});
Expand Down Expand Up @@ -559,7 +572,10 @@ impl TryFrom<pb::participate_request::Contribution> for Phase1RawCeremonyContrib
let out = transform_parallel(data, |(parent_hash, updated, update_proof)| {
Ok::<_, anyhow::Error>(Phase1RawContribution {
parent: ContributionHash::try_from(parent_hash.as_slice())?,
new_elements: from_bytes::<Phase1RawCRSElements>(updated.as_slice())?,
new_elements: Phase1RawCRSElements::checked_deserialize_parallel(
SERIALIZATION_COMPRESSION,
updated.as_slice(),
)?,
linking_proof: from_bytes::<LinkingProof>(update_proof.as_slice())?,
})
});
Expand Down
23 changes: 23 additions & 0 deletions crates/crypto/proof-setup/src/parallel_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,26 @@ pub fn flatten_results<A, E, const N: usize>(data: [Result<A, E>; N]) -> Result<
_ => panic!("The size of the iterator should not have changed"),
}
}

#[cfg(not(feature = "parallel"))]
pub fn zip_map_parallel<A: Send, B: Send, C: Sync + Send>(
a: &mut [A],
b: &mut [B],
f: impl Fn(&A, &B) -> C + Send + Sync,
) -> Vec<C> {
a.iter().zip(b.iter()).map(|(a, b)| f(a, b)).collect()
}

#[cfg(feature = "parallel")]
pub fn zip_map_parallel<A: Send, B: Send, C: Sync + Send>(
a: &mut [A],
b: &mut [B],
f: impl Fn(&A, &B) -> C + Send + Sync,
) -> Vec<C> {
use rayon::prelude::*;

a.into_par_iter()
.zip(b.into_par_iter())
.map(|(a, b)| f(a, b))
.collect()
}
158 changes: 125 additions & 33 deletions crates/crypto/proof-setup/src/single/phase1.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use anyhow::anyhow;
use ark_ec::Group;
use ark_ff::{One, UniformRand, Zero};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Valid, Validate};
use rand_core::{CryptoRngCore, OsRng};

use crate::parallel_utils::{flatten_results, transform_parallel};
use crate::parallel_utils::{flatten_results, transform_parallel, zip_map_parallel};
use crate::single::dlog;
use crate::single::group::{
BatchedPairingChecker11, BatchedPairingChecker12, GroupHasher, F, G1, G2,
Expand Down Expand Up @@ -149,6 +149,76 @@ impl RawCRSElements {
raw: self,
}
}

/// This is a replacement for the CanonicalDeserialize trait impl (more or less).
#[cfg(not(feature = "parallel"))]
pub(crate) fn checked_deserialize_parallel(compress: Compress, data: &[u8]) -> Self {
Self::deserialize_with_mode(data, compress, Validate::Yes)
}

/// This is a replacement for the CanonicalDeserialize trait impl (more or less).
#[cfg(feature = "parallel")]
pub(crate) fn checked_deserialize_parallel(
compress: Compress,
data: &[u8],
) -> anyhow::Result<Self> {
use rayon::prelude::*;

let out = Self::deserialize_with_mode(data, compress, Validate::No)?;
out.alpha_1.check()?;
out.beta_1.check()?;
out.beta_2.check()?;

let mut check_x_1 = Ok(());
let mut check_x_2 = Ok(());
let mut check_alpha_x_1 = Ok(());
let mut check_beta_x_1 = Ok(());

rayon::join(
|| {
rayon::join(
|| {
check_x_1 = out
.x_1
.par_iter()
.map(|x| x.check())
.collect::<Result<_, _>>();
},
|| {
check_x_2 = out
.x_2
.par_iter()
.map(|x| x.check())
.collect::<Result<_, _>>();
},
)
},
|| {
rayon::join(
|| {
check_alpha_x_1 = out
.alpha_x_1
.par_iter()
.map(|x| x.check())
.collect::<Result<_, _>>();
},
|| {
check_beta_x_1 = out
.beta_x_1
.par_iter()
.map(|x| x.check())
.collect::<Result<_, _>>();
},
)
},
);

check_x_1?;
check_x_2?;
check_alpha_x_1?;
check_beta_x_1?;
Ok(out)
}
}

impl Hashable for RawCRSElements {
Expand Down Expand Up @@ -324,38 +394,11 @@ impl Contribution {
let beta = F::rand(rng);
let x = F::rand(rng);

let mut new = old.clone();

new.raw.alpha_1 *= alpha;
new.raw.beta_1 *= beta;
new.raw.beta_2 *= beta;

let mut x_i = F::one();
let mut alpha_x_i = alpha;
let mut beta_x_i = beta;

let d = old.degree;
for i in 0..short_len(d) {
new.raw.x_1[i] *= x_i;
new.raw.x_2[i] *= x_i;
new.raw.alpha_x_1[i] *= alpha_x_i;
new.raw.beta_x_1[i] *= beta_x_i;

x_i *= x;
alpha_x_i *= x;
beta_x_i *= x;
}
for i in short_len(d)..long_len(d) {
new.raw.x_1[i] *= x_i;

x_i *= x;
}

let alpha_proof = dlog::prove(
rng,
b"phase1 alpha proof",
dlog::Statement {
result: new.raw.alpha_1,
result: old.raw.alpha_1 * alpha,
base: old.raw.alpha_1,
},
dlog::Witness { dlog: alpha },
Expand All @@ -364,7 +407,7 @@ impl Contribution {
rng,
b"phase1 beta proof",
dlog::Statement {
result: new.raw.beta_1,
result: old.raw.beta_1 * beta,
base: old.raw.beta_1,
},
dlog::Witness { dlog: beta },
Expand All @@ -373,15 +416,64 @@ impl Contribution {
rng,
b"phase1 x proof",
dlog::Statement {
result: new.raw.x_1[1],
result: old.raw.x_1[1] * x,
base: old.raw.x_1[1],
},
dlog::Witness { dlog: x },
);

let d = old.degree;

let (mut x_i_tweaks, mut alpha_x_i_tweaks, mut beta_x_i_tweaks) = {
let mut x_i_tweaks = Vec::new();
let mut alpha_x_i_tweaks = Vec::new();
let mut beta_x_i_tweaks = Vec::new();

let mut x_i = F::one();
let mut alpha_x_i = alpha;
let mut beta_x_i = beta;

for _ in 0..short_len(d) {
x_i_tweaks.push(x_i);
alpha_x_i_tweaks.push(alpha_x_i);
beta_x_i_tweaks.push(beta_x_i);

x_i *= x;
alpha_x_i *= x;
beta_x_i *= x;
}
for _ in short_len(d)..long_len(d) {
x_i_tweaks.push(x_i);

x_i *= x;
}

(x_i_tweaks, alpha_x_i_tweaks, beta_x_i_tweaks)
};

let mut old = old.clone();
let x_1 = zip_map_parallel(&mut old.raw.x_1, &mut x_i_tweaks, |g, x| *g * x);
let x_2 = zip_map_parallel(&mut old.raw.x_2, &mut x_i_tweaks, |g, x| *g * x);
let alpha_x_1 =
zip_map_parallel(&mut old.raw.alpha_x_1, &mut alpha_x_i_tweaks, |g, x| *g * x);
let beta_x_1 = zip_map_parallel(&mut old.raw.beta_x_1, &mut beta_x_i_tweaks, |g, x| *g * x);

let new_elements = CRSElements {
degree: d,
raw: RawCRSElements {
alpha_1: old.raw.alpha_1 * alpha,
beta_1: old.raw.beta_1 * beta,
beta_2: old.raw.beta_2 * beta,
x_1,
x_2,
alpha_x_1,
beta_x_1,
},
};

Self {
parent,
new_elements: new,
new_elements,
linking_proof: LinkingProof {
alpha_proof,
beta_proof,
Expand Down
45 changes: 44 additions & 1 deletion crates/crypto/proof-setup/src/single/phase2.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This module is very similar to the one for phase1, so reading that one might be useful.
use ark_ec::Group;
use ark_ff::{fields::Field, UniformRand, Zero};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Valid, Validate};
use rand_core::{CryptoRngCore, OsRng};

use crate::single::log::{ContributionHash, Hashable, Phase};
Expand Down Expand Up @@ -59,6 +59,49 @@ impl RawCRSElements {
pub(crate) fn assume_valid(self) -> CRSElements {
CRSElements { raw: self }
}

/// This is a replacement for the CanonicalDeserialize trait impl (more or less).
#[cfg(not(feature = "parallel"))]
pub(crate) fn checked_deserialize_parallel(compress: Compress, data: &[u8]) -> Self {
Self::deserialize_with_mode(data, compress, Validate::Yes)
}

/// This is a replacement for the CanonicalDeserialize trait impl (more or less).
#[cfg(feature = "parallel")]
pub(crate) fn checked_deserialize_parallel(
compress: Compress,
data: &[u8],
) -> anyhow::Result<Self> {
use rayon::prelude::*;

let out = Self::deserialize_with_mode(data, compress, Validate::No)?;
out.delta_1.check()?;
out.delta_2.check()?;

let mut check_inv_delta_p_1 = Ok(());
let mut check_inv_delta_t_1 = Ok(());

rayon::join(
|| {
check_inv_delta_p_1 = out
.inv_delta_p_1
.par_iter()
.map(|x| x.check())
.collect::<Result<_, _>>();
},
|| {
check_inv_delta_t_1 = out
.inv_delta_t_1
.par_iter()
.map(|x| x.check())
.collect::<Result<_, _>>();
},
);

check_inv_delta_p_1?;
check_inv_delta_t_1?;
Ok(out)
}
}

impl Hashable for RawCRSElements {
Expand Down
Loading