Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Restructure library #72

Merged
merged 10 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ jobs:
with:
cache-on-failure: "true"
- name: Run clippy
run: cargo clippy --all --lib --exclude cggmp21-tests -- --no-deps -D clippy::all -D clippy::unwrap_used -D clippy::expect_used
run: cargo clippy --all --all-features --lib --exclude cggmp21-tests -- --no-deps -D clippy::all -D clippy::unwrap_used -D clippy::expect_used
- name: Run clippy tests
run: cargo clippy --tests --lib -- -D clippy::all
run: cargo clippy --tests --all-features --lib -- -D clippy::all
bench:
runs-on: ubuntu-latest
permissions:
Expand Down
44 changes: 39 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
resolver = "2"
members = [
"cggmp21",
"cggmp21-keygen",
"key-share",
"tests",
]

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ let aux_info = cggmp21::aux_info_gen(eid, i, n, pregenerated_primes)

After keygen and aux info gen are done, you can make a “complete” key share that can be used for signing:
```rust
let key_share = cggmp21::KeyShare::make(incomplete_key_share, aux_info)?;
let key_share = cggmp21::KeyShare::from_parts((incomplete_key_share, aux_info))?;
```

### Signing
Expand Down
35 changes: 35 additions & 0 deletions cggmp21-keygen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[package]
name = "cggmp21-keygen"
version = "0.1.0"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "UC-secure DKG implementation based on CGGMP21 paper"
repository = "https://github.com/dfns/cggmp21"
categories = ["algorithms", "cryptography"]
keywords = ["mpc", "dkg", "threshold-signatures", "tss", "ecdsa", "t-ecdsa"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
key-share = { path = "../key-share", features = ["serde"] }
slip-10 = { git = "https://github.com/dfns/slip-10", branch = "m", optional = true }

generic-ec = { version = "0.1", features = ["serde", "udigest"] }
generic-ec-zkp = { version = "0.1", features = ["serde", "udigest"] }
udigest = { version = "0.1", features = ["std", "derive"]}

round-based = { version = "0.2", features = ["derive"] }
futures = "0.3"

sha2 = "0.10"
digest = "0.10"
rand_core = "0.6"

serde = { version = "1", features = ["derive"] }
serde_with = { version = "2" }
hex = { version = "0.4", default-features = false, features = ["serde"] }

thiserror = "1"

[features]
hd-wallets = ["slip-10", "key-share/hd-wallets"]
57 changes: 57 additions & 0 deletions cggmp21-keygen/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use std::convert::Infallible;

use round_based::rounds_router::{
errors::{self as router_error, CompleteRoundError},
simple_store::RoundInputError,
};
use thiserror::Error;

pub type BoxedError = Box<dyn std::error::Error + Send + Sync>;

#[derive(Debug, Error)]
pub enum IoError {
#[error("send message")]
SendMessage(#[source] BoxedError),
#[error("receive message")]
ReceiveMessage(#[source] BoxedError),
#[error("got eof while recieving messages")]
ReceiveMessageEof,
#[error("route received message (possibly malicious behavior)")]
RouteReceivedError(router_error::CompleteRoundError<RoundInputError, Infallible>),
}

impl IoError {
pub fn send_message<E: std::error::Error + Send + Sync + 'static>(err: E) -> Self {
Self::SendMessage(Box::new(err))
}

pub fn receive_message<E: std::error::Error + Send + Sync + 'static>(
err: CompleteRoundError<RoundInputError, E>,
) -> Self {
match err {
CompleteRoundError::Io(router_error::IoError::Io(e)) => {
Self::ReceiveMessage(Box::new(e))
}
CompleteRoundError::Io(router_error::IoError::UnexpectedEof) => Self::ReceiveMessageEof,

CompleteRoundError::ProcessMessage(e) => {
Self::RouteReceivedError(CompleteRoundError::ProcessMessage(e))
}
CompleteRoundError::Other(e) => Self::RouteReceivedError(CompleteRoundError::Other(e)),
}
}
}

macro_rules! impl_from {
(impl From for $target:ty {
$($var:ident: $ty:ty => $new:expr),+,
}) => {$(
impl From<$ty> for $target {
fn from($var: $ty) -> Self {
$new
}
}
)+}
}

pub(crate) use impl_from;
File renamed without changes.
57 changes: 36 additions & 21 deletions cggmp21/src/keygen.rs → cggmp21-keygen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,54 @@
//! Threshold and non-threshold DKG
//! Threshold and non-threshold CGGMP21 DKG
#![allow(non_snake_case, clippy::too_many_arguments)]

pub mod progress;
pub mod security_level;

/// Non-threshold DKG specific types
mod non_threshold;
/// Threshold DKG specific types
mod threshold;

mod errors;
mod execution_id;
mod rng;
mod utils;

use digest::Digest;
use generic_ec::Curve;
use rand_core::{CryptoRng, RngCore};
use round_based::{Mpc, MsgId, PartyIndex};
use thiserror::Error;

#[doc(inline)]
pub use key_share;

use crate::progress::Tracer;
use crate::utils;
use crate::{
errors::IoError,
key_share::{IncompleteKeyShare, InvalidKeyShare},
key_share::{CoreKeyShare, InvalidCoreShare},
security_level::SecurityLevel,
ExecutionId,
};

pub use self::execution_id::ExecutionId;
#[doc(no_inline)]
pub use self::msg::{non_threshold::Msg as NonThresholdMsg, threshold::Msg as ThresholdMsg};

#[doc = include_str!("../docs/mpc_message.md")]
/// Defines default choice for digest and security level used across the crate
mod default_choice {
pub type Digest = sha2::Sha256;
pub type SecurityLevel = crate::security_level::SecurityLevel128;
}

#[doc = include_str!("../../docs/mpc_message.md")]
pub mod msg {
/// Messages types related to non threshold DKG protocol
pub mod non_threshold {
pub use crate::keygen::non_threshold::{
Msg, MsgReliabilityCheck, MsgRound1, MsgRound2, MsgRound3,
};
pub use crate::non_threshold::{Msg, MsgReliabilityCheck, MsgRound1, MsgRound2, MsgRound3};
}
/// Messages types related to threshold DKG protocol
pub mod threshold {
pub use crate::keygen::threshold::{
pub use crate::threshold::{
Msg, MsgReliabilityCheck, MsgRound1, MsgRound2Broad, MsgRound2Uni, MsgRound3,
};
}
Expand Down Expand Up @@ -163,7 +178,7 @@ where
self
}

#[doc = include_str!("../docs/enforce_reliable_broadcast.md")]
#[doc = include_str!("../../docs/enforce_reliable_broadcast.md")]
pub fn enforce_reliable_broadcast(self, enforce: bool) -> Self {
Self {
reliable_broadcast_enforced: enforce,
Expand All @@ -186,11 +201,7 @@ where
D: Digest + Clone + 'static,
{
/// Starts key generation
pub async fn start<R, M>(
self,
rng: &mut R,
party: M,
) -> Result<IncompleteKeyShare<E>, KeygenError>
pub async fn start<R, M>(self, rng: &mut R, party: M) -> Result<CoreKeyShare<E>, KeygenError>
where
R: RngCore + CryptoRng,
M: Mpc<ProtocolMessage = non_threshold::Msg<E, L, D>>,
Expand All @@ -217,11 +228,7 @@ where
D: Digest + Clone + 'static,
{
/// Starts threshold key generation
pub async fn start<R, M>(
self,
rng: &mut R,
party: M,
) -> Result<IncompleteKeyShare<E>, KeygenError>
pub async fn start<R, M>(self, rng: &mut R, party: M) -> Result<CoreKeyShare<E>, KeygenError>
where
R: RngCore + CryptoRng,
M: Mpc<ProtocolMessage = threshold::Msg<E, L, D>>,
Expand Down Expand Up @@ -294,10 +301,18 @@ enum KeygenAborted {
#[derive(Debug, Error)]
enum Bug {
#[error("resulting key share is not valid")]
InvalidKeyShare(#[source] InvalidKeyShare),
InvalidKeyShare(#[source] InvalidCoreShare),
#[error("unexpected zero value")]
NonZeroScalar,
#[cfg(feature = "hd-wallets")]
#[error("chain code is missing although we checked that it should be present")]
NoChainCode,
}

/// Distributed key generation protocol
///
/// Each party of the protocol should have uniquely assigned index $i$ such that $0 \le i < n$
/// (where $n$ is amount of parties in the protocol).
pub fn keygen<E: Curve>(eid: ExecutionId, i: u16, n: u16) -> KeygenBuilder<E> {
KeygenBuilder::new(eid, i, n)
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
use crate::progress::Tracer;
use crate::{
errors::IoError,
key_share::{DirtyIncompleteKeyShare, IncompleteKeyShare},
key_share::{CoreKeyShare, DirtyCoreKeyShare, Validate},
security_level::SecurityLevel,
utils, ExecutionId,
};
Expand Down Expand Up @@ -51,7 +51,7 @@ pub struct MsgRound1<D: Digest> {
#[udigest(tag = "dfns.cggmp21.keygen.non_threshold.round2")]
pub struct MsgRound2<E: Curve, L: SecurityLevel> {
/// `rid_i`
#[serde_as(as = "utils::serde::HexOrBin")]
#[serde_as(as = "utils::HexOrBin")]
#[udigest(as_bytes)]
pub rid: L::Rid,
/// $X_i$
Expand All @@ -60,7 +60,7 @@ pub struct MsgRound2<E: Curve, L: SecurityLevel> {
pub sch_commit: schnorr_pok::Commit<E>,
/// Party contribution to chain code
#[cfg(feature = "hd-wallets")]
#[serde_as(as = "Option<utils::serde::HexOrBin>")]
#[serde_as(as = "Option<utils::HexOrBin>")]
#[udigest(with = utils::encoding::maybe_bytes)]
pub chain_code: Option<slip_10::ChainCode>,
/// $u_i$
Expand Down Expand Up @@ -105,7 +105,7 @@ pub async fn run_keygen<E, R, M, L, D>(
rng: &mut R,
party: M,
#[cfg(feature = "hd-wallets")] hd_enabled: bool,
) -> Result<IncompleteKeyShare<E>, KeygenError>
) -> Result<CoreKeyShare<E>, KeygenError>
where
E: Curve,
L: SecurityLevel,
Expand Down Expand Up @@ -286,7 +286,7 @@ where
.chain_update(rid.as_ref())
.finalize()
};
let mut rng = paillier_zk::rng::HashRng::new(hash);
let mut rng = crate::rng::HashRng::new(hash);
Scalar::random(&mut rng)
};
let challenge = schnorr_pok::Challenge { nonce: challenge };
Expand Down Expand Up @@ -321,7 +321,7 @@ where
.chain_update(rid.as_ref())
.finalize()
};
let mut rng = paillier_zk::rng::HashRng::new(hash);
let mut rng = crate::rng::HashRng::new(hash);
Scalar::random(&mut rng)
};
let challenge = schnorr_pok::Challenge { nonce: challenge };
Expand All @@ -336,7 +336,7 @@ where

tracer.protocol_ends();

Ok(DirtyIncompleteKeyShare {
Ok(DirtyCoreKeyShare {
curve: Default::default(),
i,
shared_public_key: decommitments
Expand All @@ -352,6 +352,6 @@ where
#[cfg(feature = "hd-wallets")]
chain_code,
}
.try_into()
.map_err(Bug::InvalidKeyShare)?)
.validate()
.map_err(|e| Bug::InvalidKeyShare(e.into_error()))?)
}
Loading
Loading