From 5ec16fae1aaa862a195ac9e573a00bdbe9c88fdc Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Tue, 30 Aug 2022 15:39:36 -0700 Subject: [PATCH 01/60] wip: trusted setup client and server --- .../src/groth16/ceremony/client.rs | 35 ++++++++ .../src/groth16/ceremony/mod.rs | 7 +- .../src/groth16/ceremony/server.rs | 83 +++++++++++++++++++ .../src/groth16/ceremony/signature.rs | 15 +++- 4 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 manta-trusted-setup/src/groth16/ceremony/client.rs create mode 100644 manta-trusted-setup/src/groth16/ceremony/server.rs diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs new file mode 100644 index 000000000..ebc899baf --- /dev/null +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -0,0 +1,35 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Trusted Setup Client + +use crate::groth16::ceremony::{signature::Nonce, Ceremony, Participant}; +use manta_crypto::dalek::ed25519::Ed25519; + +/// Client +pub struct Client +where + C: Ceremony, +{ + /// Identifier + Identifier: C::Identifier, + + /// Current Nonce + nonce: u64, + + /// Private Key + private_key: Ed25519, +} diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index d03db33d7..b6e013d3c 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -16,7 +16,7 @@ //! Groth16 Trusted Setup Ceremony -use crate::mpc; +use crate::{groth16::ceremony::signature::SignatureScheme, mpc}; pub mod registry; @@ -24,6 +24,8 @@ pub mod registry; #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] pub mod coordinator; +pub mod client; +pub mod server; #[cfg(all(feature = "bincode", feature = "serde"))] #[cfg_attr(doc_cfg, doc(cfg(all(feature = "bincode", feature = "serde"))))] pub mod signature; @@ -51,4 +53,7 @@ pub trait Ceremony: mpc::Types { /// Participant Type type Participant: Participant; + + /// Signature Scheme + type SignatureScheme: SignatureScheme; } diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs new file mode 100644 index 000000000..d9fbb5750 --- /dev/null +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -0,0 +1,83 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Trusted Setup Server + +use crate::groth16::{ + ceremony::{ + coordinator::{ChallengeArray, Coordinator, StateArray}, + registry::Registry, + Ceremony, + }, + mpc::StateSize, +}; +use manta_util::Array; +use std::sync::{Arc, Mutex}; +use manta_crypto::signature::{MessageType, SignatureType, SignedMessage}; + +pub struct Server +where + C: Ceremony, + R: Registry, +{ + /// Coordinator + coordinator: Arc>>, + + /// Recovery directory path + recovery_path: String, +} + +impl + Server +where + C: Ceremony, + R: Registry, +{ + /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a `recovery_path`. + #[inline] + pub fn new( + state: StateArray, + challenge: ChallengeArray, + registry: R, + recovery_path: String, + size: Array, + ) -> Self { + let coordinator = Coordinator { + registry, + queue: Default::default(), + participant_lock: Default::default(), + state, + challenge, + latest_contributor: None, + latest_proof: None, + size, + round: 0, + }; + Self { + coordinator: Arc::new(Mutex::new(coordinator)), + recovery_path, + } + } + + /// Processes a request by checking nonce and verifying signature. + #[inline] + pub fn process_request( + registry: &mut R, + request: &SignedMessage + ) where T: MessageType + SignatureType{ + let participant = match registry.get_mut(&request.) + } +} diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index 5fe9d3751..07f12951e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -17,7 +17,11 @@ //! Groth16 Trusted Setup Ceremony Signatures use alloc::vec::Vec; -use manta_crypto::signature; +use manta_crypto::{ + dalek::ed25519::{Ed25519, SignatureError}, + signature, + signature::{Sign, Verify}, +}; use manta_util::{serde::Serialize, AsBytes}; /// Nonce @@ -148,3 +152,12 @@ where ) .map_err(VerificationError::Error) } + +// impl SignatureScheme for Ed25519> +// where +// N: Nonce + Default, +// { +// type Nonce = N; +// +// type Error = SignatureError; +// } From 41eff548bde3c44de1cc2b8ebd759e5535d3b0ec Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Tue, 30 Aug 2022 17:01:24 -0700 Subject: [PATCH 02/60] wip: server and message --- .../src/groth16/ceremony/message.rs | 248 ++++++++++++++++++ .../src/groth16/ceremony/mod.rs | 15 +- .../src/groth16/ceremony/registry.rs | 8 +- .../src/groth16/ceremony/server.rs | 44 +++- manta-trusted-setup/src/groth16/mod.rs | 42 +++ manta-trusted-setup/src/lib.rs | 1 + manta-trusted-setup/src/utils.rs | 34 +++ 7 files changed, 382 insertions(+), 10 deletions(-) create mode 100644 manta-trusted-setup/src/groth16/ceremony/message.rs create mode 100644 manta-trusted-setup/src/utils.rs diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs new file mode 100644 index 000000000..06797e399 --- /dev/null +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -0,0 +1,248 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Messages through Network + +use crate::{ + groth16::{ + ceremony::{signature::Nonce as _, Ceremony, Nonce, Proof, Signature, SigningKey}, + mpc::State, + }, + mpc::Challenge, + utils::BytesRepr, +}; +use derivative::Derivative; +use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; +use manta_util::{ + serde, + serde::{Deserialize, Deserializer, Serialize, Serializer}, + Array, +}; +use std::marker::PhantomData; + +use super::signature::sign; + +/// Query Request +#[derive(Deserialize, Serialize)] +#[serde(crate = "manta_util::serde", deny_unknown_fields)] +pub struct QueryRequest; + +/// Response for [`QueryRequest`] +#[derive(Deserialize, Serialize)] +#[serde( + bound( + serialize = "MPCState: Serialize", + deserialize = "MPCState: Deserialize<'de>" + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub enum QueryResponse +where + C: Ceremony, +{ + /// Queue Position + QueuePosition(usize), + + /// MPC State + Mpc(MPCState), +} + +/// Contribute Request +#[derive(Serialize, Deserialize)] +#[serde( + bound( + serialize = "ContributeState: Serialize", + deserialize = "ContributeState: Deserialize<'de>" + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct ContributeRequest +where + C: Ceremony, +{ + /// Contribute state including state and proof + pub contribute_state: ContributeState, +} + +/// Signed Message +#[derive(Deserialize, Serialize)] +#[serde( + bound( + serialize = r" + C::Identifier: Serialize, + T: Serialize, + Nonce: Serialize, + Signature: Serialize, + ", + deserialize = r" + C::Identifier: Deserialize<'de>, + T: Deserialize<'de>, + Nonce: Deserialize<'de>, + Signature: Deserialize<'de>, + ", + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct Signed +where + C: Ceremony, +{ + /// Participant + pub identifier: C::Identifier, + + /// Message + pub message: T, + + /// Nonce + pub nonce: Nonce, + + /// Signature + pub signature: Signature, +} + +impl Signed +where + C: Ceremony, +{ + /// Generates a signed message using user's identifier, nonce, and key pair, and increment nonce by 1. + #[inline] + pub fn new( + message: T, + identifier: C::Identifier, + nonce: &mut Nonce, + signing_key: &SigningKey, + ) -> Result + where + T: Serialize, + { + let signature = sign::<_, C::SignatureScheme>(&message, nonce.clone(), signing_key)?; + let message = Signed { + message, + identifier, + nonce: nonce.clone(), + signature, + }; + nonce.increment(); + Ok(message) + } +} + +/// Ceremony Error +/// +/// # Note +/// +/// All errors here are visible to users. +#[derive(PartialEq, Serialize, Deserialize, Derivative)] +#[derivative(Debug(bound = "Nonce: core::fmt::Debug"))] +#[serde( + bound( + serialize = "Nonce: Serialize", + deserialize = "Nonce: Deserialize<'de>", + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub enum CeremonyError +where + C: Ceremony, +{ + /// Malformed request that should not come from official client + BadRequest, + + /// Nonce not in sync, and client needs to update the nonce + NonceNotInSync(Nonce), + + /// Not Registered + NotRegistered, + + /// Already Contributed + AlreadyContributed, + + /// Not Your Turn + NotYourTurn, + + /// Timed-out + Timeout, +} + +/// MPC States +#[derive(Deserialize, Serialize)] +#[serde( + bound( + serialize = "State: CanonicalSerialize, Challenge: CanonicalSerialize", + deserialize = "State: CanonicalDeserialize, Challenge: CanonicalDeserialize" + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct MPCState +where + C: Ceremony, +{ + /// State + pub state: Array>, N>, + + /// Challenge + pub challenge: Array>, N>, + + __: PhantomData, +} + +/// Contribute States +#[derive(Deserialize, Serialize)] +#[serde( + bound( + serialize = "State: CanonicalSerialize, Proof: CanonicalSerialize", + deserialize = "State: CanonicalDeserialize, Proof: CanonicalDeserialize" + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct ContributeState +where + C: Ceremony, +{ + /// State + pub state: Array>, CIRCUIT_COUNT>, + + /// Proof + pub proof: Array>, CIRCUIT_COUNT>, +} + +/// Response for State Sizes +#[derive(Clone, Serialize, Deserialize)] +#[serde(crate = "manta_util::serde", deny_unknown_fields)] +pub struct ServerSize(pub Array); + +/// State Size +#[derive(Clone, Serialize, Deserialize)] +#[serde(crate = "manta_util::serde", deny_unknown_fields)] +pub struct StateSize { + /// Size of gamma_abc_g1 in verifying key + pub gamma_abc_g1: usize, + + /// Size of a_query, b_g1_query, and b_g2_query which are equal + pub a_b_g1_b_g2_query: usize, + + /// Size of h_query + pub h_query: usize, + + /// Size of l_query + pub l_query: usize, +} diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index b6e013d3c..0cda79671 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -16,7 +16,8 @@ //! Groth16 Trusted Setup Ceremony -use crate::{groth16::ceremony::signature::SignatureScheme, mpc}; +use crate::{groth16::ceremony::signature::SignatureScheme, mpc, mpc::ProofType}; +use manta_crypto::signature::{SignatureType, SigningKeyType, VerifyingKeyType}; pub mod registry; @@ -25,6 +26,7 @@ pub mod registry; pub mod coordinator; pub mod client; +pub mod message; pub mod server; #[cfg(all(feature = "bincode", feature = "serde"))] #[cfg_attr(doc_cfg, doc(cfg(all(feature = "bincode", feature = "serde"))))] @@ -34,10 +36,15 @@ pub mod signature; pub trait Participant { /// Participant Identifier Type type Identifier; + /// Participant Verifying Key Type + type VerifyingKey; /// Returns the [`Identifier`](Self::Identifier) for `self`. fn id(&self) -> &Self::Identifier; + /// Returns the [`VerifyingKey`](Self::VerifyingKey) for `self`. + fn verifying_key(&self) -> &Self::VerifyingKey; + /// Returns the priority level for `self`. /// /// # Note @@ -57,3 +64,9 @@ pub trait Ceremony: mpc::Types { /// Signature Scheme type SignatureScheme: SignatureScheme; } + +pub type Nonce = <::SignatureScheme as SignatureScheme>::Nonce; +pub type Signature = <::SignatureScheme as SignatureType>::Signature; +pub type SigningKey = <::SignatureScheme as SigningKeyType>::SigningKey; +pub type VerifyingKey = <::SignatureScheme as VerifyingKeyType>::VerifyingKey; +pub type Proof = ::Proof; diff --git a/manta-trusted-setup/src/groth16/ceremony/registry.rs b/manta-trusted-setup/src/groth16/ceremony/registry.rs index 7637086d2..7ba158b46 100644 --- a/manta-trusted-setup/src/groth16/ceremony/registry.rs +++ b/manta-trusted-setup/src/groth16/ceremony/registry.rs @@ -17,7 +17,7 @@ //! Groth16 Trusted Setup Ceremony Registry /// Participant Registry -pub trait Registry { +pub trait Registry { /// Registers the `participant` into `self` returning `false` if the `participant` is already /// registered or their registration would conflict with another existing participant. fn register(&mut self, participant: P) -> bool; @@ -31,4 +31,10 @@ pub trait Registry { /// Returns `true` if the participant with the given `id` has already contributed to the /// ceremony. fn has_contributed(&self, id: &I) -> bool; + + /// Returns nonce of current participant. + fn get_nonce(&self, id: &I) -> Option; + + /// Set nonce of current participant + fn set_nonce(&mut self, id: &I, nonce: N); } diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index d9fbb5750..5e0492b74 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -19,19 +19,21 @@ use crate::groth16::{ ceremony::{ coordinator::{ChallengeArray, Coordinator, StateArray}, + message::Signed, registry::Registry, - Ceremony, + signature::{check_nonce, verify, Nonce as _}, + Ceremony, Nonce, Participant, }, mpc::StateSize, + CeremonyError, }; use manta_util::Array; use std::sync::{Arc, Mutex}; -use manta_crypto::signature::{MessageType, SignatureType, SignedMessage}; pub struct Server where C: Ceremony, - R: Registry, + R: Registry>, { /// Coordinator coordinator: Arc>>, @@ -44,7 +46,7 @@ impl Server where C: Ceremony, - R: Registry, + R: Registry>, { /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a `recovery_path`. #[inline] @@ -72,12 +74,38 @@ where } } - /// Processes a request by checking nonce and verifying signature. + /// Preprocess a request by checking nonce and verifying signature. #[inline] pub fn process_request( registry: &mut R, - request: &SignedMessage - ) where T: MessageType + SignatureType{ - let participant = match registry.get_mut(&request.) + request: &Signed, + ) -> Result<(), CeremonyError> { + if registry.has_contributed(&request.identifier) { + return Err(CeremonyError::AlreadyContributed); + } + + let participant_nonce = registry + .get_nonce(&request.identifier) + .ok_or_else(|| CeremonyError::NotRegistered)?; + + if !check_nonce(&participant_nonce, &request.nonce) { + return Err(CeremonyError::NonceNotInSync(participant_nonce)); + }; + + let participant = match registry.get(&request.identifier) { + Some(participant) => participant, + None => unreachable!("participant registration has been checked"), + }; + + verify( + participant.verifying_key(), + participant_nonce, + &request.message, + &request.signature, + ) + .map_err(|_| CeremonyError::BadRequest)?; + + registry.set_nonce(&request.identifier, participant_nonce.increment()); + Ok(()) } } diff --git a/manta-trusted-setup/src/groth16/mod.rs b/manta-trusted-setup/src/groth16/mod.rs index 91db5cd52..533ff7110 100644 --- a/manta-trusted-setup/src/groth16/mod.rs +++ b/manta-trusted-setup/src/groth16/mod.rs @@ -22,3 +22,45 @@ pub mod mpc; #[cfg(test)] pub mod test; + +use derivative::Derivative; +use manta_util::serde::{Serialize, Deserialize}; +use crate::groth16::ceremony::{Ceremony, Nonce}; + +/// Ceremony Error +/// +/// # Note +/// +/// All errors here are visible to users. +#[derive(PartialEq, Serialize, Deserialize, Derivative)] +#[derivative(Debug(bound = "Nonce: core::fmt::Debug"))] +#[serde( +bound( +serialize = "Nonce: Serialize", +deserialize = "Nonce: Deserialize<'de>", +), +crate = "manta_util::serde", +deny_unknown_fields +)] +pub enum CeremonyError + where + C: Ceremony, +{ + /// Malformed request that should not come from official client + BadRequest, + + /// Nonce not in sync, and client needs to update the nonce + NonceNotInSync(Nonce), + + /// Not Registered + NotRegistered, + + /// Already Contributed + AlreadyContributed, + + /// Not Your Turn + NotYourTurn, + + /// Timed-out + Timeout, +} \ No newline at end of file diff --git a/manta-trusted-setup/src/lib.rs b/manta-trusted-setup/src/lib.rs index 60f92c197..fbcbedb1b 100644 --- a/manta-trusted-setup/src/lib.rs +++ b/manta-trusted-setup/src/lib.rs @@ -27,3 +27,4 @@ pub mod groth16; pub mod mpc; pub mod ratio; pub mod util; +mod utils; diff --git a/manta-trusted-setup/src/utils.rs b/manta-trusted-setup/src/utils.rs new file mode 100644 index 000000000..a994c6a4d --- /dev/null +++ b/manta-trusted-setup/src/utils.rs @@ -0,0 +1,34 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Groth16 Trusted Setup Utilities + +use std::marker::PhantomData; + +use manta_util::serde::{Deserialize, Serialize}; + +/// Store `T` in bytes form. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde( + bound(serialize = r"", deserialize = "",), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct BytesRepr { + /// The bytes representation of `T` + pub bytes: Vec, + __: PhantomData, +} From cc1c2b8b5a44dbffc25054ed8bbdfc4d29837de7 Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Sat, 3 Sep 2022 22:43:32 -0700 Subject: [PATCH 03/60] wip: save point --- .../src/groth16/ceremony/client.rs | 34 ++++---- .../src/groth16/ceremony/coordinator.rs | 11 ++- .../src/groth16/ceremony/message.rs | 36 ++++----- .../src/groth16/ceremony/mod.rs | 3 + .../src/groth16/ceremony/server.rs | 80 ++++++++++++++++--- 5 files changed, 112 insertions(+), 52 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index ebc899baf..7b543e419 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -16,20 +16,20 @@ //! Trusted Setup Client -use crate::groth16::ceremony::{signature::Nonce, Ceremony, Participant}; -use manta_crypto::dalek::ed25519::Ed25519; - -/// Client -pub struct Client -where - C: Ceremony, -{ - /// Identifier - Identifier: C::Identifier, - - /// Current Nonce - nonce: u64, - - /// Private Key - private_key: Ed25519, -} +// use crate::groth16::ceremony::{signature::Nonce, Ceremony, Participant}; +// use manta_crypto::dalek::ed25519::Ed25519; +// +// /// Client +// pub struct Client +// where +// C: Ceremony, +// { +// /// Identifier +// Identifier: C::Identifier, +// +// /// Current Nonce +// nonce: u64, +// +// /// Private Key +// private_key: Ed25519, +// } diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index dcd4f9de7..0364e37f9 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -25,6 +25,7 @@ use crate::{ }; use manta_util::{collections::vec_deque::MultiVecDeque, time::lock::Timed, Array, BoxArray}; +use crate::groth16::ceremony::Nonce; #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; @@ -73,7 +74,7 @@ pub type Queue = pub struct Coordinator where C: Ceremony, - R: Registry, + R: Registry>, { /// Participant Registry pub registry: R, @@ -109,7 +110,7 @@ impl Coordinator where C: Ceremony, - R: Registry, + R: Registry>, { /// Returns the current round number. #[inline] @@ -141,4 +142,10 @@ where self.queue .push_back_at(participant.level(), participant.id().clone()); } + + /// + #[inline] + pub fn nonce(&self, id: &C::Identifier) -> Option> { + self.registry.get_nonce(id) + } } diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 06797e399..b34e36c6d 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -185,8 +185,8 @@ where #[derive(Deserialize, Serialize)] #[serde( bound( - serialize = "State: CanonicalSerialize, Challenge: CanonicalSerialize", - deserialize = "State: CanonicalDeserialize, Challenge: CanonicalDeserialize" + serialize = "State: CanonicalSerialize, Challenge: CanonicalSerialize", + deserialize = "State: CanonicalDeserialize, Challenge: CanonicalDeserialize" ), crate = "manta_util::serde", deny_unknown_fields @@ -196,7 +196,7 @@ where C: Ceremony, { /// State - pub state: Array>, N>, + pub state: Array>, N>, /// Challenge pub challenge: Array>, N>, @@ -208,8 +208,8 @@ where #[derive(Deserialize, Serialize)] #[serde( bound( - serialize = "State: CanonicalSerialize, Proof: CanonicalSerialize", - deserialize = "State: CanonicalDeserialize, Proof: CanonicalDeserialize" + serialize = "State: CanonicalSerialize, Proof: CanonicalSerialize", + deserialize = "State: CanonicalDeserialize, Proof: CanonicalDeserialize" ), crate = "manta_util::serde", deny_unknown_fields @@ -219,7 +219,7 @@ where C: Ceremony, { /// State - pub state: Array>, CIRCUIT_COUNT>, + pub state: Array>, CIRCUIT_COUNT>, /// Proof pub proof: Array>, CIRCUIT_COUNT>, @@ -230,19 +230,13 @@ where #[serde(crate = "manta_util::serde", deny_unknown_fields)] pub struct ServerSize(pub Array); -/// State Size -#[derive(Clone, Serialize, Deserialize)] -#[serde(crate = "manta_util::serde", deny_unknown_fields)] -pub struct StateSize { - /// Size of gamma_abc_g1 in verifying key - pub gamma_abc_g1: usize, - - /// Size of a_query, b_g1_query, and b_g2_query which are equal - pub a_b_g1_b_g2_query: usize, - - /// Size of h_query - pub h_query: usize, - - /// Size of l_query - pub l_query: usize, +impl From> + for ServerSize +{ + fn from(inner: Array) -> Self { + ServerSize(inner) + } } + +/// State Size +pub type StateSize = crate::groth16::mpc::StateSize; diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 0cda79671..c1be82b30 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -16,6 +16,7 @@ //! Groth16 Trusted Setup Ceremony +use manta_crypto::arkworks::pairing::Pairing; use crate::{groth16::ceremony::signature::SignatureScheme, mpc, mpc::ProofType}; use manta_crypto::signature::{SignatureType, SigningKeyType, VerifyingKeyType}; @@ -55,6 +56,8 @@ pub trait Participant { /// Ceremony Configuration pub trait Ceremony: mpc::Types { + type Pairing: Pairing; + /// Participant Identifier Type type Identifier: Clone + PartialEq; diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 5e0492b74..ef861273e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -16,18 +16,22 @@ //! Trusted Setup Server -use crate::groth16::{ - ceremony::{ - coordinator::{ChallengeArray, Coordinator, StateArray}, - message::Signed, - registry::Registry, - signature::{check_nonce, verify, Nonce as _}, - Ceremony, Nonce, Participant, +use crate::{ + groth16::{ + ceremony::{ + coordinator::{ChallengeArray, Coordinator, StateArray}, + message::{QueryRequest, QueryResponse, ServerSize, Signed}, + registry::Registry, + signature::{check_nonce, verify, Nonce as _}, + Ceremony, Nonce, Participant, + }, + mpc::{State, StateSize}, + CeremonyError, }, - mpc::StateSize, - CeremonyError, + mpc::Challenge, }; -use manta_util::Array; +use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; +use manta_util::{serde::Serialize, Array}; use std::sync::{Arc, Mutex}; pub struct Server @@ -76,10 +80,13 @@ where /// Preprocess a request by checking nonce and verifying signature. #[inline] - pub fn process_request( + pub fn preprocess_request( registry: &mut R, request: &Signed, - ) -> Result<(), CeremonyError> { + ) -> Result<(), CeremonyError> + where + T: Serialize, + { if registry.has_contributed(&request.identifier) { return Err(CeremonyError::AlreadyContributed); } @@ -108,4 +115,53 @@ where registry.set_nonce(&request.identifier, participant_nonce.increment()); Ok(()) } + + /// Gets the server state size and the current nonce of the participant. + #[inline] + pub async fn start( + self, + request: C::Identifier, + ) -> Result<(ServerSize, Nonce), CeremonyError> { + let coordinator = self + .coordinator + .lock() + .expect("acquiring a lock is not allowed to fail"); + Ok(( + coordinator.size.clone().into(), + coordinator + .nonce(&request) + .ok_or_else(|| CeremonyError::NotRegistered)?, + )) + } + + /// Queries the server state + #[inline] + pub async fn query( + self, + request: Signed, + ) -> Result, CeremonyError> + where + C::Identifier: Serialize, + State: CanonicalSerialize + CanonicalDeserialize, + Challenge: CanonicalSerialize + CanonicalDeserialize, + { + let mut coordinator = self.coordinator.lock(); + Self::preprocess_request(&mut coordinator.registry, &request)?; + if !coordinator.is_in_queue(&request.identifier)? { + coordinator.enqueue_participant(&request.identifier)?; + } + if coordinator.is_next(&request.identifier) { + Ok(QueryResponse::Mpc(coordinator.state_and_challenge())) + } else { + Ok(QueryResponse::QueuePosition( + coordinator + .position( + coordinator + .get_participant(&request.identifier) + .expect("Participant existence is checked in `process_request`."), + ) + .expect("Participant should be always in the queue here"), + )) + } + } } From 9945ff09ef54f661dfe978524ba35b8e5a74f2ac Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Tue, 6 Sep 2022 16:30:39 -0700 Subject: [PATCH 04/60] wip: fix compilation issues --- manta-trusted-setup/Cargo.toml | 4 +- .../src/groth16/ceremony/coordinator.rs | 63 +++--- .../src/groth16/ceremony/message.rs | 188 +++++++----------- .../src/groth16/ceremony/mod.rs | 97 +++++++-- .../src/groth16/ceremony/registry.rs | 8 +- .../src/groth16/ceremony/server.rs | 25 +-- .../src/groth16/ceremony/signature.rs | 17 +- manta-trusted-setup/src/groth16/mod.rs | 47 +---- manta-trusted-setup/src/lib.rs | 1 - manta-trusted-setup/src/utils.rs | 34 ---- manta-util/src/bytes.rs | 17 ++ 11 files changed, 221 insertions(+), 280 deletions(-) delete mode 100644 manta-trusted-setup/src/utils.rs diff --git a/manta-trusted-setup/Cargo.toml b/manta-trusted-setup/Cargo.toml index 51f4a1139..1e3bf01c1 100644 --- a/manta-trusted-setup/Cargo.toml +++ b/manta-trusted-setup/Cargo.toml @@ -53,8 +53,8 @@ ark-std = { version = "0.3.0", default-features = false } bincode = { version = "1.3.3", optional = true, default-features = false } blake2 = { version = "0.10.4", default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } -manta-crypto = { path = "../manta-crypto", default-features = false, features = ["arkworks", "getrandom", "rand_chacha"] } -manta-util = { path = "../manta-util", default-features = false } +manta-crypto = { path = "../manta-crypto", default-features = false, features = ["arkworks", "getrandom", "rand_chacha", "dalek"] } +manta-util = { path = "../manta-util", default-features = false, features = ["serde"] } [dev-dependencies] ark-bls12-381 = { version = "0.3.0", default-features = false, features = ["curve", "scalar_field"] } diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 0364e37f9..3824b687d 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -14,18 +14,17 @@ // You should have received a copy of the GNU General Public License // along with manta-rs. If not, see . -//! Groth16 Trusted Setup Ceremony Coordinator +//! Coordinator use crate::{ groth16::{ - ceremony::{registry::Registry, Ceremony, Participant}, + ceremony::{registry::Registry, Ceremony, Nonce, Participant}, mpc::StateSize, }, mpc::{Challenge, Proof, State}, }; use manta_util::{collections::vec_deque::MultiVecDeque, time::lock::Timed, Array, BoxArray}; -use crate::groth16::ceremony::Nonce; #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; @@ -48,24 +47,20 @@ pub type Queue = derive(Deserialize, Serialize), serde( bound( - deserialize = r" - R: Deserialize<'de>, - Queue: Deserialize<'de>, - C::Identifier: Deserialize<'de>, - State: Deserialize<'de>, - Challenge: Deserialize<'de>, - Proof: Deserialize<'de>, - C::Participant: Deserialize<'de>, - ", serialize = r" - R: Serialize, - Queue: Serialize, - C::Identifier: Serialize, - State: Serialize, - Challenge: Serialize, - Proof: Serialize, - C::Participant: Serialize, - " + R: Serialize, + State: Serialize, + Challenge: Serialize, + Proof: Serialize, + C::Participant: Serialize, + ", + deserialize = r" + R: Deserialize<'de>, + State: Deserialize<'de>, + Challenge: Deserialize<'de>, + Proof: Deserialize<'de>, + C::Participant: Deserialize<'de>, + " ), crate = "manta_util::serde", deny_unknown_fields @@ -74,17 +69,11 @@ pub type Queue = pub struct Coordinator where C: Ceremony, - R: Registry>, + R: Registry, { /// Participant Registry pub registry: R, - /// Participant Queue - pub queue: Queue, - - /// Participant Lock - pub participant_lock: Timed>, - /// State pub state: StateArray, @@ -104,20 +93,22 @@ where /// Current Round Number pub round: usize, + + /// Participant Queue + #[serde(skip)] + pub queue: Queue, + + /// Participant Lock + #[serde(skip)] + pub participant_lock: Timed>, } impl Coordinator where C: Ceremony, - R: Registry>, + R: Registry, { - /// Returns the current round number. - #[inline] - pub fn round(&self) -> usize { - self.round - } - /// Returns a shared reference to the participant data for `id` from the registry. #[inline] pub fn participant(&self, id: &C::Identifier) -> Option<&C::Participant> { @@ -143,9 +134,9 @@ where .push_back_at(participant.level(), participant.id().clone()); } - /// + /// Gets nonce of a participant with `id`. #[inline] pub fn nonce(&self, id: &C::Identifier) -> Option> { - self.registry.get_nonce(id) + Some(self.registry.get(id)?.get_nonce()) } } diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index b34e36c6d..b095caace 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -18,22 +18,71 @@ use crate::{ groth16::{ - ceremony::{signature::Nonce as _, Ceremony, Nonce, Proof, Signature, SigningKey}, - mpc::State, + ceremony::{signature::sign, Ceremony, CeremonyError, Nonce, Proof, Signature, SigningKey}, + mpc::{State, StateSize}, }, mpc::Challenge, - utils::BytesRepr, }; -use derivative::Derivative; use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{ - serde, - serde::{Deserialize, Deserializer, Serialize, Serializer}, - Array, + serde::{Deserialize, Serialize}, + Array, BytesRepr, }; -use std::marker::PhantomData; -use super::signature::sign; +/// MPC States +#[derive(Deserialize, Serialize)] +#[serde( + bound( + serialize = "State: CanonicalSerialize, Challenge: CanonicalSerialize", + deserialize = "State: CanonicalDeserialize, Challenge: CanonicalDeserialize" + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct MPCState +where + C: Ceremony, +{ + /// State + pub state: Array>, N>, + + /// Challenge + pub challenge: Array>, N>, +} + +/// Contribute States +#[derive(Deserialize, Serialize)] +#[serde( + bound( + serialize = "State: CanonicalSerialize, Proof: CanonicalSerialize", + deserialize = "State: CanonicalDeserialize, Proof: CanonicalDeserialize" + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct ContributeState +where + C: Ceremony, +{ + /// State + pub state: Array>, CIRCUIT_COUNT>, + + /// Proof + pub proof: Array>, CIRCUIT_COUNT>, +} + +/// Response for State Sizes +#[derive(Clone, Serialize, Deserialize)] +#[serde(crate = "manta_util::serde", deny_unknown_fields)] +pub struct ServerSize(pub Array); + +impl From> + for ServerSize +{ + fn from(inner: Array) -> Self { + ServerSize(inner) + } +} /// Query Request #[derive(Deserialize, Serialize)] @@ -103,9 +152,6 @@ pub struct Signed where C: Ceremony, { - /// Participant - pub identifier: C::Identifier, - /// Message pub message: T, @@ -114,129 +160,37 @@ where /// Signature pub signature: Signature, + + /// Participant Identifier + pub identifier: C::Identifier, } impl Signed where C: Ceremony, { - /// Generates a signed message using user's identifier, nonce, and key pair, and increment nonce by 1. + /// Generates a signed message with `signing_key` on `message` and `nonce`. #[inline] pub fn new( message: T, - identifier: C::Identifier, - nonce: &mut Nonce, + nonce: &Nonce, signing_key: &SigningKey, - ) -> Result + identifier: C::Identifier, + ) -> Result> where T: Serialize, + Nonce: Clone, { - let signature = sign::<_, C::SignatureScheme>(&message, nonce.clone(), signing_key)?; + let signature = match sign::<_, C::SignatureScheme>(signing_key, nonce.clone(), &message) { + Ok(signature) => signature, + Err(_) => return Err(CeremonyError::::BadRequest), + }; let message = Signed { message, - identifier, nonce: nonce.clone(), signature, + identifier, }; - nonce.increment(); Ok(message) } } - -/// Ceremony Error -/// -/// # Note -/// -/// All errors here are visible to users. -#[derive(PartialEq, Serialize, Deserialize, Derivative)] -#[derivative(Debug(bound = "Nonce: core::fmt::Debug"))] -#[serde( - bound( - serialize = "Nonce: Serialize", - deserialize = "Nonce: Deserialize<'de>", - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub enum CeremonyError -where - C: Ceremony, -{ - /// Malformed request that should not come from official client - BadRequest, - - /// Nonce not in sync, and client needs to update the nonce - NonceNotInSync(Nonce), - - /// Not Registered - NotRegistered, - - /// Already Contributed - AlreadyContributed, - - /// Not Your Turn - NotYourTurn, - - /// Timed-out - Timeout, -} - -/// MPC States -#[derive(Deserialize, Serialize)] -#[serde( - bound( - serialize = "State: CanonicalSerialize, Challenge: CanonicalSerialize", - deserialize = "State: CanonicalDeserialize, Challenge: CanonicalDeserialize" - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct MPCState -where - C: Ceremony, -{ - /// State - pub state: Array>, N>, - - /// Challenge - pub challenge: Array>, N>, - - __: PhantomData, -} - -/// Contribute States -#[derive(Deserialize, Serialize)] -#[serde( - bound( - serialize = "State: CanonicalSerialize, Proof: CanonicalSerialize", - deserialize = "State: CanonicalDeserialize, Proof: CanonicalDeserialize" - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct ContributeState -where - C: Ceremony, -{ - /// State - pub state: Array>, CIRCUIT_COUNT>, - - /// Proof - pub proof: Array>, CIRCUIT_COUNT>, -} - -/// Response for State Sizes -#[derive(Clone, Serialize, Deserialize)] -#[serde(crate = "manta_util::serde", deny_unknown_fields)] -pub struct ServerSize(pub Array); - -impl From> - for ServerSize -{ - fn from(inner: Array) -> Self { - ServerSize(inner) - } -} - -/// State Size -pub type StateSize = crate::groth16::mpc::StateSize; diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index c1be82b30..1e22f0b53 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -16,30 +16,50 @@ //! Groth16 Trusted Setup Ceremony -use manta_crypto::arkworks::pairing::Pairing; use crate::{groth16::ceremony::signature::SignatureScheme, mpc, mpc::ProofType}; -use manta_crypto::signature::{SignatureType, SigningKeyType, VerifyingKeyType}; +use derivative::Derivative; +use manta_crypto::{ + arkworks::pairing::Pairing, + signature::{SignatureType, SigningKeyType, VerifyingKeyType}, +}; +use manta_util::serde::{Deserialize, Serialize}; +// pub mod client; +pub mod message; pub mod registry; +// pub mod server; +pub mod signature; -#[cfg(feature = "std")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] +#[cfg(feature = "serde")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] pub mod coordinator; -pub mod client; -pub mod message; -pub mod server; -#[cfg(all(feature = "bincode", feature = "serde"))] -#[cfg_attr(doc_cfg, doc(cfg(all(feature = "bincode", feature = "serde"))))] -pub mod signature; +/// Nonce +pub type Nonce = <::SignatureScheme as SignatureScheme>::Nonce; + +/// Signature +pub type Signature = <::SignatureScheme as SignatureType>::Signature; + +/// Signing Key +pub type SigningKey = <::SignatureScheme as SigningKeyType>::SigningKey; + +/// Verifying Key +pub type VerifyingKey = <::SignatureScheme as VerifyingKeyType>::VerifyingKey; + +/// Proof +pub type Proof = ::Proof; /// Participant pub trait Participant { /// Participant Identifier Type type Identifier; + /// Participant Verifying Key Type type VerifyingKey; + /// Nonce + type Nonce; + /// Returns the [`Identifier`](Self::Identifier) for `self`. fn id(&self) -> &Self::Identifier; @@ -52,24 +72,67 @@ pub trait Participant { /// /// Lower level indicates a higher priority. fn level(&self) -> usize; + + /// Returns nonce for `self`. + fn get_nonce(&self) -> Self::Nonce; + + /// Set nonce of current participant + fn increment_nonce(&mut self); } /// Ceremony Configuration pub trait Ceremony: mpc::Types { + /// Pairing Type type Pairing: Pairing; - + /// Participant Identifier Type type Identifier: Clone + PartialEq; /// Participant Type - type Participant: Participant; + type Participant: Participant< + Identifier = Self::Identifier, + Nonce = Nonce, + VerifyingKey = VerifyingKey, + >; /// Signature Scheme type SignatureScheme: SignatureScheme; } -pub type Nonce = <::SignatureScheme as SignatureScheme>::Nonce; -pub type Signature = <::SignatureScheme as SignatureType>::Signature; -pub type SigningKey = <::SignatureScheme as SigningKeyType>::SigningKey; -pub type VerifyingKey = <::SignatureScheme as VerifyingKeyType>::VerifyingKey; -pub type Proof = ::Proof; +/// Ceremony Error +/// +/// # Note +/// +/// All errors here are visible to users. +#[derive(PartialEq, Serialize, Deserialize, Derivative)] +#[derivative(Debug(bound = "Nonce: core::fmt::Debug"))] +#[serde( + bound( + serialize = "Nonce: Serialize", + deserialize = "Nonce: Deserialize<'de>", + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub enum CeremonyError +where + C: Ceremony, +{ + /// Malformed request that should not come from official client + BadRequest, + + /// Nonce not in sync, and client needs to update the nonce + NonceNotInSync(Nonce), + + /// Not Registered + NotRegistered, + + /// Already Contributed + AlreadyContributed, + + /// Not Your Turn + NotYourTurn, + + /// Timed-out + Timeout, +} diff --git a/manta-trusted-setup/src/groth16/ceremony/registry.rs b/manta-trusted-setup/src/groth16/ceremony/registry.rs index 7ba158b46..7637086d2 100644 --- a/manta-trusted-setup/src/groth16/ceremony/registry.rs +++ b/manta-trusted-setup/src/groth16/ceremony/registry.rs @@ -17,7 +17,7 @@ //! Groth16 Trusted Setup Ceremony Registry /// Participant Registry -pub trait Registry { +pub trait Registry { /// Registers the `participant` into `self` returning `false` if the `participant` is already /// registered or their registration would conflict with another existing participant. fn register(&mut self, participant: P) -> bool; @@ -31,10 +31,4 @@ pub trait Registry { /// Returns `true` if the participant with the given `id` has already contributed to the /// ceremony. fn has_contributed(&self, id: &I) -> bool; - - /// Returns nonce of current participant. - fn get_nonce(&self, id: &I) -> Option; - - /// Set nonce of current participant - fn set_nonce(&mut self, id: &I, nonce: N); } diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index ef861273e..fbd635949 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -23,10 +23,9 @@ use crate::{ message::{QueryRequest, QueryResponse, ServerSize, Signed}, registry::Registry, signature::{check_nonce, verify, Nonce as _}, - Ceremony, Nonce, Participant, + Ceremony, CeremonyError, Nonce, Participant, }, mpc::{State, StateSize}, - CeremonyError, }, mpc::Challenge, }; @@ -34,10 +33,12 @@ use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize use manta_util::{serde::Serialize, Array}; use std::sync::{Arc, Mutex}; +use super::Signature; + pub struct Server where C: Ceremony, - R: Registry>, + R: Registry, { /// Coordinator coordinator: Arc>>, @@ -50,7 +51,7 @@ impl Server where C: Ceremony, - R: Registry>, + R: Registry, { /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a `recovery_path`. #[inline] @@ -90,29 +91,25 @@ where if registry.has_contributed(&request.identifier) { return Err(CeremonyError::AlreadyContributed); } - let participant_nonce = registry - .get_nonce(&request.identifier) - .ok_or_else(|| CeremonyError::NotRegistered)?; - + .get(&request.identifier) + .ok_or_else(|| CeremonyError::NotRegistered)? + .get_nonce(); if !check_nonce(&participant_nonce, &request.nonce) { return Err(CeremonyError::NonceNotInSync(participant_nonce)); }; - - let participant = match registry.get(&request.identifier) { + let mut participant = match registry.get(&request.identifier) { Some(participant) => participant, None => unreachable!("participant registration has been checked"), }; - - verify( + verify::( participant.verifying_key(), participant_nonce, &request.message, &request.signature, ) .map_err(|_| CeremonyError::BadRequest)?; - - registry.set_nonce(&request.identifier, participant_nonce.increment()); + participant.increment_nonce(); Ok(()) } diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index 07f12951e..0e53f21a0 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -20,7 +20,6 @@ use alloc::vec::Vec; use manta_crypto::{ dalek::ed25519::{Ed25519, SignatureError}, signature, - signature::{Sign, Verify}, }; use manta_util::{serde::Serialize, AsBytes}; @@ -153,11 +152,11 @@ where .map_err(VerificationError::Error) } -// impl SignatureScheme for Ed25519> -// where -// N: Nonce + Default, -// { -// type Nonce = N; -// -// type Error = SignatureError; -// } +impl SignatureScheme for Ed25519> +where + N: AsBytes + Default + Nonce, +{ + type Nonce = N; + + type Error = SignatureError; +} diff --git a/manta-trusted-setup/src/groth16/mod.rs b/manta-trusted-setup/src/groth16/mod.rs index 734b303a4..7f6db0096 100644 --- a/manta-trusted-setup/src/groth16/mod.rs +++ b/manta-trusted-setup/src/groth16/mod.rs @@ -16,55 +16,16 @@ //! Groth16 Trusted Setup -pub mod ceremony; pub mod kzg; pub mod mpc; +#[cfg(all(feature = "bincode", feature = "serde"))] +#[cfg_attr(doc_cfg, doc(cfg(all(feature = "bincode", feature = "serde"))))] +pub mod ceremony; + #[cfg(feature = "ppot")] #[cfg_attr(doc_cfg, doc(cfg(feature = "ppot")))] pub mod ppot; #[cfg(test)] pub mod test; - -use derivative::Derivative; -use manta_util::serde::{Serialize, Deserialize}; -use crate::groth16::ceremony::{Ceremony, Nonce}; - -/// Ceremony Error -/// -/// # Note -/// -/// All errors here are visible to users. -#[derive(PartialEq, Serialize, Deserialize, Derivative)] -#[derivative(Debug(bound = "Nonce: core::fmt::Debug"))] -#[serde( -bound( -serialize = "Nonce: Serialize", -deserialize = "Nonce: Deserialize<'de>", -), -crate = "manta_util::serde", -deny_unknown_fields -)] -pub enum CeremonyError - where - C: Ceremony, -{ - /// Malformed request that should not come from official client - BadRequest, - - /// Nonce not in sync, and client needs to update the nonce - NonceNotInSync(Nonce), - - /// Not Registered - NotRegistered, - - /// Already Contributed - AlreadyContributed, - - /// Not Your Turn - NotYourTurn, - - /// Timed-out - Timeout, -} \ No newline at end of file diff --git a/manta-trusted-setup/src/lib.rs b/manta-trusted-setup/src/lib.rs index 9c345f2cf..84dabb22a 100644 --- a/manta-trusted-setup/src/lib.rs +++ b/manta-trusted-setup/src/lib.rs @@ -26,4 +26,3 @@ extern crate alloc; pub mod groth16; pub mod mpc; pub mod util; -mod utils; diff --git a/manta-trusted-setup/src/utils.rs b/manta-trusted-setup/src/utils.rs deleted file mode 100644 index a994c6a4d..000000000 --- a/manta-trusted-setup/src/utils.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2019-2022 Manta Network. -// This file is part of manta-rs. -// -// manta-rs is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// manta-rs is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with manta-rs. If not, see . - -//! Groth16 Trusted Setup Utilities - -use std::marker::PhantomData; - -use manta_util::serde::{Deserialize, Serialize}; - -/// Store `T` in bytes form. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde( - bound(serialize = r"", deserialize = "",), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct BytesRepr { - /// The bytes representation of `T` - pub bytes: Vec, - __: PhantomData, -} diff --git a/manta-util/src/bytes.rs b/manta-util/src/bytes.rs index 592bc0c98..92558e980 100644 --- a/manta-util/src/bytes.rs +++ b/manta-util/src/bytes.rs @@ -16,6 +16,8 @@ //! Utilities for Manipulating Bytes +use core::marker::PhantomData; + #[cfg(feature = "alloc")] use alloc::vec::Vec; @@ -106,3 +108,18 @@ pub trait AsBytes { /// Returns an owned byte representation of `self`. fn as_bytes(&self) -> Vec; } + +#[cfg(feature = "serde")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] +/// Store `T` in bytes form. +#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +#[serde( + bound(serialize = r"", deserialize = "",), + crate = "crate::serde", + deny_unknown_fields +)] +pub struct BytesRepr { + /// The bytes representation of `T` + pub bytes: Vec, + __: PhantomData, +} From 5ad55c726f72388c1ff43799a03f5827ad2a4829 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Wed, 7 Sep 2022 11:48:45 -0700 Subject: [PATCH 05/60] wip: serde --- manta-trusted-setup/Cargo.toml | 2 +- .../src/groth16/ceremony/message.rs | 315 +++++++++--------- .../src/groth16/ceremony/mod.rs | 4 + .../src/groth16/ceremony/serde.rs | 83 +++++ manta-util/src/bytes.rs | 17 - 5 files changed, 248 insertions(+), 173 deletions(-) create mode 100644 manta-trusted-setup/src/groth16/ceremony/serde.rs diff --git a/manta-trusted-setup/Cargo.toml b/manta-trusted-setup/Cargo.toml index 1e3bf01c1..f36f41fcd 100644 --- a/manta-trusted-setup/Cargo.toml +++ b/manta-trusted-setup/Cargo.toml @@ -54,7 +54,7 @@ bincode = { version = "1.3.3", optional = true, default-features = false } blake2 = { version = "0.10.4", default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["arkworks", "getrandom", "rand_chacha", "dalek"] } -manta-util = { path = "../manta-util", default-features = false, features = ["serde"] } +manta-util = { path = "../manta-util", default-features = false } [dev-dependencies] ark-bls12-381 = { version = "0.3.0", default-features = false, features = ["curve", "scalar_field"] } diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index b095caace..cb2d5f8d2 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -18,7 +18,11 @@ use crate::{ groth16::{ - ceremony::{signature::sign, Ceremony, CeremonyError, Nonce, Proof, Signature, SigningKey}, + ceremony::{ + serde::{deserialize_arkworks, serialize_arkworks}, + signature::sign, + Ceremony, CeremonyError, Nonce, Proof, Signature, SigningKey, + }, mpc::{State, StateSize}, }, mpc::Challenge, @@ -26,16 +30,13 @@ use crate::{ use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{ serde::{Deserialize, Serialize}, - Array, BytesRepr, + Array, }; /// MPC States -#[derive(Deserialize, Serialize)] +#[derive(Serialize, Deserialize)] #[serde( - bound( - serialize = "State: CanonicalSerialize, Challenge: CanonicalSerialize", - deserialize = "State: CanonicalDeserialize, Challenge: CanonicalDeserialize" - ), + bound(serialize = "", deserialize = ""), crate = "manta_util::serde", deny_unknown_fields )] @@ -44,153 +45,157 @@ where C: Ceremony, { /// State - pub state: Array>, N>, - - /// Challenge - pub challenge: Array>, N>, -} - -/// Contribute States -#[derive(Deserialize, Serialize)] -#[serde( - bound( - serialize = "State: CanonicalSerialize, Proof: CanonicalSerialize", - deserialize = "State: CanonicalDeserialize, Proof: CanonicalDeserialize" - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct ContributeState -where - C: Ceremony, -{ - /// State - pub state: Array>, CIRCUIT_COUNT>, - - /// Proof - pub proof: Array>, CIRCUIT_COUNT>, -} - -/// Response for State Sizes -#[derive(Clone, Serialize, Deserialize)] -#[serde(crate = "manta_util::serde", deny_unknown_fields)] -pub struct ServerSize(pub Array); - -impl From> - for ServerSize -{ - fn from(inner: Array) -> Self { - ServerSize(inner) - } -} - -/// Query Request -#[derive(Deserialize, Serialize)] -#[serde(crate = "manta_util::serde", deny_unknown_fields)] -pub struct QueryRequest; - -/// Response for [`QueryRequest`] -#[derive(Deserialize, Serialize)] -#[serde( - bound( - serialize = "MPCState: Serialize", - deserialize = "MPCState: Deserialize<'de>" - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub enum QueryResponse -where - C: Ceremony, -{ - /// Queue Position - QueuePosition(usize), - - /// MPC State - Mpc(MPCState), -} - -/// Contribute Request -#[derive(Serialize, Deserialize)] -#[serde( - bound( - serialize = "ContributeState: Serialize", - deserialize = "ContributeState: Deserialize<'de>" - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct ContributeRequest -where - C: Ceremony, -{ - /// Contribute state including state and proof - pub contribute_state: ContributeState, + #[cfg_attr( + feature = "serde", + serde(serialize_with = "serialize_arkworks::, _>") + )] + pub state: Array, N>, + + // /// Challenge + // pub challenge: Array, N>, } -/// Signed Message -#[derive(Deserialize, Serialize)] -#[serde( - bound( - serialize = r" - C::Identifier: Serialize, - T: Serialize, - Nonce: Serialize, - Signature: Serialize, - ", - deserialize = r" - C::Identifier: Deserialize<'de>, - T: Deserialize<'de>, - Nonce: Deserialize<'de>, - Signature: Deserialize<'de>, - ", - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct Signed -where - C: Ceremony, -{ - /// Message - pub message: T, - - /// Nonce - pub nonce: Nonce, - - /// Signature - pub signature: Signature, - - /// Participant Identifier - pub identifier: C::Identifier, -} - -impl Signed -where - C: Ceremony, -{ - /// Generates a signed message with `signing_key` on `message` and `nonce`. - #[inline] - pub fn new( - message: T, - nonce: &Nonce, - signing_key: &SigningKey, - identifier: C::Identifier, - ) -> Result> - where - T: Serialize, - Nonce: Clone, - { - let signature = match sign::<_, C::SignatureScheme>(signing_key, nonce.clone(), &message) { - Ok(signature) => signature, - Err(_) => return Err(CeremonyError::::BadRequest), - }; - let message = Signed { - message, - nonce: nonce.clone(), - signature, - identifier, - }; - Ok(message) - } -} +// /// Contribute States +// #[derive(Deserialize, Serialize)] +// #[serde( +// bound( +// serialize = "State: CanonicalSerialize, Proof: CanonicalSerialize", +// deserialize = "State: CanonicalDeserialize, Proof: CanonicalDeserialize" +// ), +// crate = "manta_util::serde", +// deny_unknown_fields +// )] +// pub struct ContributeState +// where +// C: Ceremony, +// { +// /// State +// pub state: Array, CIRCUIT_COUNT>, + +// /// Proof +// pub proof: Array, CIRCUIT_COUNT>, +// } + +// /// Response for State Sizes +// #[derive(Clone, Serialize, Deserialize)] +// #[serde(crate = "manta_util::serde", deny_unknown_fields)] +// pub struct ServerSize(pub Array); + +// impl From> +// for ServerSize +// { +// fn from(inner: Array) -> Self { +// ServerSize(inner) +// } +// } + +// /// Query Request +// #[derive(Deserialize, Serialize)] +// #[serde(crate = "manta_util::serde", deny_unknown_fields)] +// pub struct QueryRequest; + +// /// Response for [`QueryRequest`] +// #[derive(Deserialize, Serialize)] +// #[serde( +// bound( +// serialize = "MPCState: Serialize", +// deserialize = "MPCState: Deserialize<'de>" +// ), +// crate = "manta_util::serde", +// deny_unknown_fields +// )] +// pub enum QueryResponse +// where +// C: Ceremony, +// { +// /// Queue Position +// QueuePosition(usize), + +// /// MPC State +// Mpc(MPCState), +// } + +// /// Contribute Request +// #[derive(Serialize, Deserialize)] +// #[serde( +// bound( +// serialize = "ContributeState: Serialize", +// deserialize = "ContributeState: Deserialize<'de>" +// ), +// crate = "manta_util::serde", +// deny_unknown_fields +// )] +// pub struct ContributeRequest +// where +// C: Ceremony, +// { +// /// Contribute state including state and proof +// pub contribute_state: ContributeState, +// } + +// /// Signed Message +// #[derive(Deserialize, Serialize)] +// #[serde( +// bound( +// serialize = r" +// C::Identifier: Serialize, +// T: Serialize, +// Nonce: Serialize, +// Signature: Serialize, +// ", +// deserialize = r" +// C::Identifier: Deserialize<'de>, +// T: Deserialize<'de>, +// Nonce: Deserialize<'de>, +// Signature: Deserialize<'de>, +// ", +// ), +// crate = "manta_util::serde", +// deny_unknown_fields +// )] +// pub struct Signed +// where +// C: Ceremony, +// { +// /// Message +// pub message: T, + +// /// Nonce +// pub nonce: Nonce, + +// /// Signature +// pub signature: Signature, + +// /// Participant Identifier +// pub identifier: C::Identifier, +// } + +// impl Signed +// where +// C: Ceremony, +// { +// /// Generates a signed message with `signing_key` on `message` and `nonce`. +// #[inline] +// pub fn new( +// message: T, +// nonce: &Nonce, +// signing_key: &SigningKey, +// identifier: C::Identifier, +// ) -> Result> +// where +// T: Serialize, +// Nonce: Clone, +// { +// let signature = match sign::<_, C::SignatureScheme>(signing_key, nonce.clone(), &message) { +// Ok(signature) => signature, +// Err(_) => return Err(CeremonyError::::BadRequest), +// }; +// let message = Signed { +// message, +// nonce: nonce.clone(), +// signature, +// identifier, +// }; +// Ok(message) +// } +// } diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 1e22f0b53..4b8e55c95 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -34,6 +34,10 @@ pub mod signature; #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] pub mod coordinator; +#[cfg(feature = "serde")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] +pub mod serde; + /// Nonce pub type Nonce = <::SignatureScheme as SignatureScheme>::Nonce; diff --git a/manta-trusted-setup/src/groth16/ceremony/serde.rs b/manta-trusted-setup/src/groth16/ceremony/serde.rs new file mode 100644 index 000000000..28529a09b --- /dev/null +++ b/manta-trusted-setup/src/groth16/ceremony/serde.rs @@ -0,0 +1,83 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Serde + +use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; +use manta_util::{ + serde::{Deserialize, Deserializer, Serialize, Serializer}, + Array, +}; + +/// Uses `serializer` to serialize `data` that implements `CanonicalSerialize`. +#[inline] +pub fn serialize_arkworks(data: &T, serializer: S) -> Result +where + T: CanonicalSerialize, + S: Serializer, +{ + let mut bytes = Vec::new(); + data.serialize(&mut bytes).unwrap(); + Serialize::serialize(&bytes, serializer) +} + +/// Uses `deserializer` to deserialize into data with type `T` that implements `CanonicalDeserialize`. +#[inline] +pub fn deserialize_arkworks<'de, D, T>(deserializer: D) -> Result +where + D: Deserializer<'de>, + T: CanonicalDeserialize, +{ + let bytes: Vec = Deserialize::deserialize(deserializer)?; + Ok(CanonicalDeserialize::deserialize(bytes.as_slice()).expect("Deserialize should succeed.")) +} + +/// +#[inline] +pub fn serialize_array( + data: &Array, + serializer: S, +) -> Result +where + T: CanonicalSerialize, + S: Serializer, +{ + let mut bytes = Vec::new(); + for i in 0..N { + data.0[i].serialize(&mut bytes).unwrap(); + } + Serialize::serialize(&bytes, serializer) +} + +/// +#[inline] +pub fn deserialize_array<'de, D, T, const N: usize>( + deserializer: D, +) -> Result, D::Error> +where + D: Deserializer<'de>, + T: CanonicalDeserialize, +{ + let mut bytes: Vec = Deserialize::deserialize(deserializer)?; + let mut data = Vec::with_capacity(N); + for _ in 0..N { + data.push( + CanonicalDeserialize::deserialize(bytes.as_slice()) // TODO: Issue here + .expect("Deserialize should succeed."), + ) + } + Ok(Array::from_vec(data)) +} diff --git a/manta-util/src/bytes.rs b/manta-util/src/bytes.rs index 92558e980..592bc0c98 100644 --- a/manta-util/src/bytes.rs +++ b/manta-util/src/bytes.rs @@ -16,8 +16,6 @@ //! Utilities for Manipulating Bytes -use core::marker::PhantomData; - #[cfg(feature = "alloc")] use alloc::vec::Vec; @@ -108,18 +106,3 @@ pub trait AsBytes { /// Returns an owned byte representation of `self`. fn as_bytes(&self) -> Vec; } - -#[cfg(feature = "serde")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] -/// Store `T` in bytes form. -#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -#[serde( - bound(serialize = r"", deserialize = "",), - crate = "crate::serde", - deny_unknown_fields -)] -pub struct BytesRepr { - /// The bytes representation of `T` - pub bytes: Vec, - __: PhantomData, -} From 7fdc20c2984c2b39f995b1bee0fb9843c9ce6e09 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Wed, 7 Sep 2022 14:17:16 -0700 Subject: [PATCH 06/60] feat: serde --- .../src/groth16/ceremony/message.rs | 322 +++++++++--------- .../src/groth16/ceremony/mod.rs | 5 +- .../src/groth16/ceremony/serde.rs | 44 ++- 3 files changed, 210 insertions(+), 161 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index cb2d5f8d2..d818de34e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -19,15 +19,14 @@ use crate::{ groth16::{ ceremony::{ - serde::{deserialize_arkworks, serialize_arkworks}, + serde::{deserialize_array, serialize_array}, signature::sign, - Ceremony, CeremonyError, Nonce, Proof, Signature, SigningKey, + Ceremony, CeremonyError, Nonce, Signature, SigningKey, }, - mpc::{State, StateSize}, + mpc::{Proof, State, StateSize}, }, mpc::Challenge, }; -use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{ serde::{Deserialize, Serialize}, Array, @@ -35,167 +34,184 @@ use manta_util::{ /// MPC States #[derive(Serialize, Deserialize)] +#[serde( + bound( + serialize = "Challenge: Serialize", + deserialize = "Challenge: Deserialize<'de>", + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct MPCState +where + C: Ceremony, +{ + /// State + #[cfg_attr( + feature = "serde", + serde( + serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" + ) + )] + pub state: Array, CIRCUIT_COUNT>, + + /// Challenge + pub challenge: Array, CIRCUIT_COUNT>, +} + +/// Contribute States +#[derive(Serialize)] #[serde( bound(serialize = "", deserialize = ""), crate = "manta_util::serde", deny_unknown_fields )] -pub struct MPCState +pub struct ContributeState where C: Ceremony, { /// State #[cfg_attr( feature = "serde", - serde(serialize_with = "serialize_arkworks::, _>") + serde( + serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" + ) )] - pub state: Array, N>, + pub state: Array, CIRCUIT_COUNT>, + + /// Proof + #[cfg_attr( + feature = "serde", + serde( + serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + deserialize_with = "deserialize_array::<'de, _, Proof, CIRCUIT_COUNT>" + ) + )] + pub proof: Array, CIRCUIT_COUNT>, +} + +/// Response for State Sizes +#[derive(Clone, Serialize, Deserialize)] +#[serde(crate = "manta_util::serde", deny_unknown_fields)] +pub struct ServerSize(pub Array); + +impl From> + for ServerSize +{ + fn from(inner: Array) -> Self { + ServerSize(inner) + } +} + +/// Query Request +#[derive(Deserialize, Serialize)] +#[serde(crate = "manta_util::serde", deny_unknown_fields)] +pub struct QueryRequest; + +/// Response for [`QueryRequest`] +#[derive(Deserialize, Serialize)] +#[serde( + bound( + serialize = "MPCState: Serialize", + deserialize = "MPCState: Deserialize<'de>" + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub enum QueryResponse +where + C: Ceremony, +{ + /// Queue Position + QueuePosition(usize), - // /// Challenge - // pub challenge: Array, N>, + /// MPC State + Mpc(MPCState), } -// /// Contribute States -// #[derive(Deserialize, Serialize)] -// #[serde( -// bound( -// serialize = "State: CanonicalSerialize, Proof: CanonicalSerialize", -// deserialize = "State: CanonicalDeserialize, Proof: CanonicalDeserialize" -// ), -// crate = "manta_util::serde", -// deny_unknown_fields -// )] -// pub struct ContributeState -// where -// C: Ceremony, -// { -// /// State -// pub state: Array, CIRCUIT_COUNT>, - -// /// Proof -// pub proof: Array, CIRCUIT_COUNT>, -// } - -// /// Response for State Sizes -// #[derive(Clone, Serialize, Deserialize)] -// #[serde(crate = "manta_util::serde", deny_unknown_fields)] -// pub struct ServerSize(pub Array); - -// impl From> -// for ServerSize -// { -// fn from(inner: Array) -> Self { -// ServerSize(inner) -// } -// } - -// /// Query Request -// #[derive(Deserialize, Serialize)] -// #[serde(crate = "manta_util::serde", deny_unknown_fields)] -// pub struct QueryRequest; - -// /// Response for [`QueryRequest`] -// #[derive(Deserialize, Serialize)] -// #[serde( -// bound( -// serialize = "MPCState: Serialize", -// deserialize = "MPCState: Deserialize<'de>" -// ), -// crate = "manta_util::serde", -// deny_unknown_fields -// )] -// pub enum QueryResponse -// where -// C: Ceremony, -// { -// /// Queue Position -// QueuePosition(usize), - -// /// MPC State -// Mpc(MPCState), -// } - -// /// Contribute Request -// #[derive(Serialize, Deserialize)] -// #[serde( -// bound( -// serialize = "ContributeState: Serialize", -// deserialize = "ContributeState: Deserialize<'de>" -// ), -// crate = "manta_util::serde", -// deny_unknown_fields -// )] -// pub struct ContributeRequest -// where -// C: Ceremony, -// { -// /// Contribute state including state and proof -// pub contribute_state: ContributeState, -// } - -// /// Signed Message -// #[derive(Deserialize, Serialize)] -// #[serde( -// bound( -// serialize = r" -// C::Identifier: Serialize, -// T: Serialize, -// Nonce: Serialize, -// Signature: Serialize, -// ", -// deserialize = r" -// C::Identifier: Deserialize<'de>, -// T: Deserialize<'de>, -// Nonce: Deserialize<'de>, -// Signature: Deserialize<'de>, -// ", -// ), -// crate = "manta_util::serde", -// deny_unknown_fields -// )] -// pub struct Signed -// where -// C: Ceremony, -// { -// /// Message -// pub message: T, - -// /// Nonce -// pub nonce: Nonce, - -// /// Signature -// pub signature: Signature, - -// /// Participant Identifier -// pub identifier: C::Identifier, -// } - -// impl Signed -// where -// C: Ceremony, -// { -// /// Generates a signed message with `signing_key` on `message` and `nonce`. -// #[inline] -// pub fn new( -// message: T, -// nonce: &Nonce, -// signing_key: &SigningKey, -// identifier: C::Identifier, -// ) -> Result> -// where -// T: Serialize, -// Nonce: Clone, -// { -// let signature = match sign::<_, C::SignatureScheme>(signing_key, nonce.clone(), &message) { -// Ok(signature) => signature, -// Err(_) => return Err(CeremonyError::::BadRequest), -// }; -// let message = Signed { -// message, -// nonce: nonce.clone(), -// signature, -// identifier, -// }; -// Ok(message) -// } -// } +/// Contribute Request +#[derive(Serialize, Deserialize)] +#[serde( + bound( + serialize = "ContributeState: Serialize", + deserialize = "ContributeState: Deserialize<'de>" + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct ContributeRequest +where + C: Ceremony, +{ + /// Contribute state including state and proof + pub contribute_state: ContributeState, +} + +/// Signed Message +#[derive(Deserialize, Serialize)] +#[serde( + bound( + serialize = r" + C::Identifier: Serialize, + T: Serialize, + Nonce: Serialize, + Signature: Serialize, + ", + deserialize = r" + C::Identifier: Deserialize<'de>, + T: Deserialize<'de>, + Nonce: Deserialize<'de>, + Signature: Deserialize<'de>, + ", + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct Signed +where + C: Ceremony, +{ + /// Message + pub message: T, + + /// Nonce + pub nonce: Nonce, + + /// Signature + pub signature: Signature, + + /// Participant Identifier + pub identifier: C::Identifier, +} + +impl Signed +where + C: Ceremony, +{ + /// Generates a signed message with `signing_key` on `message` and `nonce`. + #[inline] + pub fn new( + message: T, + nonce: &Nonce, + signing_key: &SigningKey, + identifier: C::Identifier, + ) -> Result> + where + T: Serialize, + Nonce: Clone, + { + let signature = match sign::<_, C::SignatureScheme>(signing_key, nonce.clone(), &message) { + Ok(signature) => signature, + Err(_) => return Err(CeremonyError::::BadRequest), + }; + let message = Signed { + message, + nonce: nonce.clone(), + signature, + identifier, + }; + Ok(message) + } +} diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 4b8e55c95..f29631e71 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -16,7 +16,7 @@ //! Groth16 Trusted Setup Ceremony -use crate::{groth16::ceremony::signature::SignatureScheme, mpc, mpc::ProofType}; +use crate::{groth16::ceremony::signature::SignatureScheme, mpc}; use derivative::Derivative; use manta_crypto::{ arkworks::pairing::Pairing, @@ -50,9 +50,6 @@ pub type SigningKey = <::SignatureScheme as SigningKeyType>::S /// Verifying Key pub type VerifyingKey = <::SignatureScheme as VerifyingKeyType>::VerifyingKey; -/// Proof -pub type Proof = ::Proof; - /// Participant pub trait Participant { /// Participant Identifier Type diff --git a/manta-trusted-setup/src/groth16/ceremony/serde.rs b/manta-trusted-setup/src/groth16/ceremony/serde.rs index 28529a09b..23465513a 100644 --- a/manta-trusted-setup/src/groth16/ceremony/serde.rs +++ b/manta-trusted-setup/src/groth16/ceremony/serde.rs @@ -24,7 +24,7 @@ use manta_util::{ /// Uses `serializer` to serialize `data` that implements `CanonicalSerialize`. #[inline] -pub fn serialize_arkworks(data: &T, serializer: S) -> Result +pub fn serialize_element(data: &T, serializer: S) -> Result where T: CanonicalSerialize, S: Serializer, @@ -36,7 +36,7 @@ where /// Uses `deserializer` to deserialize into data with type `T` that implements `CanonicalDeserialize`. #[inline] -pub fn deserialize_arkworks<'de, D, T>(deserializer: D) -> Result +pub fn deserialize_element<'de, D, T>(deserializer: D) -> Result where D: Deserializer<'de>, T: CanonicalDeserialize, @@ -71,13 +71,49 @@ where D: Deserializer<'de>, T: CanonicalDeserialize, { - let mut bytes: Vec = Deserialize::deserialize(deserializer)?; + let bytes: Vec = Deserialize::deserialize(deserializer)?; + let bytes = bytes.as_slice(); let mut data = Vec::with_capacity(N); for _ in 0..N { data.push( - CanonicalDeserialize::deserialize(bytes.as_slice()) // TODO: Issue here + CanonicalDeserialize::deserialize(bytes) // TODO: Issue here .expect("Deserialize should succeed."), ) } Ok(Array::from_vec(data)) } + +// /// Testing Suites +// TODO: Check if serde works correctly. +// #[cfg(test)] +// mod test { +// use super::*; +// use ark_bls12_381::Bls12_381; +// use ark_groth16::{ProvingKey, VerifyingKey}; +// use manta_crypto::{ +// arkworks::ec::PairingEngine, +// rand::{OsRng, Rand}, +// }; + +// /// Samples a dummy verifying key `vk`. +// fn sample_dummy_vk(rng: &mut R) -> VerifyingKey +// where +// R: Rand, +// { +// VerifyingKey { +// alpha_g1: rng.gen(), +// beta_g2: rng.gen(), +// gamma_g2: rng.gen(), +// delta_g2: rng.gen(), +// gamma_abc_g1: vec![rng.gen()], +// } +// } + +// #[test] +// fn serde_element_is_correct() { +// let mut rng = OsRng; +// let dummy_vk = sample_dummy_vk(&mut rng); +// let mut serialized_data = Vec::new(); +// serialize_element(&dummy_vk, &mut serialized_data); +// } +// } From 69768134230cdc804825ceab7f64cc15f062fcdb Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Wed, 7 Sep 2022 16:07:03 -0700 Subject: [PATCH 07/60] chore: fix comments --- manta-trusted-setup/Cargo.toml | 1 + .../src/groth16/ceremony/coordinator.rs | 158 +++++++++++++----- .../src/groth16/ceremony/message.rs | 17 +- .../src/groth16/ceremony/mod.rs | 54 +++++- .../src/groth16/ceremony/registry.rs | 10 ++ .../src/groth16/ceremony/serde.rs | 8 +- .../src/groth16/ceremony/server.rs | 96 +++-------- manta-util/src/collections/vec_deque.rs | 18 +- 8 files changed, 226 insertions(+), 136 deletions(-) diff --git a/manta-trusted-setup/Cargo.toml b/manta-trusted-setup/Cargo.toml index f36f41fcd..9f8521c81 100644 --- a/manta-trusted-setup/Cargo.toml +++ b/manta-trusted-setup/Cargo.toml @@ -55,6 +55,7 @@ blake2 = { version = "0.10.4", default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["arkworks", "getrandom", "rand_chacha", "dalek"] } manta-util = { path = "../manta-util", default-features = false } +parking_lot = { version = "0.12.1", default-features = false } [dev-dependencies] ark-bls12-381 = { version = "0.3.0", default-features = false, features = ["curve", "scalar_field"] } diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 3824b687d..763d7e825 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -18,29 +18,23 @@ use crate::{ groth16::{ - ceremony::{registry::Registry, Ceremony, Nonce, Participant}, - mpc::StateSize, + ceremony::{ + message::{MPCState, Signed}, + registry::Registry, + serde::{deserialize_array, serialize_array}, + signature::{check_nonce, verify}, + Ceremony, CeremonyError, Participant, Queue, UserPriority, + }, + mpc::{Proof, State, StateSize}, }, - mpc::{Challenge, Proof, State}, + mpc::Challenge, }; -use manta_util::{collections::vec_deque::MultiVecDeque, time::lock::Timed, Array, BoxArray}; +use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; +use manta_util::{time::lock::Timed, Array, BoxArray}; #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; -/// Proof Array Type -pub type ProofArray = BoxArray, N>; - -/// State Array Type -pub type StateArray = BoxArray, N>; - -/// Challenge Array Type -pub type ChallengeArray = BoxArray, N>; - -/// Participant Queue Type -pub type Queue = - MultiVecDeque<::Identifier, LEVEL_COUNT>; - /// Ceremony Coordinator #[cfg_attr( feature = "serde", @@ -49,17 +43,17 @@ pub type Queue = bound( serialize = r" R: Serialize, - State: Serialize, Challenge: Serialize, - Proof: Serialize, C::Participant: Serialize, + State: CanonicalSerialize, + Proof: Serialize, ", deserialize = r" R: Deserialize<'de>, - State: Deserialize<'de>, Challenge: Deserialize<'de>, - Proof: Deserialize<'de>, C::Participant: Deserialize<'de>, + State: CanonicalDeserialize, + Proof: Deserialize<'de>, " ), crate = "manta_util::serde", @@ -72,35 +66,49 @@ where R: Registry, { /// Participant Registry - pub registry: R, + registry: R, /// State - pub state: StateArray, + #[cfg_attr( + feature = "serde", + serde( + serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" + ) + )] + state: BoxArray, CIRCUIT_COUNT>, /// Challenge - pub challenge: ChallengeArray, + challenge: BoxArray, CIRCUIT_COUNT>, /// Latest Contributor /// /// This participant was the last one to perform a successful contribution to the ceremony. - pub latest_contributor: Option, + latest_contributor: Option, /// Latest Proof - pub latest_proof: Option>, + // #[cfg_attr( + // feature = "serde", + // serde( + // serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + // deserialize_with = "deserialize_array::<'de, _, Proof, CIRCUIT_COUNT>" + // ) + // )] + latest_proof: Option, CIRCUIT_COUNT>>, // TODO: Implement serialize /// State Sizes - pub size: Array, + size: Array, /// Current Round Number - pub round: usize, + round: usize, /// Participant Queue #[serde(skip)] - pub queue: Queue, + queue: Queue, /// Participant Lock #[serde(skip)] - pub participant_lock: Timed>, + participant_lock: Timed>, } impl @@ -109,6 +117,45 @@ where C: Ceremony, R: Registry, { + /// Builds a new [`Coordinator`]. + #[inline] + pub fn new( + registry: R, + state: BoxArray, CIRCUIT_COUNT>, + challenge: BoxArray, CIRCUIT_COUNT>, + size: Array, + ) -> Self { + Self { + registry, + state, + challenge, + latest_contributor: None, + latest_proof: None, + size, + round: 0, + queue: Default::default(), + participant_lock: Default::default(), + } + } + + /// Returns the current round number. + #[inline] + pub fn round(&self) -> usize { + self.round + } + + /// Returns the state size. + #[inline] + pub fn size(&self) -> &Array { + &self.size + } + + /// Returns the registry. + #[inline] + pub fn registry(&self) -> &R { + &self.registry + } + /// Returns a shared reference to the participant data for `id` from the registry. #[inline] pub fn participant(&self, id: &C::Identifier) -> Option<&C::Participant> { @@ -121,22 +168,51 @@ where self.registry.get_mut(id) } - /// Returns the current position for a `participant` in the queue. - #[inline] - pub fn position(&self, participant: &C::Participant) -> Option { - self.queue.position(participant.level(), participant.id()) + /// + pub fn queue_mut(&mut self) -> &mut Queue { + &mut self.queue } - /// Inserts `participant` into the queue. + /// Gets the current state and challenge. #[inline] - pub fn insert_participant(&mut self, participant: &C::Participant) { - self.queue - .push_back_at(participant.level(), participant.id().clone()); + pub fn state_and_challenge(&self) -> MPCState + where + Challenge: Clone, + { + MPCState { + state: self.state.clone(), + challenge: self.challenge.clone(), + } } - /// Gets nonce of a participant with `id`. + /// Preprocesses a request by checking nonce and verifying signature. #[inline] - pub fn nonce(&self, id: &C::Identifier) -> Option> { - Some(self.registry.get(id)?.get_nonce()) + pub fn preprocess_request( + &mut self, + request: &Signed, + ) -> Result> + where + T: Serialize, + { + if self.registry.has_contributed(&request.identifier) { + return Err(CeremonyError::AlreadyContributed); + } + let participant = self + .registry + .get_mut(&request.identifier) + .ok_or_else(|| CeremonyError::NotRegistered)?; + let participant_nonce = participant.get_nonce(); + if !check_nonce(&participant_nonce, &request.nonce) { + return Err(CeremonyError::NonceNotInSync(participant_nonce)); + }; + verify::( + participant.verifying_key(), + participant_nonce, + &request.message, + &request.signature, + ) + .map_err(|_| CeremonyError::BadRequest)?; + participant.increment_nonce(); + Ok(participant.level()) } } diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index d818de34e..fa53dc17a 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -27,17 +27,18 @@ use crate::{ }, mpc::Challenge, }; +use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{ serde::{Deserialize, Serialize}, - Array, + Array, BoxArray, }; /// MPC States #[derive(Serialize, Deserialize)] #[serde( bound( - serialize = "Challenge: Serialize", - deserialize = "Challenge: Deserialize<'de>", + serialize = "Challenge: Serialize, State: CanonicalSerialize,", + deserialize = "Challenge: Deserialize<'de>, State: CanonicalDeserialize,", ), crate = "manta_util::serde", deny_unknown_fields @@ -54,14 +55,14 @@ where deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" ) )] - pub state: Array, CIRCUIT_COUNT>, + pub state: BoxArray, CIRCUIT_COUNT>, /// Challenge - pub challenge: Array, CIRCUIT_COUNT>, + pub challenge: BoxArray, CIRCUIT_COUNT>, } /// Contribute States -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] #[serde( bound(serialize = "", deserialize = ""), crate = "manta_util::serde", @@ -79,7 +80,7 @@ where deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" ) )] - pub state: Array, CIRCUIT_COUNT>, + pub state: BoxArray, CIRCUIT_COUNT>, /// Proof #[cfg_attr( @@ -89,7 +90,7 @@ where deserialize_with = "deserialize_array::<'de, _, Proof, CIRCUIT_COUNT>" ) )] - pub proof: Array, CIRCUIT_COUNT>, + pub proof: BoxArray, CIRCUIT_COUNT>, } /// Response for State Sizes diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index f29631e71..652d9b531 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -16,18 +16,21 @@ //! Groth16 Trusted Setup Ceremony -use crate::{groth16::ceremony::signature::SignatureScheme, mpc}; +use crate::{groth16::ceremony::signature::SignatureScheme, mpc::Types}; use derivative::Derivative; use manta_crypto::{ arkworks::pairing::Pairing, signature::{SignatureType, SigningKeyType, VerifyingKeyType}, }; -use manta_util::serde::{Deserialize, Serialize}; +use manta_util::{ + collections::vec_deque::MultiVecDeque, + serde::{Deserialize, Serialize}, +}; // pub mod client; pub mod message; pub mod registry; -// pub mod server; +pub mod server; pub mod signature; #[cfg(feature = "serde")] @@ -50,6 +53,10 @@ pub type SigningKey = <::SignatureScheme as SigningKeyType>::S /// Verifying Key pub type VerifyingKey = <::SignatureScheme as VerifyingKeyType>::VerifyingKey; +/// Participant Queue Type +pub type Queue = + MultiVecDeque<::Identifier, LEVEL_COUNT>; + /// Participant pub trait Participant { /// Participant Identifier Type @@ -72,7 +79,7 @@ pub trait Participant { /// # Note /// /// Lower level indicates a higher priority. - fn level(&self) -> usize; + fn level(&self) -> UserPriority; /// Returns nonce for `self`. fn get_nonce(&self) -> Self::Nonce; @@ -82,7 +89,7 @@ pub trait Participant { } /// Ceremony Configuration -pub trait Ceremony: mpc::Types { +pub trait Ceremony: Types { /// Pairing Type type Pairing: Pairing; @@ -136,4 +143,41 @@ where /// Timed-out Timeout, + + /// Unexpected Server Error + Unexpected, +} + +/// Priority +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[serde( + bound(deserialize = "", serialize = ""), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub enum UserPriority { + /// High Priority + High, + + /// Normal Priority + Normal, +} + +impl From for UserPriority { + fn from(priority: usize) -> Self { + match priority { + 0 => Self::High, + 1 => Self::Normal, + _ => unimplemented!(), + } + } +} + +impl From for usize { + fn from(priority: UserPriority) -> Self { + match priority { + UserPriority::High => 0, + UserPriority::Normal => 1, + } + } } diff --git a/manta-trusted-setup/src/groth16/ceremony/registry.rs b/manta-trusted-setup/src/groth16/ceremony/registry.rs index 7637086d2..475a71a9f 100644 --- a/manta-trusted-setup/src/groth16/ceremony/registry.rs +++ b/manta-trusted-setup/src/groth16/ceremony/registry.rs @@ -16,6 +16,8 @@ //! Groth16 Trusted Setup Ceremony Registry +use crate::groth16::ceremony::Participant; + /// Participant Registry pub trait Registry { /// Registers the `participant` into `self` returning `false` if the `participant` is already @@ -31,4 +33,12 @@ pub trait Registry { /// Returns `true` if the participant with the given `id` has already contributed to the /// ceremony. fn has_contributed(&self, id: &I) -> bool; + + /// Gets nonce of a participant with `id`. + fn nonce(&self, id: &I) -> Option + where + P: Participant, + { + Some(self.get(id)?.get_nonce()) + } } diff --git a/manta-trusted-setup/src/groth16/ceremony/serde.rs b/manta-trusted-setup/src/groth16/ceremony/serde.rs index 23465513a..84fccadb6 100644 --- a/manta-trusted-setup/src/groth16/ceremony/serde.rs +++ b/manta-trusted-setup/src/groth16/ceremony/serde.rs @@ -19,7 +19,7 @@ use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{ serde::{Deserialize, Deserializer, Serialize, Serializer}, - Array, + BoxArray, }; /// Uses `serializer` to serialize `data` that implements `CanonicalSerialize`. @@ -48,7 +48,7 @@ where /// #[inline] pub fn serialize_array( - data: &Array, + data: &BoxArray, serializer: S, ) -> Result where @@ -66,7 +66,7 @@ where #[inline] pub fn deserialize_array<'de, D, T, const N: usize>( deserializer: D, -) -> Result, D::Error> +) -> Result, D::Error> where D: Deserializer<'de>, T: CanonicalDeserialize, @@ -80,7 +80,7 @@ where .expect("Deserialize should succeed."), ) } - Ok(Array::from_vec(data)) + Ok(BoxArray::from_vec(data)) } // /// Testing Suites diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index fbd635949..09036572a 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -19,22 +19,20 @@ use crate::{ groth16::{ ceremony::{ - coordinator::{ChallengeArray, Coordinator, StateArray}, + coordinator::Coordinator, message::{QueryRequest, QueryResponse, ServerSize, Signed}, registry::Registry, - signature::{check_nonce, verify, Nonce as _}, - Ceremony, CeremonyError, Nonce, Participant, + Ceremony, CeremonyError, Nonce, }, mpc::{State, StateSize}, }, mpc::Challenge, }; -use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; -use manta_util::{serde::Serialize, Array}; -use std::sync::{Arc, Mutex}; - -use super::Signature; +use alloc::sync::Arc; +use manta_util::{Array, BoxArray}; +use parking_lot::Mutex; +/// Server pub struct Server where C: Ceremony, @@ -56,76 +54,30 @@ where /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a `recovery_path`. #[inline] pub fn new( - state: StateArray, - challenge: ChallengeArray, + state: BoxArray, CIRCUIT_COUNT>, + challenge: BoxArray, CIRCUIT_COUNT>, registry: R, recovery_path: String, size: Array, ) -> Self { - let coordinator = Coordinator { - registry, - queue: Default::default(), - participant_lock: Default::default(), - state, - challenge, - latest_contributor: None, - latest_proof: None, - size, - round: 0, - }; + let coordinator = Coordinator::new(registry, state, challenge, size); Self { coordinator: Arc::new(Mutex::new(coordinator)), recovery_path, } } - /// Preprocess a request by checking nonce and verifying signature. - #[inline] - pub fn preprocess_request( - registry: &mut R, - request: &Signed, - ) -> Result<(), CeremonyError> - where - T: Serialize, - { - if registry.has_contributed(&request.identifier) { - return Err(CeremonyError::AlreadyContributed); - } - let participant_nonce = registry - .get(&request.identifier) - .ok_or_else(|| CeremonyError::NotRegistered)? - .get_nonce(); - if !check_nonce(&participant_nonce, &request.nonce) { - return Err(CeremonyError::NonceNotInSync(participant_nonce)); - }; - let mut participant = match registry.get(&request.identifier) { - Some(participant) => participant, - None => unreachable!("participant registration has been checked"), - }; - verify::( - participant.verifying_key(), - participant_nonce, - &request.message, - &request.signature, - ) - .map_err(|_| CeremonyError::BadRequest)?; - participant.increment_nonce(); - Ok(()) - } - /// Gets the server state size and the current nonce of the participant. #[inline] pub async fn start( self, request: C::Identifier, ) -> Result<(ServerSize, Nonce), CeremonyError> { - let coordinator = self - .coordinator - .lock() - .expect("acquiring a lock is not allowed to fail"); + let coordinator = self.coordinator.lock(); Ok(( - coordinator.size.clone().into(), + coordinator.size().clone().into(), coordinator + .registry() .nonce(&request) .ok_or_else(|| CeremonyError::NotRegistered)?, )) @@ -138,27 +90,17 @@ where request: Signed, ) -> Result, CeremonyError> where - C::Identifier: Serialize, - State: CanonicalSerialize + CanonicalDeserialize, - Challenge: CanonicalSerialize + CanonicalDeserialize, + Challenge: Clone, { let mut coordinator = self.coordinator.lock(); - Self::preprocess_request(&mut coordinator.registry, &request)?; - if !coordinator.is_in_queue(&request.identifier)? { - coordinator.enqueue_participant(&request.identifier)?; - } - if coordinator.is_next(&request.identifier) { + let priority = coordinator.preprocess_request(&request)?; + let position = coordinator + .queue_mut() + .push_back_if_missing(priority.into(), request.identifier); + if position == 0 { Ok(QueryResponse::Mpc(coordinator.state_and_challenge())) } else { - Ok(QueryResponse::QueuePosition( - coordinator - .position( - coordinator - .get_participant(&request.identifier) - .expect("Participant existence is checked in `process_request`."), - ) - .expect("Participant should be always in the queue here"), - )) + Ok(QueryResponse::QueuePosition(position)) } } } diff --git a/manta-util/src/collections/vec_deque.rs b/manta-util/src/collections/vec_deque.rs index 4ce9e3806..9ca1ff97b 100644 --- a/manta-util/src/collections/vec_deque.rs +++ b/manta-util/src/collections/vec_deque.rs @@ -156,7 +156,7 @@ impl MultiVecDeque { /// /// This method is an alias for `self.at_level_mut(level).push_back(item)`. #[inline] - pub fn push_back_at(&mut self, level: usize, item: T) { + pub fn push_back(&mut self, level: usize, item: T) { self.0[level].push_back(item) } @@ -165,6 +165,22 @@ impl MultiVecDeque { pub fn pop_front(&mut self) -> Option { self.0.iter_mut().find_map(VecDeque::pop_front) } + + /// Pushes back `item` at `level` if `item` is missing. Returns the position + /// of `item` in both cases. + #[inline] + pub fn push_back_if_missing(&mut self, level: usize, item: T) -> usize + where + T: PartialEq, + { + match self.position(level, &item) { + Some(position) => position, + None => { + self.push_back(level, item); + self.0[level].len()-1 + }, + } + } } impl Default for MultiVecDeque { From aacf8fe583553cc3b0ce1f1abc19756a824423af Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Wed, 7 Sep 2022 22:44:28 -0700 Subject: [PATCH 08/60] feat: server --- .../src/groth16/ceremony/coordinator.rs | 104 +++++++++++---- .../src/groth16/ceremony/message.rs | 37 +++--- .../src/groth16/ceremony/mod.rs | 25 ++-- .../src/groth16/ceremony/server.rs | 55 ++++++-- .../src/groth16/ceremony/util.rs | 123 ++++++++++++++++++ manta-trusted-setup/src/groth16/mpc.rs | 14 +- manta-trusted-setup/src/groth16/test/mod.rs | 2 +- 7 files changed, 289 insertions(+), 71 deletions(-) create mode 100644 manta-trusted-setup/src/groth16/ceremony/util.rs diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 763d7e825..af12e76e0 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -16,25 +16,26 @@ //! Coordinator -use crate::{ - groth16::{ - ceremony::{ - message::{MPCState, Signed}, - registry::Registry, - serde::{deserialize_array, serialize_array}, - signature::{check_nonce, verify}, - Ceremony, CeremonyError, Participant, Queue, UserPriority, - }, - mpc::{Proof, State, StateSize}, +use crate::groth16::{ + ceremony::{ + message::{MPCState, Signed}, + registry::Registry, + serde::{deserialize_array, serialize_array}, + signature::{check_nonce, verify}, + Ceremony, CeremonyError, Challenge, Participant, Queue, UserPriority, }, - mpc::Challenge, + mpc::{verify_transform, Proof, State, StateSize}, }; +use core::{mem, time::Duration}; use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{time::lock::Timed, Array, BoxArray}; #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; +/// Time limit for a participant at the front of the queue to contribute with unit as second +pub const TIME_LIMIT: Duration = Duration::from_secs(360); + /// Ceremony Coordinator #[cfg_attr( feature = "serde", @@ -45,15 +46,13 @@ use manta_util::serde::{Deserialize, Serialize}; R: Serialize, Challenge: Serialize, C::Participant: Serialize, - State: CanonicalSerialize, - Proof: Serialize, + State: CanonicalSerialize, ", deserialize = r" R: Deserialize<'de>, Challenge: Deserialize<'de>, C::Participant: Deserialize<'de>, - State: CanonicalDeserialize, - Proof: Deserialize<'de>, + State: CanonicalDeserialize, " ), crate = "manta_util::serde", @@ -72,11 +71,11 @@ where #[cfg_attr( feature = "serde", serde( - serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" + serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" ) )] - state: BoxArray, CIRCUIT_COUNT>, + state: BoxArray, CIRCUIT_COUNT>, /// Challenge challenge: BoxArray, CIRCUIT_COUNT>, @@ -90,11 +89,12 @@ where // #[cfg_attr( // feature = "serde", // serde( - // serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - // deserialize_with = "deserialize_array::<'de, _, Proof, CIRCUIT_COUNT>" + // serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + // deserialize_with = "deserialize_array::<'de, _, Proof, CIRCUIT_COUNT>" // ) // )] - latest_proof: Option, CIRCUIT_COUNT>>, // TODO: Implement serialize + #[serde(skip)] //TODO + latest_proof: Option, CIRCUIT_COUNT>>, // TODO: Implement serialize /// State Sizes size: Array, @@ -121,7 +121,7 @@ where #[inline] pub fn new( registry: R, - state: BoxArray, CIRCUIT_COUNT>, + state: BoxArray, CIRCUIT_COUNT>, challenge: BoxArray, CIRCUIT_COUNT>, size: Array, ) -> Self { @@ -144,6 +144,12 @@ where self.round } + /// Increments the round number. + #[inline] + pub fn increment_round(&mut self) { + self.round += 1; + } + /// Returns the state size. #[inline] pub fn size(&self) -> &Array { @@ -215,4 +221,58 @@ where participant.increment_nonce(); Ok(participant.level()) } + + /// Checks the lock update errors for the [`Coordinator::update`] method. + #[inline] + pub fn check_lock_update_errors( + has_expired: bool, + lhs: &Option, + rhs: &C::Identifier, + ) -> Result<(), CeremonyError> { + match lhs { + Some(lhs) if lhs == rhs && has_expired => Err(CeremonyError::Timeout), + Some(lhs) if lhs != rhs => Err(CeremonyError::NotYourTurn), + _ => Ok(()), + } + } + + /// Updates the expired lock by reducing the priority of it's participant and setting it's + /// contained value to the new front of the queue. The previous participant in the lock is + /// returned. + #[inline] + pub fn update_expired_lock(&mut self) -> Option { + self.participant_lock.mutate(|p| { + if let Some(identifier) = p { + if let Some(participant) = self.registry.get_mut(identifier) { + participant.reduce_priority(); + } + } + mem::replace(p, self.queue.pop_front()) + }) + } + + /// Updates the MPC state and challenge using client's contribution. If the contribution is + /// valid, the participant will be removed from the waiting queue, and cannot participate in + /// this ceremony again. + #[inline] + pub fn update( + &mut self, + participant: &C::Identifier, + state: BoxArray, CIRCUIT_COUNT>, + proof: BoxArray, CIRCUIT_COUNT>, + ) -> Result<(), CeremonyError> { + if self.participant_lock.has_expired(TIME_LIMIT) { + Self::check_lock_update_errors(true, &self.update_expired_lock(), participant)?; + } else { + Self::check_lock_update_errors(false, self.participant_lock.get(), participant)?; + } + for (i, (state, proof)) in state.into_iter().zip(proof.clone().into_iter()).enumerate() { + self.state[i] = verify_transform(&self.challenge[i], &self.state[i], state, proof) + .map_err(|_| CeremonyError::BadRequest)? + .1 + } + self.latest_proof = Some(proof); + self.participant_lock.set(self.queue.pop_front()); + Ok(()) + } } diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index fa53dc17a..3f4c875fb 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -16,16 +16,13 @@ //! Messages through Network -use crate::{ - groth16::{ - ceremony::{ - serde::{deserialize_array, serialize_array}, - signature::sign, - Ceremony, CeremonyError, Nonce, Signature, SigningKey, - }, - mpc::{Proof, State, StateSize}, +use crate::groth16::{ + ceremony::{ + serde::{deserialize_array, serialize_array}, + signature::sign, + Ceremony, CeremonyError, Challenge, Nonce, Signature, SigningKey, }, - mpc::Challenge, + mpc::{Proof, State, StateSize}, }; use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{ @@ -37,8 +34,8 @@ use manta_util::{ #[derive(Serialize, Deserialize)] #[serde( bound( - serialize = "Challenge: Serialize, State: CanonicalSerialize,", - deserialize = "Challenge: Deserialize<'de>, State: CanonicalDeserialize,", + serialize = "Challenge: Serialize, State: CanonicalSerialize,", + deserialize = "Challenge: Deserialize<'de>, State: CanonicalDeserialize,", ), crate = "manta_util::serde", deny_unknown_fields @@ -51,11 +48,11 @@ where #[cfg_attr( feature = "serde", serde( - serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" + serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" ) )] - pub state: BoxArray, CIRCUIT_COUNT>, + pub state: BoxArray, CIRCUIT_COUNT>, /// Challenge pub challenge: BoxArray, CIRCUIT_COUNT>, @@ -76,21 +73,21 @@ where #[cfg_attr( feature = "serde", serde( - serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" + serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" ) )] - pub state: BoxArray, CIRCUIT_COUNT>, + pub state: BoxArray, CIRCUIT_COUNT>, /// Proof #[cfg_attr( feature = "serde", serde( - serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - deserialize_with = "deserialize_array::<'de, _, Proof, CIRCUIT_COUNT>" + serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", + deserialize_with = "deserialize_array::<'de, _, Proof, CIRCUIT_COUNT>" ) )] - pub proof: BoxArray, CIRCUIT_COUNT>, + pub proof: BoxArray, CIRCUIT_COUNT>, } /// Response for State Sizes diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 652d9b531..7bc145304 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -16,12 +16,9 @@ //! Groth16 Trusted Setup Ceremony -use crate::{groth16::ceremony::signature::SignatureScheme, mpc::Types}; +use crate::groth16::{ceremony::signature::SignatureScheme, mpc::Configuration}; use derivative::Derivative; -use manta_crypto::{ - arkworks::pairing::Pairing, - signature::{SignatureType, SigningKeyType, VerifyingKeyType}, -}; +use manta_crypto::signature::{SignatureType, SigningKeyType, VerifyingKeyType}; use manta_util::{ collections::vec_deque::MultiVecDeque, serde::{Deserialize, Serialize}, @@ -32,6 +29,7 @@ pub mod message; pub mod registry; pub mod server; pub mod signature; +pub mod util; #[cfg(feature = "serde")] #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] @@ -53,6 +51,9 @@ pub type SigningKey = <::SignatureScheme as SigningKeyType>::S /// Verifying Key pub type VerifyingKey = <::SignatureScheme as VerifyingKeyType>::VerifyingKey; +/// Challenge Type +pub type Challenge = <::Configuration as Configuration>::Challenge; + /// Participant Queue Type pub type Queue = MultiVecDeque<::Identifier, LEVEL_COUNT>; @@ -86,13 +87,16 @@ pub trait Participant { /// Set nonce of current participant fn increment_nonce(&mut self); + + /// Reduces the priority. + fn reduce_priority(&mut self); + + /// Sets contributed. + fn set_contributed(&mut self); } /// Ceremony Configuration -pub trait Ceremony: Types { - /// Pairing Type - type Pairing: Pairing; - +pub trait Ceremony { /// Participant Identifier Type type Identifier: Clone + PartialEq; @@ -105,6 +109,9 @@ pub trait Ceremony: Types { /// Signature Scheme type SignatureScheme: SignatureScheme; + + /// Configuration + type Configuration: Configuration; } /// Ceremony Error diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 09036572a..77c458f49 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -16,21 +16,21 @@ //! Trusted Setup Server -use crate::{ - groth16::{ - ceremony::{ - coordinator::Coordinator, - message::{QueryRequest, QueryResponse, ServerSize, Signed}, - registry::Registry, - Ceremony, CeremonyError, Nonce, - }, - mpc::{State, StateSize}, +use crate::groth16::{ + ceremony::{ + coordinator::Coordinator, + message::{ContributeRequest, QueryRequest, QueryResponse, ServerSize, Signed}, + registry::Registry, + util::log_to_file, + Ceremony, CeremonyError, Challenge, Nonce, Participant, }, - mpc::Challenge, + mpc::{State, StateSize}, }; use alloc::sync::Arc; -use manta_util::{Array, BoxArray}; +use core::ops::Deref; +use manta_util::{serde::Serialize, Array, BoxArray}; use parking_lot::Mutex; +use std::path::Path; /// Server pub struct Server @@ -54,7 +54,7 @@ where /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a `recovery_path`. #[inline] pub fn new( - state: BoxArray, CIRCUIT_COUNT>, + state: BoxArray, CIRCUIT_COUNT>, challenge: BoxArray, CIRCUIT_COUNT>, registry: R, recovery_path: String, @@ -103,4 +103,35 @@ where Ok(QueryResponse::QueuePosition(position)) } } + + /// Processes a request to update the MPC state and remove the participant if successfully updated the state. + /// If update succeeds, save the current coordinator to disk. + #[inline] + pub async fn update( + self, + request: Signed, C>, + ) -> Result<(), CeremonyError> + where + Coordinator: Serialize, + { + let mut coordinator = self.coordinator.lock(); + coordinator.preprocess_request(&request)?; + let contribute_state = request.message.contribute_state; + coordinator.update( + &request.identifier, + contribute_state.state, + contribute_state.proof, + )?; + coordinator + .participant_mut(&request.identifier) + .expect("Geting participant should succeed.") + .set_contributed(); + coordinator.increment_round(); + log_to_file( + &Path::new(&self.recovery_path).join(format!("transcript{}.data", coordinator.round())), + &coordinator.deref(), + ); + println!("{} participants have contributed.", coordinator.round()); + Ok(()) + } } diff --git a/manta-trusted-setup/src/groth16/ceremony/util.rs b/manta-trusted-setup/src/groth16/ceremony/util.rs new file mode 100644 index 000000000..febfbd954 --- /dev/null +++ b/manta-trusted-setup/src/groth16/ceremony/util.rs @@ -0,0 +1,123 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Utilities + +extern crate alloc; + +use manta_crypto::arkworks::pairing::Pairing; +use manta_util::{ + serde::{de::DeserializeOwned, Serialize}, + BoxArray, +}; +use std::{ + fs::File, + io::{Read, Write}, + path::Path, +}; + +use crate::groth16::mpc::State; + +use super::message::ServerSize; + +/// Logs `data` to a disk file at `path`. +#[inline] +pub fn log_to_file(path: &P, data: &T) +where + T: Serialize, + P: AsRef, +{ + let mut file = File::create(path).expect("Open file should succeed."); + let encoded = bincode::serialize(data).expect(""); + file.write_all(&encoded) + .expect("Writing phase one parameters to disk should succeed."); + file.flush().expect("Flushing file should succeed."); +} + +/// Loads `data` from a disk file at `path`. +#[inline] +pub fn load_from_file(path: P) -> T +where + P: AsRef, + T: DeserializeOwned, +{ + let mut file = File::open(path).expect("Opening file should succeed."); + let mut buf = Vec::new(); + file.read_to_end(&mut buf) + .expect("Reading data should succeed."); + bincode::deserialize(&buf[..]).unwrap() +} + +// /// Prepares phase one parameter `powers` for phase two parameters of circuit `cs` with `name`. +// #[inline] +// pub fn prepare_parameters(powers: Accumulator, cs: S, name: &str) +// where +// C: Pairing + Size + kzg::Configuration + mpc::ProvingKeyHasher + mpc::Configuration, +// S: ConstraintSynthesizer, +// D: CeremonyConfig>, +// ::Challenge: +// From<>::Output> + CanonicalSerialize, +// { +// let now = Instant::now(); +// let state = initialize::(powers, cs).expect("failed to initialize state"); +// let challenge = >::hash(&state); +// let mpc_state = MPCState:: { +// state: Array::from_unchecked([AsBytes::from_actual(state)]), +// challenge: Array::from_unchecked([AsBytes::from_actual(challenge.into())]), +// }; +// log_to_file(&format!("prepared_{}.data", name), &mpc_state); +// println!( +// "Preparing Phase 2 parameters for {} circuit takes {:?}\n", +// name, +// now.elapsed() +// ); +// } + +/// Checks `states` has the same size as `size`. +pub fn check_state_size( + states: &BoxArray, CIRCUIT_COUNT>, + size: &ServerSize, +) -> bool +where + P: Pairing, +{ + let mut validity = true; + for i in 0..CIRCUIT_COUNT { + validity = validity + || (states[i].vk.gamma_abc_g1.len() == size.0[i].gamma_abc_g1) + || (states[i].a_query.len() == size.0[i].a_query) + || (states[i].b_g1_query.len() == size.0[i].a_query) + || (states[i].b_g2_query.len() == size.0[i].a_query) + || (states[i].h_query.len() == size.0[i].h_query) + || (states[i].l_query.len() == size.0[i].l_query); + } + validity +} + +/// Testing Suites +#[cfg(test)] +mod test { + use super::*; + + /// Tests if logging and loading data is correct. + #[test] + fn log_load_file_is_correct() { + let data = "Testing data".to_string(); + log_to_file(&"test_transcript.data", &data); + let loaded_data: String = load_from_file(&"test_transcript.data"); + assert_eq!(data, loaded_data); + } +} diff --git a/manta-trusted-setup/src/groth16/mpc.rs b/manta-trusted-setup/src/groth16/mpc.rs index 29a15a909..0b80fea30 100644 --- a/manta-trusted-setup/src/groth16/mpc.rs +++ b/manta-trusted-setup/src/groth16/mpc.rs @@ -37,6 +37,12 @@ use manta_crypto::{ #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; +/// MPC State +pub type State

= ProvingKey<

::Pairing>; + +/// MPC Proof +pub type Proof

= RatioProof

; + /// Proving Key Hasher pub trait ProvingKeyHasher

where @@ -49,12 +55,6 @@ where fn hash(proving_key: &ProvingKey) -> Self::Output; } -/// MPC State -pub type State

= ProvingKey<

::Pairing>; - -/// MPC Proof -pub type Proof

= RatioProof

; - /// MPC State Size #[cfg_attr( feature = "serde", @@ -373,7 +373,7 @@ where #[inline] pub fn verify_transform( challenge: &C::Challenge, - prev: State, + prev: &State, next: State, proof: Proof, ) -> Result<(C::Challenge, State), Error> diff --git a/manta-trusted-setup/src/groth16/test/mod.rs b/manta-trusted-setup/src/groth16/test/mod.rs index 0f3f99d0f..749bcb609 100644 --- a/manta-trusted-setup/src/groth16/test/mod.rs +++ b/manta-trusted-setup/src/groth16/test/mod.rs @@ -275,7 +275,7 @@ fn trusted_setup_phase_two_is_valid() { for _ in 0..5 { prev_state = state.clone(); proof = contribute(&hasher, &challenge, &mut state, &mut rng).unwrap(); - (challenge, state) = verify_transform(&challenge, prev_state, state, proof.clone()) + (challenge, state) = verify_transform(&challenge, &prev_state, state, proof.clone()) .expect("Verify transform failed"); transcript.rounds.push((state.clone(), proof)); } From 320731c2ad52533021bdfd190d586500a3a5cd59 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Wed, 7 Sep 2022 23:28:21 -0700 Subject: [PATCH 09/60] wip: server --- manta-trusted-setup/Cargo.toml | 7 + .../src/groth16/ceremony/coordinator.rs | 8 +- .../src/groth16/ceremony/message.rs | 6 +- .../src/groth16/ceremony/registry.rs | 3 + .../src/groth16/ceremony/server.rs | 129 +++++++++++++++++- 5 files changed, 140 insertions(+), 13 deletions(-) diff --git a/manta-trusted-setup/Cargo.toml b/manta-trusted-setup/Cargo.toml index 9f8521c81..ff9cb93f9 100644 --- a/manta-trusted-setup/Cargo.toml +++ b/manta-trusted-setup/Cargo.toml @@ -38,6 +38,11 @@ serde = [ "manta-util/serde-array" ] +# Tide +tide = [ + "manta-util/tide" +] + # Standard Library std = ["manta-util/std"] @@ -52,6 +57,8 @@ ark-relations = { version = "0.3.0", default-features = false } ark-std = { version = "0.3.0", default-features = false } bincode = { version = "1.3.3", optional = true, default-features = false } blake2 = { version = "0.10.4", default-features = false } +bs58 = { version = "0.4", default-features = false, features = ["alloc"] } +csv = { version = "1.1" } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["arkworks", "getrandom", "rand_chacha", "dalek"] } manta-util = { path = "../manta-util", default-features = false } diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index af12e76e0..32619125a 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -28,7 +28,7 @@ use crate::groth16::{ }; use core::{mem, time::Duration}; use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; -use manta_util::{time::lock::Timed, Array, BoxArray}; +use manta_util::{time::lock::Timed, BoxArray}; #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; @@ -97,7 +97,7 @@ where latest_proof: Option, CIRCUIT_COUNT>>, // TODO: Implement serialize /// State Sizes - size: Array, + size: BoxArray, /// Current Round Number round: usize, @@ -123,7 +123,7 @@ where registry: R, state: BoxArray, CIRCUIT_COUNT>, challenge: BoxArray, CIRCUIT_COUNT>, - size: Array, + size: BoxArray, ) -> Self { Self { registry, @@ -152,7 +152,7 @@ where /// Returns the state size. #[inline] - pub fn size(&self) -> &Array { + pub fn size(&self) -> &BoxArray { &self.size } diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 3f4c875fb..2a5437247 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -93,12 +93,12 @@ where /// Response for State Sizes #[derive(Clone, Serialize, Deserialize)] #[serde(crate = "manta_util::serde", deny_unknown_fields)] -pub struct ServerSize(pub Array); +pub struct ServerSize(pub BoxArray); -impl From> +impl From> for ServerSize { - fn from(inner: Array) -> Self { + fn from(inner: BoxArray) -> Self { ServerSize(inner) } } diff --git a/manta-trusted-setup/src/groth16/ceremony/registry.rs b/manta-trusted-setup/src/groth16/ceremony/registry.rs index 475a71a9f..1694a9081 100644 --- a/manta-trusted-setup/src/groth16/ceremony/registry.rs +++ b/manta-trusted-setup/src/groth16/ceremony/registry.rs @@ -20,6 +20,9 @@ use crate::groth16::ceremony::Participant; /// Participant Registry pub trait Registry { + /// Builds a new [`Registry`]. + fn new() -> Self; + /// Registers the `participant` into `self` returning `false` if the `participant` is already /// registered or their registration would conflict with another existing participant. fn register(&mut self, participant: P) -> bool; diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 77c458f49..2c8491818 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -21,16 +21,21 @@ use crate::groth16::{ coordinator::Coordinator, message::{ContributeRequest, QueryRequest, QueryResponse, ServerSize, Signed}, registry::Registry, - util::log_to_file, - Ceremony, CeremonyError, Challenge, Nonce, Participant, + signature::{verify, Message, SignatureScheme}, + util::{load_from_file, log_to_file}, + Ceremony, CeremonyError, Challenge, Nonce, Participant, VerifyingKey, }, mpc::{State, StateSize}, }; use alloc::sync::Arc; -use core::ops::Deref; -use manta_util::{serde::Serialize, Array, BoxArray}; +use core::{future::Future, ops::Deref}; +use manta_crypto::dalek::ed25519::Ed25519; +use manta_util::{ + serde::{de::DeserializeOwned, Serialize}, + BoxArray, +}; use parking_lot::Mutex; -use std::path::Path; +use std::{fs::File, path::Path}; /// Server pub struct Server @@ -58,7 +63,7 @@ where challenge: BoxArray, CIRCUIT_COUNT>, registry: R, recovery_path: String, - size: Array, + size: BoxArray, ) -> Self { let coordinator = Coordinator::new(registry, state, challenge, size); Self { @@ -135,3 +140,115 @@ where Ok(()) } } + +// #[cfg(all(feature = "serde", feature = "tide"))] +// #[cfg_attr(doc_cfg, doc(cfg(all(feature = "serde", feature = "tide"))))] +// pub mod network { +// use super::*; +// use core::future::Future; +// use manta_util::http::tide::{self, Body, Request, Response}; + +// /// Generates the JSON body for the output of `f`, returning an HTTP reponse. +// #[inline] +// pub async fn into_body(f: F) -> Result +// where +// F: FnOnce() -> Fut, +// Fut: Future>>, +// C: Ceremony, +// { +// Ok(Body::from_json(&f().await)?.into()) +// } + +// /// Executes `f` on the incoming `request`. +// #[inline] +// pub async fn execute( +// mut request: Request, +// f: F, +// ) -> Result +// where +// C: Ceremony, +// T: DeserializeOwned, +// R: Serialize, +// F: FnOnce(Self, T) -> Fut, +// >>::Nonce: Serialize, +// Fut: Future>>, +// { +// into_body::(move || async move { +// f( +// request.state().clone(), +// request +// .body_json::() +// .await +// .expect("Read and deserialize should succeed."), +// ) +// .await +// }) +// .await +// } +// } + +/// Recovers from a disk file at `recovery` and use `backup` as the backup directory. +#[inline] +pub fn recover( + recovery: String, + backup: String, +) -> Server +where + C: Ceremony, + R: Registry, + Coordinator: DeserializeOwned, +{ + Server { + coordinator: Arc::new(Mutex::new(load_from_file(recovery))), + recovery_path: backup, + } +} + +/// Loads registry from a disk file at `registry`. +#[inline] +pub fn load_registry(registry_file: P) -> R +where + C: Ceremony, + C::SignatureScheme: SignatureScheme, + P: AsRef, + R: Registry, C::Participant>, + // C: CeremonyConfig>, + // S: SignatureScheme, Nonce = u64, VerifyingKey = Array>, + // S::VerifyingKey: Ord, +{ + let mut registry = R::new(); + for record in + csv::Reader::from_reader(File::open(registry_file).expect("Registry file should exist.")) + .records() + { + let result = record.expect("Read csv should succeed."); + let twitter = result[0].to_string(); + let email = result[1].to_string(); + let verifying_key: BoxArray = + BoxArray::from_vec(bs58::decode(result[3].to_string()).into_vec().unwrap()); + let signature: BoxArray = + BoxArray::from_vec(bs58::decode(result[4].to_string()).into_vec().unwrap()); + // verify::<_, Ed25519>>>( + // &verifying_key, + // 0, + // &format!( + // "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", + // twitter, email + // ), + // &signature, + // ) + // .expect("Should verify the signature."); + // let participant = Participant { + // twitter, + // priority: match result[2].to_string().parse::().unwrap() { + // true => UserPriority::High, + // false => UserPriority::Normal, + // }, + // public_key, + // nonce: OsRng.gen::<_, u16>() as u64, + // contributed: false, + // }; + // registry.insert(participant.public_key, participant); + } + registry +} From bd95e32471686f5be8030c732a620fd8236aa574 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Thu, 8 Sep 2022 11:29:04 -0700 Subject: [PATCH 10/60] wip: server checkpoint --- manta-crypto/src/dalek/ed25519.rs | 22 ++++++ .../src/groth16/ceremony/message.rs | 2 +- .../src/groth16/ceremony/mod.rs | 5 ++ .../src/groth16/ceremony/registry.rs | 4 +- .../src/groth16/ceremony/server.rs | 76 +++++++++++-------- manta-util/Cargo.toml | 1 + manta-util/src/bytes.rs | 8 ++ 7 files changed, 82 insertions(+), 36 deletions(-) diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index 0b7b39521..c257367b1 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -38,6 +38,28 @@ pub fn secret_key_from_bytes(bytes: [u8; SECRET_KEY_LENGTH]) -> SecretKey { } } +/// Converts `bytes` into a [`PublicKey`]. +#[inline] +pub fn public_key_from_bytes(bytes: [u8; PUBLIC_KEY_LENGTH]) -> PublicKey { + match PublicKey::from_bytes(&bytes) { + Ok(public_key) => public_key, + _ => { + unreachable!("We are guaranteed the correct number of bytes from `PUBLIC_KEY_LENGTH`.") + } + } +} + +/// Converts `bytes` into [`Signature`]. +#[inline] +pub fn signature_from_bytes(bytes: [u8; SIGNATURE_LENGTH]) -> Signature { + match Signature::from_bytes(&bytes) { + Ok(signature) => signature, + _ => { + unreachable!("We are guaranteed the correct number of bytes from `PUBLIC_KEY_LENGTH`.") + } + } +} + /// Clones the `secret_key` by serializing and then deserializing. #[inline] pub fn clone_secret_key(secret_key: &SecretKey) -> SecretKey { diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 2a5437247..a3f40d4c5 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -27,7 +27,7 @@ use crate::groth16::{ use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{ serde::{Deserialize, Serialize}, - Array, BoxArray, + BoxArray, }; /// MPC States diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 7bc145304..c54b53af9 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -69,6 +69,11 @@ pub trait Participant { /// Nonce type Nonce; + // /// Builds a new [`Participant`]. + // fn new( + + // ) -> Self; + /// Returns the [`Identifier`](Self::Identifier) for `self`. fn id(&self) -> &Self::Identifier; diff --git a/manta-trusted-setup/src/groth16/ceremony/registry.rs b/manta-trusted-setup/src/groth16/ceremony/registry.rs index 1694a9081..88d3e7804 100644 --- a/manta-trusted-setup/src/groth16/ceremony/registry.rs +++ b/manta-trusted-setup/src/groth16/ceremony/registry.rs @@ -23,9 +23,9 @@ pub trait Registry { /// Builds a new [`Registry`]. fn new() -> Self; - /// Registers the `participant` into `self` returning `false` if the `participant` is already + /// Registers the `id` and `participant` into `self` returning `false` if the `participant` is already /// registered or their registration would conflict with another existing participant. - fn register(&mut self, participant: P) -> bool; + fn register(&mut self, id: &I, participant: P) -> bool; /// Returns a shared reference to the participant with the given `id` if they are registered. fn get(&self, id: &I) -> Option<&P>; diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 2c8491818..4ca7e9671 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -28,8 +28,8 @@ use crate::groth16::{ mpc::{State, StateSize}, }; use alloc::sync::Arc; -use core::{future::Future, ops::Deref}; -use manta_crypto::dalek::ed25519::Ed25519; +use core::{convert::TryInto, ops::Deref}; +use manta_crypto::dalek::ed25519::{self, Ed25519}; use manta_util::{ serde::{de::DeserializeOwned, Serialize}, BoxArray, @@ -187,11 +187,11 @@ where // } // } -/// Recovers from a disk file at `recovery` and use `backup` as the backup directory. +/// Recovers from a disk file at `recovery` and use `recovery_path` as the backup directory. #[inline] pub fn recover( recovery: String, - backup: String, + recovery_path: String, ) -> Server where C: Ceremony, @@ -200,7 +200,7 @@ where { Server { coordinator: Arc::new(Mutex::new(load_from_file(recovery))), - recovery_path: backup, + recovery_path, } } @@ -208,13 +208,13 @@ where #[inline] pub fn load_registry(registry_file: P) -> R where - C: Ceremony, - C::SignatureScheme: SignatureScheme, + C: Ceremony, + S: SignatureScheme, P: AsRef, R: Registry, C::Participant>, // C: CeremonyConfig>, - // S: SignatureScheme, Nonce = u64, VerifyingKey = Array>, // S::VerifyingKey: Ord, + // C::SignatureScheme: SignatureScheme, { let mut registry = R::new(); for record in @@ -224,31 +224,41 @@ where let result = record.expect("Read csv should succeed."); let twitter = result[0].to_string(); let email = result[1].to_string(); - let verifying_key: BoxArray = - BoxArray::from_vec(bs58::decode(result[3].to_string()).into_vec().unwrap()); - let signature: BoxArray = - BoxArray::from_vec(bs58::decode(result[4].to_string()).into_vec().unwrap()); - // verify::<_, Ed25519>>>( - // &verifying_key, - // 0, - // &format!( - // "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", - // twitter, email - // ), - // &signature, - // ) - // .expect("Should verify the signature."); - // let participant = Participant { - // twitter, - // priority: match result[2].to_string().parse::().unwrap() { - // true => UserPriority::High, - // false => UserPriority::Normal, - // }, - // public_key, - // nonce: OsRng.gen::<_, u16>() as u64, - // contributed: false, - // }; - // registry.insert(participant.public_key, participant); + let verifying_key: ed25519::PublicKey = ed25519::public_key_from_bytes( + bs58::decode(result[3].to_string()) + .into_vec() + .expect("Should convert into a vector") + .try_into() + .expect("Should give an array"), + ); + let signature: ed25519::Signature = ed25519::signature_from_bytes( + bs58::decode(result[4].to_string()) + .into_vec() + .expect("Should convert into a vector") + .try_into() + .expect("Should give an array"), + ); + verify::<_, Ed25519>>>( + &verifying_key, + 0, + &format!( + "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", + twitter, email + ), + &signature, + ) + .expect("Should verify the signature."); + // let participant = Participant { + // twitter, + // priority: match result[2].to_string().parse::().unwrap() { + // true => UserPriority::High, + // false => UserPriority::Normal, + // }, + // public_key, + // nonce: OsRng.gen::<_, u16>() as u64, + // contributed: false, + // }; + // registry.register(participant.public_key, participant); } registry } diff --git a/manta-util/Cargo.toml b/manta-util/Cargo.toml index 0a51ddcf8..334f0c81a 100644 --- a/manta-util/Cargo.toml +++ b/manta-util/Cargo.toml @@ -38,6 +38,7 @@ serde-array = ["serde", "serde_with"] std = ["alloc", "crossbeam-channel?/std", "serde?/std"] [dependencies] +bincode = { version = "1.3.3", optional = true, default-features = false } crossbeam-channel = { version = "0.5.6", optional = true, default-features = false } rayon = { version = "1.5.3", optional = true, default-features = false } reqwest = { version = "0.11.11", optional = true, default-features = false, features = ["json"] } diff --git a/manta-util/src/bytes.rs b/manta-util/src/bytes.rs index 592bc0c98..4379be1d4 100644 --- a/manta-util/src/bytes.rs +++ b/manta-util/src/bytes.rs @@ -106,3 +106,11 @@ pub trait AsBytes { /// Returns an owned byte representation of `self`. fn as_bytes(&self) -> Vec; } + +#[cfg(feature = "bincode")] +impl AsBytes for u64 { + #[inline] + fn as_bytes(&self) -> Vec { + bincode::serialize(self).unwrap() + } +} \ No newline at end of file From 6dacc1b4ced3f6ef379b5b064bd0d7b89a87ad44 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Thu, 8 Sep 2022 17:36:20 -0700 Subject: [PATCH 11/60] feat: serde --- manta-crypto/src/arkworks/mod.rs | 2 +- manta-crypto/src/arkworks/serialize.rs | 48 +++++++ .../src/groth16/ceremony/coordinator.rs | 21 +--- .../src/groth16/ceremony/message.rs | 32 +---- .../src/groth16/ceremony/mod.rs | 4 - .../src/groth16/ceremony/serde.rs | 119 ------------------ .../src/groth16/ceremony/util.rs | 12 +- manta-trusted-setup/src/groth16/mpc.rs | 105 +++++++++++----- manta-trusted-setup/src/groth16/ppot/mpc.rs | 6 +- manta-trusted-setup/src/groth16/test/mod.rs | 20 +-- 10 files changed, 146 insertions(+), 223 deletions(-) create mode 100644 manta-crypto/src/arkworks/serialize.rs delete mode 100644 manta-trusted-setup/src/groth16/ceremony/serde.rs diff --git a/manta-crypto/src/arkworks/mod.rs b/manta-crypto/src/arkworks/mod.rs index c959806b7..99e2e3673 100644 --- a/manta-crypto/src/arkworks/mod.rs +++ b/manta-crypto/src/arkworks/mod.rs @@ -19,7 +19,6 @@ pub use ark_ec as ec; pub use ark_r1cs_std as r1cs_std; pub use ark_relations as relations; -pub use ark_serialize as serialize; pub mod algebra; pub mod constraint; @@ -27,3 +26,4 @@ pub mod ff; pub mod pairing; pub mod rand; pub mod ratio; +pub mod serialize; diff --git a/manta-crypto/src/arkworks/serialize.rs b/manta-crypto/src/arkworks/serialize.rs new file mode 100644 index 000000000..1e8572f37 --- /dev/null +++ b/manta-crypto/src/arkworks/serialize.rs @@ -0,0 +1,48 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Arkworks Canonical Serialize and Deserialize Backend + +use alloc::vec::Vec; +use manta_util::serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer}; + +#[doc(inline)] +pub use ark_serialize::*; + +/// Uses `serializer` to serialize `data` that implements `CanonicalSerialize`. +#[inline] +pub fn canonical_serialize(data: &T, serializer: S) -> Result +where + T: CanonicalSerialize, + S: Serializer, +{ + let mut bytes = Vec::new(); + data.serialize(&mut bytes) + .map_err(|_| -> S::Error { ser::Error::custom("Canonical serialize should succeed.") })?; + Serialize::serialize(&bytes, serializer) +} + +/// Uses `deserializer` to deserialize into data with type `T` that implements `CanonicalDeserialize`. +#[inline] +pub fn canonical_deserialize<'de, D, T>(deserializer: D) -> Result +where + D: Deserializer<'de>, + T: CanonicalDeserialize, +{ + let bytes: Vec = Deserialize::deserialize(deserializer)?; + Ok(CanonicalDeserialize::deserialize(bytes.as_slice()) + .map_err(|_| -> D::Error { de::Error::custom("Canonical serialize should succeed.") })?) +} diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 32619125a..e4f2f5b8b 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -20,14 +20,12 @@ use crate::groth16::{ ceremony::{ message::{MPCState, Signed}, registry::Registry, - serde::{deserialize_array, serialize_array}, signature::{check_nonce, verify}, Ceremony, CeremonyError, Challenge, Participant, Queue, UserPriority, }, mpc::{verify_transform, Proof, State, StateSize}, }; use core::{mem, time::Duration}; -use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{time::lock::Timed, BoxArray}; #[cfg(feature = "serde")] @@ -46,13 +44,11 @@ pub const TIME_LIMIT: Duration = Duration::from_secs(360); R: Serialize, Challenge: Serialize, C::Participant: Serialize, - State: CanonicalSerialize, ", deserialize = r" R: Deserialize<'de>, Challenge: Deserialize<'de>, C::Participant: Deserialize<'de>, - State: CanonicalDeserialize, " ), crate = "manta_util::serde", @@ -68,13 +64,6 @@ where registry: R, /// State - #[cfg_attr( - feature = "serde", - serde( - serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" - ) - )] state: BoxArray, CIRCUIT_COUNT>, /// Challenge @@ -86,15 +75,7 @@ where latest_contributor: Option, /// Latest Proof - // #[cfg_attr( - // feature = "serde", - // serde( - // serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - // deserialize_with = "deserialize_array::<'de, _, Proof, CIRCUIT_COUNT>" - // ) - // )] - #[serde(skip)] //TODO - latest_proof: Option, CIRCUIT_COUNT>>, // TODO: Implement serialize + latest_proof: Option, CIRCUIT_COUNT>>, /// State Sizes size: BoxArray, diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index a3f40d4c5..d4cfb7614 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -17,14 +17,9 @@ //! Messages through Network use crate::groth16::{ - ceremony::{ - serde::{deserialize_array, serialize_array}, - signature::sign, - Ceremony, CeremonyError, Challenge, Nonce, Signature, SigningKey, - }, + ceremony::{signature::sign, Ceremony, CeremonyError, Challenge, Nonce, Signature, SigningKey}, mpc::{Proof, State, StateSize}, }; -use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; use manta_util::{ serde::{Deserialize, Serialize}, BoxArray, @@ -34,8 +29,8 @@ use manta_util::{ #[derive(Serialize, Deserialize)] #[serde( bound( - serialize = "Challenge: Serialize, State: CanonicalSerialize,", - deserialize = "Challenge: Deserialize<'de>, State: CanonicalDeserialize,", + serialize = "Challenge: Serialize", + deserialize = "Challenge: Deserialize<'de>", ), crate = "manta_util::serde", deny_unknown_fields @@ -45,13 +40,6 @@ where C: Ceremony, { /// State - #[cfg_attr( - feature = "serde", - serde( - serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" - ) - )] pub state: BoxArray, CIRCUIT_COUNT>, /// Challenge @@ -70,23 +58,9 @@ where C: Ceremony, { /// State - #[cfg_attr( - feature = "serde", - serde( - serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - deserialize_with = "deserialize_array::<'de, _, State, CIRCUIT_COUNT>" - ) - )] pub state: BoxArray, CIRCUIT_COUNT>, /// Proof - #[cfg_attr( - feature = "serde", - serde( - serialize_with = "serialize_array::, _, CIRCUIT_COUNT>", - deserialize_with = "deserialize_array::<'de, _, Proof, CIRCUIT_COUNT>" - ) - )] pub proof: BoxArray, CIRCUIT_COUNT>, } diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index c54b53af9..04123f781 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -35,10 +35,6 @@ pub mod util; #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] pub mod coordinator; -#[cfg(feature = "serde")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] -pub mod serde; - /// Nonce pub type Nonce = <::SignatureScheme as SignatureScheme>::Nonce; diff --git a/manta-trusted-setup/src/groth16/ceremony/serde.rs b/manta-trusted-setup/src/groth16/ceremony/serde.rs deleted file mode 100644 index 84fccadb6..000000000 --- a/manta-trusted-setup/src/groth16/ceremony/serde.rs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2019-2022 Manta Network. -// This file is part of manta-rs. -// -// manta-rs is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// manta-rs is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with manta-rs. If not, see . - -//! Serde - -use manta_crypto::arkworks::serialize::{CanonicalDeserialize, CanonicalSerialize}; -use manta_util::{ - serde::{Deserialize, Deserializer, Serialize, Serializer}, - BoxArray, -}; - -/// Uses `serializer` to serialize `data` that implements `CanonicalSerialize`. -#[inline] -pub fn serialize_element(data: &T, serializer: S) -> Result -where - T: CanonicalSerialize, - S: Serializer, -{ - let mut bytes = Vec::new(); - data.serialize(&mut bytes).unwrap(); - Serialize::serialize(&bytes, serializer) -} - -/// Uses `deserializer` to deserialize into data with type `T` that implements `CanonicalDeserialize`. -#[inline] -pub fn deserialize_element<'de, D, T>(deserializer: D) -> Result -where - D: Deserializer<'de>, - T: CanonicalDeserialize, -{ - let bytes: Vec = Deserialize::deserialize(deserializer)?; - Ok(CanonicalDeserialize::deserialize(bytes.as_slice()).expect("Deserialize should succeed.")) -} - -/// -#[inline] -pub fn serialize_array( - data: &BoxArray, - serializer: S, -) -> Result -where - T: CanonicalSerialize, - S: Serializer, -{ - let mut bytes = Vec::new(); - for i in 0..N { - data.0[i].serialize(&mut bytes).unwrap(); - } - Serialize::serialize(&bytes, serializer) -} - -/// -#[inline] -pub fn deserialize_array<'de, D, T, const N: usize>( - deserializer: D, -) -> Result, D::Error> -where - D: Deserializer<'de>, - T: CanonicalDeserialize, -{ - let bytes: Vec = Deserialize::deserialize(deserializer)?; - let bytes = bytes.as_slice(); - let mut data = Vec::with_capacity(N); - for _ in 0..N { - data.push( - CanonicalDeserialize::deserialize(bytes) // TODO: Issue here - .expect("Deserialize should succeed."), - ) - } - Ok(BoxArray::from_vec(data)) -} - -// /// Testing Suites -// TODO: Check if serde works correctly. -// #[cfg(test)] -// mod test { -// use super::*; -// use ark_bls12_381::Bls12_381; -// use ark_groth16::{ProvingKey, VerifyingKey}; -// use manta_crypto::{ -// arkworks::ec::PairingEngine, -// rand::{OsRng, Rand}, -// }; - -// /// Samples a dummy verifying key `vk`. -// fn sample_dummy_vk(rng: &mut R) -> VerifyingKey -// where -// R: Rand, -// { -// VerifyingKey { -// alpha_g1: rng.gen(), -// beta_g2: rng.gen(), -// gamma_g2: rng.gen(), -// delta_g2: rng.gen(), -// gamma_abc_g1: vec![rng.gen()], -// } -// } - -// #[test] -// fn serde_element_is_correct() { -// let mut rng = OsRng; -// let dummy_vk = sample_dummy_vk(&mut rng); -// let mut serialized_data = Vec::new(); -// serialize_element(&dummy_vk, &mut serialized_data); -// } -// } diff --git a/manta-trusted-setup/src/groth16/ceremony/util.rs b/manta-trusted-setup/src/groth16/ceremony/util.rs index febfbd954..61cfae148 100644 --- a/manta-trusted-setup/src/groth16/ceremony/util.rs +++ b/manta-trusted-setup/src/groth16/ceremony/util.rs @@ -97,12 +97,12 @@ where let mut validity = true; for i in 0..CIRCUIT_COUNT { validity = validity - || (states[i].vk.gamma_abc_g1.len() == size.0[i].gamma_abc_g1) - || (states[i].a_query.len() == size.0[i].a_query) - || (states[i].b_g1_query.len() == size.0[i].a_query) - || (states[i].b_g2_query.len() == size.0[i].a_query) - || (states[i].h_query.len() == size.0[i].h_query) - || (states[i].l_query.len() == size.0[i].l_query); + || (states[i].0.vk.gamma_abc_g1.len() == size.0[i].gamma_abc_g1) + || (states[i].0.a_query.len() == size.0[i].a_query) + || (states[i].0.b_g1_query.len() == size.0[i].a_query) + || (states[i].0.b_g2_query.len() == size.0[i].a_query) + || (states[i].0.h_query.len() == size.0[i].h_query) + || (states[i].0.l_query.len() == size.0[i].l_query); } validity } diff --git a/manta-trusted-setup/src/groth16/mpc.rs b/manta-trusted-setup/src/groth16/mpc.rs index 0b80fea30..0f987d6fe 100644 --- a/manta-trusted-setup/src/groth16/mpc.rs +++ b/manta-trusted-setup/src/groth16/mpc.rs @@ -30,6 +30,7 @@ use manta_crypto::{ pairing::{Pairing, PairingEngineExt}, ratio::{HashToGroup, RatioProof}, relations::r1cs::{ConstraintSynthesizer, ConstraintSystem, SynthesisError}, + serialize::{canonical_deserialize, canonical_serialize}, }, rand::{CryptoRng, RngCore}, }; @@ -38,10 +39,46 @@ use manta_crypto::{ use manta_util::serde::{Deserialize, Serialize}; /// MPC State -pub type State

= ProvingKey<

::Pairing>; +#[derive(Serialize, Deserialize, derivative::Derivative)] +#[derivative(Clone(bound = ""))] +#[serde( + bound(serialize = "", deserialize = ""), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct State

( + #[cfg_attr( + feature = "serde", + serde( + serialize_with = "canonical_serialize::, _>", + deserialize_with = "canonical_deserialize::<'de, _, ProvingKey>" + ) + )] + pub ProvingKey, +) +where + P: Pairing + ?Sized; /// MPC Proof -pub type Proof

= RatioProof

; +#[derive(Serialize, Deserialize, derivative::Derivative)] +#[derivative(Clone(bound = ""))] +#[serde( + bound(serialize = "", deserialize = "",), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct Proof

( + #[cfg_attr( + feature = "serde", + serde( + serialize_with = "canonical_serialize::, _>", + deserialize_with = "canonical_deserialize::<'de, _, RatioProof

>" + ) + )] + pub RatioProof

, +) +where + P: Pairing + ?Sized; /// Proving Key Hasher pub trait ProvingKeyHasher

@@ -217,34 +254,34 @@ pub fn check_invariants

(prev: &State

, next: &State

) -> Result<(), Error where P: Pairing, { - if prev.h_query.len() != next.h_query.len() { + if prev.0.h_query.len() != next.0.h_query.len() { return Err(Error::InvariantViolated("H length changed")); } - if prev.l_query.len() != next.l_query.len() { + if prev.0.l_query.len() != next.0.l_query.len() { return Err(Error::InvariantViolated("L length changed")); } - if prev.a_query != next.a_query { + if prev.0.a_query != next.0.a_query { return Err(Error::InvariantViolated("A query changed")); } - if prev.b_g1_query != next.b_g1_query { + if prev.0.b_g1_query != next.0.b_g1_query { return Err(Error::InvariantViolated("B_G1 query changed")); } - if prev.b_g2_query != next.b_g2_query { + if prev.0.b_g2_query != next.0.b_g2_query { return Err(Error::InvariantViolated("B_G2 query changed")); } - if prev.vk.alpha_g1 != next.vk.alpha_g1 { + if prev.0.vk.alpha_g1 != next.0.vk.alpha_g1 { return Err(Error::InvariantViolated("alpha_G1 changed")); } - if prev.beta_g1 != next.beta_g1 { + if prev.0.beta_g1 != next.0.beta_g1 { return Err(Error::InvariantViolated("beta_G1 changed")); } - if prev.vk.beta_g2 != next.vk.beta_g2 { + if prev.0.vk.beta_g2 != next.0.vk.beta_g2 { return Err(Error::InvariantViolated("beta_G2 changed")); } - if prev.vk.gamma_g2 != next.vk.gamma_g2 { + if prev.0.vk.gamma_g2 != next.0.vk.gamma_g2 { return Err(Error::InvariantViolated("gamma_G2 changed")); } - if prev.vk.gamma_abc_g1 != next.vk.gamma_abc_g1 { + if prev.0.vk.gamma_abc_g1 != next.0.vk.gamma_abc_g1 { return Err(Error::InvariantViolated("Public input cross terms changed")); } Ok(()) @@ -312,7 +349,7 @@ where let ext = ProjectiveCurve::batch_normalization_into_affine(&ext); let public_cross_terms = Vec::from(&ext[..constraint_matrices.num_instance_variables]); let private_cross_terms = Vec::from(&ext[constraint_matrices.num_instance_variables..]); - Ok(ProvingKey { + Ok(State(ProvingKey { vk: VerifyingKey { alpha_g1: powers.alpha_tau_powers_g1[0], beta_g2: powers.beta_g2, @@ -327,7 +364,7 @@ where b_g2_query, h_query, l_query: private_cross_terms, - }) + })) } /// Configuration @@ -362,11 +399,11 @@ where { let delta = C::Scalar::rand(rng); let delta_inverse = delta.inverse()?; - batch_mul_fixed_scalar(&mut state.l_query, delta_inverse); - batch_mul_fixed_scalar(&mut state.h_query, delta_inverse); - state.delta_g1 = state.delta_g1.mul(delta).into_affine(); - state.vk.delta_g2 = state.vk.delta_g2.mul(delta).into_affine(); - Proof::prove(hasher, challenge, &delta, rng) + batch_mul_fixed_scalar(&mut state.0.l_query, delta_inverse); + batch_mul_fixed_scalar(&mut state.0.h_query, delta_inverse); + state.0.delta_g1 = state.0.delta_g1.mul(delta).into_affine(); + state.0.vk.delta_g2 = state.0.vk.delta_g2.mul(delta).into_affine(); + RatioProof::prove(hasher, challenge, &delta, rng).map(Proof) } /// Verifies transforming from `prev` to `next` is correct given `challenge` and `proof`. @@ -383,26 +420,27 @@ where check_invariants::(&prev, &next)?; let next_challenge = C::challenge(challenge, &prev, &next, &proof); let ((ratio_0, ratio_1), _) = proof + .0 .verify(&C::Hasher::default(), challenge) .ok_or(Error::InvalidRatioProof)?; - if !C::Pairing::same_ratio((ratio_0, ratio_1), (prev.vk.delta_g2, next.vk.delta_g2)) { + if !C::Pairing::same_ratio((ratio_0, ratio_1), (prev.0.vk.delta_g2, next.0.vk.delta_g2)) { return Err(Error::InconsistentDeltaChange); } if !C::Pairing::same_ratio( - (prev.delta_g1, next.delta_g1), - (prev.vk.delta_g2, next.vk.delta_g2), + (prev.0.delta_g1, next.0.delta_g1), + (prev.0.vk.delta_g2, next.0.vk.delta_g2), ) { return Err(Error::InconsistentDeltaChange); } if !C::Pairing::same_ratio( - merge_pairs_affine(&next.h_query, &prev.h_query), - (prev.vk.delta_g2, next.vk.delta_g2), + merge_pairs_affine(&next.0.h_query, &prev.0.h_query), + (prev.0.vk.delta_g2, next.0.vk.delta_g2), ) { return Err(Error::InconsistentHChange); } if !C::Pairing::same_ratio( - merge_pairs_affine(&next.l_query, &prev.l_query), - (prev.vk.delta_g2, next.vk.delta_g2), + merge_pairs_affine(&next.0.l_query, &prev.0.l_query), + (prev.0.vk.delta_g2, next.0.vk.delta_g2), ) { return Err(Error::InconsistentLChange); } @@ -426,11 +464,12 @@ where for (next_state, next_proof) in iter { let next_challenge = C::challenge(&challenge, &state, &next_state, &next_proof); let ((ratio_0, ratio_1), _) = next_proof + .0 .verify(&C::Hasher::default(), &challenge) .ok_or(Error::InvalidRatioProof)?; if !C::Pairing::same_ratio( (ratio_0, ratio_1), - (state.vk.delta_g2, next_state.vk.delta_g2), + (state.0.vk.delta_g2, next_state.0.vk.delta_g2), ) { return Err(Error::InconsistentDeltaChange); } @@ -438,20 +477,20 @@ where } check_invariants::(&initial_state, &state)?; if !C::Pairing::same_ratio( - (initial_state.delta_g1, state.delta_g1), - (initial_state.vk.delta_g2, state.vk.delta_g2), + (initial_state.0.delta_g1, state.0.delta_g1), + (initial_state.0.vk.delta_g2, state.0.vk.delta_g2), ) { return Err(Error::InconsistentDeltaChange); } if !C::Pairing::same_ratio( - merge_pairs_affine(&state.h_query, &initial_state.h_query), - (initial_state.vk.delta_g2, state.vk.delta_g2), + merge_pairs_affine(&state.0.h_query, &initial_state.0.h_query), + (initial_state.0.vk.delta_g2, state.0.vk.delta_g2), ) { return Err(Error::InconsistentHChange); } if !C::Pairing::same_ratio( - merge_pairs_affine(&state.l_query, &initial_state.l_query), - (initial_state.vk.delta_g2, state.vk.delta_g2), + merge_pairs_affine(&state.0.l_query, &initial_state.0.l_query), + (initial_state.0.vk.delta_g2, state.0.vk.delta_g2), ) { return Err(Error::InconsistentLChange); } diff --git a/manta-trusted-setup/src/groth16/ppot/mpc.rs b/manta-trusted-setup/src/groth16/ppot/mpc.rs index 29d064f08..242235c50 100644 --- a/manta-trusted-setup/src/groth16/ppot/mpc.rs +++ b/manta-trusted-setup/src/groth16/ppot/mpc.rs @@ -42,11 +42,11 @@ impl Configuration for PerpetualPowersOfTauCeremony Self::Challenge { let mut hasher = Self::Hasher::default(); hasher.0.update(challenge); - prev.serialize(&mut hasher) + prev.0.serialize(&mut hasher) .expect("Consuming the previous state failed."); - next.serialize(&mut hasher) + next.0.serialize(&mut hasher) .expect("Consuming the current state failed."); - proof + proof.0 .serialize(&mut hasher) .expect("Consuming proof failed"); into_array_unchecked(hasher.0.finalize()) diff --git a/manta-trusted-setup/src/groth16/test/mod.rs b/manta-trusted-setup/src/groth16/test/mod.rs index 448423551..9746a2c01 100644 --- a/manta-trusted-setup/src/groth16/test/mod.rs +++ b/manta-trusted-setup/src/groth16/test/mod.rs @@ -144,11 +144,14 @@ impl mpc::Configuration for Test { ) -> Self::Challenge { let mut hasher = Self::Hasher::default(); hasher.0.update(challenge); - prev.serialize(&mut hasher) + prev.0 + .serialize(&mut hasher) .expect("Consuming the previous state failed."); - next.serialize(&mut hasher) + next.0 + .serialize(&mut hasher) .expect("Consuming the current state failed."); proof + .0 .serialize(&mut hasher) .expect("Consuming proof failed"); into_array_unchecked(hasher.0.finalize()) @@ -215,7 +218,7 @@ pub fn dummy_circuit(cs: &mut R1CS) { pub fn dummy_prover_key() -> ProvingKey { let mut cs = R1CS::for_contexts(); dummy_circuit(&mut cs); - initialize(dummy_phase_one_trusted_setup(), cs).unwrap() + initialize(dummy_phase_one_trusted_setup(), cs).unwrap().0 } /// Proves and verifies a R1CS circuit with proving key `pk` and a random number generator `rng`. @@ -263,9 +266,9 @@ fn proving_and_verifying_ratio_proof_is_correct() { #[test] fn trusted_setup_phase_two_is_valid() { let mut rng = OsRng; - let mut state = dummy_prover_key(); + let mut state = State(dummy_prover_key()); let mut transcript = Transcript:: { - initial_challenge: >::hash(&state), + initial_challenge: >::hash(&state.0), initial_state: state.clone(), rounds: Vec::new(), }; @@ -275,8 +278,9 @@ fn trusted_setup_phase_two_is_valid() { for _ in 0..5 { prev_state = state.clone(); proof = contribute(&hasher, &challenge, &mut state, &mut rng).unwrap(); - (challenge, state) = verify_transform(&challenge, &prev_state, state, proof.clone()) - .expect("Verify transform failed"); + (challenge, state) = + verify_transform(&challenge, &prev_state, state, proof.clone()) + .expect("Verify transform failed"); transcript.rounds.push((state.clone(), proof)); } verify_transform_all( @@ -287,5 +291,5 @@ fn trusted_setup_phase_two_is_valid() { .expect("Verifying all transformations failed."); let mut cs = R1CS::for_proofs(); dummy_circuit(&mut cs); - prove_and_verify_circuit(state, cs, &mut rng); + prove_and_verify_circuit(state.0, cs, &mut rng); } From f61a089f10b97dbf23dbf2bd4c2e9075fa53bfa2 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Thu, 8 Sep 2022 18:16:09 -0700 Subject: [PATCH 12/60] wip: fix comments --- manta-crypto/src/dalek/ed25519.rs | 2 +- .../src/groth16/ceremony/coordinator.rs | 6 ++-- .../src/groth16/ceremony/message.rs | 22 +++++++++++-- .../src/groth16/ceremony/mod.rs | 13 ++------ .../src/groth16/ceremony/registry.rs | 16 +--------- .../src/groth16/ceremony/server.rs | 9 +++--- .../src/groth16/ceremony/util.rs | 31 +------------------ 7 files changed, 33 insertions(+), 66 deletions(-) diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index c257367b1..0b199516d 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -55,7 +55,7 @@ pub fn signature_from_bytes(bytes: [u8; SIGNATURE_LENGTH]) -> Signature { match Signature::from_bytes(&bytes) { Ok(signature) => signature, _ => { - unreachable!("We are guaranteed the correct number of bytes from `PUBLIC_KEY_LENGTH`.") + unreachable!("We are guaranteed the correct number of bytes from `SIGNATURE_LENGTH`.") } } } diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index e4f2f5b8b..778604751 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -181,13 +181,13 @@ where where T: Serialize, { - if self.registry.has_contributed(&request.identifier) { - return Err(CeremonyError::AlreadyContributed); - } let participant = self .registry .get_mut(&request.identifier) .ok_or_else(|| CeremonyError::NotRegistered)?; + if participant.has_contributed() { + return Err(CeremonyError::AlreadyContributed); + } let participant_nonce = participant.get_nonce(); if !check_nonce(&participant_nonce, &request.nonce) { return Err(CeremonyError::NonceNotInSync(participant_nonce)); diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index d4cfb7614..4fd558fcd 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -20,6 +20,7 @@ use crate::groth16::{ ceremony::{signature::sign, Ceremony, CeremonyError, Challenge, Nonce, Signature, SigningKey}, mpc::{Proof, State, StateSize}, }; +use manta_crypto::arkworks::pairing::Pairing; use manta_util::{ serde::{Deserialize, Serialize}, BoxArray, @@ -67,13 +68,28 @@ where /// Response for State Sizes #[derive(Clone, Serialize, Deserialize)] #[serde(crate = "manta_util::serde", deny_unknown_fields)] -pub struct ServerSize(pub BoxArray); +pub struct CeremonySize(pub BoxArray); impl From> - for ServerSize + for CeremonySize { fn from(inner: BoxArray) -> Self { - ServerSize(inner) + CeremonySize(inner) + } +} + +impl CeremonySize { + /// Checks `states` matches [`CeremonySize`]. + #[inline] + pub fn check_state_size

(&self, states: &BoxArray, CIRCUIT_COUNT>) -> bool + where + P: Pairing, + { + let mut validity = true; + for i in 0..CIRCUIT_COUNT { + validity = validity || self.0[i].matches(&states[i].0); + } + validity } } diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 04123f781..945521f00 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -92,6 +92,9 @@ pub trait Participant { /// Reduces the priority. fn reduce_priority(&mut self); + /// Checks if the participant has contributed. + fn has_contributed(&self) -> bool; + /// Sets contributed. fn set_contributed(&mut self); } @@ -171,16 +174,6 @@ pub enum UserPriority { Normal, } -impl From for UserPriority { - fn from(priority: usize) -> Self { - match priority { - 0 => Self::High, - 1 => Self::Normal, - _ => unimplemented!(), - } - } -} - impl From for usize { fn from(priority: UserPriority) -> Self { match priority { diff --git a/manta-trusted-setup/src/groth16/ceremony/registry.rs b/manta-trusted-setup/src/groth16/ceremony/registry.rs index 88d3e7804..6d2dfc4b7 100644 --- a/manta-trusted-setup/src/groth16/ceremony/registry.rs +++ b/manta-trusted-setup/src/groth16/ceremony/registry.rs @@ -16,8 +16,6 @@ //! Groth16 Trusted Setup Ceremony Registry -use crate::groth16::ceremony::Participant; - /// Participant Registry pub trait Registry { /// Builds a new [`Registry`]. @@ -25,23 +23,11 @@ pub trait Registry { /// Registers the `id` and `participant` into `self` returning `false` if the `participant` is already /// registered or their registration would conflict with another existing participant. - fn register(&mut self, id: &I, participant: P) -> bool; + fn register(&mut self, id: I, participant: P) -> bool; /// Returns a shared reference to the participant with the given `id` if they are registered. fn get(&self, id: &I) -> Option<&P>; /// Returns a mutable reference to the participant with the given `id` if they are registered. fn get_mut(&mut self, id: &I) -> Option<&mut P>; - - /// Returns `true` if the participant with the given `id` has already contributed to the - /// ceremony. - fn has_contributed(&self, id: &I) -> bool; - - /// Gets nonce of a participant with `id`. - fn nonce(&self, id: &I) -> Option - where - P: Participant, - { - Some(self.get(id)?.get_nonce()) - } } diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 4ca7e9671..515494c3e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -19,7 +19,7 @@ use crate::groth16::{ ceremony::{ coordinator::Coordinator, - message::{ContributeRequest, QueryRequest, QueryResponse, ServerSize, Signed}, + message::{ContributeRequest, QueryRequest, QueryResponse, CeremonySize, Signed}, registry::Registry, signature::{verify, Message, SignatureScheme}, util::{load_from_file, log_to_file}, @@ -77,14 +77,15 @@ where pub async fn start( self, request: C::Identifier, - ) -> Result<(ServerSize, Nonce), CeremonyError> { + ) -> Result<(CeremonySize, Nonce), CeremonyError> { let coordinator = self.coordinator.lock(); Ok(( coordinator.size().clone().into(), coordinator .registry() - .nonce(&request) - .ok_or_else(|| CeremonyError::NotRegistered)?, + .get(&request) + .ok_or_else(|| CeremonyError::NotRegistered)? + .get_nonce(), )) } diff --git a/manta-trusted-setup/src/groth16/ceremony/util.rs b/manta-trusted-setup/src/groth16/ceremony/util.rs index 61cfae148..02bfa6dd9 100644 --- a/manta-trusted-setup/src/groth16/ceremony/util.rs +++ b/manta-trusted-setup/src/groth16/ceremony/util.rs @@ -18,21 +18,13 @@ extern crate alloc; -use manta_crypto::arkworks::pairing::Pairing; -use manta_util::{ - serde::{de::DeserializeOwned, Serialize}, - BoxArray, -}; +use manta_util::serde::{de::DeserializeOwned, Serialize}; use std::{ fs::File, io::{Read, Write}, path::Path, }; -use crate::groth16::mpc::State; - -use super::message::ServerSize; - /// Logs `data` to a disk file at `path`. #[inline] pub fn log_to_file(path: &P, data: &T) @@ -86,27 +78,6 @@ where // ); // } -/// Checks `states` has the same size as `size`. -pub fn check_state_size( - states: &BoxArray, CIRCUIT_COUNT>, - size: &ServerSize, -) -> bool -where - P: Pairing, -{ - let mut validity = true; - for i in 0..CIRCUIT_COUNT { - validity = validity - || (states[i].0.vk.gamma_abc_g1.len() == size.0[i].gamma_abc_g1) - || (states[i].0.a_query.len() == size.0[i].a_query) - || (states[i].0.b_g1_query.len() == size.0[i].a_query) - || (states[i].0.b_g2_query.len() == size.0[i].a_query) - || (states[i].0.h_query.len() == size.0[i].h_query) - || (states[i].0.l_query.len() == size.0[i].l_query); - } - validity -} - /// Testing Suites #[cfg(test)] mod test { From 95079136ad38915d2796310bac236f5b69b685df Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Thu, 8 Sep 2022 18:33:19 -0700 Subject: [PATCH 13/60] feat: fix comments --- .../src/groth16/ceremony/coordinator.rs | 12 ++++++------ .../src/groth16/ceremony/message.rs | 8 ++++---- .../src/groth16/ceremony/mod.rs | 18 ++++++------------ .../src/groth16/ceremony/server.rs | 5 ++--- .../src/groth16/ceremony/signature.rs | 1 - manta-util/Cargo.toml | 1 - manta-util/src/bytes.rs | 3 +-- 7 files changed, 19 insertions(+), 29 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 778604751..2b99a4e8c 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -64,7 +64,7 @@ where registry: R, /// State - state: BoxArray, CIRCUIT_COUNT>, + state: BoxArray, CIRCUIT_COUNT>, /// Challenge challenge: BoxArray, CIRCUIT_COUNT>, @@ -75,7 +75,7 @@ where latest_contributor: Option, /// Latest Proof - latest_proof: Option, CIRCUIT_COUNT>>, + latest_proof: Option, CIRCUIT_COUNT>>, /// State Sizes size: BoxArray, @@ -102,7 +102,7 @@ where #[inline] pub fn new( registry: R, - state: BoxArray, CIRCUIT_COUNT>, + state: BoxArray, CIRCUIT_COUNT>, challenge: BoxArray, CIRCUIT_COUNT>, size: BoxArray, ) -> Self { @@ -192,7 +192,7 @@ where if !check_nonce(&participant_nonce, &request.nonce) { return Err(CeremonyError::NonceNotInSync(participant_nonce)); }; - verify::( + verify::( participant.verifying_key(), participant_nonce, &request.message, @@ -239,8 +239,8 @@ where pub fn update( &mut self, participant: &C::Identifier, - state: BoxArray, CIRCUIT_COUNT>, - proof: BoxArray, CIRCUIT_COUNT>, + state: BoxArray, CIRCUIT_COUNT>, + proof: BoxArray, CIRCUIT_COUNT>, ) -> Result<(), CeremonyError> { if self.participant_lock.has_expired(TIME_LIMIT) { Self::check_lock_update_errors(true, &self.update_expired_lock(), participant)?; diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 4fd558fcd..49df6f27a 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -41,7 +41,7 @@ where C: Ceremony, { /// State - pub state: BoxArray, CIRCUIT_COUNT>, + pub state: BoxArray, CIRCUIT_COUNT>, /// Challenge pub challenge: BoxArray, CIRCUIT_COUNT>, @@ -59,10 +59,10 @@ where C: Ceremony, { /// State - pub state: BoxArray, CIRCUIT_COUNT>, + pub state: BoxArray, CIRCUIT_COUNT>, /// Proof - pub proof: BoxArray, CIRCUIT_COUNT>, + pub proof: BoxArray, CIRCUIT_COUNT>, } /// Response for State Sizes @@ -190,7 +190,7 @@ where T: Serialize, Nonce: Clone, { - let signature = match sign::<_, C::SignatureScheme>(signing_key, nonce.clone(), &message) { + let signature = match sign::<_, C>(signing_key, nonce.clone(), &message) { Ok(signature) => signature, Err(_) => return Err(CeremonyError::::BadRequest), }; diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 945521f00..c214c216c 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -36,19 +36,19 @@ pub mod util; pub mod coordinator; /// Nonce -pub type Nonce = <::SignatureScheme as SignatureScheme>::Nonce; +pub type Nonce = ::Nonce; /// Signature -pub type Signature = <::SignatureScheme as SignatureType>::Signature; +pub type Signature = ::Signature; /// Signing Key -pub type SigningKey = <::SignatureScheme as SigningKeyType>::SigningKey; +pub type SigningKey = ::SigningKey; /// Verifying Key -pub type VerifyingKey = <::SignatureScheme as VerifyingKeyType>::VerifyingKey; +pub type VerifyingKey = ::VerifyingKey; /// Challenge Type -pub type Challenge = <::Configuration as Configuration>::Challenge; +pub type Challenge = ::Challenge; /// Participant Queue Type pub type Queue = @@ -100,7 +100,7 @@ pub trait Participant { } /// Ceremony Configuration -pub trait Ceremony { +pub trait Ceremony: SignatureScheme + Configuration { /// Participant Identifier Type type Identifier: Clone + PartialEq; @@ -110,12 +110,6 @@ pub trait Ceremony { Nonce = Nonce, VerifyingKey = VerifyingKey, >; - - /// Signature Scheme - type SignatureScheme: SignatureScheme; - - /// Configuration - type Configuration: Configuration; } /// Ceremony Error diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 515494c3e..511f7b0c0 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -59,7 +59,7 @@ where /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a `recovery_path`. #[inline] pub fn new( - state: BoxArray, CIRCUIT_COUNT>, + state: BoxArray, CIRCUIT_COUNT>, challenge: BoxArray, CIRCUIT_COUNT>, registry: R, recovery_path: String, @@ -209,8 +209,7 @@ where #[inline] pub fn load_registry(registry_file: P) -> R where - C: Ceremony, - S: SignatureScheme, + C: Ceremony, P: AsRef, R: Registry, C::Participant>, // C: CeremonyConfig>, diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index 0e53f21a0..029033320 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -157,6 +157,5 @@ where N: AsBytes + Default + Nonce, { type Nonce = N; - type Error = SignatureError; } diff --git a/manta-util/Cargo.toml b/manta-util/Cargo.toml index 334f0c81a..0a51ddcf8 100644 --- a/manta-util/Cargo.toml +++ b/manta-util/Cargo.toml @@ -38,7 +38,6 @@ serde-array = ["serde", "serde_with"] std = ["alloc", "crossbeam-channel?/std", "serde?/std"] [dependencies] -bincode = { version = "1.3.3", optional = true, default-features = false } crossbeam-channel = { version = "0.5.6", optional = true, default-features = false } rayon = { version = "1.5.3", optional = true, default-features = false } reqwest = { version = "0.11.11", optional = true, default-features = false, features = ["json"] } diff --git a/manta-util/src/bytes.rs b/manta-util/src/bytes.rs index 4379be1d4..fbbf1d0fa 100644 --- a/manta-util/src/bytes.rs +++ b/manta-util/src/bytes.rs @@ -107,10 +107,9 @@ pub trait AsBytes { fn as_bytes(&self) -> Vec; } -#[cfg(feature = "bincode")] impl AsBytes for u64 { #[inline] fn as_bytes(&self) -> Vec { - bincode::serialize(self).unwrap() + self.to_le_bytes().to_vec() } } \ No newline at end of file From 4698fde035d34cb1aae2443a7a621e5fba261971 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Thu, 8 Sep 2022 22:07:15 -0700 Subject: [PATCH 14/60] chore: fix comments --- manta-trusted-setup/.gitignore | 1 + .../src/groth16/ceremony/coordinator.rs | 25 ++++-- .../src/groth16/ceremony/message.rs | 34 ++----- .../src/groth16/ceremony/server.rs | 88 +++++-------------- .../src/groth16/ceremony/util.rs | 38 ++++---- 5 files changed, 63 insertions(+), 123 deletions(-) create mode 100644 manta-trusted-setup/.gitignore diff --git a/manta-trusted-setup/.gitignore b/manta-trusted-setup/.gitignore new file mode 100644 index 000000000..9bc63fdc9 --- /dev/null +++ b/manta-trusted-setup/.gitignore @@ -0,0 +1 @@ +test_transcript.data \ No newline at end of file diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 2b99a4e8c..d5597639e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -133,7 +133,7 @@ where /// Returns the state size. #[inline] - pub fn size(&self) -> &BoxArray { + pub fn size(&self) -> &[StateSize; CIRCUIT_COUNT] { &self.size } @@ -155,7 +155,7 @@ where self.registry.get_mut(id) } - /// + /// Returns a mutable reference to `queue`. pub fn queue_mut(&mut self) -> &mut Queue { &mut self.queue } @@ -232,6 +232,16 @@ where }) } + /// Checks lock for `participant`. + #[inline] + pub fn check_lock(&mut self, participant: &C::Identifier) -> Result<(), CeremonyError> { + if self.participant_lock.has_expired(TIME_LIMIT) { + Self::check_lock_update_errors(true, &self.update_expired_lock(), participant) + } else { + Self::check_lock_update_errors(false, self.participant_lock.get(), participant) + } + } + /// Updates the MPC state and challenge using client's contribution. If the contribution is /// valid, the participant will be removed from the waiting queue, and cannot participate in /// this ceremony again. @@ -242,11 +252,7 @@ where state: BoxArray, CIRCUIT_COUNT>, proof: BoxArray, CIRCUIT_COUNT>, ) -> Result<(), CeremonyError> { - if self.participant_lock.has_expired(TIME_LIMIT) { - Self::check_lock_update_errors(true, &self.update_expired_lock(), participant)?; - } else { - Self::check_lock_update_errors(false, self.participant_lock.get(), participant)?; - } + self.check_lock(participant)?; for (i, (state, proof)) in state.into_iter().zip(proof.clone().into_iter()).enumerate() { self.state[i] = verify_transform(&self.challenge[i], &self.state[i], state, proof) .map_err(|_| CeremonyError::BadRequest)? @@ -254,6 +260,11 @@ where } self.latest_proof = Some(proof); self.participant_lock.set(self.queue.pop_front()); + match self.participant_mut(participant) { + Some(participant) => participant.set_contributed(), + None => return Err(CeremonyError::Unexpected), + }; + self.increment_round(); Ok(()) } } diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 49df6f27a..cc63f5e65 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -47,24 +47,6 @@ where pub challenge: BoxArray, CIRCUIT_COUNT>, } -/// Contribute States -#[derive(Serialize, Deserialize)] -#[serde( - bound(serialize = "", deserialize = ""), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct ContributeState -where - C: Ceremony, -{ - /// State - pub state: BoxArray, CIRCUIT_COUNT>, - - /// Proof - pub proof: BoxArray, CIRCUIT_COUNT>, -} - /// Response for State Sizes #[derive(Clone, Serialize, Deserialize)] #[serde(crate = "manta_util::serde", deny_unknown_fields)] @@ -122,20 +104,16 @@ where /// Contribute Request #[derive(Serialize, Deserialize)] #[serde( - bound( - serialize = "ContributeState: Serialize", - deserialize = "ContributeState: Deserialize<'de>" - ), + bound(serialize = "", deserialize = ""), crate = "manta_util::serde", deny_unknown_fields )] -pub struct ContributeRequest +pub struct ContributeRequest( + pub (BoxArray, CIRCUIT_COUNT>, + BoxArray, CIRCUIT_COUNT>) +) where - C: Ceremony, -{ - /// Contribute state including state and proof - pub contribute_state: ContributeState, -} + C: Ceremony; /// Signed Message #[derive(Deserialize, Serialize)] diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 511f7b0c0..7244ed4f4 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -19,10 +19,10 @@ use crate::groth16::{ ceremony::{ coordinator::Coordinator, - message::{ContributeRequest, QueryRequest, QueryResponse, CeremonySize, Signed}, + message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse, Signed}, registry::Registry, - signature::{verify, Message, SignatureScheme}, - util::{load_from_file, log_to_file}, + signature::{verify, Message}, + util::{deserialize_from_file, serialize_into_file}, Ceremony, CeremonyError, Challenge, Nonce, Participant, VerifyingKey, }, mpc::{State, StateSize}, @@ -35,7 +35,10 @@ use manta_util::{ BoxArray, }; use parking_lot::Mutex; -use std::{fs::File, path::Path}; +use std::{ + fs::{File, OpenOptions}, + path::Path, +}; /// Server pub struct Server @@ -80,7 +83,7 @@ where ) -> Result<(CeremonySize, Nonce), CeremonyError> { let coordinator = self.coordinator.lock(); Ok(( - coordinator.size().clone().into(), + CeremonySize(BoxArray::from_unchecked(coordinator.size().clone())), coordinator .registry() .get(&request) @@ -122,87 +125,36 @@ where { let mut coordinator = self.coordinator.lock(); coordinator.preprocess_request(&request)?; - let contribute_state = request.message.contribute_state; - coordinator.update( - &request.identifier, - contribute_state.state, - contribute_state.proof, - )?; - coordinator - .participant_mut(&request.identifier) - .expect("Geting participant should succeed.") - .set_contributed(); - coordinator.increment_round(); - log_to_file( + let (state, proof) = request.message.0; + coordinator.update(&request.identifier, state, proof)?; + serialize_into_file( &Path::new(&self.recovery_path).join(format!("transcript{}.data", coordinator.round())), &coordinator.deref(), - ); + OpenOptions::new().write(true).create_new(true), + ) + .map_err(|_| CeremonyError::Unexpected)?; println!("{} participants have contributed.", coordinator.round()); Ok(()) } } -// #[cfg(all(feature = "serde", feature = "tide"))] -// #[cfg_attr(doc_cfg, doc(cfg(all(feature = "serde", feature = "tide"))))] -// pub mod network { -// use super::*; -// use core::future::Future; -// use manta_util::http::tide::{self, Body, Request, Response}; - -// /// Generates the JSON body for the output of `f`, returning an HTTP reponse. -// #[inline] -// pub async fn into_body(f: F) -> Result -// where -// F: FnOnce() -> Fut, -// Fut: Future>>, -// C: Ceremony, -// { -// Ok(Body::from_json(&f().await)?.into()) -// } - -// /// Executes `f` on the incoming `request`. -// #[inline] -// pub async fn execute( -// mut request: Request, -// f: F, -// ) -> Result -// where -// C: Ceremony, -// T: DeserializeOwned, -// R: Serialize, -// F: FnOnce(Self, T) -> Fut, -// >>::Nonce: Serialize, -// Fut: Future>>, -// { -// into_body::(move || async move { -// f( -// request.state().clone(), -// request -// .body_json::() -// .await -// .expect("Read and deserialize should succeed."), -// ) -// .await -// }) -// .await -// } -// } - /// Recovers from a disk file at `recovery` and use `recovery_path` as the backup directory. #[inline] pub fn recover( recovery: String, recovery_path: String, -) -> Server +) -> Result, CeremonyError> where C: Ceremony, R: Registry, Coordinator: DeserializeOwned, { - Server { - coordinator: Arc::new(Mutex::new(load_from_file(recovery))), + Ok(Server { + coordinator: Arc::new(Mutex::new( + deserialize_from_file(recovery).map_err(|_| CeremonyError::Unexpected)?, + )), recovery_path, - } + }) } /// Loads registry from a disk file at `registry`. diff --git a/manta-trusted-setup/src/groth16/ceremony/util.rs b/manta-trusted-setup/src/groth16/ceremony/util.rs index 02bfa6dd9..a838921fe 100644 --- a/manta-trusted-setup/src/groth16/ceremony/util.rs +++ b/manta-trusted-setup/src/groth16/ceremony/util.rs @@ -16,41 +16,34 @@ //! Utilities -extern crate alloc; - use manta_util::serde::{de::DeserializeOwned, Serialize}; use std::{ - fs::File, - io::{Read, Write}, + fs::{File, OpenOptions}, path::Path, }; -/// Logs `data` to a disk file at `path`. +/// Logs `data` to a disk file at `path` assuming this file does not exist. #[inline] -pub fn log_to_file(path: &P, data: &T) +pub fn serialize_into_file( + path: &P, + data: &T, + option: &mut OpenOptions, +) -> bincode::Result<()> where - T: Serialize, P: AsRef, + T: Serialize, { - let mut file = File::create(path).expect("Open file should succeed."); - let encoded = bincode::serialize(data).expect(""); - file.write_all(&encoded) - .expect("Writing phase one parameters to disk should succeed."); - file.flush().expect("Flushing file should succeed."); + Ok(bincode::serialize_into(option.open(path)?, data)?) } /// Loads `data` from a disk file at `path`. #[inline] -pub fn load_from_file(path: P) -> T +pub fn deserialize_from_file(path: P) -> bincode::Result where P: AsRef, T: DeserializeOwned, { - let mut file = File::open(path).expect("Opening file should succeed."); - let mut buf = Vec::new(); - file.read_to_end(&mut buf) - .expect("Reading data should succeed."); - bincode::deserialize(&buf[..]).unwrap() + Ok(bincode::deserialize_from(File::open(path)?)?) } // /// Prepares phase one parameter `powers` for phase two parameters of circuit `cs` with `name`. @@ -87,8 +80,13 @@ mod test { #[test] fn log_load_file_is_correct() { let data = "Testing data".to_string(); - log_to_file(&"test_transcript.data", &data); - let loaded_data: String = load_from_file(&"test_transcript.data"); + serialize_into_file( + &"test_transcript.data", + &data, + OpenOptions::new().write(true).create_new(true), + ) + .unwrap(); + let loaded_data: String = deserialize_from_file(&"test_transcript.data").unwrap(); assert_eq!(data, loaded_data); } } From 5a3b51ee24fc46b19e9a40773a7b2021133f3081 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Thu, 8 Sep 2022 22:32:17 -0700 Subject: [PATCH 15/60] feat: finish server --- .../src/groth16/ceremony/mod.rs | 1 + .../src/groth16/ceremony/participant.rs | 112 ++++++++++++++++++ .../src/groth16/ceremony/server.rs | 37 +++--- 3 files changed, 132 insertions(+), 18 deletions(-) create mode 100644 manta-trusted-setup/src/groth16/ceremony/participant.rs diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index c214c216c..7ae5b037e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -26,6 +26,7 @@ use manta_util::{ // pub mod client; pub mod message; +pub mod participant; pub mod registry; pub mod server; pub mod signature; diff --git a/manta-trusted-setup/src/groth16/ceremony/participant.rs b/manta-trusted-setup/src/groth16/ceremony/participant.rs new file mode 100644 index 000000000..a8bab0518 --- /dev/null +++ b/manta-trusted-setup/src/groth16/ceremony/participant.rs @@ -0,0 +1,112 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Participant + +use crate::groth16::ceremony::{self, signature::SignatureScheme, UserPriority}; + +/// Participant +pub struct Participant +where + S: SignatureScheme, +{ + /// Verifying Key + verifying_key: S::VerifyingKey, + + /// Twitter Account + twitter: String, + + /// Priority + priority: UserPriority, + + /// Nonce + nonce: S::Nonce, + + /// Boolean on whether this participant has contributed + contributed: bool, +} + +impl ceremony::Participant for Participant +where + S: SignatureScheme, +{ + type Identifier = S::VerifyingKey; + + type VerifyingKey = S::VerifyingKey; + + type Nonce = S::Nonce; + + fn id(&self) -> &Self::Identifier { + &self.verifying_key + } + + fn verifying_key(&self) -> &Self::VerifyingKey { + &self.verifying_key + } + + fn level(&self) -> UserPriority { + self.priority + } + + fn get_nonce(&self) -> Self::Nonce { + self.nonce + } + + fn increment_nonce(&mut self) { + self.nonce += 1; + } + + fn reduce_priority(&mut self) { + self.priority = UserPriority::Normal; + } + + fn has_contributed(&self) -> bool { + self.contributed + } + + fn set_contributed(&mut self) { + self.contributed = true + } +} + +impl Participant +where + S: SignatureScheme, +{ + /// Builds a new [`Participant`]. + #[inline] + pub fn new( + verifying_key: S::VerifyingKey, + twitter: String, + priority: UserPriority, + nonce: S::Nonce, + contributed: bool, + ) -> Self { + Self { + verifying_key, + twitter, + priority, + nonce, + contributed, + } + } + + /// Gets `twitter`. + #[inline] + pub fn twitter(&self) -> String { + self.twitter.clone() + } +} diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 7244ed4f4..bc6946961 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -20,16 +20,20 @@ use crate::groth16::{ ceremony::{ coordinator::Coordinator, message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse, Signed}, + participant::Participant, registry::Registry, signature::{verify, Message}, util::{deserialize_from_file, serialize_into_file}, - Ceremony, CeremonyError, Challenge, Nonce, Participant, VerifyingKey, + Ceremony, CeremonyError, Challenge, Nonce, Participant as _, UserPriority, VerifyingKey, }, mpc::{State, StateSize}, }; use alloc::sync::Arc; use core::{convert::TryInto, ops::Deref}; -use manta_crypto::dalek::ed25519::{self, Ed25519}; +use manta_crypto::{ + dalek::ed25519::{self, Ed25519}, + rand::{OsRng, Rand}, +}; use manta_util::{ serde::{de::DeserializeOwned, Serialize}, BoxArray, @@ -159,14 +163,11 @@ where /// Loads registry from a disk file at `registry`. #[inline] -pub fn load_registry(registry_file: P) -> R +pub fn load_registry(registry_file: P) -> R where - C: Ceremony, + C: Ceremony, VerifyingKey = ed25519::PublicKey>, P: AsRef, R: Registry, C::Participant>, - // C: CeremonyConfig>, - // S::VerifyingKey: Ord, - // C::SignatureScheme: SignatureScheme, { let mut registry = R::new(); for record in @@ -200,17 +201,17 @@ where &signature, ) .expect("Should verify the signature."); - // let participant = Participant { - // twitter, - // priority: match result[2].to_string().parse::().unwrap() { - // true => UserPriority::High, - // false => UserPriority::Normal, - // }, - // public_key, - // nonce: OsRng.gen::<_, u16>() as u64, - // contributed: false, - // }; - // registry.register(participant.public_key, participant); + let participant: Participant = Participant::new( + verifying_key, + twitter, + match result[2].to_string().parse::().unwrap() { + true => UserPriority::High, + false => UserPriority::Normal, + }, + OsRng.gen::<_, u16>() as u64, + false, + ); + registry.register(verifying_key, participant); } registry } From c1b0b8be2ff359e442e112d4bc448c10b902c56a Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 13:02:58 -0700 Subject: [PATCH 16/60] wip: client --- .../src/groth16/ceremony/client.rs | 70 ++++++++++++++----- .../src/groth16/ceremony/coordinator.rs | 12 ++-- .../src/groth16/ceremony/message.rs | 32 +++++---- .../src/groth16/ceremony/mod.rs | 54 +++++--------- .../src/groth16/ceremony/participant.rs | 32 ++++++--- .../src/groth16/ceremony/server.rs | 12 ++-- .../src/groth16/ceremony/signature.rs | 6 +- 7 files changed, 124 insertions(+), 94 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index 7b543e419..38b8c16eb 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -16,20 +16,56 @@ //! Trusted Setup Client -// use crate::groth16::ceremony::{signature::Nonce, Ceremony, Participant}; -// use manta_crypto::dalek::ed25519::Ed25519; -// -// /// Client -// pub struct Client -// where -// C: Ceremony, -// { -// /// Identifier -// Identifier: C::Identifier, -// -// /// Current Nonce -// nonce: u64, -// -// /// Private Key -// private_key: Ed25519, -// } +use crate::groth16::ceremony::{signature::Nonce, Ceremony, Participant}; +use manta_crypto::dalek::ed25519::Ed25519; + +use super::{ + message::{QueryRequest, Signed}, + CeremonyError, +}; + +/// Client +pub struct Client +where + C: Ceremony, +{ + /// Identifier + identifier: C::Identifier, + + /// Current Nonce + nonce: C::Nonce, + + /// Signing Key + signing_key: C::SigningKey, +} + +impl Client +where + C: Ceremony, +{ + /// Builds a new [`Client`] with `participant` and `private_key`. + #[inline] + pub fn new(identifier: C::Identifier, nonce: C::Nonce, signing_key: C::SigningKey) -> Self { + Self { + identifier, + nonce, + signing_key, + } + } + + /// Queries the server state. + #[inline] + pub fn query(&mut self) -> Result, CeremonyError> + where + C::Nonce: Clone, + { + let signed_message = Signed::new( + QueryRequest, + &self.nonce, + &self.signing_key, + self.identifier.clone(), + )?; + self.nonce.increment(); + Ok(signed_message) + } +} diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index d5597639e..ff42e771f 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -21,7 +21,7 @@ use crate::groth16::{ message::{MPCState, Signed}, registry::Registry, signature::{check_nonce, verify}, - Ceremony, CeremonyError, Challenge, Participant, Queue, UserPriority, + Ceremony, CeremonyError, Participant, Queue, UserPriority, }, mpc::{verify_transform, Proof, State, StateSize}, }; @@ -42,12 +42,12 @@ pub const TIME_LIMIT: Duration = Duration::from_secs(360); bound( serialize = r" R: Serialize, - Challenge: Serialize, + C::Challenge: Serialize, C::Participant: Serialize, ", deserialize = r" R: Deserialize<'de>, - Challenge: Deserialize<'de>, + C::Challenge: Deserialize<'de>, C::Participant: Deserialize<'de>, " ), @@ -67,7 +67,7 @@ where state: BoxArray, CIRCUIT_COUNT>, /// Challenge - challenge: BoxArray, CIRCUIT_COUNT>, + challenge: BoxArray, /// Latest Contributor /// @@ -103,7 +103,7 @@ where pub fn new( registry: R, state: BoxArray, CIRCUIT_COUNT>, - challenge: BoxArray, CIRCUIT_COUNT>, + challenge: BoxArray, size: BoxArray, ) -> Self { Self { @@ -164,7 +164,7 @@ where #[inline] pub fn state_and_challenge(&self) -> MPCState where - Challenge: Clone, + C::Challenge: Clone, { MPCState { state: self.state.clone(), diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index cc63f5e65..5c7464817 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -17,7 +17,7 @@ //! Messages through Network use crate::groth16::{ - ceremony::{signature::sign, Ceremony, CeremonyError, Challenge, Nonce, Signature, SigningKey}, + ceremony::{signature::sign, Ceremony, CeremonyError}, mpc::{Proof, State, StateSize}, }; use manta_crypto::arkworks::pairing::Pairing; @@ -30,8 +30,8 @@ use manta_util::{ #[derive(Serialize, Deserialize)] #[serde( bound( - serialize = "Challenge: Serialize", - deserialize = "Challenge: Deserialize<'de>", + serialize = "C::Challenge: Serialize", + deserialize = "C::Challenge: Deserialize<'de>", ), crate = "manta_util::serde", deny_unknown_fields @@ -44,7 +44,7 @@ where pub state: BoxArray, CIRCUIT_COUNT>, /// Challenge - pub challenge: BoxArray, CIRCUIT_COUNT>, + pub challenge: BoxArray, } /// Response for State Sizes @@ -109,8 +109,10 @@ where deny_unknown_fields )] pub struct ContributeRequest( - pub (BoxArray, CIRCUIT_COUNT>, - BoxArray, CIRCUIT_COUNT>) + pub ( + BoxArray, CIRCUIT_COUNT>, + BoxArray, CIRCUIT_COUNT>, + ), ) where C: Ceremony; @@ -122,14 +124,14 @@ where serialize = r" C::Identifier: Serialize, T: Serialize, - Nonce: Serialize, - Signature: Serialize, + C::Nonce: Serialize, + C::Signature: Serialize, ", deserialize = r" C::Identifier: Deserialize<'de>, T: Deserialize<'de>, - Nonce: Deserialize<'de>, - Signature: Deserialize<'de>, + C::Nonce: Deserialize<'de>, + C::Signature: Deserialize<'de>, ", ), crate = "manta_util::serde", @@ -143,10 +145,10 @@ where pub message: T, /// Nonce - pub nonce: Nonce, + pub nonce: C::Nonce, /// Signature - pub signature: Signature, + pub signature: C::Signature, /// Participant Identifier pub identifier: C::Identifier, @@ -160,13 +162,13 @@ where #[inline] pub fn new( message: T, - nonce: &Nonce, - signing_key: &SigningKey, + nonce: &C::Nonce, + signing_key: &C::SigningKey, identifier: C::Identifier, ) -> Result> where T: Serialize, - Nonce: Clone, + C::Nonce: Clone, { let signature = match sign::<_, C>(signing_key, nonce.clone(), &message) { Ok(signature) => signature, diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 7ae5b037e..062c686c4 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -16,15 +16,17 @@ //! Groth16 Trusted Setup Ceremony -use crate::groth16::{ceremony::signature::SignatureScheme, mpc::Configuration}; +use crate::groth16::{ + ceremony::signature::{Nonce, SignatureScheme}, + mpc::Configuration, +}; use derivative::Derivative; -use manta_crypto::signature::{SignatureType, SigningKeyType, VerifyingKeyType}; use manta_util::{ collections::vec_deque::MultiVecDeque, serde::{Deserialize, Serialize}, }; -// pub mod client; +pub mod client; pub mod message; pub mod participant; pub mod registry; @@ -36,21 +38,6 @@ pub mod util; #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] pub mod coordinator; -/// Nonce -pub type Nonce = ::Nonce; - -/// Signature -pub type Signature = ::Signature; - -/// Signing Key -pub type SigningKey = ::SigningKey; - -/// Verifying Key -pub type VerifyingKey = ::VerifyingKey; - -/// Challenge Type -pub type Challenge = ::Challenge; - /// Participant Queue Type pub type Queue = MultiVecDeque<::Identifier, LEVEL_COUNT>; @@ -64,12 +51,7 @@ pub trait Participant { type VerifyingKey; /// Nonce - type Nonce; - - // /// Builds a new [`Participant`]. - // fn new( - - // ) -> Self; + type Nonce: Nonce; /// Returns the [`Identifier`](Self::Identifier) for `self`. fn id(&self) -> &Self::Identifier; @@ -84,12 +66,6 @@ pub trait Participant { /// Lower level indicates a higher priority. fn level(&self) -> UserPriority; - /// Returns nonce for `self`. - fn get_nonce(&self) -> Self::Nonce; - - /// Set nonce of current participant - fn increment_nonce(&mut self); - /// Reduces the priority. fn reduce_priority(&mut self); @@ -98,6 +74,12 @@ pub trait Participant { /// Sets contributed. fn set_contributed(&mut self); + + /// Returns nonce. + fn get_nonce(&self) -> Self::Nonce; + + /// Increments the current nonce by one. + fn increment_nonce(&mut self); } /// Ceremony Configuration @@ -108,8 +90,8 @@ pub trait Ceremony: SignatureScheme + Configuration { /// Participant Type type Participant: Participant< Identifier = Self::Identifier, - Nonce = Nonce, - VerifyingKey = VerifyingKey, + Nonce = Self::Nonce, + VerifyingKey = Self::VerifyingKey, >; } @@ -119,11 +101,11 @@ pub trait Ceremony: SignatureScheme + Configuration { /// /// All errors here are visible to users. #[derive(PartialEq, Serialize, Deserialize, Derivative)] -#[derivative(Debug(bound = "Nonce: core::fmt::Debug"))] +#[derivative(Debug(bound = "C::Nonce: core::fmt::Debug"))] #[serde( bound( - serialize = "Nonce: Serialize", - deserialize = "Nonce: Deserialize<'de>", + serialize = "C::Nonce: Serialize", + deserialize = "C::Nonce: Deserialize<'de>", ), crate = "manta_util::serde", deny_unknown_fields @@ -136,7 +118,7 @@ where BadRequest, /// Nonce not in sync, and client needs to update the nonce - NonceNotInSync(Nonce), + NonceNotInSync(C::Nonce), /// Not Registered NotRegistered, diff --git a/manta-trusted-setup/src/groth16/ceremony/participant.rs b/manta-trusted-setup/src/groth16/ceremony/participant.rs index a8bab0518..777bb28f4 100644 --- a/manta-trusted-setup/src/groth16/ceremony/participant.rs +++ b/manta-trusted-setup/src/groth16/ceremony/participant.rs @@ -16,7 +16,11 @@ //! Participant -use crate::groth16::ceremony::{self, signature::SignatureScheme, UserPriority}; +use crate::groth16::ceremony::{ + self, + signature::{Nonce, SignatureScheme}, + UserPriority, +}; /// Participant pub struct Participant @@ -44,42 +48,48 @@ where S: SignatureScheme, { type Identifier = S::VerifyingKey; - type VerifyingKey = S::VerifyingKey; - type Nonce = S::Nonce; + #[inline] fn id(&self) -> &Self::Identifier { &self.verifying_key } + #[inline] fn verifying_key(&self) -> &Self::VerifyingKey { &self.verifying_key } + #[inline] fn level(&self) -> UserPriority { self.priority } - fn get_nonce(&self) -> Self::Nonce { - self.nonce - } - - fn increment_nonce(&mut self) { - self.nonce += 1; - } - + #[inline] fn reduce_priority(&mut self) { self.priority = UserPriority::Normal; } + #[inline] fn has_contributed(&self) -> bool { self.contributed } + #[inline] fn set_contributed(&mut self) { self.contributed = true } + + #[inline] + fn get_nonce(&self) -> Self::Nonce { + self.nonce + } + + #[inline] + fn increment_nonce(&mut self) { + self.nonce.increment(); + } } impl Participant diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index bc6946961..937d04c57 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -24,7 +24,7 @@ use crate::groth16::{ registry::Registry, signature::{verify, Message}, util::{deserialize_from_file, serialize_into_file}, - Ceremony, CeremonyError, Challenge, Nonce, Participant as _, UserPriority, VerifyingKey, + Ceremony, CeremonyError, Participant as _, UserPriority, }, mpc::{State, StateSize}, }; @@ -67,7 +67,7 @@ where #[inline] pub fn new( state: BoxArray, CIRCUIT_COUNT>, - challenge: BoxArray, CIRCUIT_COUNT>, + challenge: BoxArray, registry: R, recovery_path: String, size: BoxArray, @@ -84,7 +84,7 @@ where pub async fn start( self, request: C::Identifier, - ) -> Result<(CeremonySize, Nonce), CeremonyError> { + ) -> Result<(CeremonySize, C::Nonce), CeremonyError> { let coordinator = self.coordinator.lock(); Ok(( CeremonySize(BoxArray::from_unchecked(coordinator.size().clone())), @@ -103,7 +103,7 @@ where request: Signed, ) -> Result, CeremonyError> where - Challenge: Clone, + C::Challenge: Clone, { let mut coordinator = self.coordinator.lock(); let priority = coordinator.preprocess_request(&request)?; @@ -167,7 +167,7 @@ pub fn load_registry(registry_file: P) -> R where C: Ceremony, VerifyingKey = ed25519::PublicKey>, P: AsRef, - R: Registry, C::Participant>, + R: Registry, { let mut registry = R::new(); for record in @@ -191,7 +191,7 @@ where .try_into() .expect("Should give an array"), ); - verify::<_, Ed25519>>>( + verify::<_, Ed25519>>( &verifying_key, 0, &format!( diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index 029033320..c34e143d1 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -26,7 +26,7 @@ use manta_util::{serde::Serialize, AsBytes}; /// Nonce pub trait Nonce: PartialEq { /// Increments the current nonce by one. - fn increment(&self) -> Self; + fn increment(&mut self); /// Checks if the current nonce is valid. fn is_valid(&self) -> bool; @@ -34,8 +34,8 @@ pub trait Nonce: PartialEq { impl Nonce for u64 { #[inline] - fn increment(&self) -> Self { - self.saturating_add(1) + fn increment(&mut self) { + *self = self.saturating_add(1); } #[inline] From 8de6be77e782a553d0b3e5c0512230860ab428d1 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Fri, 9 Sep 2022 17:52:26 -0400 Subject: [PATCH 17/60] fix: clean up interfaces and add abstract priority Signed-off-by: Brandon H. Gomes --- manta-crypto/src/arkworks/serialize.rs | 26 ++++---- manta-trusted-setup/Cargo.toml | 1 + .../src/groth16/ceremony/client.rs | 9 ++- .../src/groth16/ceremony/coordinator.rs | 12 ++-- .../src/groth16/ceremony/mod.rs | 60 ++++++------------- .../src/groth16/ceremony/participant.rs | 38 ++++++++++-- .../src/groth16/ceremony/server.rs | 16 ++--- .../src/groth16/ceremony/util.rs | 10 ++-- manta-trusted-setup/src/groth16/mpc.rs | 10 ++-- manta-trusted-setup/src/groth16/ppot/mpc.rs | 9 ++- manta-trusted-setup/src/groth16/test/mod.rs | 5 +- manta-util/src/bytes.rs | 2 +- manta-util/src/collections/vec_deque.rs | 4 +- 13 files changed, 106 insertions(+), 96 deletions(-) diff --git a/manta-crypto/src/arkworks/serialize.rs b/manta-crypto/src/arkworks/serialize.rs index 1e8572f37..879ca6648 100644 --- a/manta-crypto/src/arkworks/serialize.rs +++ b/manta-crypto/src/arkworks/serialize.rs @@ -16,33 +16,39 @@ //! Arkworks Canonical Serialize and Deserialize Backend -use alloc::vec::Vec; -use manta_util::serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer}; +#[cfg(feature = "serde")] +use { + alloc::vec::Vec, + manta_util::serde::{de, ser, Deserialize, Serialize}, +}; #[doc(inline)] pub use ark_serialize::*; -/// Uses `serializer` to serialize `data` that implements `CanonicalSerialize`. +/// Serializes `data` using the [`CanonicalSerialize`] format with `S` as the [`Serializer`]. +#[cfg(feature = "serde")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] #[inline] pub fn canonical_serialize(data: &T, serializer: S) -> Result where T: CanonicalSerialize, - S: Serializer, + S: ser::Serializer, { let mut bytes = Vec::new(); - data.serialize(&mut bytes) - .map_err(|_| -> S::Error { ser::Error::custom("Canonical serialize should succeed.") })?; + data.serialize(&mut bytes).map_err(ser::Error::custom)?; Serialize::serialize(&bytes, serializer) } -/// Uses `deserializer` to deserialize into data with type `T` that implements `CanonicalDeserialize`. +/// Deserializes data of type `T` using the [`CanonicalDeserialize`] format with `D` as the +/// [`Deserializer`]. +#[cfg(feature = "serde")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] #[inline] pub fn canonical_deserialize<'de, D, T>(deserializer: D) -> Result where - D: Deserializer<'de>, + D: de::Deserializer<'de>, T: CanonicalDeserialize, { let bytes: Vec = Deserialize::deserialize(deserializer)?; - Ok(CanonicalDeserialize::deserialize(bytes.as_slice()) - .map_err(|_| -> D::Error { de::Error::custom("Canonical serialize should succeed.") })?) + CanonicalDeserialize::deserialize(bytes.as_slice()).map_err(de::Error::custom) } diff --git a/manta-trusted-setup/Cargo.toml b/manta-trusted-setup/Cargo.toml index a85883666..3c6bb4711 100644 --- a/manta-trusted-setup/Cargo.toml +++ b/manta-trusted-setup/Cargo.toml @@ -33,6 +33,7 @@ rayon = ["manta-util/rayon"] # Serde Serialization serde = [ + "manta-crypto/serde", "manta-util/serde", "manta-util/serde-alloc", "manta-util/serde-array" diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index 38b8c16eb..9202f5c51 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -16,13 +16,12 @@ //! Trusted Setup Client -use crate::groth16::ceremony::{signature::Nonce, Ceremony, Participant}; -use manta_crypto::dalek::ed25519::Ed25519; - -use super::{ +use crate::groth16::ceremony::{ message::{QueryRequest, Signed}, - CeremonyError, + signature::Nonce, + Ceremony, CeremonyError, Participant, }; +use manta_crypto::dalek::ed25519::Ed25519; /// Client pub struct Client diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index ff42e771f..bfcca254e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -21,7 +21,7 @@ use crate::groth16::{ message::{MPCState, Signed}, registry::Registry, signature::{check_nonce, verify}, - Ceremony, CeremonyError, Participant, Queue, UserPriority, + Ceremony, CeremonyError, Participant, Queue, }, mpc::{verify_transform, Proof, State, StateSize}, }; @@ -131,7 +131,7 @@ where self.round += 1; } - /// Returns the state size. + /// Returns the state size for each circuit in this ceremony. #[inline] pub fn size(&self) -> &[StateSize; CIRCUIT_COUNT] { &self.size @@ -177,18 +177,18 @@ where pub fn preprocess_request( &mut self, request: &Signed, - ) -> Result> + ) -> Result> where T: Serialize, { let participant = self .registry .get_mut(&request.identifier) - .ok_or_else(|| CeremonyError::NotRegistered)?; + .ok_or(CeremonyError::NotRegistered)?; if participant.has_contributed() { return Err(CeremonyError::AlreadyContributed); } - let participant_nonce = participant.get_nonce(); + let participant_nonce = participant.nonce(); if !check_nonce(&participant_nonce, &request.nonce) { return Err(CeremonyError::NonceNotInSync(participant_nonce)); }; @@ -200,7 +200,7 @@ where ) .map_err(|_| CeremonyError::BadRequest)?; participant.increment_nonce(); - Ok(participant.level()) + Ok(participant.priority()) } /// Checks the lock update errors for the [`Coordinator::update`] method. diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 062c686c4..cbef56e66 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -20,7 +20,6 @@ use crate::groth16::{ ceremony::signature::{Nonce, SignatureScheme}, mpc::Configuration, }; -use derivative::Derivative; use manta_util::{ collections::vec_deque::MultiVecDeque, serde::{Deserialize, Serialize}, @@ -44,13 +43,16 @@ pub type Queue = /// Participant pub trait Participant { - /// Participant Identifier Type + /// Identifier Type type Identifier; - /// Participant Verifying Key Type + /// Verifying Key Type type VerifyingKey; - /// Nonce + /// Priority Type + type Priority; + + /// Nonce Type type Nonce: Nonce; /// Returns the [`Identifier`](Self::Identifier) for `self`. @@ -60,11 +62,7 @@ pub trait Participant { fn verifying_key(&self) -> &Self::VerifyingKey; /// Returns the priority level for `self`. - /// - /// # Note - /// - /// Lower level indicates a higher priority. - fn level(&self) -> UserPriority; + fn priority(&self) -> Self::Priority; /// Reduces the priority. fn reduce_priority(&mut self); @@ -75,32 +73,32 @@ pub trait Participant { /// Sets contributed. fn set_contributed(&mut self); - /// Returns nonce. - fn get_nonce(&self) -> Self::Nonce; + /// Returns the current nonce for `self`. + fn nonce(&self) -> Self::Nonce; - /// Increments the current nonce by one. + /// Increments the current nonce of `self` by one. fn increment_nonce(&mut self); } /// Ceremony Configuration -pub trait Ceremony: SignatureScheme + Configuration { +pub trait Ceremony: Configuration + SignatureScheme { /// Participant Identifier Type type Identifier: Clone + PartialEq; + /// Participant Priority Type + type Priority: Into; + /// Participant Type type Participant: Participant< Identifier = Self::Identifier, - Nonce = Self::Nonce, VerifyingKey = Self::VerifyingKey, + Priority = Self::Priority, + Nonce = Self::Nonce, >; } /// Ceremony Error -/// -/// # Note -/// -/// All errors here are visible to users. -#[derive(PartialEq, Serialize, Deserialize, Derivative)] +#[derive(derivative::Derivative, Deserialize, Serialize, PartialEq)] #[derivative(Debug(bound = "C::Nonce: core::fmt::Debug"))] #[serde( bound( @@ -135,27 +133,3 @@ where /// Unexpected Server Error Unexpected, } - -/// Priority -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] -#[serde( - bound(deserialize = "", serialize = ""), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub enum UserPriority { - /// High Priority - High, - - /// Normal Priority - Normal, -} - -impl From for usize { - fn from(priority: UserPriority) -> Self { - match priority { - UserPriority::High => 0, - UserPriority::Normal => 1, - } - } -} diff --git a/manta-trusted-setup/src/groth16/ceremony/participant.rs b/manta-trusted-setup/src/groth16/ceremony/participant.rs index 777bb28f4..0f244aafd 100644 --- a/manta-trusted-setup/src/groth16/ceremony/participant.rs +++ b/manta-trusted-setup/src/groth16/ceremony/participant.rs @@ -19,8 +19,33 @@ use crate::groth16::ceremony::{ self, signature::{Nonce, SignatureScheme}, - UserPriority, }; +use manta_util::serde::{Deserialize, Serialize}; + +/// Priority +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[serde( + bound(deserialize = "", serialize = ""), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub enum Priority { + /// High Priority + High, + + /// Normal Priority + Normal, +} + +impl From for usize { + #[inline] + fn from(priority: Priority) -> Self { + match priority { + Priority::High => 0, + Priority::Normal => 1, + } + } +} /// Participant pub struct Participant @@ -34,7 +59,7 @@ where twitter: String, /// Priority - priority: UserPriority, + priority: Priority, /// Nonce nonce: S::Nonce, @@ -49,6 +74,7 @@ where { type Identifier = S::VerifyingKey; type VerifyingKey = S::VerifyingKey; + type Priority = Priority; type Nonce = S::Nonce; #[inline] @@ -62,13 +88,13 @@ where } #[inline] - fn level(&self) -> UserPriority { + fn priority(&self) -> Self::Priority { self.priority } #[inline] fn reduce_priority(&mut self) { - self.priority = UserPriority::Normal; + self.priority = Priority::Normal; } #[inline] @@ -82,7 +108,7 @@ where } #[inline] - fn get_nonce(&self) -> Self::Nonce { + fn nonce(&self) -> Self::Nonce { self.nonce } @@ -101,7 +127,7 @@ where pub fn new( verifying_key: S::VerifyingKey, twitter: String, - priority: UserPriority, + priority: Priority, nonce: S::Nonce, contributed: bool, ) -> Self { diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 937d04c57..4f748f35f 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -20,11 +20,11 @@ use crate::groth16::{ ceremony::{ coordinator::Coordinator, message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse, Signed}, - participant::Participant, + participant::{Participant, Priority}, registry::Registry, signature::{verify, Message}, util::{deserialize_from_file, serialize_into_file}, - Ceremony, CeremonyError, Participant as _, UserPriority, + Ceremony, CeremonyError, Participant as _, }, mpc::{State, StateSize}, }; @@ -87,12 +87,12 @@ where ) -> Result<(CeremonySize, C::Nonce), CeremonyError> { let coordinator = self.coordinator.lock(); Ok(( - CeremonySize(BoxArray::from_unchecked(coordinator.size().clone())), + CeremonySize(BoxArray::from_unchecked(*coordinator.size())), coordinator .registry() .get(&request) - .ok_or_else(|| CeremonyError::NotRegistered)? - .get_nonce(), + .ok_or(CeremonyError::NotRegistered)? + .nonce(), )) } @@ -132,9 +132,9 @@ where let (state, proof) = request.message.0; coordinator.update(&request.identifier, state, proof)?; serialize_into_file( + OpenOptions::new().write(true).create_new(true), &Path::new(&self.recovery_path).join(format!("transcript{}.data", coordinator.round())), &coordinator.deref(), - OpenOptions::new().write(true).create_new(true), ) .map_err(|_| CeremonyError::Unexpected)?; println!("{} participants have contributed.", coordinator.round()); @@ -205,8 +205,8 @@ where verifying_key, twitter, match result[2].to_string().parse::().unwrap() { - true => UserPriority::High, - false => UserPriority::Normal, + true => Priority::High, + false => Priority::Normal, }, OsRng.gen::<_, u16>() as u64, false, diff --git a/manta-trusted-setup/src/groth16/ceremony/util.rs b/manta-trusted-setup/src/groth16/ceremony/util.rs index a838921fe..a32fc3394 100644 --- a/manta-trusted-setup/src/groth16/ceremony/util.rs +++ b/manta-trusted-setup/src/groth16/ceremony/util.rs @@ -22,28 +22,28 @@ use std::{ path::Path, }; -/// Logs `data` to a disk file at `path` assuming this file does not exist. +/// Serializes `data` to a file at `path` with the given `open_options`. #[inline] pub fn serialize_into_file( + open_options: &mut OpenOptions, path: &P, data: &T, - option: &mut OpenOptions, ) -> bincode::Result<()> where P: AsRef, T: Serialize, { - Ok(bincode::serialize_into(option.open(path)?, data)?) + bincode::serialize_into(open_options.open(path)?, data) } -/// Loads `data` from a disk file at `path`. +/// Deserializes an element of type `T` from the file at `path`. #[inline] pub fn deserialize_from_file(path: P) -> bincode::Result where P: AsRef, T: DeserializeOwned, { - Ok(bincode::deserialize_from(File::open(path)?)?) + bincode::deserialize_from(File::open(path)?) } // /// Prepares phase one parameter `powers` for phase two parameters of circuit `cs` with `name`. diff --git a/manta-trusted-setup/src/groth16/mpc.rs b/manta-trusted-setup/src/groth16/mpc.rs index 0f987d6fe..9fef08df5 100644 --- a/manta-trusted-setup/src/groth16/mpc.rs +++ b/manta-trusted-setup/src/groth16/mpc.rs @@ -30,13 +30,15 @@ use manta_crypto::{ pairing::{Pairing, PairingEngineExt}, ratio::{HashToGroup, RatioProof}, relations::r1cs::{ConstraintSynthesizer, ConstraintSystem, SynthesisError}, - serialize::{canonical_deserialize, canonical_serialize}, }, rand::{CryptoRng, RngCore}, }; #[cfg(feature = "serde")] -use manta_util::serde::{Deserialize, Serialize}; +use { + manta_crypto::arkworks::serialize::{canonical_deserialize, canonical_serialize}, + manta_util::serde::{Deserialize, Serialize}, +}; /// MPC State #[derive(Serialize, Deserialize, derivative::Derivative)] @@ -417,8 +419,8 @@ pub fn verify_transform( where C: Configuration, { - check_invariants::(&prev, &next)?; - let next_challenge = C::challenge(challenge, &prev, &next, &proof); + check_invariants::(prev, &next)?; + let next_challenge = C::challenge(challenge, prev, &next, &proof); let ((ratio_0, ratio_1), _) = proof .0 .verify(&C::Hasher::default(), challenge) diff --git a/manta-trusted-setup/src/groth16/ppot/mpc.rs b/manta-trusted-setup/src/groth16/ppot/mpc.rs index 242235c50..405974878 100644 --- a/manta-trusted-setup/src/groth16/ppot/mpc.rs +++ b/manta-trusted-setup/src/groth16/ppot/mpc.rs @@ -42,11 +42,14 @@ impl Configuration for PerpetualPowersOfTauCeremony Self::Challenge { let mut hasher = Self::Hasher::default(); hasher.0.update(challenge); - prev.0.serialize(&mut hasher) + prev.0 + .serialize(&mut hasher) .expect("Consuming the previous state failed."); - next.0.serialize(&mut hasher) + next.0 + .serialize(&mut hasher) .expect("Consuming the current state failed."); - proof.0 + proof + .0 .serialize(&mut hasher) .expect("Consuming proof failed"); into_array_unchecked(hasher.0.finalize()) diff --git a/manta-trusted-setup/src/groth16/test/mod.rs b/manta-trusted-setup/src/groth16/test/mod.rs index 610f62437..a1f0d1889 100644 --- a/manta-trusted-setup/src/groth16/test/mod.rs +++ b/manta-trusted-setup/src/groth16/test/mod.rs @@ -267,9 +267,8 @@ fn trusted_setup_phase_two_is_valid() { for _ in 0..5 { prev_state = state.clone(); proof = contribute(&hasher, &challenge, &mut state, &mut rng).unwrap(); - (challenge, state) = - verify_transform(&challenge, &prev_state, state, proof.clone()) - .expect("Verify transform failed"); + (challenge, state) = verify_transform(&challenge, &prev_state, state, proof.clone()) + .expect("Verify transform failed"); transcript.rounds.push((state.clone(), proof)); } verify_transform_all( diff --git a/manta-util/src/bytes.rs b/manta-util/src/bytes.rs index fbbf1d0fa..9157fdf31 100644 --- a/manta-util/src/bytes.rs +++ b/manta-util/src/bytes.rs @@ -112,4 +112,4 @@ impl AsBytes for u64 { fn as_bytes(&self) -> Vec { self.to_le_bytes().to_vec() } -} \ No newline at end of file +} diff --git a/manta-util/src/collections/vec_deque.rs b/manta-util/src/collections/vec_deque.rs index 9ca1ff97b..2c32f3fd1 100644 --- a/manta-util/src/collections/vec_deque.rs +++ b/manta-util/src/collections/vec_deque.rs @@ -177,8 +177,8 @@ impl MultiVecDeque { Some(position) => position, None => { self.push_back(level, item); - self.0[level].len()-1 - }, + self.0[level].len() - 1 + } } } } From 40a6be4e28b789e5d001317ce143cc8c6d89b329 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Fri, 9 Sep 2022 18:07:17 -0400 Subject: [PATCH 18/60] feat: use macro for dalek byte conversions Signed-off-by: Brandon H. Gomes --- manta-crypto/src/arkworks/serialize.rs | 6 +-- manta-crypto/src/dalek/ed25519.rs | 59 ++++++++++++-------------- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/manta-crypto/src/arkworks/serialize.rs b/manta-crypto/src/arkworks/serialize.rs index 879ca6648..084602117 100644 --- a/manta-crypto/src/arkworks/serialize.rs +++ b/manta-crypto/src/arkworks/serialize.rs @@ -19,7 +19,7 @@ #[cfg(feature = "serde")] use { alloc::vec::Vec, - manta_util::serde::{de, ser, Deserialize, Serialize}, + manta_util::serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer}, }; #[doc(inline)] @@ -32,7 +32,7 @@ pub use ark_serialize::*; pub fn canonical_serialize(data: &T, serializer: S) -> Result where T: CanonicalSerialize, - S: ser::Serializer, + S: Serializer, { let mut bytes = Vec::new(); data.serialize(&mut bytes).map_err(ser::Error::custom)?; @@ -46,7 +46,7 @@ where #[inline] pub fn canonical_deserialize<'de, D, T>(deserializer: D) -> Result where - D: de::Deserializer<'de>, + D: Deserializer<'de>, T: CanonicalDeserialize, { let bytes: Vec = Deserialize::deserialize(deserializer)?; diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index 0b199516d..25dd931cc 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with manta-rs. If not, see . -//! Dalek Cryptography `ed25519` Backend +//! Dalek Cryptography [`ed25519`](ed25519_dalek) Backend use crate::{ rand::{CryptoRng, Rand, RngCore}, @@ -27,38 +27,33 @@ use manta_util::AsBytes; pub use ed25519_dalek::*; -/// Converts `bytes` into a [`SecretKey`]. -#[inline] -pub fn secret_key_from_bytes(bytes: [u8; SECRET_KEY_LENGTH]) -> SecretKey { - match SecretKey::from_bytes(&bytes) { - Ok(secret_key) => secret_key, - _ => { - unreachable!("We are guaranteed the correct number of bytes from `SECRET_KEY_LENGTH`.") +/// Implements byte conversion from an array of bytes of length `$len` into the given `$type`. +macro_rules! byte_conversion { + ($name:ident, $type:tt, $len:ident) => { + #[doc = "Converts the `bytes` fixed-length array into [`"] + #[doc = stringify!($type)] + #[doc = "`]."] + /// + /// # Note + /// + /// We don't need to return an error here because `bytes` already has the correct length. + #[inline] + pub fn $name(bytes: [u8; $len]) -> $type { + match $type::from_bytes(&bytes) { + Ok(value) => value, + _ => unreachable!(concat!( + "We are guaranteed the correct number of bytes from `", + stringify!($len), + "`." + )), + } } - } + }; } -/// Converts `bytes` into a [`PublicKey`]. -#[inline] -pub fn public_key_from_bytes(bytes: [u8; PUBLIC_KEY_LENGTH]) -> PublicKey { - match PublicKey::from_bytes(&bytes) { - Ok(public_key) => public_key, - _ => { - unreachable!("We are guaranteed the correct number of bytes from `PUBLIC_KEY_LENGTH`.") - } - } -} - -/// Converts `bytes` into [`Signature`]. -#[inline] -pub fn signature_from_bytes(bytes: [u8; SIGNATURE_LENGTH]) -> Signature { - match Signature::from_bytes(&bytes) { - Ok(signature) => signature, - _ => { - unreachable!("We are guaranteed the correct number of bytes from `SIGNATURE_LENGTH`.") - } - } -} +byte_conversion!(secret_key_from_bytes, SecretKey, SECRET_KEY_LENGTH); +byte_conversion!(public_key_from_bytes, PublicKey, PUBLIC_KEY_LENGTH); +byte_conversion!(signature_from_bytes, Signature, SIGNATURE_LENGTH); /// Clones the `secret_key` by serializing and then deserializing. #[inline] @@ -107,7 +102,9 @@ impl MessageType for Ed25519 { } impl RandomnessType for Ed25519 { - /// The `ed25519_dalek` crate provides randomness internally so we set it as `()` here. + /// Empty Randomness + /// + /// The [`ed25519_dalek`] crate provides randomness internally so we set it as `()` here. type Randomness = (); } From 7fa08c405edab1a148d8676f0f2e5ba8fcfae371 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 15:10:07 -0700 Subject: [PATCH 19/60] wip: client --- manta-trusted-setup/Cargo.toml | 2 + .../src/groth16/ceremony/client.rs | 55 +++++++++++++++++-- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/manta-trusted-setup/Cargo.toml b/manta-trusted-setup/Cargo.toml index 3c6bb4711..0f849d490 100644 --- a/manta-trusted-setup/Cargo.toml +++ b/manta-trusted-setup/Cargo.toml @@ -57,6 +57,8 @@ ark-std = { version = "0.3.0", default-features = false } bincode = { version = "1.3.3", optional = true, default-features = false } blake2 = { version = "0.10.4", default-features = false } bs58 = { version = "0.4", default-features = false, features = ["alloc"] } +colored = { version = "2.0.0" } +console = { version = "0.15.1" } csv = { version = "1.1" } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["arkworks", "getrandom", "rand_chacha", "dalek"] } diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index 9202f5c51..3eaa409cb 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -16,12 +16,17 @@ //! Trusted Setup Client -use crate::groth16::ceremony::{ - message::{QueryRequest, Signed}, - signature::Nonce, - Ceremony, CeremonyError, Participant, +use crate::groth16::{ + ceremony::{ + message::{ContributeRequest, QueryRequest, Signed}, + signature::Nonce, + Ceremony, CeremonyError, Participant, + }, + mpc::{contribute, State}, }; -use manta_crypto::dalek::ed25519::Ed25519; +use console::style; +use manta_crypto::{dalek::ed25519::Ed25519, rand::OsRng}; +use manta_util::BoxArray; /// Client pub struct Client @@ -67,4 +72,44 @@ where self.nonce.increment(); Ok(signed_message) } + + /// Contributes to the state on the server. + #[inline] + pub fn contribute( + &mut self, + hasher: &C::Hasher, + challenge: &BoxArray, + mut state: BoxArray, CIRCUIT_COUNT>, + ) -> Result, C>, CeremonyError> + where + C::Nonce: Clone, + { + let circuit_name = ["ToPrivate", "PrivateTransfer", "ToPublic"]; + let mut rng = OsRng; + let mut proofs = Vec::new(); + for i in 0..CIRCUIT_COUNT { + println!( + "{} Contributing to {} Circuits...", + style(format!("[{}/9]", i + 5)).bold().dim(), + circuit_name[i], + ); + match contribute(hasher, &challenge[i], &mut state[i], &mut rng) { + Some(proof) => proofs.push(proof), + None => return Err(CeremonyError::Unexpected), + } + } + println!( + "{} Waiting for Confirmation from Server... Estimated Waiting Time: {} minutes.", + style("[8/9]").bold().dim(), + style("3").bold().blue(), + ); + let signed_message = Signed::new( + ContributeRequest((state, BoxArray::from_vec(proofs))), + &self.nonce, + &self.signing_key, + self.identifier.clone(), + ); + self.nonce.increment(); + signed_message + } } From ec8712c21a8cf06c93aef91d5e3dca29f78d2768 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Fri, 9 Sep 2022 18:17:12 -0400 Subject: [PATCH 20/60] chore: clean up ceremony size Signed-off-by: Brandon H. Gomes --- .../src/groth16/ceremony/message.rs | 50 ++++++++----------- .../src/groth16/ceremony/server.rs | 4 +- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 5c7464817..095aec431 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -47,36 +47,26 @@ where pub challenge: BoxArray, } -/// Response for State Sizes -#[derive(Clone, Serialize, Deserialize)] +/// Ceremony Size +#[derive(Clone, Deserialize, Serialize)] #[serde(crate = "manta_util::serde", deny_unknown_fields)] pub struct CeremonySize(pub BoxArray); -impl From> - for CeremonySize -{ - fn from(inner: BoxArray) -> Self { - CeremonySize(inner) - } -} - impl CeremonySize { - /// Checks `states` matches [`CeremonySize`]. + /// Checks that each size in `self` matches each [`State`] in `states`. #[inline] - pub fn check_state_size

(&self, states: &BoxArray, CIRCUIT_COUNT>) -> bool + pub fn matches

(&self, states: &[State

; CIRCUIT_COUNT]) -> bool where P: Pairing, { - let mut validity = true; - for i in 0..CIRCUIT_COUNT { - validity = validity || self.0[i].matches(&states[i].0); - } - validity + self.0.iter().zip(states).all(|(l, r)| l.matches(&r.0)) } } /// Query Request -#[derive(Deserialize, Serialize)] +#[derive( + Clone, Copy, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, +)] #[serde(crate = "manta_util::serde", deny_unknown_fields)] pub struct QueryRequest; @@ -84,8 +74,8 @@ pub struct QueryRequest; #[derive(Deserialize, Serialize)] #[serde( bound( - serialize = "MPCState: Serialize", - deserialize = "MPCState: Deserialize<'de>" + deserialize = "MPCState: Deserialize<'de>", + serialize = "MPCState: Serialize" ), crate = "manta_util::serde", deny_unknown_fields @@ -102,20 +92,22 @@ where } /// Contribute Request -#[derive(Serialize, Deserialize)] +#[derive(Deserialize, Serialize)] #[serde( - bound(serialize = "", deserialize = ""), + bound(deserialize = "", serialize = ""), crate = "manta_util::serde", deny_unknown_fields )] -pub struct ContributeRequest( - pub ( - BoxArray, CIRCUIT_COUNT>, - BoxArray, CIRCUIT_COUNT>, - ), -) +pub struct ContributeRequest where - C: Ceremony; + C: Ceremony, +{ + /// State + pub state: BoxArray, CIRCUIT_COUNT>, + + /// Proof + pub proof: BoxArray, CIRCUIT_COUNT>, +} /// Signed Message #[derive(Deserialize, Serialize)] diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 4f748f35f..f6dcb1992 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -129,8 +129,8 @@ where { let mut coordinator = self.coordinator.lock(); coordinator.preprocess_request(&request)?; - let (state, proof) = request.message.0; - coordinator.update(&request.identifier, state, proof)?; + let message = request.message; + coordinator.update(&request.identifier, message.state, message.proof)?; serialize_into_file( OpenOptions::new().write(true).create_new(true), &Path::new(&self.recovery_path).join(format!("transcript{}.data", coordinator.round())), From e10d9143150ff061b763c696715ab6b6f94ff7ab Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 16:22:01 -0700 Subject: [PATCH 21/60] wip: client --- manta-crypto/src/dalek/ed25519.rs | 18 +- manta-trusted-setup/Cargo.toml | 15 +- .../src/groth16/ceremony/client.rs | 303 +++++++++++++++++- .../src/groth16/ceremony/coordinator.rs | 6 +- .../src/groth16/ceremony/mod.rs | 5 +- .../src/groth16/ceremony/server.rs | 5 +- .../src/groth16/ceremony/signature.rs | 13 +- .../src/groth16/ceremony/util.rs | 2 +- 8 files changed, 344 insertions(+), 23 deletions(-) diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index 25dd931cc..2bb811d28 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -22,7 +22,7 @@ use crate::{ MessageType, RandomnessType, Sign, SignatureType, SigningKeyType, Verify, VerifyingKeyType, }, }; -use core::marker::PhantomData; +use core::{convert::TryInto, marker::PhantomData}; use manta_util::AsBytes; pub use ed25519_dalek::*; @@ -92,6 +92,22 @@ where } } +/// Generates a [`KeyPair`] from `bytes`. +#[inline] +pub fn generate_keys(bytes: &[u8]) -> Option { + if SECRET_KEY_LENGTH > bytes.len() { + return None; + } + let sk = match bytes[0..SECRET_KEY_LENGTH].try_into() { + Ok(bytes) => secret_key_from_bytes(bytes), + Err(_) => return None, + }; + Some(Keypair { + public: (&sk).into(), + secret: sk, + }) +} + /// Edwards Curve Signature Scheme for the `Curve25519` Elliptic Curve #[derive(derivative::Derivative)] #[derivative(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] diff --git a/manta-trusted-setup/Cargo.toml b/manta-trusted-setup/Cargo.toml index 0f849d490..26da1c066 100644 --- a/manta-trusted-setup/Cargo.toml +++ b/manta-trusted-setup/Cargo.toml @@ -39,11 +39,6 @@ serde = [ "manta-util/serde-array" ] -# Tide -tide = [ - "manta-util/tide" -] - # Standard Library std = ["manta-util/std"] @@ -57,13 +52,15 @@ ark-std = { version = "0.3.0", default-features = false } bincode = { version = "1.3.3", optional = true, default-features = false } blake2 = { version = "0.10.4", default-features = false } bs58 = { version = "0.4", default-features = false, features = ["alloc"] } -colored = { version = "2.0.0" } -console = { version = "0.15.1" } -csv = { version = "1.1" } +colored = { version = "2.0.0", default-features = false } +console = { version = "0.15.1", default-features = false } +csv = { version = "1.1", default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } +dialoguer = { version = "0.10.2", default-features = false } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["arkworks", "getrandom", "rand_chacha", "dalek"] } -manta-util = { path = "../manta-util", default-features = false } +manta-util = { path = "../manta-util", default-features = false, features = ["reqwest"] } parking_lot = { version = "0.12.1", default-features = false } +tiny-bip39 = { version = "1.0.0", default-features = false } [dev-dependencies] ark-snark = { version = "0.3.0", default-features = false } diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index 3eaa409cb..f825ee4f0 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -18,15 +18,26 @@ use crate::groth16::{ ceremony::{ - message::{ContributeRequest, QueryRequest, Signed}, - signature::Nonce, - Ceremony, CeremonyError, Participant, + message::{CeremonySize, ContributeRequest, QueryRequest, Signed}, + signature::{sign, Message, Nonce}, + Ceremony, CeremonyError, }, mpc::{contribute, State}, }; -use console::style; -use manta_crypto::{dalek::ed25519::Ed25519, rand::OsRng}; -use manta_util::BoxArray; +use bip39::{Language, Mnemonic, MnemonicType, Seed}; +use colored::Colorize; +use console::{style, Term}; +use core::fmt::Debug; +use dialoguer::{theme::ColorfulTheme, Input}; +use manta_crypto::{ + dalek::ed25519::{generate_keys, Ed25519}, + rand::OsRng, +}; +use manta_util::{ + http::reqwest::KnownUrlClient, + serde::{de::DeserializeOwned, Serialize}, + BoxArray, +}; /// Client pub struct Client @@ -95,7 +106,7 @@ where ); match contribute(hasher, &challenge[i], &mut state[i], &mut rng) { Some(proof) => proofs.push(proof), - None => return Err(CeremonyError::Unexpected), + None => return Err(CeremonyError::Unexpected("Cannot contribute.".to_string())), } } println!( @@ -113,3 +124,281 @@ where signed_message } } + +/// Registers a participant. +#[inline] +pub fn register(twitter_account: String, email: String) { + println!( + "Your {}: \nCopy the following text to \"Twitter\" Section in Google Sheet:\n {}\n", + "Twitter Account".italic(), + twitter_account.blue(), + ); + println!( + "Your {}: \nCopy the following text to \"Email\" Section in Google Sheet:\n {}\n", + "Email".italic(), + email.blue(), + ); + let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); + let seed = Seed::new(&mnemonic, "manta-trusted-setup"); + let key_pair = generate_keys(seed.as_bytes()).expect("Should generate a key pair."); + println!( + "Your {}: \nCopy the following text to \"Public Key\" Section in Google Sheet:\n {}\n", + "Public Key".italic(), + bs58::encode(key_pair.public).into_string().blue(), + ); + let signature = sign::<_, Ed25519>>( + &key_pair.secret, + 0, + &format!( + "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", + twitter_account, email + ), + ) + .expect("Signing message should succeed."); + println!( + "Your {}: \nCopy the following text to \"Signature\" Section in Google Sheet: \n {}\n", + "Signature".italic(), + bs58::encode(signature).into_string().blue() + ); + println!( + "Your {}: \nThe following text stores your secret for trusted setup. \ + Save the following text somewhere safe. \n DO NOT share this to anyone else! \ + Please discard this data after the trusted setup ceremony.\n {}", + "Secret".italic(), + mnemonic.phrase().red(), + ); +} + +/// Prompts the client information and get client keys. +#[inline] +pub fn get_client_keys() -> Result<(C::SigningKey, C::VerifyingKey), CeremonyError> +where + C: Ceremony, +{ + println!( + "Please enter your {} that you get when you registered yourself using this tool.", + "Secret".italic() + ); + let seed_bytes = Seed::new( + &Mnemonic::from_phrase( + Input::with_theme(&ColorfulTheme::default()) + .with_prompt("Your Secret") + .validate_with(|input: &String| -> Result<(), &str> { + Mnemonic::validate(input, Language::English) + .map_err(|_| "This is not a valid secret.") + }) + .interact_text() + .expect("Please enter your secret received during `Register`.") + .as_str(), + Language::English, + ) + .expect("Should produce a mnemonic from the secret."), + "manta-trusted-setup", + ) + .as_bytes() + .to_vec(); + match C::generate_keys(&seed_bytes) { + Some(key_pair) => Ok(key_pair), + None => Err(CeremonyError::Unexpected( + "Cannot generate keys.".to_string(), + )), + } +} + +/// Gets state size from server. +#[inline] +pub async fn get_start_meta_data( + identity: C::Identifier, + network_client: &KnownUrlClient, +) -> Result<(CeremonySize, C::Nonce), CeremonyError> +where + C: Ceremony, + C::Identifier: Serialize, + C::Nonce: DeserializeOwned + Debug, +{ + match network_client + .post::<_, Result<(CeremonySize, C::Nonce), CeremonyError>>( + "start", &identity, + ) + .await + .map_err(|_| { + return CeremonyError::Network( + "Should have received starting meta data from server".to_string(), + ); + })? { + Ok((server_size, nonce)) => Ok((server_size, nonce)), + Err(CeremonyError::NotRegistered) => Err(CeremonyError::NotRegistered), + Err(e) => Err(CeremonyError::Unexpected(format!("{:?}", e))), + } +} + +// /// Contributes to the server. +// #[inline] +// pub async fn client_contribute() -> Result<(), CeremonyError> +// where +// C: Ceremony, +// C::Identifier: Serialize, +// C::Nonce: DeserializeOwned + Debug, +// // C::Participant: CHasIdentifier> + Clone, +// // E: PairingEngine, +// // P: Pairing, +// // ParticipantIdentifier: Serialize, +// // Nonce: DeserializeOwned + Debug, +// // State: CanonicalDeserialize, +// // Challenge: CanonicalDeserialize, +// // Proof: CanonicalSerialize, +// // ::Setup: Types>, +// { +// let network_client = KnownUrlClient::new("http://localhost:8080").expect("Should succeed."); +// let (sk, pk) = get_client_keys()?; +// println!( +// "{} Contacting Server for Meta Data...", +// style("[1/9]").bold().dim() +// ); +// let term = Term::stdout(); +// let (size, nonce) = get_start_meta_data::(pk, &network_client).await?; +// // let mut trusted_setup_client = Client::::new(pk, nonce, sk); +// // println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); +// // loop { +// // let mpc_state = match network_client +// // .post::<_, Result, CeremonyError>>( +// // "query", +// // &trusted_setup_client +// // .query() +// // .map_err(|_| Error::UnableToGenerateRequest("Queries the server state."))?, +// // ) +// // .await +// // .map_err(|_| { +// // return Error::NetworkError( +// // "Should have received starting meta data from server".to_string(), +// // ); +// // })? { +// // Err(CeremonyError::Timeout) => { +// // term.clear_last_lines(1) +// // .expect("Clear last lines should succeed."); +// // println!( +// // "{} You have timed out. Waiting in Queue again...", +// // style("[2/9]").bold().dim(), +// // ); +// // continue; +// // } +// // Err(CeremonyError::NotRegistered) => return Err(Error::NotRegistered), +// // Err(CeremonyError::NonceNotInSync(_)) => { +// // return Err(Error::UnexpectedError( +// // "Unexpected error when query mpc state. Nonce should have been synced." +// // .to_string(), +// // )) +// // } +// // Err(CeremonyError::BadRequest) => { +// // return Err(Error::UnexpectedError( +// // "Unexpected error when query mpc state since finding a bad request." +// // .to_string(), +// // )) +// // } +// // Err(CeremonyError::AlreadyContributed) => return Err(Error::AlreadyContributed), +// // Err(CeremonyError::NotYourTurn) => { +// // return Err(Error::UnexpectedError( +// // "Unexpected error when query mpc state. Should not receive NotYourTurn message." +// // .to_string(), +// // )); +// // } +// // Ok(message) => match message { +// // QueryResponse::QueuePosition(position) => { +// // term.clear_last_lines(1) +// // .expect("Clear last lines should succeed."); +// // println!( +// // "{} Waiting in Queue... There are {} people ahead of you. Estimated Waiting Time: {} minutes.", +// // style("[2/9]").bold().dim(), +// // style(position).bold().red(), +// // style(5*position).bold().blue(), +// // ); +// // thread::sleep(Duration::from_secs(10)); +// // continue; +// // } +// // QueryResponse::Mpc(mpc_state) => { +// // term.clear_last_lines(1) +// // .expect("Clear last lines should succeed."); +// // println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); +// // println!( +// // "{} Downloading Ceremony States...", +// // style("[3/9]").bold().dim(), +// // ); +// // if !check_state_size::(&mpc_state.state, &size) { +// // return Err(Error::UnexpectedError( +// // "Received mpc state size is not correct.".to_string(), +// // )); +// // } +// // mpc_state +// // } +// // }, +// // }; +// // println!( +// // "{} Starting contribution to 3 Circuits...", +// // style("[4/9]").bold().dim(), +// // ); +// // match network_client +// // .post::<_, Result<(), CeremonyError>>( +// // "update", +// // &trusted_setup_client +// // .contribute( +// // &Hasher::::default(), +// // &mpc_state.challenge, +// // mpc_state.state, +// // ) +// // .map_err(|_| Error::UnableToGenerateRequest("contribute"))?, +// // ) +// // .await +// // .map_err(|_| { +// // return Error::NetworkError( +// // "Should have received starting meta data from server".to_string(), +// // ); +// // })? { +// // Err(CeremonyError::Timeout) => { +// // term.clear_last_lines(1) +// // .expect("Clear last lines should succeed."); +// // println!( +// // "{} You have timed out. Waiting in Queue again...", +// // style("[2/9]").bold().dim(), +// // ); +// // continue; +// // } +// // Err(CeremonyError::NotRegistered) => { +// // return Err(Error::UnexpectedError( +// // "unexpected error when contribute. Should have registered.".to_string(), +// // )) +// // } +// // Err(CeremonyError::NonceNotInSync(_)) => { +// // return Err(Error::UnexpectedError( +// // "unexpected error when contribute. Nonce should have been synced.".to_string(), +// // )) +// // } +// // Err(CeremonyError::BadRequest) => { +// // return Err(Error::UnexpectedError( +// // "unexpected error when contribute since finding a bad request.".to_string(), +// // )) +// // } +// // Err(CeremonyError::NotYourTurn) => { +// // println!( +// // "{} Lag behind server. Contacting Server again...", +// // style("[8/9]").bold().dim(), +// // ); +// // continue; +// // } +// // Err(CeremonyError::AlreadyContributed) => return Err(Error::AlreadyContributed), +// // Ok(_) => { +// // term.clear_last_lines(1) +// // .expect("Clear last lines should succeed."); +// // println!( +// // "{} Waiting for Confirmation from Server...", +// // style("[8/9]").bold().dim(), +// // ); +// // println!( +// // "{} Congratulations! You have successfully contributed to Manta Trusted Setup Ceremony!...", +// // style("[9/9]").bold().dim(), +// // ); +// // break; +// // } +// // } +// // } +// Ok(()) +// } diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index bfcca254e..b0726e73d 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -262,7 +262,11 @@ where self.participant_lock.set(self.queue.pop_front()); match self.participant_mut(participant) { Some(participant) => participant.set_contributed(), - None => return Err(CeremonyError::Unexpected), + None => { + return Err(CeremonyError::Unexpected( + "Cannot get participant.".to_string(), + )) + } }; self.increment_round(); Ok(()) diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index cbef56e66..22bc7e7e5 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -131,5 +131,8 @@ where Timeout, /// Unexpected Server Error - Unexpected, + Unexpected(String), + + /// Network Error + Network(String), } diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index f6dcb1992..8946e9c49 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -136,7 +136,7 @@ where &Path::new(&self.recovery_path).join(format!("transcript{}.data", coordinator.round())), &coordinator.deref(), ) - .map_err(|_| CeremonyError::Unexpected)?; + .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?; println!("{} participants have contributed.", coordinator.round()); Ok(()) } @@ -155,7 +155,8 @@ where { Ok(Server { coordinator: Arc::new(Mutex::new( - deserialize_from_file(recovery).map_err(|_| CeremonyError::Unexpected)?, + deserialize_from_file(recovery) + .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?, )), recovery_path, }) diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index c34e143d1..8ef878722 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -18,7 +18,7 @@ use alloc::vec::Vec; use manta_crypto::{ - dalek::ed25519::{Ed25519, SignatureError}, + dalek::ed25519::{Ed25519, SignatureError, self}, signature, }; use manta_util::{serde::Serialize, AsBytes}; @@ -86,6 +86,9 @@ pub trait SignatureScheme: /// Verification Error Type type Error; + + /// Generates key pair from `bytes`. + fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)>; } /// Signs the `message` with the `nonce` attached using the `signing_key`. @@ -158,4 +161,12 @@ where { type Nonce = N; type Error = SignatureError; + + #[inline] + fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)> { + match ed25519::generate_keys(bytes) { + Some(key_pair) => Some((key_pair.secret, key_pair.public)), + None => None, + } + } } diff --git a/manta-trusted-setup/src/groth16/ceremony/util.rs b/manta-trusted-setup/src/groth16/ceremony/util.rs index a32fc3394..4e8e26f28 100644 --- a/manta-trusted-setup/src/groth16/ceremony/util.rs +++ b/manta-trusted-setup/src/groth16/ceremony/util.rs @@ -81,9 +81,9 @@ mod test { fn log_load_file_is_correct() { let data = "Testing data".to_string(); serialize_into_file( + OpenOptions::new().write(true).create_new(true), &"test_transcript.data", &data, - OpenOptions::new().write(true).create_new(true), ) .unwrap(); let loaded_data: String = deserialize_from_file(&"test_transcript.data").unwrap(); From 178032b69aac0d9ac3ffbc4aa29b1bcd08678802 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 19:44:14 -0700 Subject: [PATCH 22/60] feat: client --- .../src/groth16/ceremony/client.rs | 334 +++++++++--------- .../src/groth16/ceremony/mod.rs | 3 + 2 files changed, 164 insertions(+), 173 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index f825ee4f0..301a7e50e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -18,7 +18,7 @@ use crate::groth16::{ ceremony::{ - message::{CeremonySize, ContributeRequest, QueryRequest, Signed}, + message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse, Signed}, signature::{sign, Message, Nonce}, Ceremony, CeremonyError, }, @@ -30,14 +30,16 @@ use console::{style, Term}; use core::fmt::Debug; use dialoguer::{theme::ColorfulTheme, Input}; use manta_crypto::{ - dalek::ed25519::{generate_keys, Ed25519}, + dalek::ed25519::{self, generate_keys, Ed25519}, rand::OsRng, }; use manta_util::{ http::reqwest::KnownUrlClient, serde::{de::DeserializeOwned, Serialize}, + time::Duration, BoxArray, }; +use std::thread; /// Client pub struct Client @@ -115,7 +117,10 @@ where style("3").bold().blue(), ); let signed_message = Signed::new( - ContributeRequest((state, BoxArray::from_vec(proofs))), + ContributeRequest { + state, + proof: BoxArray::from_vec(proofs), + }, &self.nonce, &self.signing_key, self.identifier.clone(), @@ -232,173 +237,156 @@ where } } -// /// Contributes to the server. -// #[inline] -// pub async fn client_contribute() -> Result<(), CeremonyError> -// where -// C: Ceremony, -// C::Identifier: Serialize, -// C::Nonce: DeserializeOwned + Debug, -// // C::Participant: CHasIdentifier> + Clone, -// // E: PairingEngine, -// // P: Pairing, -// // ParticipantIdentifier: Serialize, -// // Nonce: DeserializeOwned + Debug, -// // State: CanonicalDeserialize, -// // Challenge: CanonicalDeserialize, -// // Proof: CanonicalSerialize, -// // ::Setup: Types>, -// { -// let network_client = KnownUrlClient::new("http://localhost:8080").expect("Should succeed."); -// let (sk, pk) = get_client_keys()?; -// println!( -// "{} Contacting Server for Meta Data...", -// style("[1/9]").bold().dim() -// ); -// let term = Term::stdout(); -// let (size, nonce) = get_start_meta_data::(pk, &network_client).await?; -// // let mut trusted_setup_client = Client::::new(pk, nonce, sk); -// // println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); -// // loop { -// // let mpc_state = match network_client -// // .post::<_, Result, CeremonyError>>( -// // "query", -// // &trusted_setup_client -// // .query() -// // .map_err(|_| Error::UnableToGenerateRequest("Queries the server state."))?, -// // ) -// // .await -// // .map_err(|_| { -// // return Error::NetworkError( -// // "Should have received starting meta data from server".to_string(), -// // ); -// // })? { -// // Err(CeremonyError::Timeout) => { -// // term.clear_last_lines(1) -// // .expect("Clear last lines should succeed."); -// // println!( -// // "{} You have timed out. Waiting in Queue again...", -// // style("[2/9]").bold().dim(), -// // ); -// // continue; -// // } -// // Err(CeremonyError::NotRegistered) => return Err(Error::NotRegistered), -// // Err(CeremonyError::NonceNotInSync(_)) => { -// // return Err(Error::UnexpectedError( -// // "Unexpected error when query mpc state. Nonce should have been synced." -// // .to_string(), -// // )) -// // } -// // Err(CeremonyError::BadRequest) => { -// // return Err(Error::UnexpectedError( -// // "Unexpected error when query mpc state since finding a bad request." -// // .to_string(), -// // )) -// // } -// // Err(CeremonyError::AlreadyContributed) => return Err(Error::AlreadyContributed), -// // Err(CeremonyError::NotYourTurn) => { -// // return Err(Error::UnexpectedError( -// // "Unexpected error when query mpc state. Should not receive NotYourTurn message." -// // .to_string(), -// // )); -// // } -// // Ok(message) => match message { -// // QueryResponse::QueuePosition(position) => { -// // term.clear_last_lines(1) -// // .expect("Clear last lines should succeed."); -// // println!( -// // "{} Waiting in Queue... There are {} people ahead of you. Estimated Waiting Time: {} minutes.", -// // style("[2/9]").bold().dim(), -// // style(position).bold().red(), -// // style(5*position).bold().blue(), -// // ); -// // thread::sleep(Duration::from_secs(10)); -// // continue; -// // } -// // QueryResponse::Mpc(mpc_state) => { -// // term.clear_last_lines(1) -// // .expect("Clear last lines should succeed."); -// // println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); -// // println!( -// // "{} Downloading Ceremony States...", -// // style("[3/9]").bold().dim(), -// // ); -// // if !check_state_size::(&mpc_state.state, &size) { -// // return Err(Error::UnexpectedError( -// // "Received mpc state size is not correct.".to_string(), -// // )); -// // } -// // mpc_state -// // } -// // }, -// // }; -// // println!( -// // "{} Starting contribution to 3 Circuits...", -// // style("[4/9]").bold().dim(), -// // ); -// // match network_client -// // .post::<_, Result<(), CeremonyError>>( -// // "update", -// // &trusted_setup_client -// // .contribute( -// // &Hasher::::default(), -// // &mpc_state.challenge, -// // mpc_state.state, -// // ) -// // .map_err(|_| Error::UnableToGenerateRequest("contribute"))?, -// // ) -// // .await -// // .map_err(|_| { -// // return Error::NetworkError( -// // "Should have received starting meta data from server".to_string(), -// // ); -// // })? { -// // Err(CeremonyError::Timeout) => { -// // term.clear_last_lines(1) -// // .expect("Clear last lines should succeed."); -// // println!( -// // "{} You have timed out. Waiting in Queue again...", -// // style("[2/9]").bold().dim(), -// // ); -// // continue; -// // } -// // Err(CeremonyError::NotRegistered) => { -// // return Err(Error::UnexpectedError( -// // "unexpected error when contribute. Should have registered.".to_string(), -// // )) -// // } -// // Err(CeremonyError::NonceNotInSync(_)) => { -// // return Err(Error::UnexpectedError( -// // "unexpected error when contribute. Nonce should have been synced.".to_string(), -// // )) -// // } -// // Err(CeremonyError::BadRequest) => { -// // return Err(Error::UnexpectedError( -// // "unexpected error when contribute since finding a bad request.".to_string(), -// // )) -// // } -// // Err(CeremonyError::NotYourTurn) => { -// // println!( -// // "{} Lag behind server. Contacting Server again...", -// // style("[8/9]").bold().dim(), -// // ); -// // continue; -// // } -// // Err(CeremonyError::AlreadyContributed) => return Err(Error::AlreadyContributed), -// // Ok(_) => { -// // term.clear_last_lines(1) -// // .expect("Clear last lines should succeed."); -// // println!( -// // "{} Waiting for Confirmation from Server...", -// // style("[8/9]").bold().dim(), -// // ); -// // println!( -// // "{} Congratulations! You have successfully contributed to Manta Trusted Setup Ceremony!...", -// // style("[9/9]").bold().dim(), -// // ); -// // break; -// // } -// // } -// // } -// Ok(()) -// } +/// Contributes to the server. +#[inline] +pub async fn client_contribute() -> Result<(), CeremonyError> +where + C: Ceremony, + C::Challenge: DeserializeOwned, + C::Identifier: Serialize, + C::Nonce: Clone + Debug + DeserializeOwned + Serialize, + C::Signature: Serialize, +{ + let network_client = KnownUrlClient::new("http://localhost:8080").expect("Should succeed."); + let (sk, pk) = get_client_keys()?; + println!( + "{} Contacting Server for Meta Data...", + style("[1/9]").bold().dim() + ); + let term = Term::stdout(); + let (size, nonce) = get_start_meta_data::(pk, &network_client).await?; + let mut trusted_setup_client = Client::::new(pk, nonce, sk); + println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); + loop { + let mpc_state = match network_client + .post::<_, Result, CeremonyError>>( + "query", + &trusted_setup_client.query().map_err(|_| { + CeremonyError::UnableToGenerateRequest("Queries the server state.".to_string()) + })?, + ) + .await + .map_err(|_| { + return CeremonyError::Network( + "Should have received starting meta data from server".to_string(), + ); + })? { + Ok(message) => match message { + QueryResponse::QueuePosition(position) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!( + "{} Waiting in Queue... There are {} people ahead of you. Estimated Waiting Time: {} minutes.", + style("[2/9]").bold().dim(), + style(position).bold().red(), + style(5*position).bold().blue(), + ); + thread::sleep(Duration::from_secs(10)); + continue; + } + QueryResponse::Mpc(mpc_state) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); + println!( + "{} Downloading Ceremony States...", + style("[3/9]").bold().dim(), + ); + if !size.matches(&mpc_state.state) { + return Err(CeremonyError::Unexpected( + "Received mpc state size is not correct.".to_string(), + )); + } + mpc_state + } + }, + Err(CeremonyError::Timeout) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!( + "{} You have timed out. Waiting in Queue again...", + style("[2/9]").bold().dim(), + ); + continue; + } + Err(CeremonyError::NotYourTurn) => { + return Err(CeremonyError::Unexpected( + "Unexpected error when query mpc state. Should not receive NotYourTurn message." + .to_string(), + )); + } + Err(err) => return Err(err), + }; + println!( + "{} Starting contribution to 3 Circuits...", + style("[4/9]").bold().dim(), + ); + match network_client + .post::<_, Result<(), CeremonyError>>( + "update", + &trusted_setup_client + .contribute(&C::Hasher::default(), &mpc_state.challenge, mpc_state.state) + .map_err(|_| { + CeremonyError::UnableToGenerateRequest("contribute".to_string()) + })?, + ) + .await + .map_err(|_| { + return CeremonyError::Network( + "Should have received starting meta data from server".to_string(), + ); + })? { + Ok(_) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!( + "{} Waiting for Confirmation from Server...", + style("[8/9]").bold().dim(), + ); + println!( + "{} Congratulations! You have successfully contributed to Manta Trusted Setup Ceremony!...", + style("[9/9]").bold().dim(), + ); + break; + } + Err(CeremonyError::Timeout) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!( + "{} You have timed out. Waiting in Queue again...", + style("[2/9]").bold().dim(), + ); + continue; + } + Err(CeremonyError::NotRegistered) => { + return Err(CeremonyError::Unexpected( + "unexpected error when contribute. Should have registered.".to_string(), + )) + } + Err(CeremonyError::NotYourTurn) => { + println!( + "{} Lag behind server. Contacting Server again...", + style("[8/9]").bold().dim(), + ); + continue; + } + Err(err) => return Err(err), + } + } + Ok(()) +} + +/// Testing Suite +#[cfg(test)] +mod test { + use super::*; + + /// Tests if register is visually correct. + #[test] + fn register_is_visually_correct() { + register( + "Mantalorian".to_string(), + "mantalorian@manta.network".to_string(), + ); + } +} diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 22bc7e7e5..f971f8af1 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -130,6 +130,9 @@ where /// Timed-out Timeout, + /// Client unable to Generate Request + UnableToGenerateRequest(String), + /// Unexpected Server Error Unexpected(String), From c573a4c364cf94657ddc966f6358f5357790400c Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Fri, 9 Sep 2022 23:26:16 -0400 Subject: [PATCH 23/60] chore: fix clippy errors Signed-off-by: Brandon H. Gomes --- .../src/groth16/ceremony/client.rs | 12 +++++----- .../src/groth16/ceremony/signature.rs | 2 +- manta-trusted-setup/src/groth16/mpc.rs | 24 +++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index 301a7e50e..be760225a 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -227,9 +227,9 @@ where ) .await .map_err(|_| { - return CeremonyError::Network( + CeremonyError::Network( "Should have received starting meta data from server".to_string(), - ); + ) })? { Ok((server_size, nonce)) => Ok((server_size, nonce)), Err(CeremonyError::NotRegistered) => Err(CeremonyError::NotRegistered), @@ -267,9 +267,9 @@ where ) .await .map_err(|_| { - return CeremonyError::Network( + CeremonyError::Network( "Should have received starting meta data from server".to_string(), - ); + ) })? { Ok(message) => match message { QueryResponse::QueuePosition(position) => { @@ -332,9 +332,9 @@ where ) .await .map_err(|_| { - return CeremonyError::Network( + CeremonyError::Network( "Should have received starting meta data from server".to_string(), - ); + ) })? { Ok(_) => { term.clear_last_lines(1) diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index 8ef878722..571d3fab5 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -18,7 +18,7 @@ use alloc::vec::Vec; use manta_crypto::{ - dalek::ed25519::{Ed25519, SignatureError, self}, + dalek::ed25519::{self, Ed25519, SignatureError}, signature, }; use manta_util::{serde::Serialize, AsBytes}; diff --git a/manta-trusted-setup/src/groth16/mpc.rs b/manta-trusted-setup/src/groth16/mpc.rs index 9fef08df5..ed2b3f3a6 100644 --- a/manta-trusted-setup/src/groth16/mpc.rs +++ b/manta-trusted-setup/src/groth16/mpc.rs @@ -41,13 +41,13 @@ use { }; /// MPC State -#[derive(Serialize, Deserialize, derivative::Derivative)] -#[derivative(Clone(bound = ""))] -#[serde( - bound(serialize = "", deserialize = ""), - crate = "manta_util::serde", - deny_unknown_fields +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde(crate = "manta_util::serde", deny_unknown_fields) )] +#[derive(derivative::Derivative)] +#[derivative(Clone(bound = ""))] pub struct State

( #[cfg_attr( feature = "serde", @@ -62,13 +62,13 @@ where P: Pairing + ?Sized; /// MPC Proof -#[derive(Serialize, Deserialize, derivative::Derivative)] -#[derivative(Clone(bound = ""))] -#[serde( - bound(serialize = "", deserialize = "",), - crate = "manta_util::serde", - deny_unknown_fields +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde(crate = "manta_util::serde", deny_unknown_fields) )] +#[derive(derivative::Derivative)] +#[derivative(Clone(bound = ""))] pub struct Proof

( #[cfg_attr( feature = "serde", From 42fe5a3e1a5bef3218842162a36d1360c88bdc5f Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Fri, 9 Sep 2022 23:31:07 -0400 Subject: [PATCH 24/60] chore: fix docs Signed-off-by: Brandon H. Gomes --- manta-crypto/src/dalek/ed25519.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index 2bb811d28..95fe7d4ec 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -92,7 +92,7 @@ where } } -/// Generates a [`KeyPair`] from `bytes`. +/// Generates a [`Keypair`] from `bytes`. #[inline] pub fn generate_keys(bytes: &[u8]) -> Option { if SECRET_KEY_LENGTH > bytes.len() { From 3ba388c54c6aec0812570f5bd1b46f4ce8c1fb79 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Fri, 9 Sep 2022 23:48:01 -0400 Subject: [PATCH 25/60] chore: move AsBytes into macro Signed-off-by: Brandon H. Gomes --- manta-util/src/bytes.rs | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/manta-util/src/bytes.rs b/manta-util/src/bytes.rs index 9157fdf31..021724bb4 100644 --- a/manta-util/src/bytes.rs +++ b/manta-util/src/bytes.rs @@ -51,8 +51,16 @@ pub trait Bytes: FromBytes + IntoBytes {} impl Bytes for B where B: FromBytes + IntoBytes {} -/// Implements [`Bytes`] for the primitive `$type` of a given `$size` using `from_le_bytes` and -/// `to_le_bytes` for little-endian conversion. +/// Byte Vector Conversion +#[cfg(feature = "alloc")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] +pub trait AsBytes { + /// Returns an owned byte representation of `self`. + fn as_bytes(&self) -> Vec; +} + +/// Implements [`Bytes`] and [`AsBytes`] for the primitive `$type` of a given `$size` using +/// `from_le_bytes` and `to_le_bytes` for little-endian conversion. macro_rules! impl_bytes_primitive { ($type:tt, $size:expr) => { impl FromBytes<$size> for $type { @@ -68,6 +76,15 @@ macro_rules! impl_bytes_primitive { self.to_le_bytes() } } + + #[cfg(feature = "alloc")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] + impl AsBytes for $type { + #[inline] + fn as_bytes(&self) -> Vec { + self.to_le_bytes().to_vec() + } + } }; ($($type:tt),* $(,)?) => { $(impl_bytes_primitive!($type, { ($type::BITS / 8) as usize });)* @@ -98,18 +115,3 @@ impl IntoBytes for [u8; N] { self } } - -/// Byte Vector Conversion -#[cfg(feature = "alloc")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] -pub trait AsBytes { - /// Returns an owned byte representation of `self`. - fn as_bytes(&self) -> Vec; -} - -impl AsBytes for u64 { - #[inline] - fn as_bytes(&self) -> Vec { - self.to_le_bytes().to_vec() - } -} From f1b18308e347225f27e646b1a456d824ce964b90 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 20:50:57 -0700 Subject: [PATCH 26/60] chore: fix issues --- .../src/groth16/ceremony/participant.rs | 12 ++++----- .../src/groth16/ceremony/server.rs | 26 ++++++++++--------- .../src/groth16/ceremony/signature.rs | 4 +-- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/participant.rs b/manta-trusted-setup/src/groth16/ceremony/participant.rs index 0f244aafd..8e0180af1 100644 --- a/manta-trusted-setup/src/groth16/ceremony/participant.rs +++ b/manta-trusted-setup/src/groth16/ceremony/participant.rs @@ -50,7 +50,7 @@ impl From for usize { /// Participant pub struct Participant where - S: SignatureScheme, + S: SignatureScheme, { /// Verifying Key verifying_key: S::VerifyingKey, @@ -70,7 +70,7 @@ where impl ceremony::Participant for Participant where - S: SignatureScheme, + S: SignatureScheme, { type Identifier = S::VerifyingKey; type VerifyingKey = S::VerifyingKey; @@ -109,7 +109,7 @@ where #[inline] fn nonce(&self) -> Self::Nonce { - self.nonce + self.nonce.clone() } #[inline] @@ -120,7 +120,7 @@ where impl Participant where - S: SignatureScheme, + S: SignatureScheme, { /// Builds a new [`Participant`]. #[inline] @@ -142,7 +142,7 @@ where /// Gets `twitter`. #[inline] - pub fn twitter(&self) -> String { - self.twitter.clone() + pub fn twitter(&self) -> &str { + &self.twitter } } diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 8946e9c49..16f919038 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -41,7 +41,7 @@ use manta_util::{ use parking_lot::Mutex; use std::{ fs::{File, OpenOptions}, - path::Path, + path::{Path, PathBuf}, }; /// Server @@ -54,7 +54,7 @@ where coordinator: Arc>>, /// Recovery directory path - recovery_path: String, + recovery_directory: PathBuf, } impl @@ -63,19 +63,19 @@ where C: Ceremony, R: Registry, { - /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a `recovery_path`. + /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a `recovery_directory`. #[inline] pub fn new( state: BoxArray, CIRCUIT_COUNT>, challenge: BoxArray, registry: R, - recovery_path: String, + recovery_directory: PathBuf, size: BoxArray, ) -> Self { let coordinator = Coordinator::new(registry, state, challenge, size); Self { coordinator: Arc::new(Mutex::new(coordinator)), - recovery_path, + recovery_directory, } } @@ -133,7 +133,8 @@ where coordinator.update(&request.identifier, message.state, message.proof)?; serialize_into_file( OpenOptions::new().write(true).create_new(true), - &Path::new(&self.recovery_path).join(format!("transcript{}.data", coordinator.round())), + &Path::new(&self.recovery_directory) + .join(format!("transcript{}.data", coordinator.round())), &coordinator.deref(), ) .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?; @@ -142,23 +143,24 @@ where } } -/// Recovers from a disk file at `recovery` and use `recovery_path` as the backup directory. +/// Recovers from a disk file at `path` and use `recovery_directory` as the backup directory. #[inline] -pub fn recover( - recovery: String, - recovery_path: String, +pub fn recover( + path: P, + recovery_directory: PathBuf, ) -> Result, CeremonyError> where C: Ceremony, + P: AsRef, R: Registry, Coordinator: DeserializeOwned, { Ok(Server { coordinator: Arc::new(Mutex::new( - deserialize_from_file(recovery) + deserialize_from_file(path) .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?, )), - recovery_path, + recovery_directory, }) } diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index 571d3fab5..70a13164e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -82,7 +82,7 @@ pub trait SignatureScheme: + signature::Verify> { /// Message Nonce - type Nonce: Nonce; + type Nonce: Nonce + Clone; /// Verification Error Type type Error; @@ -157,7 +157,7 @@ where impl SignatureScheme for Ed25519> where - N: AsBytes + Default + Nonce, + N: AsBytes + Default + Nonce + Clone, { type Nonce = N; type Error = SignatureError; From 3bb877c083dbfc9cae82f2b476db8b99da8f4172 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 21:51:28 -0700 Subject: [PATCH 27/60] chore: fix issues --- manta-crypto/src/dalek/ed25519.rs | 13 +-- .../src/groth16/ceremony/client.rs | 57 +++++----- .../src/groth16/ceremony/message.rs | 9 +- .../src/groth16/ceremony/server.rs | 104 +++++++++++------- 4 files changed, 102 insertions(+), 81 deletions(-) diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index 95fe7d4ec..8cc457926 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -26,6 +26,8 @@ use core::{convert::TryInto, marker::PhantomData}; use manta_util::AsBytes; pub use ed25519_dalek::*; +use rand_chacha::ChaCha20Rng; +use rand_core::SeedableRng; /// Implements byte conversion from an array of bytes of length `$len` into the given `$type`. macro_rules! byte_conversion { @@ -95,17 +97,14 @@ where /// Generates a [`Keypair`] from `bytes`. #[inline] pub fn generate_keys(bytes: &[u8]) -> Option { - if SECRET_KEY_LENGTH > bytes.len() { + if SECRET_KEY_LENGTH <= bytes.len() { return None; } - let sk = match bytes[0..SECRET_KEY_LENGTH].try_into() { - Ok(bytes) => secret_key_from_bytes(bytes), + let mut rng = match bytes[0..SECRET_KEY_LENGTH].try_into() { + Ok(seed) => ChaCha20Rng::from_seed(seed), Err(_) => return None, }; - Some(Keypair { - public: (&sk).into(), - secret: sk, - }) + Some(generate_keypair(&mut rng)) } /// Edwards Curve Signature Scheme for the `Curve25519` Elliptic Curve diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index be760225a..74de9a227 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -81,7 +81,12 @@ where &self.nonce, &self.signing_key, self.identifier.clone(), - )?; + ) + .map_err(|_| { + CeremonyError::Unexpected( + "Cannot sign message since it cannot be serialized.".to_string(), + ) + })?; self.nonce.increment(); Ok(signed_message) } @@ -106,10 +111,10 @@ where style(format!("[{}/9]", i + 5)).bold().dim(), circuit_name[i], ); - match contribute(hasher, &challenge[i], &mut state[i], &mut rng) { - Some(proof) => proofs.push(proof), - None => return Err(CeremonyError::Unexpected("Cannot contribute.".to_string())), - } + proofs.push( + contribute(hasher, &challenge[i], &mut state[i], &mut rng) + .ok_or(CeremonyError::Unexpected("Cannot contribute.".to_string()))?, + ); } println!( "{} Waiting for Confirmation from Server... Estimated Waiting Time: {} minutes.", @@ -124,9 +129,14 @@ where &self.nonce, &self.signing_key, self.identifier.clone(), - ); + ) + .map_err(|_| { + CeremonyError::Unexpected( + "Cannot sign message since it cannot be serialized.".to_string(), + ) + })?; self.nonce.increment(); - signed_message + Ok(signed_message) } } @@ -202,12 +212,11 @@ where ) .as_bytes() .to_vec(); - match C::generate_keys(&seed_bytes) { - Some(key_pair) => Ok(key_pair), - None => Err(CeremonyError::Unexpected( + Ok( + C::generate_keys(&seed_bytes).ok_or(CeremonyError::Unexpected( "Cannot generate keys.".to_string(), - )), - } + ))?, + ) } /// Gets state size from server. @@ -221,7 +230,7 @@ where C::Identifier: Serialize, C::Nonce: DeserializeOwned + Debug, { - match network_client + network_client .post::<_, Result<(CeremonySize, C::Nonce), CeremonyError>>( "start", &identity, ) @@ -229,12 +238,8 @@ where .map_err(|_| { CeremonyError::Network( "Should have received starting meta data from server".to_string(), - ) - })? { - Ok((server_size, nonce)) => Ok((server_size, nonce)), - Err(CeremonyError::NotRegistered) => Err(CeremonyError::NotRegistered), - Err(e) => Err(CeremonyError::Unexpected(format!("{:?}", e))), - } + ); + })? } /// Contributes to the server. @@ -261,9 +266,7 @@ where let mpc_state = match network_client .post::<_, Result, CeremonyError>>( "query", - &trusted_setup_client.query().map_err(|_| { - CeremonyError::UnableToGenerateRequest("Queries the server state.".to_string()) - })?, + &trusted_setup_client.query()?, ) .await .map_err(|_| { @@ -324,11 +327,11 @@ where match network_client .post::<_, Result<(), CeremonyError>>( "update", - &trusted_setup_client - .contribute(&C::Hasher::default(), &mpc_state.challenge, mpc_state.state) - .map_err(|_| { - CeremonyError::UnableToGenerateRequest("contribute".to_string()) - })?, + &trusted_setup_client.contribute( + &C::Hasher::default(), + &mpc_state.challenge, + mpc_state.state, + )?, ) .await .map_err(|_| { diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 095aec431..31b654151 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -17,7 +17,7 @@ //! Messages through Network use crate::groth16::{ - ceremony::{signature::sign, Ceremony, CeremonyError}, + ceremony::{signature::sign, Ceremony}, mpc::{Proof, State, StateSize}, }; use manta_crypto::arkworks::pairing::Pairing; @@ -157,15 +157,12 @@ where nonce: &C::Nonce, signing_key: &C::SigningKey, identifier: C::Identifier, - ) -> Result> + ) -> Result where T: Serialize, C::Nonce: Clone, { - let signature = match sign::<_, C>(signing_key, nonce.clone(), &message) { - Ok(signature) => signature, - Err(_) => return Err(CeremonyError::::BadRequest), - }; + let signature = sign::<_, C>(signing_key, nonce.clone(), &message)?; let message = Signed { message, nonce: nonce.clone(), diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 16f919038..82ab64588 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -164,57 +164,79 @@ where }) } -/// Loads registry from a disk file at `registry`. +/// Prases a string `record` into a pair of `(C::Identifier, C::Participant)`. #[inline] -pub fn load_registry(registry_file: P) -> R +pub fn parse( + record: csv::StringRecord, +) -> Result<(C::VerifyingKey, C::Participant), CeremonyError> where C: Ceremony, VerifyingKey = ed25519::PublicKey>, - P: AsRef, - R: Registry, { - let mut registry = R::new(); - for record in - csv::Reader::from_reader(File::open(registry_file).expect("Registry file should exist.")) - .records() - { - let result = record.expect("Read csv should succeed."); - let twitter = result[0].to_string(); - let email = result[1].to_string(); - let verifying_key: ed25519::PublicKey = ed25519::public_key_from_bytes( - bs58::decode(result[3].to_string()) - .into_vec() - .expect("Should convert into a vector") - .try_into() - .expect("Should give an array"), - ); - let signature: ed25519::Signature = ed25519::signature_from_bytes( - bs58::decode(result[4].to_string()) - .into_vec() - .expect("Should convert into a vector") - .try_into() - .expect("Should give an array"), - ); - verify::<_, Ed25519>>( - &verifying_key, - 0, - &format!( - "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", - twitter, email - ), - &signature, - ) - .expect("Should verify the signature."); - let participant: Participant = Participant::new( + if record.len() != 5 { + return Err(CeremonyError::Unexpected( + "Record format is wrong.".to_string(), + )); + } + let twitter = record[0].to_string(); + let email = record[1].to_string(); + let verifying_key = ed25519::public_key_from_bytes( + bs58::decode(record[3].to_string()) + .into_vec() + .map_err(|_| CeremonyError::Unexpected("Cannot decode verifying key.".to_string()))? + .try_into() + .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, + ); + let signature: ed25519::Signature = ed25519::signature_from_bytes( + bs58::decode(record[4].to_string()) + .into_vec() + .map_err(|_| CeremonyError::Unexpected("Cannot decode signature.".to_string()))? + .try_into() + .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, + ); + verify::<_, Ed25519>>( + &verifying_key, + 0, + &format!( + "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", + twitter, email + ), + &signature, + ) + .map_err(|_| CeremonyError::Unexpected("Cannot verify signature.".to_string()))?; + Ok(( + verifying_key, + Participant::new( verifying_key, twitter, - match result[2].to_string().parse::().unwrap() { + match record[2].to_string().parse::().unwrap() { true => Priority::High, false => Priority::Normal, }, OsRng.gen::<_, u16>() as u64, false, - ); - registry.register(verifying_key, participant); + ), + )) +} + +/// Loads registry from a disk file at `registry`. +#[inline] +pub fn load_registry(registry_file: P) -> Result> +where + C: Ceremony, VerifyingKey = ed25519::PublicKey>, + P: AsRef, + R: Registry, +{ + let mut registry = R::new(); + for record in csv::Reader::from_reader( + File::open(registry_file) + .map_err(|_| CeremonyError::Unexpected("Cannot open registry file.".to_string()))?, + ) + .records() + { + let (identifier, participant) = parse(record.map_err(|_| { + CeremonyError::Unexpected("Cannot parse record from csv.".to_string()) + })?)?; + registry.register(identifier, participant); } - registry + Ok(registry) } From 6db0b03e229fd72e50af9d48185812904f4cbae2 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 21:58:07 -0700 Subject: [PATCH 28/60] chore: changelog --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85039811c..f5577a4ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,14 +5,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] ### Added +- [\#238](https://github.com/Manta-Network/manta-rs/pull/238) Add trusted setup ceremony primitives for server and client - [\#237](https://github.com/Manta-Network/manta-rs/pull/237) Public input fuzzing tests for transfer protocol - [\#215](https://github.com/Manta-Network/manta-rs/pull/215) Add windowed multiplication algorithm for groups - [\#213](https://github.com/Manta-Network/manta-rs/pull/197) Add Ceremony Utilities - [\#206](https://github.com/Manta-Network/manta-rs/pull/206) Move Poseidon sage script to test the hardcoded round constant values -- [\#172](https://github.com/Manta-Network/manta-rs/pull/172) Add abstract Phase 2 for Groth16 trusted setup -- [\#193](https://github.com/Manta-Network/manta-rs/pull/193) Add Bn254 curve backend for Groth16 trusted setup -- [\#196](https://github.com/Manta-Network/manta-rs/pull/172) Add fixed base scalar multiplication using precomputed bases - [\#197](https://github.com/Manta-Network/manta-rs/pull/197) Add ECLAIR utilities for next circuit upgrade +- [\#196](https://github.com/Manta-Network/manta-rs/pull/172) Add fixed base scalar multiplication using precomputed bases +- [\#193](https://github.com/Manta-Network/manta-rs/pull/193) Add Bn254 curve backend for Groth16 trusted setup +- [\#172](https://github.com/Manta-Network/manta-rs/pull/172) Add abstract Phase 2 for Groth16 trusted setup ### Changed - [\#247](https://github.com/Manta-Network/manta-rs/pull/247) Moved BLS12-381 and BN254 curves (and Edwards counterparts) to `manta-crypto` From 6f8fd41abe656f8f4bc946060b59afed0c48123a Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 22:00:13 -0700 Subject: [PATCH 29/60] chore: fix a typo --- manta-trusted-setup/src/groth16/ceremony/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index 74de9a227..772c7f25f 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -238,7 +238,7 @@ where .map_err(|_| { CeremonyError::Network( "Should have received starting meta data from server".to_string(), - ); + ) })? } From f26b97871e36407e9fc1c7038f449e5a10fa5cea Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 22:46:41 -0700 Subject: [PATCH 30/60] chore: fix ci issue --- manta-crypto/src/dalek/ed25519.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index 8cc457926..236ea2491 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -22,12 +22,14 @@ use crate::{ MessageType, RandomnessType, Sign, SignatureType, SigningKeyType, Verify, VerifyingKeyType, }, }; -use core::{convert::TryInto, marker::PhantomData}; +use core::marker::PhantomData; use manta_util::AsBytes; +#[cfg(feature = "rand_chacha")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "rand_chacha")))] +use {core::convert::TryInto, rand_core::SeedableRng}; + pub use ed25519_dalek::*; -use rand_chacha::ChaCha20Rng; -use rand_core::SeedableRng; /// Implements byte conversion from an array of bytes of length `$len` into the given `$type`. macro_rules! byte_conversion { @@ -95,13 +97,15 @@ where } /// Generates a [`Keypair`] from `bytes`. +#[cfg(feature = "rand_chacha")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "rand_chacha")))] #[inline] pub fn generate_keys(bytes: &[u8]) -> Option { if SECRET_KEY_LENGTH <= bytes.len() { return None; } let mut rng = match bytes[0..SECRET_KEY_LENGTH].try_into() { - Ok(seed) => ChaCha20Rng::from_seed(seed), + Ok(seed) => rand_chacha::ChaCha20Rng::from_seed(seed), Err(_) => return None, }; Some(generate_keypair(&mut rng)) From 023aff3216e6ff82dbea0e8cf9460b826423be17 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 23:05:02 -0700 Subject: [PATCH 31/60] chore: fix a ci issue --- manta-trusted-setup/src/groth16/ceremony/util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/manta-trusted-setup/src/groth16/ceremony/util.rs b/manta-trusted-setup/src/groth16/ceremony/util.rs index 4e8e26f28..931682017 100644 --- a/manta-trusted-setup/src/groth16/ceremony/util.rs +++ b/manta-trusted-setup/src/groth16/ceremony/util.rs @@ -78,6 +78,7 @@ mod test { /// Tests if logging and loading data is correct. #[test] + #[ignore] fn log_load_file_is_correct() { let data = "Testing data".to_string(); serialize_into_file( From b388f2239ef969546205d4c011907f634ac034bc Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 9 Sep 2022 23:13:37 -0700 Subject: [PATCH 32/60] chore: typo --- manta-crypto/src/dalek/ed25519.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index 236ea2491..94cd8d35c 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -101,7 +101,7 @@ where #[cfg_attr(doc_cfg, doc(cfg(feature = "rand_chacha")))] #[inline] pub fn generate_keys(bytes: &[u8]) -> Option { - if SECRET_KEY_LENGTH <= bytes.len() { + if SECRET_KEY_LENGTH > bytes.len() { return None; } let mut rng = match bytes[0..SECRET_KEY_LENGTH].try_into() { From e3f020cca29f04647d761f1aedcab27ce6acc594 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Sun, 11 Sep 2022 13:32:10 -0400 Subject: [PATCH 33/60] chore: clean up signature abstraction layers Signed-off-by: Brandon H. Gomes --- manta-crypto/src/dalek/ed25519.rs | 19 ----------- .../src/groth16/ceremony/client.rs | 33 +++++++++---------- .../src/groth16/ceremony/signature.rs | 13 ++++---- 3 files changed, 22 insertions(+), 43 deletions(-) diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index 94cd8d35c..25dd931cc 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -25,10 +25,6 @@ use crate::{ use core::marker::PhantomData; use manta_util::AsBytes; -#[cfg(feature = "rand_chacha")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "rand_chacha")))] -use {core::convert::TryInto, rand_core::SeedableRng}; - pub use ed25519_dalek::*; /// Implements byte conversion from an array of bytes of length `$len` into the given `$type`. @@ -96,21 +92,6 @@ where } } -/// Generates a [`Keypair`] from `bytes`. -#[cfg(feature = "rand_chacha")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "rand_chacha")))] -#[inline] -pub fn generate_keys(bytes: &[u8]) -> Option { - if SECRET_KEY_LENGTH > bytes.len() { - return None; - } - let mut rng = match bytes[0..SECRET_KEY_LENGTH].try_into() { - Ok(seed) => rand_chacha::ChaCha20Rng::from_seed(seed), - Err(_) => return None, - }; - Some(generate_keypair(&mut rng)) -} - /// Edwards Curve Signature Scheme for the `Curve25519` Elliptic Curve #[derive(derivative::Derivative)] #[derivative(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index 772c7f25f..b59ea51b7 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -19,7 +19,7 @@ use crate::groth16::{ ceremony::{ message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse, Signed}, - signature::{sign, Message, Nonce}, + signature::{sign, Nonce}, Ceremony, CeremonyError, }, mpc::{contribute, State}, @@ -29,10 +29,7 @@ use colored::Colorize; use console::{style, Term}; use core::fmt::Debug; use dialoguer::{theme::ColorfulTheme, Input}; -use manta_crypto::{ - dalek::ed25519::{self, generate_keys, Ed25519}, - rand::OsRng, -}; +use manta_crypto::{dalek::ed25519, rand::OsRng}; use manta_util::{ http::reqwest::KnownUrlClient, serde::{de::DeserializeOwned, Serialize}, @@ -113,7 +110,7 @@ where ); proofs.push( contribute(hasher, &challenge[i], &mut state[i], &mut rng) - .ok_or(CeremonyError::Unexpected("Cannot contribute.".to_string()))?, + .ok_or_else(|| CeremonyError::Unexpected("Cannot contribute.".to_string()))?, ); } println!( @@ -142,7 +139,12 @@ where /// Registers a participant. #[inline] -pub fn register(twitter_account: String, email: String) { +pub fn register(twitter_account: String, email: String) +where + C: Ceremony, + C::VerifyingKey: AsRef<[u8]>, + C::Signature: AsRef<[u8]>, +{ println!( "Your {}: \nCopy the following text to \"Twitter\" Section in Google Sheet:\n {}\n", "Twitter Account".italic(), @@ -155,15 +157,15 @@ pub fn register(twitter_account: String, email: String) { ); let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); let seed = Seed::new(&mnemonic, "manta-trusted-setup"); - let key_pair = generate_keys(seed.as_bytes()).expect("Should generate a key pair."); + let keypair = C::generate_keys(seed.as_bytes()).expect("Should generate a key pair."); println!( "Your {}: \nCopy the following text to \"Public Key\" Section in Google Sheet:\n {}\n", "Public Key".italic(), - bs58::encode(key_pair.public).into_string().blue(), + bs58::encode(keypair.1).into_string().blue(), ); - let signature = sign::<_, Ed25519>>( - &key_pair.secret, - 0, + let signature = sign::<_, C>( + &keypair.0, + Default::default(), &format!( "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", twitter_account, email @@ -212,11 +214,8 @@ where ) .as_bytes() .to_vec(); - Ok( - C::generate_keys(&seed_bytes).ok_or(CeremonyError::Unexpected( - "Cannot generate keys.".to_string(), - ))?, - ) + C::generate_keys(&seed_bytes) + .ok_or_else(|| CeremonyError::Unexpected("Cannot generate keys.".to_string())) } /// Gets state size from server. diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index 70a13164e..9cc68b0ba 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -18,13 +18,14 @@ use alloc::vec::Vec; use manta_crypto::{ - dalek::ed25519::{self, Ed25519, SignatureError}, + dalek::ed25519::{generate_keypair, Ed25519, SignatureError}, + rand::{ChaCha20Rng, SeedableRng}, signature, }; use manta_util::{serde::Serialize, AsBytes}; /// Nonce -pub trait Nonce: PartialEq { +pub trait Nonce: Default + PartialEq { /// Increments the current nonce by one. fn increment(&mut self); @@ -87,7 +88,7 @@ pub trait SignatureScheme: /// Verification Error Type type Error; - /// Generates key pair from `bytes`. + /// Generates a keypair from `bytes` returning `None` if `bytes` was not the right format. fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)>; } @@ -164,9 +165,7 @@ where #[inline] fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)> { - match ed25519::generate_keys(bytes) { - Some(key_pair) => Some((key_pair.secret, key_pair.public)), - None => None, - } + let keypair = generate_keypair(&mut ChaCha20Rng::from_seed(bytes.try_into().ok()?)); + Some((keypair.secret, keypair.public)) } } From 0b4fda7956ff2450d918565110568a9dd66ddaf4 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Sun, 11 Sep 2022 14:08:31 -0400 Subject: [PATCH 34/60] chore: start restructuring signature/message schemes Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/Cargo.toml | 5 +- manta-trusted-setup/src/ceremony/mod.rs | 25 ++++ .../src/ceremony/participant.rs | 59 ++++++++ .../src/ceremony/registry/csv.rs | 66 +++++++++ .../src/ceremony/registry/mod.rs | 37 +++++ manta-trusted-setup/src/ceremony/signature.rs | 69 ++++++++++ .../src/{groth16 => }/ceremony/util.rs | 27 +--- .../src/groth16/ceremony/client.rs | 15 +- .../src/groth16/ceremony/coordinator.rs | 19 +-- .../src/groth16/ceremony/message.rs | 66 +-------- .../src/groth16/ceremony/mod.rs | 7 +- .../src/groth16/ceremony/participant.rs | 6 +- .../src/groth16/ceremony/registry.rs | 4 +- .../src/groth16/ceremony/server.rs | 21 +-- .../src/groth16/ceremony/signature.rs | 128 ++++++++++-------- manta-trusted-setup/src/lib.rs | 1 + 16 files changed, 377 insertions(+), 178 deletions(-) create mode 100644 manta-trusted-setup/src/ceremony/mod.rs create mode 100644 manta-trusted-setup/src/ceremony/participant.rs create mode 100644 manta-trusted-setup/src/ceremony/registry/csv.rs create mode 100644 manta-trusted-setup/src/ceremony/registry/mod.rs create mode 100644 manta-trusted-setup/src/ceremony/signature.rs rename manta-trusted-setup/src/{groth16 => }/ceremony/util.rs (62%) diff --git a/manta-trusted-setup/Cargo.toml b/manta-trusted-setup/Cargo.toml index 26da1c066..8c9f4f0de 100644 --- a/manta-trusted-setup/Cargo.toml +++ b/manta-trusted-setup/Cargo.toml @@ -25,6 +25,9 @@ is-it-maintained-open-issues = { repository = "Manta-Network/manta-rs" } maintenance = { status = "actively-developed" } [features] +# CSV for Ceremony Registries +csv = ["dep:csv", "serde", "std"] + # Perpetual Powers of Tau Ceremony ppot = ["manta-crypto/ark-bn254"] @@ -54,7 +57,7 @@ blake2 = { version = "0.10.4", default-features = false } bs58 = { version = "0.4", default-features = false, features = ["alloc"] } colored = { version = "2.0.0", default-features = false } console = { version = "0.15.1", default-features = false } -csv = { version = "1.1", default-features = false } +csv = { version = "1.1.6", optional = true, default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } dialoguer = { version = "0.10.2", default-features = false } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["arkworks", "getrandom", "rand_chacha", "dalek"] } diff --git a/manta-trusted-setup/src/ceremony/mod.rs b/manta-trusted-setup/src/ceremony/mod.rs new file mode 100644 index 000000000..088a6688b --- /dev/null +++ b/manta-trusted-setup/src/ceremony/mod.rs @@ -0,0 +1,25 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Trusted Setup Ceremonies + +pub mod participant; +pub mod registry; +pub mod signature; + +#[cfg(feature = "std")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] +pub mod util; diff --git a/manta-trusted-setup/src/ceremony/participant.rs b/manta-trusted-setup/src/ceremony/participant.rs new file mode 100644 index 000000000..f5956f7da --- /dev/null +++ b/manta-trusted-setup/src/ceremony/participant.rs @@ -0,0 +1,59 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Trusted Setup Ceremony Participants + +/// Participant +pub trait Participant { + /// Identifier Type + type Identifier; + + /// Verifying Key Type + type VerifyingKey; + + /// Nonce Type + type Nonce; + + /// Returns the [`Identifier`](Self::Identifier) for `self`. + fn id(&self) -> &Self::Identifier; + + /// Returns the [`VerifyingKey`](Self::VerifyingKey) for `self`. + fn verifying_key(&self) -> &Self::VerifyingKey; + + /// Checks if the participant has contributed. + fn has_contributed(&self) -> bool; + + /// Sets contributed. + fn set_contributed(&mut self); + + /// Returns the current nonce for `self`. + fn nonce(&self) -> Self::Nonce; + + /// Increments the current nonce of `self` by one. + fn increment_nonce(&mut self); +} + +/// Priority +pub trait Priority { + /// Priority Type + type Priority; + + /// Returns the priority level for `self`. + fn priority(&self) -> Self::Priority; + + /// Reduces the priority. + fn reduce_priority(&mut self); +} diff --git a/manta-trusted-setup/src/ceremony/registry/csv.rs b/manta-trusted-setup/src/ceremony/registry/csv.rs new file mode 100644 index 000000000..ffa2d2ee7 --- /dev/null +++ b/manta-trusted-setup/src/ceremony/registry/csv.rs @@ -0,0 +1,66 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Trusted Setup Ceremony Registry CSV Compatibility + +use crate::ceremony::registry::Registry; +use manta_util::serde::de::DeserializeOwned; +use std::{fs::File, path::Path}; + +/// CSV Record +pub trait Record: DeserializeOwned { + /// Error Type + type Error; + + /// Parses a registry entry of type `(I, V)` from `self`. + fn parse(self) -> Result<(I, V), Self::Error>; +} + +/// Record Error +#[derive(Debug)] +pub enum Error { + /// Parsing Error + Parse(E), + + /// CSV Reading Error + Csv(csv::Error), +} + +impl From for Error +where + T: Into, +{ + #[inline] + fn from(err: T) -> Self { + Self::Csv(err.into()) + } +} + +/// Loads a registry of type `R` from `path` using `T` as the record type. +#[inline] +pub fn load(path: P) -> Result> +where + T: Record, + R: Registry, + P: AsRef, +{ + let mut registry = R::new(); + for record in csv::Reader::from_reader(File::open(path)?).deserialize() { + let (identifier, participant) = T::parse(record?).map_err(Error::Parse)?; + registry.insert(identifier, participant); + } + Ok(registry) +} diff --git a/manta-trusted-setup/src/ceremony/registry/mod.rs b/manta-trusted-setup/src/ceremony/registry/mod.rs new file mode 100644 index 000000000..2286d4c39 --- /dev/null +++ b/manta-trusted-setup/src/ceremony/registry/mod.rs @@ -0,0 +1,37 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Trusted Setup Ceremony Registry + +#[cfg(feature = "csv")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "csv")))] +pub mod csv; + +/// Participant Registry +pub trait Registry { + /// Builds a new [`Registry`]. + fn new() -> Self; + + /// Registers the `id` and `participant` into `self` returning `false` if the `participant` is + /// already registered or their registration would conflict with another existing participant. + fn insert(&mut self, id: I, participant: P) -> bool; + + /// Returns a shared reference to the participant with the given `id` if they are registered. + fn get(&self, id: &I) -> Option<&P>; + + /// Returns a mutable reference to the participant with the given `id` if they are registered. + fn get_mut(&mut self, id: &I) -> Option<&mut P>; +} diff --git a/manta-trusted-setup/src/ceremony/signature.rs b/manta-trusted-setup/src/ceremony/signature.rs new file mode 100644 index 000000000..b6f607bdd --- /dev/null +++ b/manta-trusted-setup/src/ceremony/signature.rs @@ -0,0 +1,69 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Trusted Setup Ceremony Signatures + +use alloc::vec::Vec; +use manta_util::AsBytes; + +/// Nonce +pub trait Nonce: Default + PartialEq { + /// Increments the current nonce by one. + fn increment(&mut self); + + /// Checks if the current nonce is valid. + fn is_valid(&self) -> bool; + + /// + #[inline] + fn matches(&self, rhs: &Self) -> bool { + self.is_valid() && rhs.is_valid() && self == rhs + } +} + +impl Nonce for u64 { + #[inline] + fn increment(&mut self) { + *self = self.saturating_add(1); + } + + #[inline] + fn is_valid(&self) -> bool { + *self != Self::MAX + } +} + +/// Message with Nonce +#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] +pub struct Message { + /// Nonce + pub nonce: N, + + /// Encoded Message + pub encoded_message: Vec, +} + +impl AsBytes for Message +where + N: AsBytes, +{ + #[inline] + fn as_bytes(&self) -> Vec { + let mut bytes = self.nonce.as_bytes(); + bytes.extend_from_slice(&self.encoded_message); + bytes + } +} diff --git a/manta-trusted-setup/src/groth16/ceremony/util.rs b/manta-trusted-setup/src/ceremony/util.rs similarity index 62% rename from manta-trusted-setup/src/groth16/ceremony/util.rs rename to manta-trusted-setup/src/ceremony/util.rs index 931682017..7b1f6dfe4 100644 --- a/manta-trusted-setup/src/groth16/ceremony/util.rs +++ b/manta-trusted-setup/src/ceremony/util.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with manta-rs. If not, see . -//! Utilities +//! Trusted Setup Ceremony Utilities use manta_util::serde::{de::DeserializeOwned, Serialize}; use std::{ @@ -46,31 +46,6 @@ where bincode::deserialize_from(File::open(path)?) } -// /// Prepares phase one parameter `powers` for phase two parameters of circuit `cs` with `name`. -// #[inline] -// pub fn prepare_parameters(powers: Accumulator, cs: S, name: &str) -// where -// C: Pairing + Size + kzg::Configuration + mpc::ProvingKeyHasher + mpc::Configuration, -// S: ConstraintSynthesizer, -// D: CeremonyConfig>, -// ::Challenge: -// From<>::Output> + CanonicalSerialize, -// { -// let now = Instant::now(); -// let state = initialize::(powers, cs).expect("failed to initialize state"); -// let challenge = >::hash(&state); -// let mpc_state = MPCState:: { -// state: Array::from_unchecked([AsBytes::from_actual(state)]), -// challenge: Array::from_unchecked([AsBytes::from_actual(challenge.into())]), -// }; -// log_to_file(&format!("prepared_{}.data", name), &mpc_state); -// println!( -// "Preparing Phase 2 parameters for {} circuit takes {:?}\n", -// name, -// now.elapsed() -// ); -// } - /// Testing Suites #[cfg(test)] mod test { diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index b59ea51b7..37f4a9673 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -16,13 +16,16 @@ //! Trusted Setup Client -use crate::groth16::{ - ceremony::{ - message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse, Signed}, - signature::{sign, Nonce}, - Ceremony, CeremonyError, +use crate::{ + ceremony::signature::Nonce, + groth16::{ + ceremony::{ + message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, + signature::{sign, Signed}, + Ceremony, CeremonyError, + }, + mpc::{contribute, State}, }, - mpc::{contribute, State}, }; use bip39::{Language, Mnemonic, MnemonicType, Seed}; use colored::Colorize; diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index b0726e73d..e0e8ccc7d 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -16,14 +16,17 @@ //! Coordinator -use crate::groth16::{ - ceremony::{ - message::{MPCState, Signed}, - registry::Registry, - signature::{check_nonce, verify}, - Ceremony, CeremonyError, Participant, Queue, +use crate::{ + ceremony::signature::Nonce, + groth16::{ + ceremony::{ + message::MPCState, + registry::Registry, + signature::{verify, Signed}, + Ceremony, CeremonyError, Participant, Queue, + }, + mpc::{verify_transform, Proof, State, StateSize}, }, - mpc::{verify_transform, Proof, State, StateSize}, }; use core::{mem, time::Duration}; use manta_util::{time::lock::Timed, BoxArray}; @@ -189,7 +192,7 @@ where return Err(CeremonyError::AlreadyContributed); } let participant_nonce = participant.nonce(); - if !check_nonce(&participant_nonce, &request.nonce) { + if !participant_nonce.matches(&request.nonce) { return Err(CeremonyError::NonceNotInSync(participant_nonce)); }; verify::( diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 31b654151..e70e7c301 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -17,7 +17,7 @@ //! Messages through Network use crate::groth16::{ - ceremony::{signature::sign, Ceremony}, + ceremony::Ceremony, mpc::{Proof, State, StateSize}, }; use manta_crypto::arkworks::pairing::Pairing; @@ -108,67 +108,3 @@ where /// Proof pub proof: BoxArray, CIRCUIT_COUNT>, } - -/// Signed Message -#[derive(Deserialize, Serialize)] -#[serde( - bound( - serialize = r" - C::Identifier: Serialize, - T: Serialize, - C::Nonce: Serialize, - C::Signature: Serialize, - ", - deserialize = r" - C::Identifier: Deserialize<'de>, - T: Deserialize<'de>, - C::Nonce: Deserialize<'de>, - C::Signature: Deserialize<'de>, - ", - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct Signed -where - C: Ceremony, -{ - /// Message - pub message: T, - - /// Nonce - pub nonce: C::Nonce, - - /// Signature - pub signature: C::Signature, - - /// Participant Identifier - pub identifier: C::Identifier, -} - -impl Signed -where - C: Ceremony, -{ - /// Generates a signed message with `signing_key` on `message` and `nonce`. - #[inline] - pub fn new( - message: T, - nonce: &C::Nonce, - signing_key: &C::SigningKey, - identifier: C::Identifier, - ) -> Result - where - T: Serialize, - C::Nonce: Clone, - { - let signature = sign::<_, C>(signing_key, nonce.clone(), &message)?; - let message = Signed { - message, - nonce: nonce.clone(), - signature, - identifier, - }; - Ok(message) - } -} diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index f971f8af1..9190e4322 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -16,9 +16,9 @@ //! Groth16 Trusted Setup Ceremony -use crate::groth16::{ - ceremony::signature::{Nonce, SignatureScheme}, - mpc::Configuration, +use crate::{ + ceremony::signature::Nonce, + groth16::{ceremony::signature::SignatureScheme, mpc::Configuration}, }; use manta_util::{ collections::vec_deque::MultiVecDeque, @@ -31,7 +31,6 @@ pub mod participant; pub mod registry; pub mod server; pub mod signature; -pub mod util; #[cfg(feature = "serde")] #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] diff --git a/manta-trusted-setup/src/groth16/ceremony/participant.rs b/manta-trusted-setup/src/groth16/ceremony/participant.rs index 8e0180af1..632bac67c 100644 --- a/manta-trusted-setup/src/groth16/ceremony/participant.rs +++ b/manta-trusted-setup/src/groth16/ceremony/participant.rs @@ -16,9 +16,9 @@ //! Participant -use crate::groth16::ceremony::{ - self, - signature::{Nonce, SignatureScheme}, +use crate::{ + ceremony::signature::Nonce, + groth16::ceremony::{self, signature::SignatureScheme}, }; use manta_util::serde::{Deserialize, Serialize}; diff --git a/manta-trusted-setup/src/groth16/ceremony/registry.rs b/manta-trusted-setup/src/groth16/ceremony/registry.rs index 6d2dfc4b7..23061697b 100644 --- a/manta-trusted-setup/src/groth16/ceremony/registry.rs +++ b/manta-trusted-setup/src/groth16/ceremony/registry.rs @@ -21,8 +21,8 @@ pub trait Registry { /// Builds a new [`Registry`]. fn new() -> Self; - /// Registers the `id` and `participant` into `self` returning `false` if the `participant` is already - /// registered or their registration would conflict with another existing participant. + /// Registers the `id` and `participant` into `self` returning `false` if the `participant` is + /// already registered or their registration would conflict with another existing participant. fn register(&mut self, id: I, participant: P) -> bool; /// Returns a shared reference to the participant with the given `id` if they are registered. diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 82ab64588..85e5a0f67 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -16,17 +16,22 @@ //! Trusted Setup Server -use crate::groth16::{ +use crate::{ ceremony::{ - coordinator::Coordinator, - message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse, Signed}, - participant::{Participant, Priority}, - registry::Registry, - signature::{verify, Message}, + signature::Message, util::{deserialize_from_file, serialize_into_file}, - Ceremony, CeremonyError, Participant as _, }, - mpc::{State, StateSize}, + groth16::{ + ceremony::{ + coordinator::Coordinator, + message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, + participant::{Participant, Priority}, + registry::Registry, + signature::{verify, Signed}, + Ceremony, CeremonyError, Participant as _, + }, + mpc::{State, StateSize}, + }, }; use alloc::sync::Arc; use core::{convert::TryInto, ops::Deref}; diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index 9cc68b0ba..69c4ececc 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -16,65 +16,19 @@ //! Groth16 Trusted Setup Ceremony Signatures -use alloc::vec::Vec; +use crate::{ + ceremony::signature::{Message, Nonce}, + groth16::ceremony::Ceremony, +}; use manta_crypto::{ dalek::ed25519::{generate_keypair, Ed25519, SignatureError}, rand::{ChaCha20Rng, SeedableRng}, signature, }; -use manta_util::{serde::Serialize, AsBytes}; - -/// Nonce -pub trait Nonce: Default + PartialEq { - /// Increments the current nonce by one. - fn increment(&mut self); - - /// Checks if the current nonce is valid. - fn is_valid(&self) -> bool; -} - -impl Nonce for u64 { - #[inline] - fn increment(&mut self) { - *self = self.saturating_add(1); - } - - #[inline] - fn is_valid(&self) -> bool { - *self != Self::MAX - } -} - -/// Checks if the two nonces, `current` and `user_nonce`, are both valid and equal to each other. -#[inline] -pub fn check_nonce(current: &N, user_nonce: &N) -> bool -where - N: Nonce, -{ - current.is_valid() && user_nonce.is_valid() && current == user_nonce -} - -/// Message with Nonce -#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] -pub struct Message { - /// Nonce - pub nonce: N, - - /// Encoded Message - pub encoded_message: Vec, -} - -impl AsBytes for Message -where - N: AsBytes, -{ - #[inline] - fn as_bytes(&self) -> Vec { - let mut bytes = self.nonce.as_bytes(); - bytes.extend_from_slice(&self.encoded_message); - bytes - } -} +use manta_util::{ + serde::{Deserialize, Serialize}, + AsBytes, +}; /// Signature Scheme pub trait SignatureScheme: @@ -83,7 +37,7 @@ pub trait SignatureScheme: + signature::Verify> { /// Message Nonce - type Nonce: Nonce + Clone; + type Nonce: Clone + Nonce; /// Verification Error Type type Error; @@ -156,6 +110,70 @@ where .map_err(VerificationError::Error) } +/// Signed Message +#[derive(Deserialize, Serialize)] +#[serde( + bound( + serialize = r" + C::Identifier: Serialize, + T: Serialize, + C::Nonce: Serialize, + C::Signature: Serialize, + ", + deserialize = r" + C::Identifier: Deserialize<'de>, + T: Deserialize<'de>, + C::Nonce: Deserialize<'de>, + C::Signature: Deserialize<'de>, + ", + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct Signed +where + C: Ceremony, +{ + /// Message + pub message: T, + + /// Nonce + pub nonce: C::Nonce, + + /// Signature + pub signature: C::Signature, + + /// Participant Identifier + pub identifier: C::Identifier, +} + +impl Signed +where + C: Ceremony, +{ + /// Generates a signed message with `signing_key` on `message` and `nonce`. + #[inline] + pub fn new( + message: T, + nonce: &C::Nonce, + signing_key: &C::SigningKey, + identifier: C::Identifier, + ) -> Result + where + T: Serialize, + C::Nonce: Clone, + { + let signature = sign::<_, C>(signing_key, nonce.clone(), &message)?; + let message = Signed { + message, + nonce: nonce.clone(), + signature, + identifier, + }; + Ok(message) + } +} + impl SignatureScheme for Ed25519> where N: AsBytes + Default + Nonce + Clone, diff --git a/manta-trusted-setup/src/lib.rs b/manta-trusted-setup/src/lib.rs index 84dabb22a..8bf82c1a2 100644 --- a/manta-trusted-setup/src/lib.rs +++ b/manta-trusted-setup/src/lib.rs @@ -23,6 +23,7 @@ extern crate alloc; +pub mod ceremony; pub mod groth16; pub mod mpc; pub mod util; From baa2f73f84f076563807d0fe6d3cfaa0479851cb Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Sun, 11 Sep 2022 15:21:16 -0400 Subject: [PATCH 35/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/Cargo.toml | 3 + .../src/ceremony/participant.rs | 2 +- manta-trusted-setup/src/ceremony/signature.rs | 203 +++++++++++++++++- .../src/groth16/ceremony/client.rs | 30 ++- .../src/groth16/ceremony/coordinator.rs | 14 +- .../src/groth16/ceremony/mod.rs | 8 +- .../src/groth16/ceremony/participant.rs | 8 +- .../src/groth16/ceremony/server.rs | 25 ++- .../src/groth16/ceremony/signature.rs | 30 +-- 9 files changed, 272 insertions(+), 51 deletions(-) diff --git a/manta-trusted-setup/Cargo.toml b/manta-trusted-setup/Cargo.toml index 8c9f4f0de..62b280bc4 100644 --- a/manta-trusted-setup/Cargo.toml +++ b/manta-trusted-setup/Cargo.toml @@ -25,6 +25,9 @@ is-it-maintained-open-issues = { repository = "Manta-Network/manta-rs" } maintenance = { status = "actively-developed" } [features] +# Bincode for Message Signing +bincode = ["dep:bincode", "serde"] + # CSV for Ceremony Registries csv = ["dep:csv", "serde", "std"] diff --git a/manta-trusted-setup/src/ceremony/participant.rs b/manta-trusted-setup/src/ceremony/participant.rs index f5956f7da..77c325df4 100644 --- a/manta-trusted-setup/src/ceremony/participant.rs +++ b/manta-trusted-setup/src/ceremony/participant.rs @@ -40,7 +40,7 @@ pub trait Participant { fn set_contributed(&mut self); /// Returns the current nonce for `self`. - fn nonce(&self) -> Self::Nonce; + fn nonce(&self) -> &Self::Nonce; /// Increments the current nonce of `self` by one. fn increment_nonce(&mut self); diff --git a/manta-trusted-setup/src/ceremony/signature.rs b/manta-trusted-setup/src/ceremony/signature.rs index b6f607bdd..00f51dadf 100644 --- a/manta-trusted-setup/src/ceremony/signature.rs +++ b/manta-trusted-setup/src/ceremony/signature.rs @@ -17,8 +17,15 @@ //! Trusted Setup Ceremony Signatures use alloc::vec::Vec; +use manta_crypto::{ + dalek::ed25519::{Ed25519, SignatureError}, + signature, +}; use manta_util::AsBytes; +#[cfg(feature = "serde")] +use manta_util::serde::{Deserialize, Serialize}; + /// Nonce pub trait Nonce: Default + PartialEq { /// Increments the current nonce by one. @@ -27,7 +34,7 @@ pub trait Nonce: Default + PartialEq { /// Checks if the current nonce is valid. fn is_valid(&self) -> bool; - /// + /// Checks that `self` and `rhs` are valid and are both equal. #[inline] fn matches(&self, rhs: &Self) -> bool { self.is_valid() && rhs.is_valid() && self == rhs @@ -48,7 +55,7 @@ impl Nonce for u64 { /// Message with Nonce #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] -pub struct Message { +pub struct RawMessage { /// Nonce pub nonce: N, @@ -56,7 +63,18 @@ pub struct Message { pub encoded_message: Vec, } -impl AsBytes for Message +impl RawMessage { + /// Builds a new [`RawMessage`] from `nonce` and `encoded_message`. + #[inline] + pub fn new(nonce: N, encoded_message: Vec) -> Self { + Self { + nonce, + encoded_message, + } + } +} + +impl AsBytes for RawMessage where N: AsBytes, { @@ -67,3 +85,182 @@ where bytes } } + +/// Signature Scheme +pub trait SignatureScheme: + Default + + signature::Sign, Randomness = ()> + + signature::Verify> +{ + /// Message Nonce Type + type Nonce: Nonce; + + /// Verification Error Type + type Error; +} + +impl SignatureScheme for Ed25519> +where + N: AsBytes + Default + Nonce, +{ + type Nonce = N; + type Error = SignatureError; + + /* TODO + #[inline] + fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)> { + let keypair = generate_keypair(&mut ChaCha20Rng::from_seed(bytes.try_into().ok()?)); + Some((keypair.secret, keypair.public)) + } + */ +} + +/// Signs the `message` with the `nonce` attached using the `signing_key`. +#[cfg(feature = "bincode")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "bincode")))] +#[inline] +pub fn sign( + signing_key: &S::SigningKey, + nonce: S::Nonce, + message: &T, +) -> Result +where + S: SignatureScheme, + T: Serialize, +{ + Ok(S::default().sign( + signing_key, + &(), + &RawMessage::new(nonce, bincode::serialize(message)?), + &mut (), + )) +} + +/// Verification Error +#[cfg(feature = "bincode")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "bincode")))] +#[derive(Debug)] +pub enum VerificationError { + /// Serialization + Serialization(bincode::Error), + + /// Base Verification Error Type + Error(E), +} + +#[cfg(feature = "bincode")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "bincode")))] +impl From for VerificationError { + #[inline] + fn from(err: bincode::Error) -> Self { + Self::Serialization(err) + } +} + +/// Verifies the `signature` of `message` with `nonce` attached using `verifying_key`. +#[cfg(feature = "bincode")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "bincode")))] +#[inline] +pub fn verify( + verifying_key: &S::VerifyingKey, + nonce: S::Nonce, + message: &T, + signature: &S::Signature, +) -> Result<(), VerificationError> +where + S: SignatureScheme, + T: Serialize, +{ + S::default() + .verify( + verifying_key, + &RawMessage::new(nonce, bincode::serialize(message)?), + signature, + &mut (), + ) + .map_err(VerificationError::Error) +} + +/// Signed Message +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde( + bound( + deserialize = r" + S::Nonce: Deserialize<'de>, + S::Signature: Deserialize<'de>, + I: Deserialize<'de>, + T: Deserialize<'de>, + ", + serialize = r" + S::Nonce: Serialize, + S::Signature: Serialize, + I: Serialize, + T: Serialize, + ", + ), + crate = "manta_util::serde", + deny_unknown_fields, + ) +)] +pub struct SignedMessage +where + S: SignatureScheme, +{ + /// Signature + signature: S::Signature, + + /// Nonce + nonce: S::Nonce, + + /// Participant Identifier + identifier: I, + + /// Message + message: T, +} + +impl SignedMessage +where + S: SignatureScheme, +{ + /// Builds a new [`SignedMessage`] without checking that the `signature` actually attests to the + /// `message`. + #[inline] + pub fn new_unchecked( + signature: S::Signature, + nonce: S::Nonce, + identifier: I, + message: T, + ) -> Self { + Self { + signature, + nonce, + identifier, + message, + } + } + + /// Generates a signed message with `signing_key` on `message` and `nonce`. + #[cfg(feature = "bincode")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "bincode")))] + #[inline] + pub fn generate( + signing_key: &S::SigningKey, + nonce: S::Nonce, + identifier: I, + message: T, + ) -> Result + where + S::Nonce: Clone, + T: Serialize, + { + Ok(Self::new_unchecked( + sign::(signing_key, nonce.clone(), &message)?, + nonce, + identifier, + message, + )) + } +} diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index 37f4a9673..f565d6be6 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -17,11 +17,10 @@ //! Trusted Setup Client use crate::{ - ceremony::signature::Nonce, + ceremony::signature::{sign, Nonce, SignedMessage}, groth16::{ ceremony::{ message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, - signature::{sign, Signed}, Ceremony, CeremonyError, }, mpc::{contribute, State}, @@ -72,15 +71,17 @@ where /// Queries the server state. #[inline] - pub fn query(&mut self) -> Result, CeremonyError> + pub fn query( + &mut self, + ) -> Result, CeremonyError> where C::Nonce: Clone, { - let signed_message = Signed::new( - QueryRequest, - &self.nonce, + let signed_message = SignedMessage::generate( &self.signing_key, + self.nonce.clone(), self.identifier.clone(), + QueryRequest, ) .map_err(|_| { CeremonyError::Unexpected( @@ -98,7 +99,10 @@ where hasher: &C::Hasher, challenge: &BoxArray, mut state: BoxArray, CIRCUIT_COUNT>, - ) -> Result, C>, CeremonyError> + ) -> Result< + SignedMessage>, + CeremonyError, + > where C::Nonce: Clone, { @@ -121,14 +125,14 @@ where style("[8/9]").bold().dim(), style("3").bold().blue(), ); - let signed_message = Signed::new( + let signed_message = SignedMessage::generate( + &self.signing_key, + self.nonce.clone(), + self.identifier.clone(), ContributeRequest { state, proof: BoxArray::from_vec(proofs), }, - &self.nonce, - &self.signing_key, - self.identifier.clone(), ) .map_err(|_| { CeremonyError::Unexpected( @@ -140,6 +144,8 @@ where } } +/* TODO: + /// Registers a participant. #[inline] pub fn register(twitter_account: String, email: String) @@ -395,3 +401,5 @@ mod test { ); } } + +*/ diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index e0e8ccc7d..95a61ed54 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -17,13 +17,10 @@ //! Coordinator use crate::{ - ceremony::signature::Nonce, + ceremony::signature::{verify, Nonce, SignedMessage}, groth16::{ ceremony::{ - message::MPCState, - registry::Registry, - signature::{verify, Signed}, - Ceremony, CeremonyError, Participant, Queue, + message::MPCState, registry::Registry, Ceremony, CeremonyError, Participant, Queue, }, mpc::{verify_transform, Proof, State, StateSize}, }, @@ -179,11 +176,12 @@ where #[inline] pub fn preprocess_request( &mut self, - request: &Signed, + request: &SignedMessage, ) -> Result> where T: Serialize, { + /* TODO: let participant = self .registry .get_mut(&request.identifier) @@ -195,7 +193,7 @@ where if !participant_nonce.matches(&request.nonce) { return Err(CeremonyError::NonceNotInSync(participant_nonce)); }; - verify::( + verify::( participant.verifying_key(), participant_nonce, &request.message, @@ -204,6 +202,8 @@ where .map_err(|_| CeremonyError::BadRequest)?; participant.increment_nonce(); Ok(participant.priority()) + */ + todo!() } /// Checks the lock update errors for the [`Coordinator::update`] method. diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 9190e4322..ff864ec47 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -17,8 +17,8 @@ //! Groth16 Trusted Setup Ceremony use crate::{ - ceremony::signature::Nonce, - groth16::{ceremony::signature::SignatureScheme, mpc::Configuration}, + ceremony::signature::{Nonce, SignatureScheme}, + groth16::mpc::Configuration, }; use manta_util::{ collections::vec_deque::MultiVecDeque, @@ -30,7 +30,7 @@ pub mod message; pub mod participant; pub mod registry; pub mod server; -pub mod signature; +// FIXME[remove]: pub mod signature; #[cfg(feature = "serde")] #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] @@ -73,7 +73,7 @@ pub trait Participant { fn set_contributed(&mut self); /// Returns the current nonce for `self`. - fn nonce(&self) -> Self::Nonce; + fn nonce(&self) -> &Self::Nonce; /// Increments the current nonce of `self` by one. fn increment_nonce(&mut self); diff --git a/manta-trusted-setup/src/groth16/ceremony/participant.rs b/manta-trusted-setup/src/groth16/ceremony/participant.rs index 632bac67c..3597479fb 100644 --- a/manta-trusted-setup/src/groth16/ceremony/participant.rs +++ b/manta-trusted-setup/src/groth16/ceremony/participant.rs @@ -17,8 +17,8 @@ //! Participant use crate::{ - ceremony::signature::Nonce, - groth16::ceremony::{self, signature::SignatureScheme}, + ceremony::signature::{Nonce, SignatureScheme}, + groth16::ceremony, }; use manta_util::serde::{Deserialize, Serialize}; @@ -108,8 +108,8 @@ where } #[inline] - fn nonce(&self) -> Self::Nonce { - self.nonce.clone() + fn nonce(&self) -> &Self::Nonce { + &self.nonce } #[inline] diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 85e5a0f67..2882a65ab 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -18,7 +18,7 @@ use crate::{ ceremony::{ - signature::Message, + signature::{RawMessage, SignedMessage}, util::{deserialize_from_file, serialize_into_file}, }, groth16::{ @@ -27,7 +27,6 @@ use crate::{ message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, participant::{Participant, Priority}, registry::Registry, - signature::{verify, Signed}, Ceremony, CeremonyError, Participant as _, }, mpc::{State, StateSize}, @@ -89,7 +88,10 @@ where pub async fn start( self, request: C::Identifier, - ) -> Result<(CeremonySize, C::Nonce), CeremonyError> { + ) -> Result<(CeremonySize, C::Nonce), CeremonyError> + where + C::Nonce: Clone, + { let coordinator = self.coordinator.lock(); Ok(( CeremonySize(BoxArray::from_unchecked(*coordinator.size())), @@ -97,7 +99,8 @@ where .registry() .get(&request) .ok_or(CeremonyError::NotRegistered)? - .nonce(), + .nonce() + .clone(), )) } @@ -105,11 +108,12 @@ where #[inline] pub async fn query( self, - request: Signed, + request: SignedMessage, ) -> Result, CeremonyError> where C::Challenge: Clone, { + /* TODO: let mut coordinator = self.coordinator.lock(); let priority = coordinator.preprocess_request(&request)?; let position = coordinator @@ -120,6 +124,8 @@ where } else { Ok(QueryResponse::QueuePosition(position)) } + */ + todo!() } /// Processes a request to update the MPC state and remove the participant if successfully updated the state. @@ -127,11 +133,12 @@ where #[inline] pub async fn update( self, - request: Signed, C>, + request: SignedMessage>, ) -> Result<(), CeremonyError> where Coordinator: Serialize, { + /* TODO: let mut coordinator = self.coordinator.lock(); coordinator.preprocess_request(&request)?; let message = request.message; @@ -145,6 +152,8 @@ where .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?; println!("{} participants have contributed.", coordinator.round()); Ok(()) + */ + todo!() } } @@ -169,6 +178,7 @@ where }) } +/* TODO[remove]: /// Prases a string `record` into a pair of `(C::Identifier, C::Participant)`. #[inline] pub fn parse( @@ -198,7 +208,7 @@ where .try_into() .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, ); - verify::<_, Ed25519>>( + verify::<_, _>( &verifying_key, 0, &format!( @@ -245,3 +255,4 @@ where } Ok(registry) } +*/ diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs index 69c4ececc..11309cf25 100644 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ b/manta-trusted-setup/src/groth16/ceremony/signature.rs @@ -46,6 +46,20 @@ pub trait SignatureScheme: fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)>; } +impl SignatureScheme for Ed25519> +where + N: AsBytes + Default + Nonce + Clone, +{ + type Nonce = N; + type Error = SignatureError; + + #[inline] + fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)> { + let keypair = generate_keypair(&mut ChaCha20Rng::from_seed(bytes.try_into().ok()?)); + Some((keypair.secret, keypair.public)) + } +} + /// Signs the `message` with the `nonce` attached using the `signing_key`. #[inline] pub fn sign( @@ -110,6 +124,7 @@ where .map_err(VerificationError::Error) } +/* TODO[remove]: /// Signed Message #[derive(Deserialize, Serialize)] #[serde( @@ -173,17 +188,4 @@ where Ok(message) } } - -impl SignatureScheme for Ed25519> -where - N: AsBytes + Default + Nonce + Clone, -{ - type Nonce = N; - type Error = SignatureError; - - #[inline] - fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)> { - let keypair = generate_keypair(&mut ChaCha20Rng::from_seed(bytes.try_into().ok()?)); - Some((keypair.secret, keypair.public)) - } -} +*/ From b6db0f38faeff9fc7a3f3df7c9fb75a0d47a8e72 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Mon, 12 Sep 2022 10:38:14 -0400 Subject: [PATCH 36/60] chore: fix abstraction layers Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/src/ceremony/signature.rs | 29 ++- manta-trusted-setup/src/ceremony/util.rs | 21 -- .../src/groth16/ceremony/client.rs | 10 +- .../ceremony/{registry.rs => config/mod.rs} | 18 +- .../src/groth16/ceremony/config/ppot.rs | 245 ++++++++++++++++++ .../src/groth16/ceremony/coordinator.rs | 33 +-- .../src/groth16/ceremony/message.rs | 6 +- .../src/groth16/ceremony/mod.rs | 85 ++---- .../src/groth16/ceremony/participant.rs | 148 ----------- .../src/groth16/ceremony/server.rs | 149 ++--------- .../src/groth16/ceremony/signature.rs | 191 -------------- 11 files changed, 341 insertions(+), 594 deletions(-) rename manta-trusted-setup/src/groth16/ceremony/{registry.rs => config/mod.rs} (50%) create mode 100644 manta-trusted-setup/src/groth16/ceremony/config/ppot.rs delete mode 100644 manta-trusted-setup/src/groth16/ceremony/participant.rs delete mode 100644 manta-trusted-setup/src/groth16/ceremony/signature.rs diff --git a/manta-trusted-setup/src/ceremony/signature.rs b/manta-trusted-setup/src/ceremony/signature.rs index 00f51dadf..507bad245 100644 --- a/manta-trusted-setup/src/ceremony/signature.rs +++ b/manta-trusted-setup/src/ceremony/signature.rs @@ -93,7 +93,7 @@ pub trait SignatureScheme: + signature::Verify> { /// Message Nonce Type - type Nonce: Nonce; + type Nonce: Clone + Nonce; /// Verification Error Type type Error; @@ -101,7 +101,7 @@ pub trait SignatureScheme: impl SignatureScheme for Ed25519> where - N: AsBytes + Default + Nonce, + N: AsBytes + Clone + Default + Nonce, { type Nonce = N; type Error = SignatureError; @@ -209,16 +209,16 @@ where S: SignatureScheme, { /// Signature - signature: S::Signature, + pub signature: S::Signature, /// Nonce - nonce: S::Nonce, + pub nonce: S::Nonce, /// Participant Identifier - identifier: I, + pub identifier: I, /// Message - message: T, + pub message: T, } impl SignedMessage @@ -253,7 +253,6 @@ where message: T, ) -> Result where - S::Nonce: Clone, T: Serialize, { Ok(Self::new_unchecked( @@ -263,4 +262,20 @@ where message, )) } + + /// Verifies `self` against the `verifying_key`. + #[cfg(feature = "bincode")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "bincode")))] + #[inline] + pub fn verify(&self, verifying_key: &S::VerifyingKey) -> Result<(), VerificationError> + where + T: Serialize, + { + verify::( + verifying_key, + self.nonce.clone(), + &self.message, + &self.signature, + ) + } } diff --git a/manta-trusted-setup/src/ceremony/util.rs b/manta-trusted-setup/src/ceremony/util.rs index 7b1f6dfe4..f347ea09f 100644 --- a/manta-trusted-setup/src/ceremony/util.rs +++ b/manta-trusted-setup/src/ceremony/util.rs @@ -45,24 +45,3 @@ where { bincode::deserialize_from(File::open(path)?) } - -/// Testing Suites -#[cfg(test)] -mod test { - use super::*; - - /// Tests if logging and loading data is correct. - #[test] - #[ignore] - fn log_load_file_is_correct() { - let data = "Testing data".to_string(); - serialize_into_file( - OpenOptions::new().write(true).create_new(true), - &"test_transcript.data", - &data, - ) - .unwrap(); - let loaded_data: String = deserialize_from_file(&"test_transcript.data").unwrap(); - assert_eq!(data, loaded_data); - } -} diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index f565d6be6..aed604953 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -73,10 +73,7 @@ where #[inline] pub fn query( &mut self, - ) -> Result, CeremonyError> - where - C::Nonce: Clone, - { + ) -> Result, CeremonyError> { let signed_message = SignedMessage::generate( &self.signing_key, self.nonce.clone(), @@ -102,10 +99,7 @@ where ) -> Result< SignedMessage>, CeremonyError, - > - where - C::Nonce: Clone, - { + > { let circuit_name = ["ToPrivate", "PrivateTransfer", "ToPublic"]; let mut rng = OsRng; let mut proofs = Vec::new(); diff --git a/manta-trusted-setup/src/groth16/ceremony/registry.rs b/manta-trusted-setup/src/groth16/ceremony/config/mod.rs similarity index 50% rename from manta-trusted-setup/src/groth16/ceremony/registry.rs rename to manta-trusted-setup/src/groth16/ceremony/config/mod.rs index 23061697b..2463af04f 100644 --- a/manta-trusted-setup/src/groth16/ceremony/registry.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/mod.rs @@ -14,20 +14,6 @@ // You should have received a copy of the GNU General Public License // along with manta-rs. If not, see . -//! Groth16 Trusted Setup Ceremony Registry +//! Groth16 Trusted Setup Ceremony Configurations -/// Participant Registry -pub trait Registry { - /// Builds a new [`Registry`]. - fn new() -> Self; - - /// Registers the `id` and `participant` into `self` returning `false` if the `participant` is - /// already registered or their registration would conflict with another existing participant. - fn register(&mut self, id: I, participant: P) -> bool; - - /// Returns a shared reference to the participant with the given `id` if they are registered. - fn get(&self, id: &I) -> Option<&P>; - - /// Returns a mutable reference to the participant with the given `id` if they are registered. - fn get_mut(&mut self, id: &I) -> Option<&mut P>; -} +pub mod ppot; diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs new file mode 100644 index 000000000..c238682c5 --- /dev/null +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -0,0 +1,245 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Groth16 Trusted Setup Ceremony Perpetual Powers of Tau Configuration + +use crate::{ceremony, ceremony::registry::csv}; + +/// +pub struct Record {} + +// TODO: impl csv::Record for Record {} + +/// +pub struct Participant {} + +// TODO: impl ceremony::Participant for Participant {} + +// TODO: impl ceremony::Priority for Participant {} + +/* TODO: replace with above abstractions + +/// Priority +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[serde( + bound(deserialize = "", serialize = ""), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub enum Priority { + /// High Priority + High, + + /// Normal Priority + Normal, +} + +impl From for usize { + #[inline] + fn from(priority: Priority) -> Self { + match priority { + Priority::High => 0, + Priority::Normal => 1, + } + } +} + +/// Participant +pub struct Participant +where + S: SignatureScheme, +{ + /// Verifying Key + verifying_key: S::VerifyingKey, + + /// Twitter Account + twitter: String, + + /// Priority + priority: Priority, + + /// Nonce + nonce: S::Nonce, + + /// Boolean on whether this participant has contributed + contributed: bool, +} + +impl Participant +where + S: SignatureScheme, +{ + /// Builds a new [`Participant`]. + #[inline] + pub fn new( + verifying_key: S::VerifyingKey, + twitter: String, + priority: Priority, + nonce: S::Nonce, + contributed: bool, + ) -> Self { + Self { + verifying_key, + twitter, + priority, + nonce, + contributed, + } + } + + /// Gets `twitter`. + #[inline] + pub fn twitter(&self) -> &str { + &self.twitter + } +} + +impl participant::Participant for Participant +where + S: SignatureScheme, +{ + type Identifier = S::VerifyingKey; + type VerifyingKey = S::VerifyingKey; + type Nonce = S::Nonce; + + #[inline] + fn id(&self) -> &Self::Identifier { + &self.verifying_key + } + + #[inline] + fn verifying_key(&self) -> &Self::VerifyingKey { + &self.verifying_key + } + + #[inline] + fn has_contributed(&self) -> bool { + self.contributed + } + + #[inline] + fn set_contributed(&mut self) { + self.contributed = true + } + + #[inline] + fn nonce(&self) -> &Self::Nonce { + &self.nonce + } + + #[inline] + fn increment_nonce(&mut self) { + self.nonce.increment(); + } +} + +impl participant::Priority for Participant +where + S: SignatureScheme, +{ + type Priority = Priority; + + #[inline] + fn priority(&self) -> Self::Priority { + self.priority + } + + #[inline] + fn reduce_priority(&mut self) { + self.priority = Priority::Normal; + } +} +*/ + +/* TODO: replace with `Record` parsing: + +/// Prases a string `record` into a pair of `(C::Identifier, C::Participant)`. +#[inline] +pub fn parse( + record: csv::StringRecord, +) -> Result<(C::VerifyingKey, C::Participant), CeremonyError> +where + C: Ceremony, VerifyingKey = ed25519::PublicKey>, +{ + if record.len() != 5 { + return Err(CeremonyError::Unexpected( + "Record format is wrong.".to_string(), + )); + } + let twitter = record[0].to_string(); + let email = record[1].to_string(); + let verifying_key = ed25519::public_key_from_bytes( + bs58::decode(record[3].to_string()) + .into_vec() + .map_err(|_| CeremonyError::Unexpected("Cannot decode verifying key.".to_string()))? + .try_into() + .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, + ); + let signature: ed25519::Signature = ed25519::signature_from_bytes( + bs58::decode(record[4].to_string()) + .into_vec() + .map_err(|_| CeremonyError::Unexpected("Cannot decode signature.".to_string()))? + .try_into() + .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, + ); + verify::<_, _>( + &verifying_key, + 0, + &format!( + "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", + twitter, email + ), + &signature, + ) + .map_err(|_| CeremonyError::Unexpected("Cannot verify signature.".to_string()))?; + Ok(( + verifying_key, + Participant::new( + verifying_key, + twitter, + match record[2].to_string().parse::().unwrap() { + true => Priority::High, + false => Priority::Normal, + }, + OsRng.gen::<_, u16>() as u64, + false, + ), + )) +} + +/// Loads registry from a disk file at `registry`. +#[inline] +pub fn load_registry(registry_file: P) -> Result> +where + C: Ceremony, VerifyingKey = ed25519::PublicKey>, + P: AsRef, + R: Registry, +{ + let mut registry = R::new(); + for record in csv::Reader::from_reader( + File::open(registry_file) + .map_err(|_| CeremonyError::Unexpected("Cannot open registry file.".to_string()))?, + ) + .records() + { + let (identifier, participant) = parse(record.map_err(|_| { + CeremonyError::Unexpected("Cannot parse record from csv.".to_string()) + })?)?; + registry.register(identifier, participant); + } + Ok(registry) +} +*/ diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 95a61ed54..faf167c2d 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -17,11 +17,13 @@ //! Coordinator use crate::{ - ceremony::signature::{verify, Nonce, SignedMessage}, + ceremony::{ + participant::{Participant, Priority}, + registry::Registry, + signature::{Nonce, SignedMessage}, + }, groth16::{ - ceremony::{ - message::MPCState, registry::Registry, Ceremony, CeremonyError, Participant, Queue, - }, + ceremony::{message::MPCState, Ceremony, CeremonyError, Queue}, mpc::{verify_transform, Proof, State, StateSize}, }, }; @@ -84,11 +86,11 @@ where round: usize, /// Participant Queue - #[serde(skip)] + #[cfg_attr(feature = "serde", serde(skip))] queue: Queue, /// Participant Lock - #[serde(skip)] + #[cfg_attr(feature = "serde", serde(skip))] participant_lock: Timed>, } @@ -181,7 +183,6 @@ where where T: Serialize, { - /* TODO: let participant = self .registry .get_mut(&request.identifier) @@ -191,19 +192,13 @@ where } let participant_nonce = participant.nonce(); if !participant_nonce.matches(&request.nonce) { - return Err(CeremonyError::NonceNotInSync(participant_nonce)); + return Err(CeremonyError::NonceNotInSync(participant_nonce.clone())); }; - verify::( - participant.verifying_key(), - participant_nonce, - &request.message, - &request.signature, - ) - .map_err(|_| CeremonyError::BadRequest)?; + request + .verify(participant.verifying_key()) + .map_err(|_| CeremonyError::BadRequest)?; participant.increment_nonce(); Ok(participant.priority()) - */ - todo!() } /// Checks the lock update errors for the [`Coordinator::update`] method. @@ -265,10 +260,10 @@ where self.participant_lock.set(self.queue.pop_front()); match self.participant_mut(participant) { Some(participant) => participant.set_contributed(), - None => { + _ => { return Err(CeremonyError::Unexpected( "Cannot get participant.".to_string(), - )) + )); } }; self.increment_round(); diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index e70e7c301..e62716adb 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -14,7 +14,9 @@ // You should have received a copy of the GNU General Public License // along with manta-rs. If not, see . -//! Messages through Network +//! Groth16 Trusted Setup Ceremony Messaging Protocol + +// FIXME: Use correct serde configuration since we don't assume it's always available use crate::groth16::{ ceremony::Ceremony, @@ -88,7 +90,7 @@ where QueuePosition(usize), /// MPC State - Mpc(MPCState), + State(MPCState), } /// Contribute Request diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index ff864ec47..5e5229f07 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -17,68 +17,28 @@ //! Groth16 Trusted Setup Ceremony use crate::{ - ceremony::signature::{Nonce, SignatureScheme}, + ceremony::{ + participant::{Participant, Priority}, + signature::SignatureScheme, + }, groth16::mpc::Configuration, }; +use core::fmt::Debug; use manta_util::{ collections::vec_deque::MultiVecDeque, serde::{Deserialize, Serialize}, }; pub mod client; +pub mod config; +pub mod coordinator; pub mod message; -pub mod participant; -pub mod registry; pub mod server; -// FIXME[remove]: pub mod signature; - -#[cfg(feature = "serde")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] -pub mod coordinator; /// Participant Queue Type pub type Queue = MultiVecDeque<::Identifier, LEVEL_COUNT>; -/// Participant -pub trait Participant { - /// Identifier Type - type Identifier; - - /// Verifying Key Type - type VerifyingKey; - - /// Priority Type - type Priority; - - /// Nonce Type - type Nonce: Nonce; - - /// Returns the [`Identifier`](Self::Identifier) for `self`. - fn id(&self) -> &Self::Identifier; - - /// Returns the [`VerifyingKey`](Self::VerifyingKey) for `self`. - fn verifying_key(&self) -> &Self::VerifyingKey; - - /// Returns the priority level for `self`. - fn priority(&self) -> Self::Priority; - - /// Reduces the priority. - fn reduce_priority(&mut self); - - /// Checks if the participant has contributed. - fn has_contributed(&self) -> bool; - - /// Sets contributed. - fn set_contributed(&mut self); - - /// Returns the current nonce for `self`. - fn nonce(&self) -> &Self::Nonce; - - /// Increments the current nonce of `self` by one. - fn increment_nonce(&mut self); -} - /// Ceremony Configuration pub trait Ceremony: Configuration + SignatureScheme { /// Participant Identifier Type @@ -89,24 +49,27 @@ pub trait Ceremony: Configuration + SignatureScheme { /// Participant Type type Participant: Participant< - Identifier = Self::Identifier, - VerifyingKey = Self::VerifyingKey, - Priority = Self::Priority, - Nonce = Self::Nonce, - >; + Identifier = Self::Identifier, + VerifyingKey = Self::VerifyingKey, + Nonce = Self::Nonce, + > + Priority; } /// Ceremony Error -#[derive(derivative::Derivative, Deserialize, Serialize, PartialEq)] -#[derivative(Debug(bound = "C::Nonce: core::fmt::Debug"))] -#[serde( - bound( - serialize = "C::Nonce: Serialize", - deserialize = "C::Nonce: Deserialize<'de>", - ), - crate = "manta_util::serde", - deny_unknown_fields +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde( + bound( + serialize = "C::Nonce: Serialize", + deserialize = "C::Nonce: Deserialize<'de>", + ), + crate = "manta_util::serde", + deny_unknown_fields + ) )] +#[derive(derivative::Derivative)] +#[derivative(Debug(bound = "C::Nonce: Debug"))] pub enum CeremonyError where C: Ceremony, diff --git a/manta-trusted-setup/src/groth16/ceremony/participant.rs b/manta-trusted-setup/src/groth16/ceremony/participant.rs deleted file mode 100644 index 3597479fb..000000000 --- a/manta-trusted-setup/src/groth16/ceremony/participant.rs +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2019-2022 Manta Network. -// This file is part of manta-rs. -// -// manta-rs is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// manta-rs is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with manta-rs. If not, see . - -//! Participant - -use crate::{ - ceremony::signature::{Nonce, SignatureScheme}, - groth16::ceremony, -}; -use manta_util::serde::{Deserialize, Serialize}; - -/// Priority -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] -#[serde( - bound(deserialize = "", serialize = ""), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub enum Priority { - /// High Priority - High, - - /// Normal Priority - Normal, -} - -impl From for usize { - #[inline] - fn from(priority: Priority) -> Self { - match priority { - Priority::High => 0, - Priority::Normal => 1, - } - } -} - -/// Participant -pub struct Participant -where - S: SignatureScheme, -{ - /// Verifying Key - verifying_key: S::VerifyingKey, - - /// Twitter Account - twitter: String, - - /// Priority - priority: Priority, - - /// Nonce - nonce: S::Nonce, - - /// Boolean on whether this participant has contributed - contributed: bool, -} - -impl ceremony::Participant for Participant -where - S: SignatureScheme, -{ - type Identifier = S::VerifyingKey; - type VerifyingKey = S::VerifyingKey; - type Priority = Priority; - type Nonce = S::Nonce; - - #[inline] - fn id(&self) -> &Self::Identifier { - &self.verifying_key - } - - #[inline] - fn verifying_key(&self) -> &Self::VerifyingKey { - &self.verifying_key - } - - #[inline] - fn priority(&self) -> Self::Priority { - self.priority - } - - #[inline] - fn reduce_priority(&mut self) { - self.priority = Priority::Normal; - } - - #[inline] - fn has_contributed(&self) -> bool { - self.contributed - } - - #[inline] - fn set_contributed(&mut self) { - self.contributed = true - } - - #[inline] - fn nonce(&self) -> &Self::Nonce { - &self.nonce - } - - #[inline] - fn increment_nonce(&mut self) { - self.nonce.increment(); - } -} - -impl Participant -where - S: SignatureScheme, -{ - /// Builds a new [`Participant`]. - #[inline] - pub fn new( - verifying_key: S::VerifyingKey, - twitter: String, - priority: Priority, - nonce: S::Nonce, - contributed: bool, - ) -> Self { - Self { - verifying_key, - twitter, - priority, - nonce, - contributed, - } - } - - /// Gets `twitter`. - #[inline] - pub fn twitter(&self) -> &str { - &self.twitter - } -} diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 2882a65ab..2ff2ab8ed 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -18,33 +18,28 @@ use crate::{ ceremony::{ - signature::{RawMessage, SignedMessage}, + registry::Registry, + signature::SignedMessage, util::{deserialize_from_file, serialize_into_file}, }, groth16::{ ceremony::{ coordinator::Coordinator, message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, - participant::{Participant, Priority}, - registry::Registry, Ceremony, CeremonyError, Participant as _, }, mpc::{State, StateSize}, }, }; use alloc::sync::Arc; -use core::{convert::TryInto, ops::Deref}; -use manta_crypto::{ - dalek::ed25519::{self, Ed25519}, - rand::{OsRng, Rand}, -}; +use core::ops::Deref; use manta_util::{ serde::{de::DeserializeOwned, Serialize}, BoxArray, }; use parking_lot::Mutex; use std::{ - fs::{File, OpenOptions}, + fs::OpenOptions, path::{Path, PathBuf}, }; @@ -67,7 +62,8 @@ where C: Ceremony, R: Registry, { - /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a `recovery_directory`. + /// Builds a ['Server`] with initial `state`, `challenge`, a loaded `registry`, and a + /// `recovery_directory`. #[inline] pub fn new( state: BoxArray, CIRCUIT_COUNT>, @@ -76,13 +72,30 @@ where recovery_directory: PathBuf, size: BoxArray, ) -> Self { - let coordinator = Coordinator::new(registry, state, challenge, size); Self { - coordinator: Arc::new(Mutex::new(coordinator)), + coordinator: Arc::new(Mutex::new(Coordinator::new( + registry, state, challenge, size, + ))), recovery_directory, } } + /// Recovers from a disk file at `path` and use `recovery_directory` as the backup directory. + #[inline] + pub fn recover

(path: P, recovery_directory: PathBuf) -> Result> + where + P: AsRef, + Coordinator: DeserializeOwned, + { + Ok(Self { + coordinator: Arc::new(Mutex::new( + deserialize_from_file(path) + .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?, + )), + recovery_directory, + }) + } + /// Gets the server state size and the current nonce of the participant. #[inline] pub async fn start( @@ -113,23 +126,20 @@ where where C::Challenge: Clone, { - /* TODO: let mut coordinator = self.coordinator.lock(); let priority = coordinator.preprocess_request(&request)?; let position = coordinator .queue_mut() .push_back_if_missing(priority.into(), request.identifier); if position == 0 { - Ok(QueryResponse::Mpc(coordinator.state_and_challenge())) + Ok(QueryResponse::State(coordinator.state_and_challenge())) } else { Ok(QueryResponse::QueuePosition(position)) } - */ - todo!() } - /// Processes a request to update the MPC state and remove the participant if successfully updated the state. - /// If update succeeds, save the current coordinator to disk. + /// Processes a request to update the MPC state and remove the participant if successfully + /// updated the state. If update succeeds, save the current coordinator to disk. #[inline] pub async fn update( self, @@ -138,7 +148,6 @@ where where Coordinator: Serialize, { - /* TODO: let mut coordinator = self.coordinator.lock(); coordinator.preprocess_request(&request)?; let message = request.message; @@ -152,107 +161,5 @@ where .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?; println!("{} participants have contributed.", coordinator.round()); Ok(()) - */ - todo!() - } -} - -/// Recovers from a disk file at `path` and use `recovery_directory` as the backup directory. -#[inline] -pub fn recover( - path: P, - recovery_directory: PathBuf, -) -> Result, CeremonyError> -where - C: Ceremony, - P: AsRef, - R: Registry, - Coordinator: DeserializeOwned, -{ - Ok(Server { - coordinator: Arc::new(Mutex::new( - deserialize_from_file(path) - .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?, - )), - recovery_directory, - }) -} - -/* TODO[remove]: -/// Prases a string `record` into a pair of `(C::Identifier, C::Participant)`. -#[inline] -pub fn parse( - record: csv::StringRecord, -) -> Result<(C::VerifyingKey, C::Participant), CeremonyError> -where - C: Ceremony, VerifyingKey = ed25519::PublicKey>, -{ - if record.len() != 5 { - return Err(CeremonyError::Unexpected( - "Record format is wrong.".to_string(), - )); - } - let twitter = record[0].to_string(); - let email = record[1].to_string(); - let verifying_key = ed25519::public_key_from_bytes( - bs58::decode(record[3].to_string()) - .into_vec() - .map_err(|_| CeremonyError::Unexpected("Cannot decode verifying key.".to_string()))? - .try_into() - .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, - ); - let signature: ed25519::Signature = ed25519::signature_from_bytes( - bs58::decode(record[4].to_string()) - .into_vec() - .map_err(|_| CeremonyError::Unexpected("Cannot decode signature.".to_string()))? - .try_into() - .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, - ); - verify::<_, _>( - &verifying_key, - 0, - &format!( - "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", - twitter, email - ), - &signature, - ) - .map_err(|_| CeremonyError::Unexpected("Cannot verify signature.".to_string()))?; - Ok(( - verifying_key, - Participant::new( - verifying_key, - twitter, - match record[2].to_string().parse::().unwrap() { - true => Priority::High, - false => Priority::Normal, - }, - OsRng.gen::<_, u16>() as u64, - false, - ), - )) -} - -/// Loads registry from a disk file at `registry`. -#[inline] -pub fn load_registry(registry_file: P) -> Result> -where - C: Ceremony, VerifyingKey = ed25519::PublicKey>, - P: AsRef, - R: Registry, -{ - let mut registry = R::new(); - for record in csv::Reader::from_reader( - File::open(registry_file) - .map_err(|_| CeremonyError::Unexpected("Cannot open registry file.".to_string()))?, - ) - .records() - { - let (identifier, participant) = parse(record.map_err(|_| { - CeremonyError::Unexpected("Cannot parse record from csv.".to_string()) - })?)?; - registry.register(identifier, participant); } - Ok(registry) } -*/ diff --git a/manta-trusted-setup/src/groth16/ceremony/signature.rs b/manta-trusted-setup/src/groth16/ceremony/signature.rs deleted file mode 100644 index 11309cf25..000000000 --- a/manta-trusted-setup/src/groth16/ceremony/signature.rs +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2019-2022 Manta Network. -// This file is part of manta-rs. -// -// manta-rs is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// manta-rs is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with manta-rs. If not, see . - -//! Groth16 Trusted Setup Ceremony Signatures - -use crate::{ - ceremony::signature::{Message, Nonce}, - groth16::ceremony::Ceremony, -}; -use manta_crypto::{ - dalek::ed25519::{generate_keypair, Ed25519, SignatureError}, - rand::{ChaCha20Rng, SeedableRng}, - signature, -}; -use manta_util::{ - serde::{Deserialize, Serialize}, - AsBytes, -}; - -/// Signature Scheme -pub trait SignatureScheme: - Default - + signature::Sign, Randomness = ()> - + signature::Verify> -{ - /// Message Nonce - type Nonce: Clone + Nonce; - - /// Verification Error Type - type Error; - - /// Generates a keypair from `bytes` returning `None` if `bytes` was not the right format. - fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)>; -} - -impl SignatureScheme for Ed25519> -where - N: AsBytes + Default + Nonce + Clone, -{ - type Nonce = N; - type Error = SignatureError; - - #[inline] - fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)> { - let keypair = generate_keypair(&mut ChaCha20Rng::from_seed(bytes.try_into().ok()?)); - Some((keypair.secret, keypair.public)) - } -} - -/// Signs the `message` with the `nonce` attached using the `signing_key`. -#[inline] -pub fn sign( - signing_key: &S::SigningKey, - nonce: S::Nonce, - message: &T, -) -> Result -where - T: Serialize, - S: SignatureScheme, -{ - Ok(S::default().sign( - signing_key, - &(), - &Message { - nonce, - encoded_message: bincode::serialize(message)?, - }, - &mut (), - )) -} - -/// Verification Error -#[derive(Debug)] -pub enum VerificationError { - /// Serialization - Serialization(bincode::Error), - - /// Base Verification Error Type - Error(E), -} - -impl From for VerificationError { - #[inline] - fn from(err: bincode::Error) -> Self { - Self::Serialization(err) - } -} - -/// Verifies the `signature` of `message` with `nonce` attached using `verifying_key`. -#[inline] -pub fn verify( - verifying_key: &S::VerifyingKey, - nonce: S::Nonce, - message: &T, - signature: &S::Signature, -) -> Result<(), VerificationError> -where - T: Serialize, - S: SignatureScheme, -{ - S::default() - .verify( - verifying_key, - &Message { - nonce, - encoded_message: bincode::serialize(message)?, - }, - signature, - &mut (), - ) - .map_err(VerificationError::Error) -} - -/* TODO[remove]: -/// Signed Message -#[derive(Deserialize, Serialize)] -#[serde( - bound( - serialize = r" - C::Identifier: Serialize, - T: Serialize, - C::Nonce: Serialize, - C::Signature: Serialize, - ", - deserialize = r" - C::Identifier: Deserialize<'de>, - T: Deserialize<'de>, - C::Nonce: Deserialize<'de>, - C::Signature: Deserialize<'de>, - ", - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct Signed -where - C: Ceremony, -{ - /// Message - pub message: T, - - /// Nonce - pub nonce: C::Nonce, - - /// Signature - pub signature: C::Signature, - - /// Participant Identifier - pub identifier: C::Identifier, -} - -impl Signed -where - C: Ceremony, -{ - /// Generates a signed message with `signing_key` on `message` and `nonce`. - #[inline] - pub fn new( - message: T, - nonce: &C::Nonce, - signing_key: &C::SigningKey, - identifier: C::Identifier, - ) -> Result - where - T: Serialize, - C::Nonce: Clone, - { - let signature = sign::<_, C>(signing_key, nonce.clone(), &message)?; - let message = Signed { - message, - nonce: nonce.clone(), - signature, - identifier, - }; - Ok(message) - } -} -*/ From 87ddc1e5860f22e017a5ef09f641b49251a33e58 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Mon, 12 Sep 2022 10:39:54 -0400 Subject: [PATCH 37/60] fix: remove extra gitignore Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/.gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 manta-trusted-setup/.gitignore diff --git a/manta-trusted-setup/.gitignore b/manta-trusted-setup/.gitignore deleted file mode 100644 index 9bc63fdc9..000000000 --- a/manta-trusted-setup/.gitignore +++ /dev/null @@ -1 +0,0 @@ -test_transcript.data \ No newline at end of file From 13406b6d7e7a904f6af10a48ab203e8db94b905f Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 13 Sep 2022 16:16:26 +0200 Subject: [PATCH 38/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- manta-benchmark/Cargo.toml | 6 ++---- manta-benchmark/src/ecc.rs | 10 +++++++--- manta-pay/Cargo.toml | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manta-benchmark/Cargo.toml b/manta-benchmark/Cargo.toml index b6488a55c..13fa290f6 100644 --- a/manta-benchmark/Cargo.toml +++ b/manta-benchmark/Cargo.toml @@ -44,15 +44,13 @@ name = "reclaim" harness = false [dependencies] -ark-ec = { version = "0.3.0", default-features = false } -ark-ff = { version = "0.3.0", default-features = false } getrandom = { version = "0.2.6", default-features = false, features = ["js"] } instant = { version = "0.1.12", default-features = false, features = [ "wasm-bindgen" ] } manta-accounting = { path = "../manta-accounting", default-features = false, features = ["test"] } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["ark-bls12-381", "getrandom", "test"] } manta-pay = { path = "../manta-pay", default-features = false, features = ["groth16", "test"] } -wasm-bindgen = { version = "0.2.82", default-features = false } -wasm-bindgen-test = { version = "0.3.30", default-features = false } +wasm-bindgen = { version = "0.2.83", default-features = false } +wasm-bindgen-test = { version = "0.3.33", default-features = false } web-sys = { version = "0.3.59", default-features = false, features = ["console"] } [dev-dependencies] diff --git a/manta-benchmark/src/ecc.rs b/manta-benchmark/src/ecc.rs index 6a4c9f8de..dd67779a8 100644 --- a/manta-benchmark/src/ecc.rs +++ b/manta-benchmark/src/ecc.rs @@ -16,10 +16,14 @@ //! Elliptic Curve Cryptography Utilities -use ark_ec::{AffineCurve, ProjectiveCurve}; -use ark_ff::UniformRand; use core::ops::AddAssign; -use manta_crypto::rand::RngCore; +use manta_crypto::{ + arkworks::{ + ec::{AffineCurve, ProjectiveCurve}, + ff::UniformRand, + }, + rand::RngCore, +}; /// Samples an affine point. #[inline] diff --git a/manta-pay/Cargo.toml b/manta-pay/Cargo.toml index 612a7d7b9..c6fa1f33a 100644 --- a/manta-pay/Cargo.toml +++ b/manta-pay/Cargo.toml @@ -106,7 +106,7 @@ ark-std = { version = "0.3.0", optional = true, default-features = false } bip32 = { version = "0.3.0", optional = true, default-features = false, features = ["bip39", "secp256k1"] } blake2 = { version = "0.10.4", default-features = false } bs58 = { version = "0.4.0", optional = true, default-features = false, features = ["alloc"] } -clap = { version = "3.2.20", optional = true, default-features = false, features = ["color", "derive", "std", "suggestions", "unicode", "wrap_help"] } +clap = { version = "3.2.21", optional = true, default-features = false, features = ["color", "derive", "std", "suggestions", "unicode", "wrap_help"] } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } futures = { version = "0.3.24", optional = true, default-features = false } indexmap = { version = "1.9.1", optional = true, default-features = false } @@ -119,7 +119,7 @@ scale-codec = { package = "parity-scale-codec", version = "3.1.2", optional = tr scale-info = { version = "2.1.2", optional = true, default-features = false, features = ["derive"] } serde_json = { version = "1.0.85", optional = true, default-features = false, features = ["alloc"] } tempfile = { version = "3.3.0", optional = true, default-features = false } -tokio = { version = "1.21.0", optional = true, default-features = false } +tokio = { version = "1.21.1", optional = true, default-features = false } tokio-tungstenite = { version = "0.17.2", optional = true, default-features = false, features = ["native-tls"] } ws_stream_wasm = { version = "0.7.3", optional = true, default-features = false } From ff3a1f39142b7f42e577742014f507663ebdaf6a Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Tue, 13 Sep 2022 12:12:17 -0400 Subject: [PATCH 39/60] wip: save point --- .../src/groth16/ceremony/config/ppot.rs | 92 +++++++++++++++---- 1 file changed, 74 insertions(+), 18 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index c238682c5..3d5aee925 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -16,21 +16,19 @@ //! Groth16 Trusted Setup Ceremony Perpetual Powers of Tau Configuration -use crate::{ceremony, ceremony::registry::csv}; +use core::marker::PhantomData; -/// -pub struct Record {} +use manta_crypto::{dalek::ed25519, signature::Sign}; +use manta_util::serde::{Deserialize, Serialize}; -// TODO: impl csv::Record for Record {} - -/// -pub struct Participant {} - -// TODO: impl ceremony::Participant for Participant {} - -// TODO: impl ceremony::Priority for Participant {} - -/* TODO: replace with above abstractions +use crate::{ + ceremony::{ + participant, + registry::csv, + signature::{Nonce, SignatureScheme}, + }, + groth16::ceremony::Ceremony, +}; /// Priority #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] @@ -62,15 +60,15 @@ pub struct Participant where S: SignatureScheme, { - /// Verifying Key - verifying_key: S::VerifyingKey, - /// Twitter Account twitter: String, /// Priority priority: Priority, + /// Verifying Key + verifying_key: S::VerifyingKey, + /// Nonce nonce: S::Nonce, @@ -154,7 +152,7 @@ where #[inline] fn priority(&self) -> Self::Priority { - self.priority + self.priority.clone() } #[inline] @@ -162,7 +160,65 @@ where self.priority = Priority::Normal; } } -*/ + +/// Record +pub struct Record; + +/* TODO: +impl csv::Record> for Record +where + S: SignatureScheme, +{ + type Error; + + fn parse(self) -> Result<(S::VerifyingKey, Participant), Self::Error> { + if self.len() != 5 { + return Err(CeremonyError::Unexpected( + "Record format is wrong.".to_string(), + )); + } + let twitter = record[0].to_string(); + let email = record[1].to_string(); + let verifying_key = ed25519::public_key_from_bytes( + bs58::decode(record[3].to_string()) + .into_vec() + .map_err(|_| CeremonyError::Unexpected("Cannot decode verifying key.".to_string()))? + .try_into() + .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, + ); + let signature: ed25519::Signature = ed25519::signature_from_bytes( + bs58::decode(record[4].to_string()) + .into_vec() + .map_err(|_| CeremonyError::Unexpected("Cannot decode signature.".to_string()))? + .try_into() + .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, + ); + verify::<_, _>( + &verifying_key, + 0, + &format!( + "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", + twitter, email + ), + &signature, + ) + .map_err(|_| CeremonyError::Unexpected("Cannot verify signature.".to_string()))?; + Ok(( + verifying_key, + Participant::new( + verifying_key, + twitter, + match record[2].to_string().parse::().unwrap() { + true => Priority::High, + false => Priority::Normal, + }, + OsRng.gen::<_, u16>() as u64, + false, + ), + )) + } +} + */ /* TODO: replace with `Record` parsing: From d049730241476fe71631aae34656ada3ea1e37ce Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Tue, 13 Sep 2022 13:38:02 -0400 Subject: [PATCH 40/60] feat: priority, participant, record for ppot --- manta-crypto/Cargo.toml | 3 +- .../src/groth16/ceremony/config/mod.rs | 2 + .../src/groth16/ceremony/config/ppot.rs | 211 ++++++------------ 3 files changed, 74 insertions(+), 142 deletions(-) diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index 4366bd1e5..6d2c044f6 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -44,7 +44,8 @@ getrandom = ["rand_core/getrandom"] serde = [ "manta-util/serde-alloc", "manta-util/serde-array", - "rand_chacha?/serde1" + "rand_chacha?/serde1", + "ed25519-dalek?/serde", ] # Standard Library diff --git a/manta-trusted-setup/src/groth16/ceremony/config/mod.rs b/manta-trusted-setup/src/groth16/ceremony/config/mod.rs index 2463af04f..d52f3fb58 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/mod.rs @@ -16,4 +16,6 @@ //! Groth16 Trusted Setup Ceremony Configurations +#[cfg(feature = "serde")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] pub mod ppot; diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index 3d5aee925..a52d0526b 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -16,19 +16,21 @@ //! Groth16 Trusted Setup Ceremony Perpetual Powers of Tau Configuration -use core::marker::PhantomData; - -use manta_crypto::{dalek::ed25519, signature::Sign}; +use crate::ceremony::{ + participant, + registry::csv, + signature::{verify, Nonce as _, RawMessage, SignatureScheme}, +}; +use manta_crypto::{ + dalek::ed25519::{self, Ed25519}, + rand::{OsRng, Rand}, + signature::VerifyingKeyType, +}; use manta_util::serde::{Deserialize, Serialize}; -use crate::{ - ceremony::{ - participant, - registry::csv, - signature::{Nonce, SignatureScheme}, - }, - groth16::ceremony::Ceremony, -}; +type Signature = Ed25519>; +type VerifyingKey = ::VerifyingKey; +type Nonce = ::Nonce; /// Priority #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] @@ -56,10 +58,22 @@ impl From for usize { } /// Participant -pub struct Participant -where - S: SignatureScheme, -{ +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +#[serde( + bound( + deserialize = " + VerifyingKey: Deserialize<'de>, + Nonce: Deserialize<'de>, + ", + serialize = " + VerifyingKey: Serialize, + Nonce: Serialize, + " + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct Participant { /// Twitter Account twitter: String, @@ -67,26 +81,23 @@ where priority: Priority, /// Verifying Key - verifying_key: S::VerifyingKey, + verifying_key: VerifyingKey, /// Nonce - nonce: S::Nonce, + nonce: Nonce, /// Boolean on whether this participant has contributed contributed: bool, } -impl Participant -where - S: SignatureScheme, -{ +impl Participant { /// Builds a new [`Participant`]. #[inline] pub fn new( - verifying_key: S::VerifyingKey, + verifying_key: VerifyingKey, twitter: String, priority: Priority, - nonce: S::Nonce, + nonce: Nonce, contributed: bool, ) -> Self { Self { @@ -105,13 +116,10 @@ where } } -impl participant::Participant for Participant -where - S: SignatureScheme, -{ - type Identifier = S::VerifyingKey; - type VerifyingKey = S::VerifyingKey; - type Nonce = S::Nonce; +impl participant::Participant for Participant { + type Identifier = VerifyingKey; + type VerifyingKey = VerifyingKey; + type Nonce = Nonce; #[inline] fn id(&self) -> &Self::Identifier { @@ -144,10 +152,7 @@ where } } -impl participant::Priority for Participant -where - S: SignatureScheme, -{ +impl participant::Priority for Participant { type Priority = Priority; #[inline] @@ -162,53 +167,58 @@ where } /// Record -pub struct Record; +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[serde( + bound(deserialize = "", serialize = ""), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct Record { + twitter: String, + email: String, + priority: String, + verifying_key: String, + signature: String, +} -/* TODO: -impl csv::Record> for Record -where - S: SignatureScheme, -{ - type Error; +impl csv::Record for Record { + type Error = String; - fn parse(self) -> Result<(S::VerifyingKey, Participant), Self::Error> { - if self.len() != 5 { - return Err(CeremonyError::Unexpected( - "Record format is wrong.".to_string(), - )); - } - let twitter = record[0].to_string(); - let email = record[1].to_string(); + fn parse(self) -> Result<(VerifyingKey, Participant), Self::Error> { let verifying_key = ed25519::public_key_from_bytes( - bs58::decode(record[3].to_string()) + bs58::decode(self.verifying_key) .into_vec() - .map_err(|_| CeremonyError::Unexpected("Cannot decode verifying key.".to_string()))? + .map_err(|_| "Cannot decode verifying key.".to_string())? .try_into() - .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, + .map_err(|_| "Cannot decode to array.".to_string())?, ); let signature: ed25519::Signature = ed25519::signature_from_bytes( - bs58::decode(record[4].to_string()) + bs58::decode(self.signature) .into_vec() - .map_err(|_| CeremonyError::Unexpected("Cannot decode signature.".to_string()))? + .map_err(|_| "Cannot decode signature.".to_string())? .try_into() - .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, + .map_err(|_| "Cannot decode to array.".to_string())?, ); - verify::<_, _>( + verify::( &verifying_key, 0, &format!( "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", - twitter, email + self.twitter, self.email ), &signature, ) - .map_err(|_| CeremonyError::Unexpected("Cannot verify signature.".to_string()))?; + .map_err(|_| "Cannot verify signature.".to_string())?; Ok(( verifying_key, Participant::new( verifying_key, - twitter, - match record[2].to_string().parse::().unwrap() { + self.twitter, + match self + .priority + .parse::() + .map_err(|_| "Cannot parse priority.".to_string())? + { true => Priority::High, false => Priority::Normal, }, @@ -218,84 +228,3 @@ where )) } } - */ - -/* TODO: replace with `Record` parsing: - -/// Prases a string `record` into a pair of `(C::Identifier, C::Participant)`. -#[inline] -pub fn parse( - record: csv::StringRecord, -) -> Result<(C::VerifyingKey, C::Participant), CeremonyError> -where - C: Ceremony, VerifyingKey = ed25519::PublicKey>, -{ - if record.len() != 5 { - return Err(CeremonyError::Unexpected( - "Record format is wrong.".to_string(), - )); - } - let twitter = record[0].to_string(); - let email = record[1].to_string(); - let verifying_key = ed25519::public_key_from_bytes( - bs58::decode(record[3].to_string()) - .into_vec() - .map_err(|_| CeremonyError::Unexpected("Cannot decode verifying key.".to_string()))? - .try_into() - .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, - ); - let signature: ed25519::Signature = ed25519::signature_from_bytes( - bs58::decode(record[4].to_string()) - .into_vec() - .map_err(|_| CeremonyError::Unexpected("Cannot decode signature.".to_string()))? - .try_into() - .map_err(|_| CeremonyError::Unexpected("Cannot decode to array.".to_string()))?, - ); - verify::<_, _>( - &verifying_key, - 0, - &format!( - "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", - twitter, email - ), - &signature, - ) - .map_err(|_| CeremonyError::Unexpected("Cannot verify signature.".to_string()))?; - Ok(( - verifying_key, - Participant::new( - verifying_key, - twitter, - match record[2].to_string().parse::().unwrap() { - true => Priority::High, - false => Priority::Normal, - }, - OsRng.gen::<_, u16>() as u64, - false, - ), - )) -} - -/// Loads registry from a disk file at `registry`. -#[inline] -pub fn load_registry(registry_file: P) -> Result> -where - C: Ceremony, VerifyingKey = ed25519::PublicKey>, - P: AsRef, - R: Registry, -{ - let mut registry = R::new(); - for record in csv::Reader::from_reader( - File::open(registry_file) - .map_err(|_| CeremonyError::Unexpected("Cannot open registry file.".to_string()))?, - ) - .records() - { - let (identifier, participant) = parse(record.map_err(|_| { - CeremonyError::Unexpected("Cannot parse record from csv.".to_string()) - })?)?; - registry.register(identifier, participant); - } - Ok(registry) -} -*/ From 2e9281dc4fcc4574532cd0591945e71cc6e253e8 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Tue, 13 Sep 2022 15:42:57 -0400 Subject: [PATCH 41/60] chore: nit --- manta-trusted-setup/src/groth16/ceremony/config/ppot.rs | 1 + manta-trusted-setup/src/groth16/ceremony/coordinator.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index a52d0526b..793efb874 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -184,6 +184,7 @@ pub struct Record { impl csv::Record for Record { type Error = String; + #[inline] fn parse(self) -> Result<(VerifyingKey, Participant), Self::Error> { let verifying_key = ed25519::public_key_from_bytes( bs58::decode(self.verifying_key) diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index faf167c2d..f5e02d5c2 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -158,6 +158,7 @@ where } /// Returns a mutable reference to `queue`. + #[inline] pub fn queue_mut(&mut self) -> &mut Queue { &mut self.queue } From cadfd61d3e1464a2ef8286275aac669481028a99 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Wed, 14 Sep 2022 15:18:31 -0400 Subject: [PATCH 42/60] chore: fix client --- manta-trusted-setup/src/ceremony/mod.rs | 4 +- manta-trusted-setup/src/ceremony/signature.rs | 8 - .../src/groth16/ceremony/client.rs | 250 +--------------- .../src/groth16/ceremony/config/ppot.rs | 270 +++++++++++++++++- 4 files changed, 268 insertions(+), 264 deletions(-) diff --git a/manta-trusted-setup/src/ceremony/mod.rs b/manta-trusted-setup/src/ceremony/mod.rs index 088a6688b..b29ec0b30 100644 --- a/manta-trusted-setup/src/ceremony/mod.rs +++ b/manta-trusted-setup/src/ceremony/mod.rs @@ -20,6 +20,6 @@ pub mod participant; pub mod registry; pub mod signature; -#[cfg(feature = "std")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] +#[cfg(all(feature = "std", feature = "bincode"))] +#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", feature = "bincode"))))] pub mod util; diff --git a/manta-trusted-setup/src/ceremony/signature.rs b/manta-trusted-setup/src/ceremony/signature.rs index 507bad245..d0b719815 100644 --- a/manta-trusted-setup/src/ceremony/signature.rs +++ b/manta-trusted-setup/src/ceremony/signature.rs @@ -105,14 +105,6 @@ where { type Nonce = N; type Error = SignatureError; - - /* TODO - #[inline] - fn generate_keys(bytes: &[u8]) -> Option<(Self::SigningKey, Self::VerifyingKey)> { - let keypair = generate_keypair(&mut ChaCha20Rng::from_seed(bytes.try_into().ok()?)); - Some((keypair.secret, keypair.public)) - } - */ } /// Signs the `message` with the `nonce` attached using the `signing_key`. diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index aed604953..d723bee9e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -17,28 +17,23 @@ //! Trusted Setup Client use crate::{ - ceremony::signature::{sign, Nonce, SignedMessage}, + ceremony::signature::{Nonce, SignedMessage}, groth16::{ ceremony::{ - message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, + message::{CeremonySize, ContributeRequest, QueryRequest}, Ceremony, CeremonyError, }, mpc::{contribute, State}, }, }; -use bip39::{Language, Mnemonic, MnemonicType, Seed}; -use colored::Colorize; -use console::{style, Term}; +use console::style; use core::fmt::Debug; -use dialoguer::{theme::ColorfulTheme, Input}; -use manta_crypto::{dalek::ed25519, rand::OsRng}; +use manta_crypto::rand::OsRng; use manta_util::{ http::reqwest::KnownUrlClient, serde::{de::DeserializeOwned, Serialize}, - time::Duration, BoxArray, }; -use std::thread; /// Client pub struct Client @@ -138,89 +133,6 @@ where } } -/* TODO: - -/// Registers a participant. -#[inline] -pub fn register(twitter_account: String, email: String) -where - C: Ceremony, - C::VerifyingKey: AsRef<[u8]>, - C::Signature: AsRef<[u8]>, -{ - println!( - "Your {}: \nCopy the following text to \"Twitter\" Section in Google Sheet:\n {}\n", - "Twitter Account".italic(), - twitter_account.blue(), - ); - println!( - "Your {}: \nCopy the following text to \"Email\" Section in Google Sheet:\n {}\n", - "Email".italic(), - email.blue(), - ); - let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); - let seed = Seed::new(&mnemonic, "manta-trusted-setup"); - let keypair = C::generate_keys(seed.as_bytes()).expect("Should generate a key pair."); - println!( - "Your {}: \nCopy the following text to \"Public Key\" Section in Google Sheet:\n {}\n", - "Public Key".italic(), - bs58::encode(keypair.1).into_string().blue(), - ); - let signature = sign::<_, C>( - &keypair.0, - Default::default(), - &format!( - "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", - twitter_account, email - ), - ) - .expect("Signing message should succeed."); - println!( - "Your {}: \nCopy the following text to \"Signature\" Section in Google Sheet: \n {}\n", - "Signature".italic(), - bs58::encode(signature).into_string().blue() - ); - println!( - "Your {}: \nThe following text stores your secret for trusted setup. \ - Save the following text somewhere safe. \n DO NOT share this to anyone else! \ - Please discard this data after the trusted setup ceremony.\n {}", - "Secret".italic(), - mnemonic.phrase().red(), - ); -} - -/// Prompts the client information and get client keys. -#[inline] -pub fn get_client_keys() -> Result<(C::SigningKey, C::VerifyingKey), CeremonyError> -where - C: Ceremony, -{ - println!( - "Please enter your {} that you get when you registered yourself using this tool.", - "Secret".italic() - ); - let seed_bytes = Seed::new( - &Mnemonic::from_phrase( - Input::with_theme(&ColorfulTheme::default()) - .with_prompt("Your Secret") - .validate_with(|input: &String| -> Result<(), &str> { - Mnemonic::validate(input, Language::English) - .map_err(|_| "This is not a valid secret.") - }) - .interact_text() - .expect("Please enter your secret received during `Register`.") - .as_str(), - Language::English, - ) - .expect("Should produce a mnemonic from the secret."), - "manta-trusted-setup", - ) - .as_bytes() - .to_vec(); - C::generate_keys(&seed_bytes) - .ok_or_else(|| CeremonyError::Unexpected("Cannot generate keys.".to_string())) -} - /// Gets state size from server. #[inline] pub async fn get_start_meta_data( @@ -243,157 +155,3 @@ where ) })? } - -/// Contributes to the server. -#[inline] -pub async fn client_contribute() -> Result<(), CeremonyError> -where - C: Ceremony, - C::Challenge: DeserializeOwned, - C::Identifier: Serialize, - C::Nonce: Clone + Debug + DeserializeOwned + Serialize, - C::Signature: Serialize, -{ - let network_client = KnownUrlClient::new("http://localhost:8080").expect("Should succeed."); - let (sk, pk) = get_client_keys()?; - println!( - "{} Contacting Server for Meta Data...", - style("[1/9]").bold().dim() - ); - let term = Term::stdout(); - let (size, nonce) = get_start_meta_data::(pk, &network_client).await?; - let mut trusted_setup_client = Client::::new(pk, nonce, sk); - println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); - loop { - let mpc_state = match network_client - .post::<_, Result, CeremonyError>>( - "query", - &trusted_setup_client.query()?, - ) - .await - .map_err(|_| { - CeremonyError::Network( - "Should have received starting meta data from server".to_string(), - ) - })? { - Ok(message) => match message { - QueryResponse::QueuePosition(position) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); - println!( - "{} Waiting in Queue... There are {} people ahead of you. Estimated Waiting Time: {} minutes.", - style("[2/9]").bold().dim(), - style(position).bold().red(), - style(5*position).bold().blue(), - ); - thread::sleep(Duration::from_secs(10)); - continue; - } - QueryResponse::Mpc(mpc_state) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); - println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); - println!( - "{} Downloading Ceremony States...", - style("[3/9]").bold().dim(), - ); - if !size.matches(&mpc_state.state) { - return Err(CeremonyError::Unexpected( - "Received mpc state size is not correct.".to_string(), - )); - } - mpc_state - } - }, - Err(CeremonyError::Timeout) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); - println!( - "{} You have timed out. Waiting in Queue again...", - style("[2/9]").bold().dim(), - ); - continue; - } - Err(CeremonyError::NotYourTurn) => { - return Err(CeremonyError::Unexpected( - "Unexpected error when query mpc state. Should not receive NotYourTurn message." - .to_string(), - )); - } - Err(err) => return Err(err), - }; - println!( - "{} Starting contribution to 3 Circuits...", - style("[4/9]").bold().dim(), - ); - match network_client - .post::<_, Result<(), CeremonyError>>( - "update", - &trusted_setup_client.contribute( - &C::Hasher::default(), - &mpc_state.challenge, - mpc_state.state, - )?, - ) - .await - .map_err(|_| { - CeremonyError::Network( - "Should have received starting meta data from server".to_string(), - ) - })? { - Ok(_) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); - println!( - "{} Waiting for Confirmation from Server...", - style("[8/9]").bold().dim(), - ); - println!( - "{} Congratulations! You have successfully contributed to Manta Trusted Setup Ceremony!...", - style("[9/9]").bold().dim(), - ); - break; - } - Err(CeremonyError::Timeout) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); - println!( - "{} You have timed out. Waiting in Queue again...", - style("[2/9]").bold().dim(), - ); - continue; - } - Err(CeremonyError::NotRegistered) => { - return Err(CeremonyError::Unexpected( - "unexpected error when contribute. Should have registered.".to_string(), - )) - } - Err(CeremonyError::NotYourTurn) => { - println!( - "{} Lag behind server. Contacting Server again...", - style("[8/9]").bold().dim(), - ); - continue; - } - Err(err) => return Err(err), - } - } - Ok(()) -} - -/// Testing Suite -#[cfg(test)] -mod test { - use super::*; - - /// Tests if register is visually correct. - #[test] - fn register_is_visually_correct() { - register( - "Mantalorian".to_string(), - "mantalorian@manta.network".to_string(), - ); - } -} - -*/ diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index 793efb874..1870e3af5 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -16,17 +16,31 @@ //! Groth16 Trusted Setup Ceremony Perpetual Powers of Tau Configuration -use crate::ceremony::{ - participant, - registry::csv, - signature::{verify, Nonce as _, RawMessage, SignatureScheme}, +use crate::{ + ceremony::{ + participant, + registry::csv, + signature::{sign, verify, Nonce as _, RawMessage, SignatureScheme}, + }, + groth16::ceremony::{ + client::{get_start_meta_data, Client}, + message::QueryResponse, + Ceremony, CeremonyError, + }, }; +use bip39::{Language, Mnemonic, MnemonicType, Seed}; +use colored::Colorize; +use console::{style, Term}; +use dialoguer::{theme::ColorfulTheme, Input}; use manta_crypto::{ - dalek::ed25519::{self, Ed25519}, - rand::{OsRng, Rand}, + dalek::ed25519::{self, generate_keypair, Ed25519}, + rand::{ChaCha20Rng, OsRng, Rand, SeedableRng}, signature::VerifyingKeyType, }; -use manta_util::serde::{Deserialize, Serialize}; +use manta_util::{ + http::reqwest::KnownUrlClient, + serde::{de::DeserializeOwned, Deserialize, Serialize}, +}; type Signature = Ed25519>; type VerifyingKey = ::VerifyingKey; @@ -157,7 +171,7 @@ impl participant::Priority for Participant { #[inline] fn priority(&self) -> Self::Priority { - self.priority.clone() + self.priority } #[inline] @@ -229,3 +243,243 @@ impl csv::Record for Record { )) } } + +/// Generates an ed25519 keypair with `bytes` as seed. +#[inline] +pub fn generate_keys(bytes: &[u8]) -> Option<(ed25519::SecretKey, ed25519::PublicKey)> { + let keypair = generate_keypair(&mut ChaCha20Rng::from_seed(bytes.try_into().ok()?)); + Some((keypair.secret, keypair.public)) +} + +/// Registers a participant. +#[inline] +pub fn register(twitter_account: String, email: String) { + println!( + "Your {}: \nCopy the following text to \"Twitter\" Section in Google Sheet:\n {}\n", + "Twitter Account".italic(), + twitter_account.blue(), + ); + println!( + "Your {}: \nCopy the following text to \"Email\" Section in Google Sheet:\n {}\n", + "Email".italic(), + email.blue(), + ); + let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); + let seed = Seed::new(&mnemonic, "manta-trusted-setup"); + let keypair = generate_keys(seed.as_bytes()).expect("Should generate a key pair."); + println!( + "Your {}: \nCopy the following text to \"Public Key\" Section in Google Sheet:\n {}\n", + "Public Key".italic(), + bs58::encode(keypair.1).into_string().blue(), + ); + let signature = sign::>, _>( + &keypair.0, + Default::default(), + &format!( + "manta-trusted-setup-twitter:{}, manta-trusted-setup-email:{}", + twitter_account, email + ), + ) + .expect("Signing message should succeed."); + println!( + "Your {}: \nCopy the following text to \"Signature\" Section in Google Sheet: \n {}\n", + "Signature".italic(), + bs58::encode(signature).into_string().blue() + ); + println!( + "Your {}: \nThe following text stores your secret for trusted setup. \ + Save the following text somewhere safe. \n DO NOT share this to anyone else! \ + Please discard this data after the trusted setup ceremony.\n {}", + "Secret".italic(), + mnemonic.phrase().red(), + ); +} + +/// Prompts the client information and get client keys. +#[inline] +pub fn get_client_keys() -> Option<(ed25519::SecretKey, ed25519::PublicKey)> { + println!( + "Please enter your {} that you get when you registered yourself using this tool.", + "Secret".italic() + ); + let seed_bytes = Seed::new( + &Mnemonic::from_phrase( + Input::with_theme(&ColorfulTheme::default()) + .with_prompt("Your Secret") + .validate_with(|input: &String| -> Result<(), &str> { + Mnemonic::validate(input, Language::English) + .map_err(|_| "This is not a valid secret.") + }) + .interact_text() + .expect("Please enter your secret received during `Register`.") + .as_str(), + Language::English, + ) + .expect("Should produce a mnemonic from the secret."), + "manta-trusted-setup", + ) + .as_bytes() + .to_vec(); + generate_keys(&seed_bytes) +} + +/// Testing Suite +#[cfg(test)] +mod test { + use super::*; + + /// Tests if register is visually correct. + #[test] + fn register_is_visually_correct() { + register( + "Mantalorian".to_string(), + "mantalorian@manta.network".to_string(), + ); + } +} + +use core::{fmt::Debug, time::Duration}; +use std::thread; + +/// Contributes to the server. +#[inline] +pub async fn client_contribute() -> Result<(), CeremonyError> +where + C: Ceremony< + Identifier = ed25519::PublicKey, + VerifyingKey = ed25519::PublicKey, + SigningKey = ed25519::SecretKey, + >, + C::Challenge: DeserializeOwned, + C::Identifier: Serialize, + C::Nonce: Clone + Debug + DeserializeOwned + Serialize, + C::Signature: Serialize, +{ + let network_client = KnownUrlClient::new("http://localhost:8080").expect("Should succeed."); + let (sk, pk) = get_client_keys().ok_or_else(|| { + CeremonyError::Unexpected("Received mpc state size is not correct.".to_string()) + })?; + println!( + "{} Contacting Server for Meta Data...", + style("[1/9]").bold().dim() + ); + let term = Term::stdout(); + let (size, nonce) = get_start_meta_data::(pk, &network_client).await?; + let mut trusted_setup_client = Client::::new(pk, nonce, sk); + println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); + loop { + let mpc_state = match network_client + .post::<_, Result, CeremonyError>>( + "query", + &trusted_setup_client.query()?, + ) + .await + .map_err(|_| { + CeremonyError::Network( + "Should have received starting meta data from server".to_string(), + ) + })? { + Ok(message) => match message { + QueryResponse::QueuePosition(position) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!( + "{} Waiting in Queue... There are {} people ahead of you. Estimated Waiting Time: {} minutes.", + style("[2/9]").bold().dim(), + style(position).bold().red(), + style(5*position).bold().blue(), + ); + thread::sleep(Duration::from_secs(10)); + continue; + } + QueryResponse::State(mpc_state) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); + println!( + "{} Downloading Ceremony States...", + style("[3/9]").bold().dim(), + ); + if !size.matches(&mpc_state.state) { + return Err(CeremonyError::Unexpected( + "Received mpc state size is not correct.".to_string(), + )); + } + mpc_state + } + }, + Err(CeremonyError::Timeout) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!( + "{} You have timed out. Waiting in Queue again...", + style("[2/9]").bold().dim(), + ); + continue; + } + Err(CeremonyError::NotYourTurn) => { + return Err(CeremonyError::Unexpected( + "Unexpected error when query mpc state. Should not receive NotYourTurn message." + .to_string(), + )); + } + Err(err) => return Err(err), + }; + println!( + "{} Starting contribution to 3 Circuits...", + style("[4/9]").bold().dim(), + ); + match network_client + .post::<_, Result<(), CeremonyError>>( + "update", + &trusted_setup_client.contribute( + &C::Hasher::default(), + &mpc_state.challenge, + mpc_state.state, + )?, + ) + .await + .map_err(|_| { + CeremonyError::Network( + "Should have received starting meta data from server".to_string(), + ) + })? { + Ok(_) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!( + "{} Waiting for Confirmation from Server...", + style("[8/9]").bold().dim(), + ); + println!( + "{} Congratulations! You have successfully contributed to Manta Trusted Setup Ceremony!...", + style("[9/9]").bold().dim(), + ); + break; + } + Err(CeremonyError::Timeout) => { + term.clear_last_lines(1) + .expect("Clear last lines should succeed."); + println!( + "{} You have timed out. Waiting in Queue again...", + style("[2/9]").bold().dim(), + ); + continue; + } + Err(CeremonyError::NotRegistered) => { + return Err(CeremonyError::Unexpected( + "unexpected error when contribute. Should have registered.".to_string(), + )) + } + Err(CeremonyError::NotYourTurn) => { + println!( + "{} Lag behind server. Contacting Server again...", + style("[8/9]").bold().dim(), + ); + continue; + } + Err(err) => return Err(err), + } + } + Ok(()) +} From bd612d9083248718b906a61e9212250e7f16bc95 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Wed, 14 Sep 2022 18:26:24 -0400 Subject: [PATCH 43/60] chore: fix `generate_keys` --- .../src/groth16/ceremony/config/ppot.rs | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index 1870e3af5..b8756bd78 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -31,9 +31,10 @@ use crate::{ use bip39::{Language, Mnemonic, MnemonicType, Seed}; use colored::Colorize; use console::{style, Term}; +use core::{fmt::Debug, time::Duration}; use dialoguer::{theme::ColorfulTheme, Input}; use manta_crypto::{ - dalek::ed25519::{self, generate_keypair, Ed25519}, + dalek::ed25519::{self, generate_keypair, Ed25519, SECRET_KEY_LENGTH}, rand::{ChaCha20Rng, OsRng, Rand, SeedableRng}, signature::VerifyingKeyType, }; @@ -41,6 +42,7 @@ use manta_util::{ http::reqwest::KnownUrlClient, serde::{de::DeserializeOwned, Deserialize, Serialize}, }; +use std::thread; type Signature = Ed25519>; type VerifyingKey = ::VerifyingKey; @@ -247,7 +249,12 @@ impl csv::Record for Record { /// Generates an ed25519 keypair with `bytes` as seed. #[inline] pub fn generate_keys(bytes: &[u8]) -> Option<(ed25519::SecretKey, ed25519::PublicKey)> { - let keypair = generate_keypair(&mut ChaCha20Rng::from_seed(bytes.try_into().ok()?)); + if ed25519::SECRET_KEY_LENGTH > bytes.len() { + return None; + } + let keypair = generate_keypair(&mut ChaCha20Rng::from_seed( + bytes[0..SECRET_KEY_LENGTH].try_into().ok()?, + )); Some((keypair.secret, keypair.public)) } @@ -323,24 +330,6 @@ pub fn get_client_keys() -> Option<(ed25519::SecretKey, ed25519::PublicKey)> { generate_keys(&seed_bytes) } -/// Testing Suite -#[cfg(test)] -mod test { - use super::*; - - /// Tests if register is visually correct. - #[test] - fn register_is_visually_correct() { - register( - "Mantalorian".to_string(), - "mantalorian@manta.network".to_string(), - ); - } -} - -use core::{fmt::Debug, time::Duration}; -use std::thread; - /// Contributes to the server. #[inline] pub async fn client_contribute() -> Result<(), CeremonyError> @@ -483,3 +472,18 @@ where } Ok(()) } + +/// Testing Suite +#[cfg(test)] +mod test { + use super::*; + + /// Tests if register is visually correct. + #[test] + fn register_is_visually_correct() { + register( + "Mantalorian".to_string(), + "mantalorian@manta.network".to_string(), + ); + } +} From 81778b4cb0688f349d760a9537149b956fb34e44 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Wed, 14 Sep 2022 20:18:09 -0400 Subject: [PATCH 44/60] fix: ci --- .../src/groth16/ceremony/client.rs | 29 +++++++++++++------ .../src/groth16/ceremony/config/mod.rs | 7 +++-- .../src/groth16/ceremony/mod.rs | 7 ++++- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index d723bee9e..b1a68b031 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -18,23 +18,33 @@ use crate::{ ceremony::signature::{Nonce, SignedMessage}, - groth16::{ - ceremony::{ - message::{CeremonySize, ContributeRequest, QueryRequest}, - Ceremony, CeremonyError, - }, - mpc::{contribute, State}, + groth16::ceremony::{ + message::{CeremonySize, QueryRequest}, + Ceremony, CeremonyError, }, }; -use console::style; +use alloc::string::ToString; use core::fmt::Debug; -use manta_crypto::rand::OsRng; use manta_util::{ http::reqwest::KnownUrlClient, serde::{de::DeserializeOwned, Serialize}, - BoxArray, }; +#[cfg(feature = "std")] +use crate::groth16::{ + ceremony::message::ContributeRequest, + mpc::{contribute, State}, +}; + +#[cfg(feature = "std")] +use console::style; + +#[cfg(feature = "std")] +use manta_crypto::rand::OsRng; + +#[cfg(feature = "std")] +use manta_util::BoxArray; + /// Client pub struct Client where @@ -85,6 +95,7 @@ where } /// Contributes to the state on the server. + #[cfg(feature = "std")] #[inline] pub fn contribute( &mut self, diff --git a/manta-trusted-setup/src/groth16/ceremony/config/mod.rs b/manta-trusted-setup/src/groth16/ceremony/config/mod.rs index d52f3fb58..50b57c40f 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/mod.rs @@ -16,6 +16,9 @@ //! Groth16 Trusted Setup Ceremony Configurations -#[cfg(feature = "serde")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] +#[cfg(all(feature = "serde", feature = "csv", feature = "std", feature = "serde"))] +#[cfg_attr( + doc_cfg, + doc(cfg(all(feature = "serde", feature = "csv", feature = "std", feature = "serde"))) +)] pub mod ppot; diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 5e5229f07..db5e2a96d 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -23,6 +23,7 @@ use crate::{ }, groth16::mpc::Configuration, }; +use alloc::string::String; use core::fmt::Debug; use manta_util::{ collections::vec_deque::MultiVecDeque, @@ -31,8 +32,12 @@ use manta_util::{ pub mod client; pub mod config; -pub mod coordinator; pub mod message; + +#[cfg(feature = "std")] +pub mod coordinator; + +#[cfg(feature = "std")] pub mod server; /// Participant Queue Type From db8b9ce31f59f0408745e1da08602a37b2b1b65b Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Sat, 17 Sep 2022 17:50:14 +0200 Subject: [PATCH 45/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- manta-crypto/Cargo.toml | 2 +- manta-parameters/Cargo.toml | 4 +- manta-pay/Cargo.toml | 2 +- manta-trusted-setup/src/ceremony/mod.rs | 4 +- manta-trusted-setup/src/ceremony/signature.rs | 69 ++++++- .../src/groth16/ceremony/client.rs | 195 +++++++----------- .../src/groth16/ceremony/config/ppot.rs | 44 ++-- .../src/groth16/ceremony/coordinator.rs | 10 +- .../src/groth16/ceremony/message.rs | 43 ++-- .../src/groth16/ceremony/mod.rs | 31 ++- .../src/groth16/ceremony/server.rs | 20 +- 11 files changed, 234 insertions(+), 190 deletions(-) diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index 6d2c044f6..d9228cb92 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -42,10 +42,10 @@ getrandom = ["rand_core/getrandom"] # Serde Serialization serde = [ + "ed25519-dalek?/serde", "manta-util/serde-alloc", "manta-util/serde-array", "rand_chacha?/serde1", - "ed25519-dalek?/serde", ] # Standard Library diff --git a/manta-parameters/Cargo.toml b/manta-parameters/Cargo.toml index 059ec8dea..e0c238b0e 100644 --- a/manta-parameters/Cargo.toml +++ b/manta-parameters/Cargo.toml @@ -32,7 +32,7 @@ download = ["anyhow", "attohttpc", "std"] std = ["anyhow?/std"] [dependencies] -anyhow = { version = "1.0.64", optional = true, default-features = false } +anyhow = { version = "1.0.65", optional = true, default-features = false } attohttpc = { version = "0.22.0", optional = true } blake3 = { version = "1.3.1", default-features = false } @@ -44,7 +44,7 @@ tempfile = { version = "3.3.0", default-features = false } walkdir = { version = "2.3.2", default-features = false } [build-dependencies] -anyhow = { version = "1.0.64", default-features = false, features = ["std"] } +anyhow = { version = "1.0.65", default-features = false, features = ["std"] } blake3 = { version = "1.3.1", default-features = false, features = ["std"] } gitignore = { version = "1.0.7", default-features = false } hex = { version = "0.4.3", default-features = false, features = ["std"] } diff --git a/manta-pay/Cargo.toml b/manta-pay/Cargo.toml index c6fa1f33a..2f11a9599 100644 --- a/manta-pay/Cargo.toml +++ b/manta-pay/Cargo.toml @@ -106,7 +106,7 @@ ark-std = { version = "0.3.0", optional = true, default-features = false } bip32 = { version = "0.3.0", optional = true, default-features = false, features = ["bip39", "secp256k1"] } blake2 = { version = "0.10.4", default-features = false } bs58 = { version = "0.4.0", optional = true, default-features = false, features = ["alloc"] } -clap = { version = "3.2.21", optional = true, default-features = false, features = ["color", "derive", "std", "suggestions", "unicode", "wrap_help"] } +clap = { version = "3.2.22", optional = true, default-features = false, features = ["color", "derive", "std", "suggestions", "unicode", "wrap_help"] } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } futures = { version = "0.3.24", optional = true, default-features = false } indexmap = { version = "1.9.1", optional = true, default-features = false } diff --git a/manta-trusted-setup/src/ceremony/mod.rs b/manta-trusted-setup/src/ceremony/mod.rs index b29ec0b30..1a2a759bd 100644 --- a/manta-trusted-setup/src/ceremony/mod.rs +++ b/manta-trusted-setup/src/ceremony/mod.rs @@ -20,6 +20,6 @@ pub mod participant; pub mod registry; pub mod signature; -#[cfg(all(feature = "std", feature = "bincode"))] -#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", feature = "bincode"))))] +#[cfg(all(feature = "bincode", feature = "std"))] +#[cfg_attr(doc_cfg, doc(cfg(all(feature = "bincode", feature = "std"))))] pub mod util; diff --git a/manta-trusted-setup/src/ceremony/signature.rs b/manta-trusted-setup/src/ceremony/signature.rs index d0b719815..296e7dafd 100644 --- a/manta-trusted-setup/src/ceremony/signature.rs +++ b/manta-trusted-setup/src/ceremony/signature.rs @@ -57,10 +57,10 @@ impl Nonce for u64 { #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] pub struct RawMessage { /// Nonce - pub nonce: N, + nonce: N, /// Encoded Message - pub encoded_message: Vec, + encoded_message: Vec, } impl RawMessage { @@ -271,3 +271,68 @@ where ) } } + +/// Signer +pub struct Signer +where + S: SignatureScheme, +{ + /// Nonce + nonce: S::Nonce, + + /// Signing Key + signing_key: S::SigningKey, + + /// Identifier + identifier: I, +} + +impl Signer +where + S: SignatureScheme, +{ + /// Builds a new [`Signer`] from `nonce`, `signing_key`, and `identifier`. + #[inline] + pub fn new(nonce: S::Nonce, signing_key: S::SigningKey, identifier: I) -> Self { + Self { + nonce, + signing_key, + identifier, + } + } + + /// Returns the nonce for `self`. + #[inline] + pub fn nonce(&self) -> &S::Nonce { + &self.nonce + } + + /// + #[inline] + pub fn increment_nonce(&mut self) { + self.nonce.increment() + } + + /// Returns the identifier for `self`. + #[inline] + pub fn identifier(&self) -> &I { + &self.identifier + } + + /// Signs `message` using the internal signing key and + #[cfg(feature = "bincode")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "bincode")))] + #[inline] + pub fn sign(&self, message: T) -> Result, bincode::Error> + where + I: Clone, + T: Serialize, + { + SignedMessage::generate( + &self.signing_key, + self.nonce.clone(), + self.identifier.clone(), + message, + ) + } +} diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index b1a68b031..a508660cb 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -17,152 +17,111 @@ //! Trusted Setup Client use crate::{ - ceremony::signature::{Nonce, SignedMessage}, - groth16::ceremony::{ - message::{CeremonySize, QueryRequest}, - Ceremony, CeremonyError, + ceremony::signature::{SignedMessage, Signer}, + groth16::{ + ceremony::{ + message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, + Ceremony, CeremonyError, UnexpectedError, + }, + mpc::{contribute, State}, }, }; -use alloc::string::ToString; -use core::fmt::Debug; +use manta_crypto::rand::OsRng; use manta_util::{ http::reqwest::KnownUrlClient, serde::{de::DeserializeOwned, Serialize}, }; -#[cfg(feature = "std")] -use crate::groth16::{ - ceremony::message::ContributeRequest, - mpc::{contribute, State}, -}; - -#[cfg(feature = "std")] -use console::style; - -#[cfg(feature = "std")] -use manta_crypto::rand::OsRng; - -#[cfg(feature = "std")] -use manta_util::BoxArray; - /// Client -pub struct Client +pub struct Client where C: Ceremony, { - /// Identifier - identifier: C::Identifier, - - /// Current Nonce - nonce: C::Nonce, + /// Signer + signer: Signer, - /// Signing Key - signing_key: C::SigningKey, + /// HTTP Client + client: KnownUrlClient, } -impl Client +impl Client where C: Ceremony, { - /// Builds a new [`Client`] with `participant` and `private_key`. + /// #[inline] - pub fn new(identifier: C::Identifier, nonce: C::Nonce, signing_key: C::SigningKey) -> Self { - Self { - identifier, - nonce, - signing_key, - } + fn sign( + &mut self, + message: T, + ) -> Result, CeremonyError> + where + T: Serialize, + { + let signed_message = self + .signer + .sign(message) + .map_err(|_| CeremonyError::Unexpected(UnexpectedError::Serialization))?; + self.signer.increment_nonce(); + Ok(signed_message) } - /// Queries the server state. + /// #[inline] - pub fn query( - &mut self, - ) -> Result, CeremonyError> { - let signed_message = SignedMessage::generate( - &self.signing_key, - self.nonce.clone(), - self.identifier.clone(), - QueryRequest, - ) - .map_err(|_| { - CeremonyError::Unexpected( - "Cannot sign message since it cannot be serialized.".to_string(), - ) - })?; - self.nonce.increment(); - Ok(signed_message) + pub async fn start(&self) -> Result<(CeremonySize, C::Nonce), CeremonyError> + where + C::Identifier: Serialize, + C::Nonce: DeserializeOwned, + { + self.client + .post("start", &self.signer.identifier()) + .await + .map_err(|_| CeremonyError::Network("".into())) + } + + /// + #[inline] + pub async fn query(&mut self) -> Result, CeremonyError> + where + C::Identifier: Serialize, + C::Nonce: Serialize, + C::Signature: Serialize, + QueryResponse: DeserializeOwned, + { + let signed_message = self.sign(QueryRequest)?; + self.client + .post("query", &signed_message) + .await + .map_err(|_| CeremonyError::Network("".into())) } - /// Contributes to the state on the server. - #[cfg(feature = "std")] + /// #[inline] - pub fn contribute( + pub async fn contribute( &mut self, hasher: &C::Hasher, - challenge: &BoxArray, - mut state: BoxArray, CIRCUIT_COUNT>, - ) -> Result< - SignedMessage>, - CeremonyError, - > { - let circuit_name = ["ToPrivate", "PrivateTransfer", "ToPublic"]; + challenge: &[C::Challenge], + mut state: Vec>, + ) -> Result<(), CeremonyError> + where + C::Identifier: Serialize, + C::Nonce: Serialize, + C::Signature: Serialize, + ContributeRequest: Serialize, + { let mut rng = OsRng; - let mut proofs = Vec::new(); - for i in 0..CIRCUIT_COUNT { - println!( - "{} Contributing to {} Circuits...", - style(format!("[{}/9]", i + 5)).bold().dim(), - circuit_name[i], - ); - proofs.push( - contribute(hasher, &challenge[i], &mut state[i], &mut rng) - .ok_or_else(|| CeremonyError::Unexpected("Cannot contribute.".to_string()))?, + let mut proof = Vec::new(); + // FIXME: have to check challenge and state lengths are equal + for i in 0..challenge.len() { + proof.push( + contribute(hasher, &challenge[i], &mut state[i], &mut rng).ok_or( + CeremonyError::Unexpected(UnexpectedError::FailedContribution), + )?, ); } - println!( - "{} Waiting for Confirmation from Server... Estimated Waiting Time: {} minutes.", - style("[8/9]").bold().dim(), - style("3").bold().blue(), - ); - let signed_message = SignedMessage::generate( - &self.signing_key, - self.nonce.clone(), - self.identifier.clone(), - ContributeRequest { - state, - proof: BoxArray::from_vec(proofs), - }, - ) - .map_err(|_| { - CeremonyError::Unexpected( - "Cannot sign message since it cannot be serialized.".to_string(), - ) - })?; - self.nonce.increment(); - Ok(signed_message) + let signed_message = self.sign(ContributeRequest { state, proof })?; + self.client + .post("update", &signed_message) + .await + .map_err(|_| CeremonyError::Network("".into())) } } - -/// Gets state size from server. -#[inline] -pub async fn get_start_meta_data( - identity: C::Identifier, - network_client: &KnownUrlClient, -) -> Result<(CeremonySize, C::Nonce), CeremonyError> -where - C: Ceremony, - C::Identifier: Serialize, - C::Nonce: DeserializeOwned + Debug, -{ - network_client - .post::<_, Result<(CeremonySize, C::Nonce), CeremonyError>>( - "start", &identity, - ) - .await - .map_err(|_| { - CeremonyError::Network( - "Should have received starting meta data from server".to_string(), - ) - })? -} diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index b8756bd78..c0a2d60a5 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -23,9 +23,7 @@ use crate::{ signature::{sign, verify, Nonce as _, RawMessage, SignatureScheme}, }, groth16::ceremony::{ - client::{get_start_meta_data, Client}, - message::QueryResponse, - Ceremony, CeremonyError, + client::Client, message::QueryResponse, Ceremony, CeremonyError, UnexpectedError, }, }; use bip39::{Language, Mnemonic, MnemonicType, Seed}; @@ -77,14 +75,14 @@ impl From for usize { #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] #[serde( bound( - deserialize = " - VerifyingKey: Deserialize<'de>, - Nonce: Deserialize<'de>, - ", - serialize = " - VerifyingKey: Serialize, - Nonce: Serialize, - " + deserialize = r" + VerifyingKey: Deserialize<'de>, + Nonce: Deserialize<'de>, + ", + serialize = r" + VerifyingKey: Serialize, + Nonce: Serialize, + " ), crate = "manta_util::serde", deny_unknown_fields @@ -344,16 +342,17 @@ where C::Nonce: Clone + Debug + DeserializeOwned + Serialize, C::Signature: Serialize, { + /* TODO: let network_client = KnownUrlClient::new("http://localhost:8080").expect("Should succeed."); - let (sk, pk) = get_client_keys().ok_or_else(|| { - CeremonyError::Unexpected("Received mpc state size is not correct.".to_string()) - })?; + let (sk, pk) = get_client_keys().ok_or(CeremonyError::Unexpected( + UnexpectedError::IncorrectStateSize, + ))?; println!( "{} Contacting Server for Meta Data...", style("[1/9]").bold().dim() ); let term = Term::stdout(); - let (size, nonce) = get_start_meta_data::(pk, &network_client).await?; + let (size, nonce) = get_start_meta_data::(&network_client, pk).await?; let mut trusted_setup_client = Client::::new(pk, nonce, sk); println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); loop { @@ -378,7 +377,7 @@ where style(position).bold().red(), style(5*position).bold().blue(), ); - thread::sleep(Duration::from_secs(10)); + thread::sleep(Duration::from_secs(1)); continue; } QueryResponse::State(mpc_state) => { @@ -391,7 +390,7 @@ where ); if !size.matches(&mpc_state.state) { return Err(CeremonyError::Unexpected( - "Received mpc state size is not correct.".to_string(), + UnexpectedError::IncorrectStateSize, )); } mpc_state @@ -407,10 +406,7 @@ where continue; } Err(CeremonyError::NotYourTurn) => { - return Err(CeremonyError::Unexpected( - "Unexpected error when query mpc state. Should not receive NotYourTurn message." - .to_string(), - )); + return Err(CeremonyError::Unexpected(UnexpectedError::SkippedTurn)); } Err(err) => return Err(err), }; @@ -457,8 +453,8 @@ where } Err(CeremonyError::NotRegistered) => { return Err(CeremonyError::Unexpected( - "unexpected error when contribute. Should have registered.".to_string(), - )) + UnexpectedError::MissingRegisteredParticipant, + )); } Err(CeremonyError::NotYourTurn) => { println!( @@ -471,6 +467,8 @@ where } } Ok(()) + */ + todo!() } /// Testing Suite diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index f5e02d5c2..d571e1bd5 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -23,7 +23,7 @@ use crate::{ signature::{Nonce, SignedMessage}, }, groth16::{ - ceremony::{message::MPCState, Ceremony, CeremonyError, Queue}, + ceremony::{message::MPCState, Ceremony, CeremonyError, Queue, UnexpectedError}, mpc::{verify_transform, Proof, State, StateSize}, }, }; @@ -165,13 +165,13 @@ where /// Gets the current state and challenge. #[inline] - pub fn state_and_challenge(&self) -> MPCState + pub fn state_and_challenge(&self) -> MPCState where C::Challenge: Clone, { MPCState { - state: self.state.clone(), - challenge: self.challenge.clone(), + state: self.state.to_vec(), + challenge: self.challenge.to_vec(), } } @@ -263,7 +263,7 @@ where Some(participant) => participant.set_contributed(), _ => { return Err(CeremonyError::Unexpected( - "Cannot get participant.".to_string(), + UnexpectedError::MissingRegisteredParticipant, )); } }; diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index e62716adb..083e669ed 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -23,45 +23,42 @@ use crate::groth16::{ mpc::{Proof, State, StateSize}, }; use manta_crypto::arkworks::pairing::Pairing; -use manta_util::{ - serde::{Deserialize, Serialize}, - BoxArray, -}; +use manta_util::serde::{Deserialize, Serialize}; /// MPC States -#[derive(Serialize, Deserialize)] +#[derive(Deserialize, Serialize)] #[serde( bound( - serialize = "C::Challenge: Serialize", deserialize = "C::Challenge: Deserialize<'de>", + serialize = "C::Challenge: Serialize", ), crate = "manta_util::serde", deny_unknown_fields )] -pub struct MPCState +pub struct MPCState where C: Ceremony, { - /// State - pub state: BoxArray, CIRCUIT_COUNT>, + /// States + pub state: Vec>, - /// Challenge - pub challenge: BoxArray, + /// Challenges + pub challenge: Vec, } /// Ceremony Size #[derive(Clone, Deserialize, Serialize)] #[serde(crate = "manta_util::serde", deny_unknown_fields)] -pub struct CeremonySize(pub BoxArray); +pub struct CeremonySize(pub Vec); -impl CeremonySize { +impl CeremonySize { /// Checks that each size in `self` matches each [`State`] in `states`. #[inline] - pub fn matches

(&self, states: &[State

; CIRCUIT_COUNT]) -> bool + pub fn matches

(&self, states: &[State

]) -> bool where P: Pairing, { - self.0.iter().zip(states).all(|(l, r)| l.matches(&r.0)) + self.0.len() == states.len() && self.0.iter().zip(states).all(|(l, r)| l.matches(&r.0)) } } @@ -76,13 +73,13 @@ pub struct QueryRequest; #[derive(Deserialize, Serialize)] #[serde( bound( - deserialize = "MPCState: Deserialize<'de>", - serialize = "MPCState: Serialize" + deserialize = "MPCState: Deserialize<'de>", + serialize = "MPCState: Serialize" ), crate = "manta_util::serde", deny_unknown_fields )] -pub enum QueryResponse +pub enum QueryResponse where C: Ceremony, { @@ -90,23 +87,23 @@ where QueuePosition(usize), /// MPC State - State(MPCState), + State(MPCState), } /// Contribute Request #[derive(Deserialize, Serialize)] #[serde( - bound(deserialize = "", serialize = ""), + bound(deserialize = "", serialize = "",), crate = "manta_util::serde", deny_unknown_fields )] -pub struct ContributeRequest +pub struct ContributeRequest where C: Ceremony, { /// State - pub state: BoxArray, CIRCUIT_COUNT>, + pub state: Vec>, /// Proof - pub proof: BoxArray, CIRCUIT_COUNT>, + pub proof: Vec>, } diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index db5e2a96d..f01ada803 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -97,12 +97,33 @@ where /// Timed-out Timeout, - /// Client unable to Generate Request - UnableToGenerateRequest(String), + /// Network Error + Network(String), /// Unexpected Server Error - Unexpected(String), + Unexpected(UnexpectedError), +} - /// Network Error - Network(String), +/// Unexpected Error +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde(crate = "manta_util::serde", deny_unknown_fields) +)] +#[derive(Debug)] +pub enum UnexpectedError { + /// Serialization Error + Serialization, + + /// Failed to generate a valid Contribution + FailedContribution, + + /// Missing Registered Participant + MissingRegisteredParticipant, + + /// Incorrect State Size + IncorrectStateSize, + + /// Unexpected Turn Skip by the Ceremony Server + SkippedTurn, } diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 2ff2ab8ed..6607c650e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -26,7 +26,7 @@ use crate::{ ceremony::{ coordinator::Coordinator, message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, - Ceremony, CeremonyError, Participant as _, + Ceremony, CeremonyError, Participant as _, UnexpectedError, }, mpc::{State, StateSize}, }, @@ -90,7 +90,7 @@ where Ok(Self { coordinator: Arc::new(Mutex::new( deserialize_from_file(path) - .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?, + .map_err(|_| CeremonyError::Unexpected(UnexpectedError::Serialization))?, )), recovery_directory, }) @@ -101,13 +101,13 @@ where pub async fn start( self, request: C::Identifier, - ) -> Result<(CeremonySize, C::Nonce), CeremonyError> + ) -> Result<(CeremonySize, C::Nonce), CeremonyError> where C::Nonce: Clone, { let coordinator = self.coordinator.lock(); Ok(( - CeremonySize(BoxArray::from_unchecked(*coordinator.size())), + CeremonySize(coordinator.size().to_vec()), coordinator .registry() .get(&request) @@ -122,7 +122,7 @@ where pub async fn query( self, request: SignedMessage, - ) -> Result, CeremonyError> + ) -> Result, CeremonyError> where C::Challenge: Clone, { @@ -143,7 +143,7 @@ where #[inline] pub async fn update( self, - request: SignedMessage>, + request: SignedMessage>, ) -> Result<(), CeremonyError> where Coordinator: Serialize, @@ -151,14 +151,18 @@ where let mut coordinator = self.coordinator.lock(); coordinator.preprocess_request(&request)?; let message = request.message; - coordinator.update(&request.identifier, message.state, message.proof)?; + coordinator.update( + &request.identifier, + BoxArray::from_vec(message.state), + BoxArray::from_vec(message.proof), + )?; serialize_into_file( OpenOptions::new().write(true).create_new(true), &Path::new(&self.recovery_directory) .join(format!("transcript{}.data", coordinator.round())), &coordinator.deref(), ) - .map_err(|e| CeremonyError::Unexpected(format!("{:?}", e)))?; + .map_err(|_| CeremonyError::Unexpected(UnexpectedError::Serialization))?; println!("{} participants have contributed.", coordinator.round()); Ok(()) } From c8efda8c3e7c37bb9b332c0cbc6668b4bd9761a2 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Sun, 18 Sep 2022 15:59:45 +0200 Subject: [PATCH 46/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- .../src/groth16/ceremony/client.rs | 42 ++++++++++++--- .../src/groth16/ceremony/config/ppot.rs | 54 +++++++++++++++---- .../src/groth16/ceremony/coordinator.rs | 6 +-- .../src/groth16/ceremony/message.rs | 29 ++-------- .../src/groth16/ceremony/mod.rs | 23 +++++++- 5 files changed, 108 insertions(+), 46 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index a508660cb..a47a1442b 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -21,7 +21,7 @@ use crate::{ groth16::{ ceremony::{ message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, - Ceremony, CeremonyError, UnexpectedError, + Ceremony, CeremonyError, MpcState, UnexpectedError, }, mpc::{contribute, State}, }, @@ -42,12 +42,29 @@ where /// HTTP Client client: KnownUrlClient, + + /// Ceremony Size + ceremony_size: CeremonySize, } impl Client where C: Ceremony, { + /// + #[inline] + fn new_unchecked( + signer: Signer, + client: KnownUrlClient, + ceremony_size: CeremonySize, + ) -> Self { + Self { + signer, + client, + ceremony_size, + } + } + /// #[inline] fn sign( @@ -67,15 +84,24 @@ where /// #[inline] - pub async fn start(&self) -> Result<(CeremonySize, C::Nonce), CeremonyError> + pub async fn start( + signing_key: C::SigningKey, + identifier: C::Identifier, + client: KnownUrlClient, + ) -> Result> where C::Identifier: Serialize, C::Nonce: DeserializeOwned, { - self.client - .post("start", &self.signer.identifier()) + let (ceremony_size, nonce) = client + .post("start", &identifier) .await - .map_err(|_| CeremonyError::Network("".into())) + .map_err(|_| CeremonyError::Network("".into()))?; + Ok(Self::new_unchecked( + Signer::new(nonce, signing_key, identifier), + client, + ceremony_size, + )) } /// @@ -99,8 +125,7 @@ where pub async fn contribute( &mut self, hasher: &C::Hasher, - challenge: &[C::Challenge], - mut state: Vec>, + mut state: MpcState, ) -> Result<(), CeremonyError> where C::Identifier: Serialize, @@ -108,6 +133,7 @@ where C::Signature: Serialize, ContributeRequest: Serialize, { + /* let mut rng = OsRng; let mut proof = Vec::new(); // FIXME: have to check challenge and state lengths are equal @@ -123,5 +149,7 @@ where .post("update", &signed_message) .await .map_err(|_| CeremonyError::Network("".into())) + */ + todo!() } } diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index c0a2d60a5..ea400c83c 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -188,10 +188,19 @@ impl participant::Priority for Participant { deny_unknown_fields )] pub struct Record { + /// twitter: String, + + /// email: String, + + /// priority: String, + + /// verifying_key: String, + + /// signature: String, } @@ -330,23 +339,48 @@ pub fn get_client_keys() -> Option<(ed25519::SecretKey, ed25519::PublicKey)> { /// Contributes to the server. #[inline] -pub async fn client_contribute() -> Result<(), CeremonyError> +pub async fn client_contribute( + signing_key: C::SigningKey, + identifier: C::Identifier, +) -> Result<(), CeremonyError> where - C: Ceremony< - Identifier = ed25519::PublicKey, - VerifyingKey = ed25519::PublicKey, - SigningKey = ed25519::SecretKey, - >, + C: Ceremony, C::Challenge: DeserializeOwned, C::Identifier: Serialize, C::Nonce: Clone + Debug + DeserializeOwned + Serialize, C::Signature: Serialize, { + let mut client = Client::start( + signing_key, + identifier, + KnownUrlClient::new("http://localhost:8080").expect("Should succeed."), + ) + .await?; + + loop { + let state = match client.query().await { + Ok(QueryResponse::QueuePosition(position)) => { + // + todo!() + } + Ok(QueryResponse::State(state)) => { + // + todo!() + } + Err(CeremonyError::Timeout) => todo!(), + Err(CeremonyError::NotYourTurn) => todo!(), + Err(err) => todo!(), + }; + match client.contribute(&C::Hasher::default(), state).await { + Ok(_) => todo!(), + Err(CeremonyError::Timeout) => todo!(), + Err(CeremonyError::NotRegistered) => todo!(), + Err(CeremonyError::NotYourTurn) => todo!(), + Err(err) => todo!(), + } + } + /* TODO: - let network_client = KnownUrlClient::new("http://localhost:8080").expect("Should succeed."); - let (sk, pk) = get_client_keys().ok_or(CeremonyError::Unexpected( - UnexpectedError::IncorrectStateSize, - ))?; println!( "{} Contacting Server for Meta Data...", style("[1/9]").bold().dim() diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index d571e1bd5..6790809e2 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -23,7 +23,7 @@ use crate::{ signature::{Nonce, SignedMessage}, }, groth16::{ - ceremony::{message::MPCState, Ceremony, CeremonyError, Queue, UnexpectedError}, + ceremony::{Ceremony, CeremonyError, MpcState, Queue, UnexpectedError}, mpc::{verify_transform, Proof, State, StateSize}, }, }; @@ -165,11 +165,11 @@ where /// Gets the current state and challenge. #[inline] - pub fn state_and_challenge(&self) -> MPCState + pub fn state_and_challenge(&self) -> MpcState where C::Challenge: Clone, { - MPCState { + MpcState { state: self.state.to_vec(), challenge: self.challenge.to_vec(), } diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 083e669ed..9207b9d2e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -19,33 +19,12 @@ // FIXME: Use correct serde configuration since we don't assume it's always available use crate::groth16::{ - ceremony::Ceremony, + ceremony::{Ceremony, MpcState}, mpc::{Proof, State, StateSize}, }; use manta_crypto::arkworks::pairing::Pairing; use manta_util::serde::{Deserialize, Serialize}; -/// MPC States -#[derive(Deserialize, Serialize)] -#[serde( - bound( - deserialize = "C::Challenge: Deserialize<'de>", - serialize = "C::Challenge: Serialize", - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct MPCState -where - C: Ceremony, -{ - /// States - pub state: Vec>, - - /// Challenges - pub challenge: Vec, -} - /// Ceremony Size #[derive(Clone, Deserialize, Serialize)] #[serde(crate = "manta_util::serde", deny_unknown_fields)] @@ -73,8 +52,8 @@ pub struct QueryRequest; #[derive(Deserialize, Serialize)] #[serde( bound( - deserialize = "MPCState: Deserialize<'de>", - serialize = "MPCState: Serialize" + deserialize = "MpcState: Deserialize<'de>", + serialize = "MpcState: Serialize" ), crate = "manta_util::serde", deny_unknown_fields @@ -87,7 +66,7 @@ where QueuePosition(usize), /// MPC State - State(MPCState), + State(MpcState), } /// Contribute Request diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index f01ada803..7fc46ccfb 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -21,7 +21,7 @@ use crate::{ participant::{Participant, Priority}, signature::SignatureScheme, }, - groth16::mpc::Configuration, + groth16::mpc::{Configuration, State}, }; use alloc::string::String; use core::fmt::Debug; @@ -60,6 +60,27 @@ pub trait Ceremony: Configuration + SignatureScheme { > + Priority; } +/// MPC States +#[derive(Deserialize, Serialize)] +#[serde( + bound( + deserialize = "C::Challenge: Deserialize<'de>", + serialize = "C::Challenge: Serialize", + ), + crate = "manta_util::serde", + deny_unknown_fields +)] +pub struct MpcState +where + C: Ceremony, +{ + /// States + pub state: Vec>, + + /// Challenges + pub challenge: Vec, +} + /// Ceremony Error #[cfg_attr( feature = "serde", From da3effc4056adeaec08db0853ac4ef0a0f0b655c Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Mon, 19 Sep 2022 23:37:43 +0200 Subject: [PATCH 47/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- .../src/groth16/ceremony/client.rs | 129 ++++++- .../src/groth16/ceremony/config/ppot.rs | 53 ++- .../src/groth16/ceremony/coordinator.rs | 11 +- .../src/groth16/ceremony/message.rs | 12 +- .../src/groth16/ceremony/mod.rs | 35 +- .../src/groth16/ceremony/server.rs | 4 +- manta-trusted-setup/src/groth16/mpc.rs | 6 +- manta-trusted-setup/src/groth16/ppot/mpc.rs | 21 +- manta-trusted-setup/src/mpc.rs | 326 +++++++++++++++++- manta-util/src/macros.rs | 23 ++ 10 files changed, 525 insertions(+), 95 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index a47a1442b..f3f7c8c9d 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -21,17 +21,41 @@ use crate::{ groth16::{ ceremony::{ message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, - Ceremony, CeremonyError, MpcState, UnexpectedError, + Ceremony, CeremonyError, Round, UnexpectedError, }, - mpc::{contribute, State}, + mpc, }, }; use manta_crypto::rand::OsRng; use manta_util::{ - http::reqwest::KnownUrlClient, + http::reqwest::{self, IntoUrl, KnownUrlClient}, serde::{de::DeserializeOwned, Serialize}, }; +/// Converts the [`reqwest`] error `err` into a [`CeremonyError`] depending on whether it comes from +/// a timeout or other network error. +#[inline] +fn into_ceremony_error(err: reqwest::Error) -> CeremonyError +where + C: Ceremony, +{ + if err.is_timeout() { + CeremonyError::Timeout + } else { + CeremonyError::Network + } +} + +/// Client Update States +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum Update { + /// Position Updated + Position(u64), + + /// Timeout + Timeout, +} + /// Client pub struct Client where @@ -96,7 +120,7 @@ where let (ceremony_size, nonce) = client .post("start", &identifier) .await - .map_err(|_| CeremonyError::Network("".into()))?; + .map_err(into_ceremony_error)?; Ok(Self::new_unchecked( Signer::new(nonce, signing_key, identifier), client, @@ -106,7 +130,7 @@ where /// #[inline] - pub async fn query(&mut self) -> Result, CeremonyError> + async fn query(&mut self) -> Result, CeremonyError> where C::Identifier: Serialize, C::Nonce: Serialize, @@ -114,18 +138,26 @@ where QueryResponse: DeserializeOwned, { let signed_message = self.sign(QueryRequest)?; - self.client - .post("query", &signed_message) - .await - .map_err(|_| CeremonyError::Network("".into())) + match self.client.post("query", &signed_message).await { + Ok(QueryResponse::State(state)) => match state.with_valid_shape() { + Some(state) if self.ceremony_size.matches(&state.state) => { + Ok(QueryResponse::State(state)) + } + _ => Err(CeremonyError::Unexpected( + UnexpectedError::IncorrectStateSize, + )), + }, + Ok(response) => Ok(response), + Err(err) => Err(into_ceremony_error(err)), + } } /// #[inline] - pub async fn contribute( + async fn contribute( &mut self, hasher: &C::Hasher, - mut state: MpcState, + mut round: Round, ) -> Result<(), CeremonyError> where C::Identifier: Serialize, @@ -133,23 +165,82 @@ where C::Signature: Serialize, ContributeRequest: Serialize, { - /* let mut rng = OsRng; let mut proof = Vec::new(); - // FIXME: have to check challenge and state lengths are equal - for i in 0..challenge.len() { + for i in 0..round.state.len() { proof.push( - contribute(hasher, &challenge[i], &mut state[i], &mut rng).ok_or( + mpc::contribute(hasher, &round.challenge[i], &mut round.state[i], &mut rng).ok_or( CeremonyError::Unexpected(UnexpectedError::FailedContribution), )?, ); } - let signed_message = self.sign(ContributeRequest { state, proof })?; + let signed_message = self.sign(ContributeRequest { + state: round.state.into(), + proof, + })?; self.client .post("update", &signed_message) .await - .map_err(|_| CeremonyError::Network("".into())) - */ - todo!() + .map_err(into_ceremony_error) + } + + /// + #[inline] + pub async fn try_contribute(&mut self) -> Result, CeremonyError> + where + C::Identifier: Serialize, + C::Nonce: Serialize, + C::Signature: Serialize, + ContributeRequest: Serialize, + QueryResponse: DeserializeOwned, + { + let state = match self.query().await { + Ok(QueryResponse::State(state)) => state, + Ok(QueryResponse::QueuePosition(position)) => { + return Ok(Some(Update::Position(position))) + } + Err(CeremonyError::Timeout) => return Ok(Some(Update::Timeout)), + Err(err) => return Err(err), + }; + match self.contribute(&C::Hasher::default(), state).await { + Ok(_) => Ok(None), + Err(CeremonyError::Timeout) | Err(CeremonyError::NotYourTurn) => { + Ok(Some(Update::Timeout)) + } + Err(err) => Err(err), + } + } +} + +/// +#[inline] +pub async fn contribute( + signing_key: C::SigningKey, + identifier: C::Identifier, + server_url: U, + mut process_update: F, +) -> Result<(), CeremonyError> +where + C: Ceremony, + C::Identifier: Serialize, + C::Nonce: DeserializeOwned + Serialize, + C::Signature: Serialize, + ContributeRequest: Serialize, + QueryResponse: DeserializeOwned, + U: IntoUrl, + F: FnMut(Update), +{ + let mut client = Client::start( + signing_key, + identifier, + KnownUrlClient::new(server_url).map_err(into_ceremony_error)?, + ) + .await?; + loop { + match client.try_contribute().await { + Ok(None) => return Ok(()), + Ok(Some(update)) => process_update(update), + Err(err) => return Err(err), + } } } diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index ea400c83c..df4562d93 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -22,9 +22,7 @@ use crate::{ registry::csv, signature::{sign, verify, Nonce as _, RawMessage, SignatureScheme}, }, - groth16::ceremony::{ - client::Client, message::QueryResponse, Ceremony, CeremonyError, UnexpectedError, - }, + groth16::ceremony::{client, message::QueryResponse, Ceremony, CeremonyError, UnexpectedError}, }; use bip39::{Language, Mnemonic, MnemonicType, Seed}; use colored::Colorize; @@ -350,35 +348,53 @@ where C::Nonce: Clone + Debug + DeserializeOwned + Serialize, C::Signature: Serialize, { + /* let mut client = Client::start( signing_key, identifier, KnownUrlClient::new("http://localhost:8080").expect("Should succeed."), ) .await?; - loop { + match client.process().await { + Ok(true) => { + // TODO: + break; + } + Ok(false) => { + // TODO: + continue; + } + Err(err) => return Err(err), + } + + /* let state = match client.query().await { Ok(QueryResponse::QueuePosition(position)) => { - // - todo!() + // TODO: + continue; } - Ok(QueryResponse::State(state)) => { - // - todo!() + Ok(QueryResponse::State(state)) => state, + Err(CeremonyError::Timeout) => { + // TODO: + continue; } - Err(CeremonyError::Timeout) => todo!(), - Err(CeremonyError::NotYourTurn) => todo!(), - Err(err) => todo!(), + Err(err) => return Err(err), }; match client.contribute(&C::Hasher::default(), state).await { - Ok(_) => todo!(), - Err(CeremonyError::Timeout) => todo!(), - Err(CeremonyError::NotRegistered) => todo!(), - Err(CeremonyError::NotYourTurn) => todo!(), - Err(err) => todo!(), + Ok(_) => { + // TODO: + break; + } + Err(CeremonyError::Timeout) | Err(CeremonyError::NotYourTurn) => { + // TODO: + continue; + } + Err(err) => return Err(err), } + */ } + */ /* TODO: println!( @@ -502,7 +518,8 @@ where } Ok(()) */ - todo!() + + client::contribute(signing_key, identifier, "http://localhost:8080", |_| {}).await } /// Testing Suite diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 6790809e2..e6a8bcda6 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -23,7 +23,7 @@ use crate::{ signature::{Nonce, SignedMessage}, }, groth16::{ - ceremony::{Ceremony, CeremonyError, MpcState, Queue, UnexpectedError}, + ceremony::{Ceremony, CeremonyError, Queue, Round, UnexpectedError}, mpc::{verify_transform, Proof, State, StateSize}, }, }; @@ -163,16 +163,13 @@ where &mut self.queue } - /// Gets the current state and challenge. + /// Returns the current round state. #[inline] - pub fn state_and_challenge(&self) -> MpcState + pub fn round_state(&self) -> Round where C::Challenge: Clone, { - MpcState { - state: self.state.to_vec(), - challenge: self.challenge.to_vec(), - } + Round::new(self.state.to_vec().into(), self.challenge.to_vec().into()) } /// Preprocesses a request by checking nonce and verifying signature. diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 9207b9d2e..7cdaca3d1 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -19,7 +19,7 @@ // FIXME: Use correct serde configuration since we don't assume it's always available use crate::groth16::{ - ceremony::{Ceremony, MpcState}, + ceremony::{Ceremony, Round}, mpc::{Proof, State, StateSize}, }; use manta_crypto::arkworks::pairing::Pairing; @@ -52,8 +52,8 @@ pub struct QueryRequest; #[derive(Deserialize, Serialize)] #[serde( bound( - deserialize = "MpcState: Deserialize<'de>", - serialize = "MpcState: Serialize" + deserialize = "Round: Deserialize<'de>", + serialize = "Round: Serialize" ), crate = "manta_util::serde", deny_unknown_fields @@ -63,10 +63,10 @@ where C: Ceremony, { /// Queue Position - QueuePosition(usize), + QueuePosition(u64), - /// MPC State - State(MpcState), + /// MPC Round State + State(Round), } /// Contribute Request diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 7fc46ccfb..453a0931f 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -21,9 +21,9 @@ use crate::{ participant::{Participant, Priority}, signature::SignatureScheme, }, - groth16::mpc::{Configuration, State}, + groth16::mpc::Configuration, + mpc, }; -use alloc::string::String; use core::fmt::Debug; use manta_util::{ collections::vec_deque::MultiVecDeque, @@ -35,9 +35,11 @@ pub mod config; pub mod message; #[cfg(feature = "std")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] pub mod coordinator; #[cfg(feature = "std")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] pub mod server; /// Participant Queue Type @@ -60,26 +62,11 @@ pub trait Ceremony: Configuration + SignatureScheme { > + Priority; } -/// MPC States -#[derive(Deserialize, Serialize)] -#[serde( - bound( - deserialize = "C::Challenge: Deserialize<'de>", - serialize = "C::Challenge: Serialize", - ), - crate = "manta_util::serde", - deny_unknown_fields -)] -pub struct MpcState -where - C: Ceremony, -{ - /// States - pub state: Vec>, - - /// Challenges - pub challenge: Vec, -} +/// Parallel Round Alias +/// +/// In the ceremony we always use parallel round structures to support multiple Groth16 circuits at +/// once. +pub type Round = mpc::ParallelRound; /// Ceremony Error #[cfg_attr( @@ -115,11 +102,11 @@ where /// Not Your Turn NotYourTurn, - /// Timed-out + /// Timed out Timeout, /// Network Error - Network(String), + Network, /// Unexpected Server Error Unexpected(UnexpectedError), diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 6607c650e..1d38c698d 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -132,9 +132,9 @@ where .queue_mut() .push_back_if_missing(priority.into(), request.identifier); if position == 0 { - Ok(QueryResponse::State(coordinator.state_and_challenge())) + Ok(QueryResponse::State(coordinator.round_state())) } else { - Ok(QueryResponse::QueuePosition(position)) + Ok(QueryResponse::QueuePosition(position as u64)) } } diff --git a/manta-trusted-setup/src/groth16/mpc.rs b/manta-trusted-setup/src/groth16/mpc.rs index ed2b3f3a6..c24dfb226 100644 --- a/manta-trusted-setup/src/groth16/mpc.rs +++ b/manta-trusted-setup/src/groth16/mpc.rs @@ -18,6 +18,7 @@ use crate::{ groth16::kzg::{self, Accumulator}, + mpc::Types, util::{batch_into_projective, batch_mul_fixed_scalar, merge_pairs_affine}, }; use alloc::{vec, vec::Vec}; @@ -370,10 +371,7 @@ where } /// Configuration -pub trait Configuration: Pairing { - /// Challenge Type - type Challenge; - +pub trait Configuration: Pairing + Types, State = State> { /// Hasher Type type Hasher: Default + HashToGroup; diff --git a/manta-trusted-setup/src/groth16/ppot/mpc.rs b/manta-trusted-setup/src/groth16/ppot/mpc.rs index 405974878..d86eea15d 100644 --- a/manta-trusted-setup/src/groth16/ppot/mpc.rs +++ b/manta-trusted-setup/src/groth16/ppot/mpc.rs @@ -29,8 +29,11 @@ use blake2::Digest; use manta_crypto::arkworks::{pairing::Pairing, serialize::CanonicalSerialize}; use manta_util::into_array_unchecked; -impl Configuration for PerpetualPowersOfTauCeremony { +impl ChallengeType for PerpetualPowersOfTauCeremony { type Challenge = [u8; 64]; +} + +impl Configuration for PerpetualPowersOfTauCeremony { type Hasher = BlakeHasher; #[inline] @@ -56,22 +59,14 @@ impl Configuration for PerpetualPowersOfTauCeremony StateType for PerpetualPowersOfTauCeremony { - type State = State; -} - -impl ChallengeType for PerpetualPowersOfTauCeremony { - type Challenge = [u8; 64]; +impl ContributionType for PerpetualPowersOfTauCeremony { + type Contribution = ::Scalar; } impl ProofType for PerpetualPowersOfTauCeremony { type Proof = Proof; } -impl ContributionType for PerpetualPowersOfTauCeremony { - type Contribution = ::Scalar; -} - impl ProvingKeyHasher for PerpetualPowersOfTauCeremony { type Output = [u8; 64]; @@ -84,3 +79,7 @@ impl ProvingKeyHasher for PerpetualPowersOfTauCere into_array_unchecked(hasher.0.finalize()) } } + +impl StateType for PerpetualPowersOfTauCeremony { + type State = State; +} diff --git a/manta-trusted-setup/src/mpc.rs b/manta-trusted-setup/src/mpc.rs index c5ea32390..200e6e5e6 100644 --- a/manta-trusted-setup/src/mpc.rs +++ b/manta-trusted-setup/src/mpc.rs @@ -16,7 +16,17 @@ //! Secure Multi-Party Computation Primitives -use alloc::vec::Vec; +use alloc::vec::{self, Vec}; +use core::{ + fmt::Debug, + hash::Hash, + ops::{Deref, DerefMut}, + slice, +}; +use manta_util::assert_all_eq_len; + +#[cfg(feature = "serde")] +use manta_util::serde::{Deserialize, Serialize}; /// State pub trait StateType { @@ -103,12 +113,12 @@ pub trait Verify: ChallengeType + ProofType + StateType { /// Verification Error Type type Error; - /// Computes the challenge associated to `challenge`, `prev`, `next`, and `proof` for the next + /// Computes the challenge associated to `challenge`, `last`, `next`, and `proof` for the next /// player. fn challenge( &self, challenge: &Self::Challenge, - prev: &Self::State, + last: &Self::State, next: &Self::State, proof: &Self::Proof, ) -> Self::Challenge; @@ -148,7 +158,7 @@ pub trait Verify: ChallengeType + ProofType + StateType { } } -/// MPC Transcript +/// Secure Multi-Party Contribution Transcript pub struct Transcript where T: ChallengeType + StateType + ProofType, @@ -162,3 +172,311 @@ where /// Rounds pub rounds: Vec<(T::State, T::Proof)>, } + +impl Transcript +where + T: ChallengeType + StateType + ProofType, +{ + /// Verifies the transcript `self` against `parameters` returning the final challenge and state. + #[inline] + pub fn verify(self, parameters: &T) -> Result<(T::Challenge, T::State), T::Error> + where + T: Verify, + { + parameters.verify_transform_all::( + self.initial_challenge, + self.initial_state, + self.rounds.into_iter().map(Ok), + ) + } +} + +/// Secure Multi-Party Computation Round +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde( + bound( + deserialize = "T::State: Deserialize<'de>, T::Challenge: Deserialize<'de>", + serialize = "T::State: Serialize, T::Challenge: Serialize" + ), + crate = "manta_util::serde", + deny_unknown_fields + ) +)] +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = "T::State: Clone, T::Challenge: Clone"), + Copy(bound = "T::State: Copy, T::Challenge: Copy"), + Debug(bound = "T::State: Debug, T::Challenge: Debug"), + Default(bound = "T::State: Default, T::Challenge: Default"), + Eq(bound = "T::State: Eq, T::Challenge: Eq"), + Hash(bound = "T::State: Hash, T::Challenge: Hash"), + PartialEq(bound = "T::State: PartialEq, T::Challenge: PartialEq") +)] +pub struct Round +where + T: ChallengeType + StateType, +{ + /// State + pub state: T::State, + + /// Challenge + pub challenge: T::Challenge, +} + +impl Round +where + T: ChallengeType + StateType, +{ + /// Builds a new [`Round`] from `state` and `challenge`. + #[inline] + pub fn new(state: T::State, challenge: T::Challenge) -> Self { + Self { state, challenge } + } + + /// Computes the contribution proof using [`Contribute::contribute`] over `parameters`. + #[inline] + pub fn contribute(&mut self, parameters: &T, contribution: &T::Contribution) -> T::Proof + where + T: Contribute, + { + parameters.contribute(&mut self.state, &self.challenge, contribution) + } + + /// Computes the round challenge using [`Verify::challenge`] over `parameters`. + #[inline] + pub fn challenge(&self, parameters: &T, next: &T::State, proof: &T::Proof) -> T::Challenge + where + T: Verify, + { + parameters.challenge(&self.challenge, &self.state, next, proof) + } + + /// Verifies that the transformation from `self` to `next` is valid, returning the next state + /// using [`Verify::verify_transform`] over `parameters`. + #[inline] + pub fn verify_transform( + self, + parameters: &T, + next: T::State, + proof: T::Proof, + ) -> Result + where + T: Verify, + { + parameters.verify_transform(&self.challenge, self.state, next, proof) + } +} + +/// Parallel MPC Wrapper +/// +/// Multiple secure multi-party computation protocols with the same round structure can be run in +/// parallel, i.e. both the contribution and verification of each protocol can be run in parallel. +/// This increases the latency of any particular instance of the protocol but reduces the overhead +/// of running multiple protocols. +/// +/// This type [`Parallel`] can be used for any component of the protocol, including types defined by +/// [`Types`] instances or the [`Contribute`] or [`Verify`] instances. +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde(crate = "manta_util::serde", deny_unknown_fields) +)] +#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] +pub struct Parallel(Vec); + +impl Deref for Parallel { + type Target = [T]; + + #[inline] + fn deref(&self) -> &[T] { + &self.0 + } +} + +impl DerefMut for Parallel { + #[inline] + fn deref_mut(&mut self) -> &mut [T] { + &mut self.0 + } +} + +impl From> for Parallel { + #[inline] + fn from(vec: Vec) -> Self { + Self(vec) + } +} + +impl From> for Vec { + #[inline] + fn from(parallel: Parallel) -> Self { + parallel.0 + } +} + +impl FromIterator for Parallel { + #[inline] + fn from_iter(iter: I) -> Self + where + I: IntoIterator, + { + Self(iter.into_iter().collect()) + } +} + +impl IntoIterator for Parallel { + type Item = T; + type IntoIter = vec::IntoIter; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl<'p, T> IntoIterator for &'p Parallel { + type Item = &'p T; + type IntoIter = slice::Iter<'p, T>; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } +} + +impl<'p, T> IntoIterator for &'p mut Parallel { + type Item = &'p mut T; + type IntoIter = slice::IterMut<'p, T>; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.0.iter_mut() + } +} + +impl ChallengeType for Parallel +where + T: ChallengeType, +{ + type Challenge = Parallel; +} + +impl ContributionType for Parallel +where + T: ContributionType, +{ + type Contribution = Parallel; +} + +impl ProofType for Parallel +where + T: ProofType, +{ + type Proof = Parallel; +} + +impl StateType for Parallel +where + T: StateType, +{ + type State = Parallel; +} + +impl Contribute for Parallel +where + C: Contribute, +{ + #[inline] + fn contribute( + &self, + state: &mut Self::State, + challenge: &Self::Challenge, + contribution: &Self::Contribution, + ) -> Self::Proof { + assert_all_eq_len!( + [self, state, challenge, contribution], + "Length mismatch in parallel `Contribute::contribute`." + ); + self.0 + .iter() + .zip(state) + .zip(challenge) + .zip(contribution) + .map(|(((this, state), challenge), contribution)| { + this.contribute(state, challenge, contribution) + }) + .collect() + } +} + +impl Verify for Parallel +where + V: Verify, +{ + type Error = V::Error; + + #[inline] + fn challenge( + &self, + challenge: &Self::Challenge, + last: &Self::State, + next: &Self::State, + proof: &Self::Proof, + ) -> Self::Challenge { + assert_all_eq_len!( + [self, challenge, last, next, proof], + "Length mismatch in parallel `Verify::challlenge`." + ); + self.0 + .iter() + .zip(challenge) + .zip(last) + .zip(next) + .zip(proof) + .map(|((((this, challenge), last), next), proof)| { + this.challenge(challenge, last, next, proof) + }) + .collect() + } + + #[inline] + fn verify_transform( + &self, + challenge: &Self::Challenge, + last: Self::State, + next: Self::State, + proof: Self::Proof, + ) -> Result { + assert_all_eq_len!( + [self, challenge, last, next, proof], + "Length mismatch in parallel `Verify::verify_transform`." + ); + self.0 + .iter() + .zip(challenge) + .zip(last) + .zip(next) + .zip(proof) + .map(|((((this, challenge), last), next), proof)| { + this.verify_transform(challenge, last, next, proof) + }) + .collect() + } +} + +/// Parallel Round Alias +pub type ParallelRound = Round>; + +impl ParallelRound +where + T: ChallengeType + StateType, +{ + /// Returns `self` if it has the correct shape expected for a [`Round`] over a [`Parallel`] + /// ceremony, i.e. that `self.state` has the same length as `self.challenge`. + #[inline] + pub fn with_valid_shape(self) -> Option { + (self.state.len() == self.challenge.len()).then_some(self) + } +} diff --git a/manta-util/src/macros.rs b/manta-util/src/macros.rs index e04266aba..9fc25c497 100644 --- a/manta-util/src/macros.rs +++ b/manta-util/src/macros.rs @@ -16,6 +16,29 @@ //! Utility Macros +/// Asserts that all the elements in `$tail` have the same length as `$head`. +#[macro_export] +macro_rules! assert_all_eq_len { + ([$head:expr, $($tail:expr),+ $(,)?]) => {{ + $( + assert_eq!( + $head.len(), + $tail.len(), + ); + )+ + }}; + ([$head:expr, $($tail:expr),+], $($arg:tt)+) => {{ + let __format = core::format_args!($($arg)+); + $( + assert_eq!( + $head.len(), + $tail.len(), + "{}", __format, + ); + )+ + }}; +} + /// Implements [`From`]`<$from>` for an enum `$to`, choosing the `$kind` variant. #[macro_export] macro_rules! from_variant { From 5de8d41009380c5644b05fbfc7fbf9a7b76e8113 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Mon, 19 Sep 2022 23:39:28 +0200 Subject: [PATCH 48/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- .../src/groth16/ceremony/config/ppot.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index df4562d93..b7b4663d3 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -22,23 +22,18 @@ use crate::{ registry::csv, signature::{sign, verify, Nonce as _, RawMessage, SignatureScheme}, }, - groth16::ceremony::{client, message::QueryResponse, Ceremony, CeremonyError, UnexpectedError}, + groth16::ceremony::{client, Ceremony, CeremonyError}, }; use bip39::{Language, Mnemonic, MnemonicType, Seed}; use colored::Colorize; -use console::{style, Term}; -use core::{fmt::Debug, time::Duration}; +use core::fmt::Debug; use dialoguer::{theme::ColorfulTheme, Input}; use manta_crypto::{ dalek::ed25519::{self, generate_keypair, Ed25519, SECRET_KEY_LENGTH}, rand::{ChaCha20Rng, OsRng, Rand, SeedableRng}, signature::VerifyingKeyType, }; -use manta_util::{ - http::reqwest::KnownUrlClient, - serde::{de::DeserializeOwned, Deserialize, Serialize}, -}; -use std::thread; +use manta_util::serde::{de::DeserializeOwned, Deserialize, Serialize}; type Signature = Ed25519>; type VerifyingKey = ::VerifyingKey; From bc81d0807a334bb1d688007c5077c1bc128de474 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Mon, 19 Sep 2022 23:47:26 +0200 Subject: [PATCH 49/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- manta-crypto/src/dalek/ed25519.rs | 4 +++- .../src/groth16/ceremony/message.rs | 20 +++++++++++-------- .../src/groth16/ceremony/mod.rs | 2 +- .../src/groth16/ceremony/server.rs | 2 +- manta-trusted-setup/src/groth16/mpc.rs | 17 +++++++++------- 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/manta-crypto/src/dalek/ed25519.rs b/manta-crypto/src/dalek/ed25519.rs index 25dd931cc..ef3c621c0 100644 --- a/manta-crypto/src/dalek/ed25519.rs +++ b/manta-crypto/src/dalek/ed25519.rs @@ -27,7 +27,9 @@ use manta_util::AsBytes; pub use ed25519_dalek::*; -/// Implements byte conversion from an array of bytes of length `$len` into the given `$type`. +/// Implements byte conversion from an array of bytes of length `$len` into the given `$type`. These +/// implementations are prefered over the ones provided by [`ed25519_dalek`] because they have no +/// error branch. macro_rules! byte_conversion { ($name:ident, $type:tt, $len:ident) => { #[doc = "Converts the `bytes` fixed-length array into [`"] diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 7cdaca3d1..3c13f7e54 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -18,17 +18,21 @@ // FIXME: Use correct serde configuration since we don't assume it's always available -use crate::groth16::{ - ceremony::{Ceremony, Round}, - mpc::{Proof, State, StateSize}, +use crate::{ + groth16::{ + ceremony::{Ceremony, Round}, + mpc::{Proof, State, StateSize}, + }, + mpc, }; use manta_crypto::arkworks::pairing::Pairing; use manta_util::serde::{Deserialize, Serialize}; -/// Ceremony Size -#[derive(Clone, Deserialize, Serialize)] -#[serde(crate = "manta_util::serde", deny_unknown_fields)] -pub struct CeremonySize(pub Vec); +/// Ceremony Size Alias +/// +/// In the ceremony we always use parallel round structures to support multiple Groth16 circuits at +/// the same time. +pub type CeremonySize = mpc::Parallel; impl CeremonySize { /// Checks that each size in `self` matches each [`State`] in `states`. @@ -37,7 +41,7 @@ impl CeremonySize { where P: Pairing, { - self.0.len() == states.len() && self.0.iter().zip(states).all(|(l, r)| l.matches(&r.0)) + self.len() == states.len() && self.iter().zip(states).all(|(l, r)| l.matches(&r.0)) } } diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 453a0931f..2838c54c1 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -65,7 +65,7 @@ pub trait Ceremony: Configuration + SignatureScheme { /// Parallel Round Alias /// /// In the ceremony we always use parallel round structures to support multiple Groth16 circuits at -/// once. +/// the same time. pub type Round = mpc::ParallelRound; /// Ceremony Error diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 1d38c698d..855d2cbee 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -107,7 +107,7 @@ where { let coordinator = self.coordinator.lock(); Ok(( - CeremonySize(coordinator.size().to_vec()), + coordinator.size().to_vec().into(), coordinator .registry() .get(&request) diff --git a/manta-trusted-setup/src/groth16/mpc.rs b/manta-trusted-setup/src/groth16/mpc.rs index c24dfb226..2b4ce97c6 100644 --- a/manta-trusted-setup/src/groth16/mpc.rs +++ b/manta-trusted-setup/src/groth16/mpc.rs @@ -18,7 +18,7 @@ use crate::{ groth16::kzg::{self, Accumulator}, - mpc::Types, + mpc, util::{batch_into_projective, batch_mul_fixed_scalar, merge_pairs_affine}, }; use alloc::{vec, vec::Vec}; @@ -371,12 +371,13 @@ where } /// Configuration -pub trait Configuration: Pairing + Types, State = State> { +pub trait Configuration: Pairing + mpc::Types, State = State> { /// Hasher Type type Hasher: Default + HashToGroup; - /// Generates the next [`Challenge`](Self::Challenge) from `challenge`, `prev` state, `next` state, - /// and `proof`. + /// Generates the next [`Challenge`] from `challenge`, `prev` state, `next` state, and `proof`. + /// + /// [`Challenge`]: mpc::ChallengeType::Challenge fn challenge( challenge: &Self::Challenge, prev: &State, @@ -447,9 +448,11 @@ where Ok((next_challenge, next)) } -/// Verifies all contributions in `iter` chaining from an initial `state` and `challenge` -/// returning the newest [`State`](State) and [`Challenge`](Configuration::Challenge) if all the -/// contributions in the chain had valid transitions. +/// Verifies all contributions in `iter` chaining from an initial `state` and `challenge` returning +/// the newest [`State`] and [`Challenge`] if all the contributions in the chain had valid +/// transitions. +/// +/// [`Challenge`]: mpc::ChallengeType::Challenge #[inline] pub fn verify_transform_all( mut challenge: C::Challenge, From 8d839155a890d59bf957740ef0e9702b249321f1 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 20 Sep 2022 07:20:11 +0200 Subject: [PATCH 50/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/src/groth16/ceremony/coordinator.rs | 4 +++- manta-trusted-setup/src/groth16/ceremony/server.rs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index e6a8bcda6..aeda4f143 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -250,9 +250,11 @@ where ) -> Result<(), CeremonyError> { self.check_lock(participant)?; for (i, (state, proof)) in state.into_iter().zip(proof.clone().into_iter()).enumerate() { + let next_challenge = C::challenge(&self.challenge[i], &self.state[i], &state, &proof); self.state[i] = verify_transform(&self.challenge[i], &self.state[i], state, proof) .map_err(|_| CeremonyError::BadRequest)? - .1 + .1; + self.challenge[i] = next_challenge; } self.latest_proof = Some(proof); self.participant_lock.set(self.queue.pop_front()); diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 855d2cbee..9a859183e 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -138,8 +138,8 @@ where } } - /// Processes a request to update the MPC state and remove the participant if successfully - /// updated the state. If update succeeds, save the current coordinator to disk. + /// Processes a request to update the MPC state and removes the participant if the state was + /// updated successfully. If the update succeeds, the current coordinator is saved to disk. #[inline] pub async fn update( self, From feeea8562215772cbfb1273b843e9998880280c5 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 20 Sep 2022 07:45:01 +0200 Subject: [PATCH 51/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- .../src/groth16/ceremony/config/ppot.rs | 190 ++---------------- 1 file changed, 22 insertions(+), 168 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index b7b4663d3..c0d74e1cd 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -22,10 +22,14 @@ use crate::{ registry::csv, signature::{sign, verify, Nonce as _, RawMessage, SignatureScheme}, }, - groth16::ceremony::{client, Ceremony, CeremonyError}, + groth16::ceremony::{ + client::{self, Update}, + Ceremony, CeremonyError, + }, }; use bip39::{Language, Mnemonic, MnemonicType, Seed}; use colored::Colorize; +use console::{style, Term}; use core::fmt::Debug; use dialoguer::{theme::ColorfulTheme, Input}; use manta_crypto::{ @@ -343,178 +347,28 @@ where C::Nonce: Clone + Debug + DeserializeOwned + Serialize, C::Signature: Serialize, { - /* - let mut client = Client::start( + const LOCK_TIME: u64 = 5; + let term = Term::stdout(); + client::contribute( signing_key, identifier, - KnownUrlClient::new("http://localhost:8080").expect("Should succeed."), - ) - .await?; - loop { - match client.process().await { - Ok(true) => { - // TODO: - break; - } - Ok(false) => { - // TODO: - continue; - } - Err(err) => return Err(err), - } - - /* - let state = match client.query().await { - Ok(QueryResponse::QueuePosition(position)) => { - // TODO: - continue; - } - Ok(QueryResponse::State(state)) => state, - Err(CeremonyError::Timeout) => { - // TODO: - continue; - } - Err(err) => return Err(err), - }; - match client.contribute(&C::Hasher::default(), state).await { - Ok(_) => { - // TODO: - break; - } - Err(CeremonyError::Timeout) | Err(CeremonyError::NotYourTurn) => { - // TODO: - continue; - } - Err(err) => return Err(err), - } - */ - } - */ - - /* TODO: - println!( - "{} Contacting Server for Meta Data...", - style("[1/9]").bold().dim() - ); - let term = Term::stdout(); - let (size, nonce) = get_start_meta_data::(&network_client, pk).await?; - let mut trusted_setup_client = Client::::new(pk, nonce, sk); - println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); - loop { - let mpc_state = match network_client - .post::<_, Result, CeremonyError>>( - "query", - &trusted_setup_client.query()?, - ) - .await - .map_err(|_| { - CeremonyError::Network( - "Should have received starting meta data from server".to_string(), - ) - })? { - Ok(message) => match message { - QueryResponse::QueuePosition(position) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); - println!( - "{} Waiting in Queue... There are {} people ahead of you. Estimated Waiting Time: {} minutes.", - style("[2/9]").bold().dim(), - style(position).bold().red(), - style(5*position).bold().blue(), - ); - thread::sleep(Duration::from_secs(1)); - continue; - } - QueryResponse::State(mpc_state) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); - println!("{} Waiting in Queue...", style("[2/9]").bold().dim(),); - println!( - "{} Downloading Ceremony States...", - style("[3/9]").bold().dim(), - ); - if !size.matches(&mpc_state.state) { - return Err(CeremonyError::Unexpected( - UnexpectedError::IncorrectStateSize, - )); - } - mpc_state - } + "http://localhost:8080", + |state| match state { + Update::Timeout => { + let _ = term.clear_last_lines(1); + println!("You have timed out. Waiting in queue again ..."); }, - Err(CeremonyError::Timeout) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); + Update::Position(position) => { + let _ = term.clear_last_lines(1); println!( - "{} You have timed out. Waiting in Queue again...", - style("[2/9]").bold().dim(), + "Waiting in queue... There are {} people ahead of you. Estimated Waiting Time: {} minutes.", + style(position).bold().red(), + style(LOCK_TIME * position).bold().blue(), ); - continue; - } - Err(CeremonyError::NotYourTurn) => { - return Err(CeremonyError::Unexpected(UnexpectedError::SkippedTurn)); - } - Err(err) => return Err(err), - }; - println!( - "{} Starting contribution to 3 Circuits...", - style("[4/9]").bold().dim(), - ); - match network_client - .post::<_, Result<(), CeremonyError>>( - "update", - &trusted_setup_client.contribute( - &C::Hasher::default(), - &mpc_state.challenge, - mpc_state.state, - )?, - ) - .await - .map_err(|_| { - CeremonyError::Network( - "Should have received starting meta data from server".to_string(), - ) - })? { - Ok(_) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); - println!( - "{} Waiting for Confirmation from Server...", - style("[8/9]").bold().dim(), - ); - println!( - "{} Congratulations! You have successfully contributed to Manta Trusted Setup Ceremony!...", - style("[9/9]").bold().dim(), - ); - break; - } - Err(CeremonyError::Timeout) => { - term.clear_last_lines(1) - .expect("Clear last lines should succeed."); - println!( - "{} You have timed out. Waiting in Queue again...", - style("[2/9]").bold().dim(), - ); - continue; - } - Err(CeremonyError::NotRegistered) => { - return Err(CeremonyError::Unexpected( - UnexpectedError::MissingRegisteredParticipant, - )); - } - Err(CeremonyError::NotYourTurn) => { - println!( - "{} Lag behind server. Contacting Server again...", - style("[8/9]").bold().dim(), - ); - continue; - } - Err(err) => return Err(err), - } - } - Ok(()) - */ - - client::contribute(signing_key, identifier, "http://localhost:8080", |_| {}).await + }, + }, + ) + .await } /// Testing Suite From c42bb86508aee2795e9e5ce2be9623a0d696ee23 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 20 Sep 2022 07:48:10 +0200 Subject: [PATCH 52/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/src/groth16/test/mod.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/manta-trusted-setup/src/groth16/test/mod.rs b/manta-trusted-setup/src/groth16/test/mod.rs index a1f0d1889..771e6c564 100644 --- a/manta-trusted-setup/src/groth16/test/mod.rs +++ b/manta-trusted-setup/src/groth16/test/mod.rs @@ -21,7 +21,7 @@ use crate::{ kzg::{self, Accumulator, Configuration, Contribution, Size}, mpc::{self, contribute, initialize, verify_transform, verify_transform_all, Proof, State}, }, - mpc::{ChallengeType, ProofType, StateType, Transcript}, + mpc::{ChallengeType, ContributionType, ProofType, StateType, Transcript}, util::{BlakeHasher, HasDistribution, KZGBlakeHasher}, }; use alloc::vec::Vec; @@ -132,7 +132,6 @@ impl kzg::Configuration for Test { } impl mpc::Configuration for Test { - type Challenge = [u8; 64]; type Hasher = BlakeHasher; #[inline] @@ -174,16 +173,20 @@ where } } -impl StateType for Test { - type State = State; -} - impl ChallengeType for Test { type Challenge = [u8; 64]; } +impl ContributionType for Test { + type Contribution = Contribution; +} + impl ProofType for Test { - type Proof = Proof; + type Proof = Proof; +} + +impl StateType for Test { + type State = State; } /// Conducts a dummy phase one trusted setup. From b69677b4d4b3d9345810f38eabbe1927110777d0 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 20 Sep 2022 08:26:14 +0200 Subject: [PATCH 53/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- .../src/groth16/ceremony/client.rs | 25 +++++++---- .../src/groth16/ceremony/config/mod.rs | 7 +-- .../src/groth16/ceremony/coordinator.rs | 6 +-- .../src/groth16/ceremony/message.rs | 44 +++++++++++-------- 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index f3f7c8c9d..a6f230381 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -75,7 +75,7 @@ impl Client where C: Ceremony, { - /// + /// Builds a new [`Client`] from `signer`, `client`, and `ceremony_size`. #[inline] fn new_unchecked( signer: Signer, @@ -89,7 +89,8 @@ where } } - /// + /// Signs the `message` with the signer in `self`, incrementing its nonce if the singing was + /// successful. #[inline] fn sign( &mut self, @@ -106,9 +107,11 @@ where Ok(signed_message) } - /// + /// Builds a new [`Client`] from `signing_key`, `identifier`, and `client` and performs the + /// initial synchronization procedure with the ceremony server to establish the correct ceremony + /// parameters and registration status. #[inline] - pub async fn start( + pub async fn build( signing_key: C::SigningKey, identifier: C::Identifier, client: KnownUrlClient, @@ -128,7 +131,8 @@ where )) } - /// + /// Queries for the state of the ceremony, returning the queue position if the participant is + /// not at the front of the queue. #[inline] async fn query(&mut self) -> Result, CeremonyError> where @@ -152,7 +156,7 @@ where } } - /// + /// Performs the ceremony contribution over `round`, sending the result to the ceremony server. #[inline] async fn contribute( &mut self, @@ -184,7 +188,9 @@ where .map_err(into_ceremony_error) } - /// + /// Tries to contribute to the ceremony if at the front of the queue. This method returns an + /// optional [`Update`] if the status of the unfinalized participant has changed. If the result + /// is `Ok(None)` then the ceremony contribution was successful. #[inline] pub async fn try_contribute(&mut self) -> Result, CeremonyError> where @@ -212,7 +218,8 @@ where } } -/// +/// Runs the contribution protocol for `signing_key`, `identifier`, and `server_url`, using +/// `process_update` as the callback for processing [`Update`] messages from the client. #[inline] pub async fn contribute( signing_key: C::SigningKey, @@ -230,7 +237,7 @@ where U: IntoUrl, F: FnMut(Update), { - let mut client = Client::start( + let mut client = Client::build( signing_key, identifier, KnownUrlClient::new(server_url).map_err(into_ceremony_error)?, diff --git a/manta-trusted-setup/src/groth16/ceremony/config/mod.rs b/manta-trusted-setup/src/groth16/ceremony/config/mod.rs index 50b57c40f..6a766d741 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/mod.rs @@ -16,9 +16,6 @@ //! Groth16 Trusted Setup Ceremony Configurations -#[cfg(all(feature = "serde", feature = "csv", feature = "std", feature = "serde"))] -#[cfg_attr( - doc_cfg, - doc(cfg(all(feature = "serde", feature = "csv", feature = "std", feature = "serde"))) -)] +#[cfg(feature = "csv")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "csv")))] pub mod ppot; diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index aeda4f143..f5f096afd 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -172,7 +172,7 @@ where Round::new(self.state.to_vec().into(), self.challenge.to_vec().into()) } - /// Preprocesses a request by checking nonce and verifying signature. + /// Preprocesses a request by checking the nonce and verifying the signature. #[inline] pub fn preprocess_request( &mut self, @@ -213,7 +213,7 @@ where } } - /// Updates the expired lock by reducing the priority of it's participant and setting it's + /// Updates the expired lock by reducing the priority of its participant and setting its /// contained value to the new front of the queue. The previous participant in the lock is /// returned. #[inline] @@ -228,7 +228,7 @@ where }) } - /// Checks lock for `participant`. + /// Checks the lock for `participant`. #[inline] pub fn check_lock(&mut self, participant: &C::Identifier) -> Result<(), CeremonyError> { if self.participant_lock.has_expired(TIME_LIMIT) { diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 3c13f7e54..6d4c69dc8 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -16,8 +16,6 @@ //! Groth16 Trusted Setup Ceremony Messaging Protocol -// FIXME: Use correct serde configuration since we don't assume it's always available - use crate::{ groth16::{ ceremony::{Ceremony, Round}, @@ -26,6 +24,8 @@ use crate::{ mpc, }; use manta_crypto::arkworks::pairing::Pairing; + +#[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; /// Ceremony Size Alias @@ -46,21 +46,26 @@ impl CeremonySize { } /// Query Request -#[derive( - Clone, Copy, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde(crate = "manta_util::serde", deny_unknown_fields) )] -#[serde(crate = "manta_util::serde", deny_unknown_fields)] +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct QueryRequest; /// Response for [`QueryRequest`] -#[derive(Deserialize, Serialize)] -#[serde( - bound( - deserialize = "Round: Deserialize<'de>", - serialize = "Round: Serialize" - ), - crate = "manta_util::serde", - deny_unknown_fields +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde( + bound( + deserialize = "Round: Deserialize<'de>", + serialize = "Round: Serialize", + ), + crate = "manta_util::serde", + deny_unknown_fields + ) )] pub enum QueryResponse where @@ -74,11 +79,14 @@ where } /// Contribute Request -#[derive(Deserialize, Serialize)] -#[serde( - bound(deserialize = "", serialize = "",), - crate = "manta_util::serde", - deny_unknown_fields +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde( + bound(deserialize = "", serialize = "",), + crate = "manta_util::serde", + deny_unknown_fields + ) )] pub struct ContributeRequest where From c8a59e9095ab804d8c3738d6cc62434ee139937c Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 20 Sep 2022 08:41:51 +0200 Subject: [PATCH 54/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/src/ceremony/signature.rs | 71 +++++++++++-------- .../src/groth16/ceremony/coordinator.rs | 12 ++-- .../src/groth16/ceremony/mod.rs | 4 +- .../src/groth16/ceremony/server.rs | 6 +- 4 files changed, 53 insertions(+), 40 deletions(-) diff --git a/manta-trusted-setup/src/ceremony/signature.rs b/manta-trusted-setup/src/ceremony/signature.rs index 296e7dafd..713c7015a 100644 --- a/manta-trusted-setup/src/ceremony/signature.rs +++ b/manta-trusted-setup/src/ceremony/signature.rs @@ -27,18 +27,12 @@ use manta_util::AsBytes; use manta_util::serde::{Deserialize, Serialize}; /// Nonce -pub trait Nonce: Default + PartialEq { +pub trait Nonce: Default { /// Increments the current nonce by one. fn increment(&mut self); /// Checks if the current nonce is valid. fn is_valid(&self) -> bool; - - /// Checks that `self` and `rhs` are valid and are both equal. - #[inline] - fn matches(&self, rhs: &Self) -> bool { - self.is_valid() && rhs.is_valid() && self == rhs - } } impl Nonce for u64 { @@ -201,16 +195,13 @@ where S: SignatureScheme, { /// Signature - pub signature: S::Signature, - - /// Nonce - pub nonce: S::Nonce, + signature: S::Signature, /// Participant Identifier - pub identifier: I, + identifier: I, /// Message - pub message: T, + message: T, } impl SignedMessage @@ -220,15 +211,9 @@ where /// Builds a new [`SignedMessage`] without checking that the `signature` actually attests to the /// `message`. #[inline] - pub fn new_unchecked( - signature: S::Signature, - nonce: S::Nonce, - identifier: I, - message: T, - ) -> Self { + pub fn new_unchecked(signature: S::Signature, identifier: I, message: T) -> Self { Self { signature, - nonce, identifier, message, } @@ -248,27 +233,55 @@ where T: Serialize, { Ok(Self::new_unchecked( - sign::(signing_key, nonce.clone(), &message)?, - nonce, + sign::(signing_key, nonce, &message)?, identifier, message, )) } + /// Returns a shared reference to the identifier for this message. + #[inline] + pub fn identifier(&self) -> &I { + &self.identifier + } + + /// Returns a shared reference the underlying message. + #[inline] + pub fn message(&self) -> &T { + &self.message + } + /// Verifies `self` against the `verifying_key`. #[cfg(feature = "bincode")] #[cfg_attr(doc_cfg, doc(cfg(feature = "bincode")))] #[inline] - pub fn verify(&self, verifying_key: &S::VerifyingKey) -> Result<(), VerificationError> + pub fn verify( + &self, + nonce: S::Nonce, + verifying_key: &S::VerifyingKey, + ) -> Result<(), VerificationError> where T: Serialize, { - verify::( - verifying_key, - self.nonce.clone(), - &self.message, - &self.signature, - ) + verify::(verifying_key, nonce, &self.message, &self.signature) + } + + /// + #[inline] + pub fn into_identifier(self) -> I { + self.identifier + } + + /// + #[inline] + pub fn into_message(self) -> T { + self.message + } + + /// + #[inline] + pub fn into_inner(self) -> (I, T) { + (self.identifier, self.message) } } diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index f5f096afd..5ec653bd7 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -183,18 +183,18 @@ where { let participant = self .registry - .get_mut(&request.identifier) + .get_mut(request.identifier()) .ok_or(CeremonyError::NotRegistered)?; if participant.has_contributed() { return Err(CeremonyError::AlreadyContributed); } let participant_nonce = participant.nonce(); - if !participant_nonce.matches(&request.nonce) { - return Err(CeremonyError::NonceNotInSync(participant_nonce.clone())); - }; + if !participant_nonce.is_valid() { + return Err(CeremonyError::Unexpected(UnexpectedError::AllNoncesUsed)); + } request - .verify(participant.verifying_key()) - .map_err(|_| CeremonyError::BadRequest)?; + .verify(participant_nonce.clone(), participant.verifying_key()) + .map_err(|_| CeremonyError::NonceNotInSync(participant_nonce.clone()))?; participant.increment_nonce(); Ok(participant.priority()) } diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 2838c54c1..2d13a3f71 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -132,6 +132,6 @@ pub enum UnexpectedError { /// Incorrect State Size IncorrectStateSize, - /// Unexpected Turn Skip by the Ceremony Server - SkippedTurn, + /// All Nonces were Used + AllNoncesUsed, } diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index 9a859183e..a9b86ada3 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -130,7 +130,7 @@ where let priority = coordinator.preprocess_request(&request)?; let position = coordinator .queue_mut() - .push_back_if_missing(priority.into(), request.identifier); + .push_back_if_missing(priority.into(), request.into_identifier()); if position == 0 { Ok(QueryResponse::State(coordinator.round_state())) } else { @@ -150,9 +150,9 @@ where { let mut coordinator = self.coordinator.lock(); coordinator.preprocess_request(&request)?; - let message = request.message; + let (identifier, message) = request.into_inner(); coordinator.update( - &request.identifier, + &identifier, BoxArray::from_vec(message.state), BoxArray::from_vec(message.proof), )?; From ecb58f09d9e6cc0b13d44e47511b5b50c7a50701 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 20 Sep 2022 08:43:25 +0200 Subject: [PATCH 55/60] wip: commit save point Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/src/ceremony/signature.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/manta-trusted-setup/src/ceremony/signature.rs b/manta-trusted-setup/src/ceremony/signature.rs index 713c7015a..ced4f8fb1 100644 --- a/manta-trusted-setup/src/ceremony/signature.rs +++ b/manta-trusted-setup/src/ceremony/signature.rs @@ -266,19 +266,19 @@ where verify::(verifying_key, nonce, &self.message, &self.signature) } - /// + /// Converts `self` into its underlying identifier. #[inline] pub fn into_identifier(self) -> I { self.identifier } - /// + /// Converts `self` into its underlying message. #[inline] pub fn into_message(self) -> T { self.message } - /// + /// Converts `self` into its identifier and message. #[inline] pub fn into_inner(self) -> (I, T) { (self.identifier, self.message) @@ -320,7 +320,7 @@ where &self.nonce } - /// + /// Increments the nonce for `self`. #[inline] pub fn increment_nonce(&mut self) { self.nonce.increment() From 5d4dd281a35c511225e49234b150c1d3b33e1b91 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 20 Sep 2022 09:15:55 +0200 Subject: [PATCH 56/60] chore: finalize APIs Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/src/ceremony/signature.rs | 14 ++++++- .../src/groth16/ceremony/client.rs | 19 +++++----- .../src/groth16/ceremony/coordinator.rs | 29 ++++++++------- .../src/groth16/ceremony/message.rs | 28 ++------------ .../src/groth16/ceremony/mod.rs | 37 ++++++++++++++++++- .../src/groth16/ceremony/server.rs | 14 +++---- 6 files changed, 83 insertions(+), 58 deletions(-) diff --git a/manta-trusted-setup/src/ceremony/signature.rs b/manta-trusted-setup/src/ceremony/signature.rs index ced4f8fb1..50ecf4cb0 100644 --- a/manta-trusted-setup/src/ceremony/signature.rs +++ b/manta-trusted-setup/src/ceremony/signature.rs @@ -174,13 +174,11 @@ where serde( bound( deserialize = r" - S::Nonce: Deserialize<'de>, S::Signature: Deserialize<'de>, I: Deserialize<'de>, T: Deserialize<'de>, ", serialize = r" - S::Nonce: Serialize, S::Signature: Serialize, I: Serialize, T: Serialize, @@ -239,6 +237,12 @@ where )) } + /// Returns a shared reference to the signature for this message. + #[inline] + pub fn signature(&self) -> &S::Signature { + &self.signature + } + /// Returns a shared reference to the identifier for this message. #[inline] pub fn identifier(&self) -> &I { @@ -326,6 +330,12 @@ where self.nonce.increment() } + /// Returns the signing key for `self`. + #[inline] + pub fn signing_key(&self) -> &S::SigningKey { + &self.signing_key + } + /// Returns the identifier for `self`. #[inline] pub fn identifier(&self) -> &I { diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index a6f230381..9d27d64ab 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -20,12 +20,13 @@ use crate::{ ceremony::signature::{SignedMessage, Signer}, groth16::{ ceremony::{ - message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, - Ceremony, CeremonyError, Round, UnexpectedError, + message::{ContributeRequest, QueryRequest, QueryResponse}, + Ceremony, CeremonyError, Metadata, Round, UnexpectedError, }, mpc, }, }; +use alloc::vec::Vec; use manta_crypto::rand::OsRng; use manta_util::{ http::reqwest::{self, IntoUrl, KnownUrlClient}, @@ -67,8 +68,8 @@ where /// HTTP Client client: KnownUrlClient, - /// Ceremony Size - ceremony_size: CeremonySize, + /// Ceremony Metadata + metadata: Metadata, } impl Client @@ -80,12 +81,12 @@ where fn new_unchecked( signer: Signer, client: KnownUrlClient, - ceremony_size: CeremonySize, + metadata: Metadata, ) -> Self { Self { signer, client, - ceremony_size, + metadata, } } @@ -120,14 +121,14 @@ where C::Identifier: Serialize, C::Nonce: DeserializeOwned, { - let (ceremony_size, nonce) = client + let (metadata, nonce) = client .post("start", &identifier) .await .map_err(into_ceremony_error)?; Ok(Self::new_unchecked( Signer::new(nonce, signing_key, identifier), client, - ceremony_size, + metadata, )) } @@ -144,7 +145,7 @@ where let signed_message = self.sign(QueryRequest)?; match self.client.post("query", &signed_message).await { Ok(QueryResponse::State(state)) => match state.with_valid_shape() { - Some(state) if self.ceremony_size.matches(&state.state) => { + Some(state) if self.metadata.ceremony_size.matches(&state.state) => { Ok(QueryResponse::State(state)) } _ => Err(CeremonyError::Unexpected( diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 5ec653bd7..881786095 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -23,19 +23,16 @@ use crate::{ signature::{Nonce, SignedMessage}, }, groth16::{ - ceremony::{Ceremony, CeremonyError, Queue, Round, UnexpectedError}, - mpc::{verify_transform, Proof, State, StateSize}, + ceremony::{Ceremony, CeremonyError, Metadata, Queue, Round, UnexpectedError}, + mpc::{verify_transform, Proof, State}, }, }; -use core::{mem, time::Duration}; +use core::mem; use manta_util::{time::lock::Timed, BoxArray}; #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; -/// Time limit for a participant at the front of the queue to contribute with unit as second -pub const TIME_LIMIT: Duration = Duration::from_secs(360); - /// Ceremony Coordinator #[cfg_attr( feature = "serde", @@ -79,8 +76,8 @@ where /// Latest Proof latest_proof: Option, CIRCUIT_COUNT>>, - /// State Sizes - size: BoxArray, + /// Ceremony Metadata + metadata: Metadata, /// Current Round Number round: usize, @@ -106,15 +103,16 @@ where registry: R, state: BoxArray, CIRCUIT_COUNT>, challenge: BoxArray, - size: BoxArray, + metadata: Metadata, ) -> Self { + assert!(metadata.ceremony_size.matches(state.as_slice())); Self { registry, state, challenge, latest_contributor: None, latest_proof: None, - size, + metadata, round: 0, queue: Default::default(), participant_lock: Default::default(), @@ -133,10 +131,10 @@ where self.round += 1; } - /// Returns the state size for each circuit in this ceremony. + /// Returns the metadata for this ceremony. #[inline] - pub fn size(&self) -> &[StateSize; CIRCUIT_COUNT] { - &self.size + pub fn metadata(&self) -> &Metadata { + &self.metadata } /// Returns the registry. @@ -231,7 +229,10 @@ where /// Checks the lock for `participant`. #[inline] pub fn check_lock(&mut self, participant: &C::Identifier) -> Result<(), CeremonyError> { - if self.participant_lock.has_expired(TIME_LIMIT) { + if self + .participant_lock + .has_expired(self.metadata.contribution_time_limit) + { Self::check_lock_update_errors(true, &self.update_expired_lock(), participant) } else { Self::check_lock_update_errors(false, self.participant_lock.get(), participant) diff --git a/manta-trusted-setup/src/groth16/ceremony/message.rs b/manta-trusted-setup/src/groth16/ceremony/message.rs index 6d4c69dc8..ab1385362 100644 --- a/manta-trusted-setup/src/groth16/ceremony/message.rs +++ b/manta-trusted-setup/src/groth16/ceremony/message.rs @@ -16,35 +16,15 @@ //! Groth16 Trusted Setup Ceremony Messaging Protocol -use crate::{ - groth16::{ - ceremony::{Ceremony, Round}, - mpc::{Proof, State, StateSize}, - }, - mpc, +use crate::groth16::{ + ceremony::{Ceremony, Round}, + mpc::{Proof, State}, }; -use manta_crypto::arkworks::pairing::Pairing; +use alloc::vec::Vec; #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; -/// Ceremony Size Alias -/// -/// In the ceremony we always use parallel round structures to support multiple Groth16 circuits at -/// the same time. -pub type CeremonySize = mpc::Parallel; - -impl CeremonySize { - /// Checks that each size in `self` matches each [`State`] in `states`. - #[inline] - pub fn matches

(&self, states: &[State

]) -> bool - where - P: Pairing, - { - self.len() == states.len() && self.iter().zip(states).all(|(l, r)| l.matches(&r.0)) - } -} - /// Query Request #[cfg_attr( feature = "serde", diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 2d13a3f71..42ede0cbc 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -21,10 +21,11 @@ use crate::{ participant::{Participant, Priority}, signature::SignatureScheme, }, - groth16::mpc::Configuration, + groth16::mpc::{Configuration, State, StateSize}, mpc, }; -use core::fmt::Debug; +use core::{fmt::Debug, time::Duration}; +use manta_crypto::arkworks::pairing::Pairing; use manta_util::{ collections::vec_deque::MultiVecDeque, serde::{Deserialize, Serialize}, @@ -68,6 +69,38 @@ pub trait Ceremony: Configuration + SignatureScheme { /// the same time. pub type Round = mpc::ParallelRound; +/// Ceremony Size Alias +/// +/// In the ceremony we always use parallel round structures to support multiple Groth16 circuits at +/// the same time. +pub type CeremonySize = mpc::Parallel; + +impl CeremonySize { + /// Checks that each size in `self` matches each [`State`] in `states`. + #[inline] + pub fn matches

(&self, states: &[State

]) -> bool + where + P: Pairing, + { + self.len() == states.len() && self.iter().zip(states).all(|(l, r)| l.matches(&r.0)) + } +} + +/// Ceremony Metadata +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde(crate = "manta_util::serde", deny_unknown_fields) +)] +#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] +pub struct Metadata { + /// Ceremony Size + pub ceremony_size: CeremonySize, + + /// Contribution Time Limit + pub contribution_time_limit: Duration, +} + /// Ceremony Error #[cfg_attr( feature = "serde", diff --git a/manta-trusted-setup/src/groth16/ceremony/server.rs b/manta-trusted-setup/src/groth16/ceremony/server.rs index a9b86ada3..0acfbc731 100644 --- a/manta-trusted-setup/src/groth16/ceremony/server.rs +++ b/manta-trusted-setup/src/groth16/ceremony/server.rs @@ -25,10 +25,10 @@ use crate::{ groth16::{ ceremony::{ coordinator::Coordinator, - message::{CeremonySize, ContributeRequest, QueryRequest, QueryResponse}, - Ceremony, CeremonyError, Participant as _, UnexpectedError, + message::{ContributeRequest, QueryRequest, QueryResponse}, + Ceremony, CeremonyError, Metadata, Participant as _, UnexpectedError, }, - mpc::{State, StateSize}, + mpc::State, }, }; use alloc::sync::Arc; @@ -70,11 +70,11 @@ where challenge: BoxArray, registry: R, recovery_directory: PathBuf, - size: BoxArray, + metadata: Metadata, ) -> Self { Self { coordinator: Arc::new(Mutex::new(Coordinator::new( - registry, state, challenge, size, + registry, state, challenge, metadata, ))), recovery_directory, } @@ -101,13 +101,13 @@ where pub async fn start( self, request: C::Identifier, - ) -> Result<(CeremonySize, C::Nonce), CeremonyError> + ) -> Result<(Metadata, C::Nonce), CeremonyError> where C::Nonce: Clone, { let coordinator = self.coordinator.lock(); Ok(( - coordinator.size().to_vec().into(), + coordinator.metadata().clone(), coordinator .registry() .get(&request) From 2e22efe83c370d4a8b4666ba314ee012ffb0e0e4 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 20 Sep 2022 20:56:15 +0200 Subject: [PATCH 57/60] fix: address some review comments Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/src/ceremony/signature.rs | 20 ++++++++++++++++++- .../src/groth16/ceremony/client.rs | 14 ++++++++++++- .../src/groth16/ceremony/coordinator.rs | 14 +++++++++++-- .../src/groth16/ceremony/mod.rs | 9 +++++++-- manta-util/src/collections/vec_deque.rs | 13 +++++++----- 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/manta-trusted-setup/src/ceremony/signature.rs b/manta-trusted-setup/src/ceremony/signature.rs index 50ecf4cb0..753c36f4a 100644 --- a/manta-trusted-setup/src/ceremony/signature.rs +++ b/manta-trusted-setup/src/ceremony/signature.rs @@ -27,12 +27,18 @@ use manta_util::AsBytes; use manta_util::serde::{Deserialize, Serialize}; /// Nonce -pub trait Nonce: Default { +pub trait Nonce: Default + PartialEq { /// Increments the current nonce by one. fn increment(&mut self); /// Checks if the current nonce is valid. fn is_valid(&self) -> bool; + + /// Checks that `self` and `rhs` are valid and are both equal. + #[inline] + fn matches(&self, rhs: &Self) -> bool { + self.is_valid() && rhs.is_valid() && self == rhs + } } impl Nonce for u64 { @@ -330,6 +336,18 @@ where self.nonce.increment() } + /// Sets the current nonce for `self` to `nonce` if it is a valid nonce. If `nonce` is valid, + /// `true` is returned and `false` otherwise. + #[inline] + pub fn set_valid_nonce(&mut self, nonce: S::Nonce) -> bool { + if nonce.is_valid() { + self.nonce = nonce; + true + } else { + false + } + } + /// Returns the signing key for `self`. #[inline] pub fn signing_key(&self) -> &S::SigningKey { diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index 9d27d64ab..fb2d4f13c 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -90,6 +90,15 @@ where } } + /// Updates the client's nonce to the `expected_nonce` returned by the server. + #[inline] + fn update_nonce(&mut self, expected_nonce: C::Nonce) -> Result<(), CeremonyError> { + self.signer + .set_valid_nonce(expected_nonce) + .then_some(()) + .ok_or(CeremonyError::Unexpected(UnexpectedError::AllNoncesUsed)) + } + /// Signs the `message` with the signer in `self`, incrementing its nonce if the singing was /// successful. #[inline] @@ -246,8 +255,11 @@ where .await?; loop { match client.try_contribute().await { - Ok(None) => return Ok(()), Ok(Some(update)) => process_update(update), + Ok(None) => return Ok(()), + Err(CeremonyError::InvalidSignature { expected_nonce }) => { + client.update_nonce(expected_nonce)?; + } Err(err) => return Err(err), } } diff --git a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs index 881786095..f3b7b7e76 100644 --- a/manta-trusted-setup/src/groth16/ceremony/coordinator.rs +++ b/manta-trusted-setup/src/groth16/ceremony/coordinator.rs @@ -105,7 +105,11 @@ where challenge: BoxArray, metadata: Metadata, ) -> Self { - assert!(metadata.ceremony_size.matches(state.as_slice())); + assert!( + metadata.ceremony_size.matches(state.as_slice()), + "Mismatch of metadata `{:?}` and state.", + metadata, + ); Self { registry, state, @@ -192,7 +196,9 @@ where } request .verify(participant_nonce.clone(), participant.verifying_key()) - .map_err(|_| CeremonyError::NonceNotInSync(participant_nonce.clone()))?; + .map_err(|_| CeremonyError::InvalidSignature { + expected_nonce: participant_nonce.clone(), + })?; participant.increment_nonce(); Ok(participant.priority()) } @@ -242,6 +248,10 @@ where /// Updates the MPC state and challenge using client's contribution. If the contribution is /// valid, the participant will be removed from the waiting queue, and cannot participate in /// this ceremony again. + /// + /// # Registration + /// + /// This method requires that `participant` is already registered. #[inline] pub fn update( &mut self, diff --git a/manta-trusted-setup/src/groth16/ceremony/mod.rs b/manta-trusted-setup/src/groth16/ceremony/mod.rs index 42ede0cbc..ec7089b00 100644 --- a/manta-trusted-setup/src/groth16/ceremony/mod.rs +++ b/manta-trusted-setup/src/groth16/ceremony/mod.rs @@ -123,8 +123,13 @@ where /// Malformed request that should not come from official client BadRequest, - /// Nonce not in sync, and client needs to update the nonce - NonceNotInSync(C::Nonce), + /// Invalid Signature + InvalidSignature { + /// Expected Nonce + /// + /// We also return the nonce here in case the client has gotten out of sync with the server. + expected_nonce: C::Nonce, + }, /// Not Registered NotRegistered, diff --git a/manta-util/src/collections/vec_deque.rs b/manta-util/src/collections/vec_deque.rs index 2c32f3fd1..be0d48f26 100644 --- a/manta-util/src/collections/vec_deque.rs +++ b/manta-util/src/collections/vec_deque.rs @@ -128,6 +128,12 @@ impl MultiVecDeque { } } + /// Returns the number of elements before the [`VecDeque`] at the given `level`. + #[inline] + fn leading_element_count(&self, level: usize) -> usize { + self.0[0..level].iter().map(VecDeque::len).sum::() + } + /// Finds the position of `item` assuming it was inserted at the given `level`. #[inline] pub fn position(&self, level: usize, item: &T) -> Option @@ -144,10 +150,7 @@ impl MultiVecDeque { where F: FnMut(&T, &T) -> bool, { - Some( - self.0[level].iter().position(|x| eq(x, item))? - + self.0[0..level].iter().map(VecDeque::len).sum::(), - ) + Some(self.0[level].iter().position(|x| eq(x, item))? + self.leading_element_count(level)) } /// Pushes `item` to the back of the deque at the given `level`. @@ -177,7 +180,7 @@ impl MultiVecDeque { Some(position) => position, None => { self.push_back(level, item); - self.0[level].len() - 1 + self.leading_element_count(level) + self.0[level].len() - 1 } } } From 55df7f347484f13facdec9e41c890e6c7bc7a3e3 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 22 Sep 2022 13:24:09 -0400 Subject: [PATCH 58/60] Apply suggestions from code review Co-authored-by: Todd Norton <93260651+GhostOfGauss@users.noreply.github.com> Signed-off-by: Brandon H. Gomes --- manta-trusted-setup/src/groth16/ceremony/client.rs | 2 +- manta-trusted-setup/src/groth16/ceremony/config/ppot.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/client.rs b/manta-trusted-setup/src/groth16/ceremony/client.rs index fb2d4f13c..d8b1c7133 100644 --- a/manta-trusted-setup/src/groth16/ceremony/client.rs +++ b/manta-trusted-setup/src/groth16/ceremony/client.rs @@ -99,7 +99,7 @@ where .ok_or(CeremonyError::Unexpected(UnexpectedError::AllNoncesUsed)) } - /// Signs the `message` with the signer in `self`, incrementing its nonce if the singing was + /// Signs the `message` with the signer in `self`, incrementing its nonce if the signing was /// successful. #[inline] fn sign( diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index c0d74e1cd..503da3634 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -310,7 +310,7 @@ pub fn register(twitter_account: String, email: String) { #[inline] pub fn get_client_keys() -> Option<(ed25519::SecretKey, ed25519::PublicKey)> { println!( - "Please enter your {} that you get when you registered yourself using this tool.", + "Please enter the {} you received when you registered yourself using this tool.", "Secret".italic() ); let seed_bytes = Seed::new( From 576e45d4c36451afdecc177ebd9a1107d9f82e90 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 22 Sep 2022 13:26:58 -0400 Subject: [PATCH 59/60] fix: address comments Signed-off-by: Brandon H. Gomes --- .../src/groth16/ceremony/config/ppot.rs | 10 +++++----- manta-util/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs index 503da3634..17b1776a4 100644 --- a/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs +++ b/manta-trusted-setup/src/groth16/ceremony/config/ppot.rs @@ -185,19 +185,19 @@ impl participant::Priority for Participant { deny_unknown_fields )] pub struct Record { - /// + /// Twitter Account twitter: String, - /// + /// Email Account email: String, - /// + /// Priority Level priority: String, - /// + /// Verifying Key verifying_key: String, - /// + /// Signature signature: String, } diff --git a/manta-util/Cargo.toml b/manta-util/Cargo.toml index 0a51ddcf8..5605378c3 100644 --- a/manta-util/Cargo.toml +++ b/manta-util/Cargo.toml @@ -40,7 +40,7 @@ std = ["alloc", "crossbeam-channel?/std", "serde?/std"] [dependencies] crossbeam-channel = { version = "0.5.6", optional = true, default-features = false } rayon = { version = "1.5.3", optional = true, default-features = false } -reqwest = { version = "0.11.11", optional = true, default-features = false, features = ["json"] } +reqwest = { version = "0.11.12", optional = true, default-features = false, features = ["json"] } serde = { version = "1.0.144", optional = true, default-features = false, features = ["derive"] } serde_with = { version = "1.14.0", optional = true, default-features = false, features = ["macros"] } tide = { version = "0.16.0", optional = true, default-features = false } From e448a1dc059b14bd1b13e84662a54b54468b6af4 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 22 Sep 2022 14:20:31 -0400 Subject: [PATCH 60/60] chore: update workspace Signed-off-by: Brandon H. Gomes --- .github/RELEASE_TEMPLATE.md | 3 +-- Cargo.toml | 12 ++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/RELEASE_TEMPLATE.md b/.github/RELEASE_TEMPLATE.md index cf4ceb7c5..bbf6c7394 100644 --- a/.github/RELEASE_TEMPLATE.md +++ b/.github/RELEASE_TEMPLATE.md @@ -3,5 +3,4 @@ - [ ] Checked that the release is on the correct branch name of the form `release-vX.Y.Z` and the PR title matches `Release vX.Y.Z` - [ ] Added the `changelog:skip` label and the relevant `release` label to this PR - [ ] Updated the [`CHANGELOG.md`](https://github.com/manta-network/manta-rs/blob/main/CHANGELOG.md) -- [ ] Updated the version numbers in the `Cargo.toml` for each crate in the workspace -- [ ] Ran `cargo hakari disable` to disable the `workspace-hack` system and checked that `workspace-hack/Cargo.toml` has no dependencies +- [ ] Updated the version number in the workspace `Cargo.toml` diff --git a/Cargo.toml b/Cargo.toml index dc1d3dbe5..f6db9e878 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,15 @@ +[workspace.package] +version = "0.5.4" +edition = "2021" +authors = ["Manta Network "] +repository = "https://github.com/Manta-Network/manta-rs" +homepage = "https://github.com/Manta-Network" +documentation = "https://github.com/Manta-Network/manta-rs" +license-file = "LICENSE" +categories = [""] +keywords = [""] +publish = false + [workspace] resolver = "2" members = ["manta-*"]