Skip to content

Commit

Permalink
refactor: ZK proofs (#48)
Browse files Browse the repository at this point in the history
* refactor: add tss-core package

* refactor: move composite dlog proof to tss-core

* refactor: use tss-core composite dlog proof

* refactor: move generate_h1_h2_N_tilde to tss-core

* refactor: allow non-snake-case

* refactor: rename to PiPrm and use instead of existing Ring-Pedersen

* refactor: define RingPedersenParams structure

* refactor: use pi-prm proof in fs-dkr

* refactor: move Pi-PRM and utilities to tss-core

* refactor: rename to PiEnc to correspond with paper

* refactor: move pi-aff-g proof

* feat: use externally generated rho in pi-enc

* refactor: move pi-log-star proof

* refactor: move pi-mul

* refactor: move pi-mul-star

* refactor: move pi-dec

* refactor: use constant security parameters

* chore: clippy

* feat: add sqrt for ring pedersen params

* fix: convert Legendre to -1

* fix: use p,q directly in sqrt

* feat: add pi-mod proof

* feat: add Pi-Fac proof

* fix: Pi-fac proof

* fix: sample sign bit for Pi-Fac challenge

* refactor: clippy suggestions
  • Loading branch information
ivokub authored Feb 6, 2024
1 parent b7a73ab commit 078443b
Show file tree
Hide file tree
Showing 41 changed files with 2,319 additions and 1,861 deletions.
20 changes: 20 additions & 0 deletions Cargo.lock

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

9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ authors = [
members = [
"multi-party-ecdsa",
"fs-dkr",
"tss-core",
]

[workspace.dependencies]
Expand All @@ -22,6 +23,9 @@ serde = { version = "1.0", features = ["derive"] }
zeroize = "1"
round-based = { git = "https://github.com/webb-tools/round-based-protocol", version = "0.1.4", features = ["dev"] }
thiserror = "1.0.23"
tss-core = { path = "tss-core" }
rand_chacha = "0.3.1"
rand = "0.8.5"

[workspace.dependencies.multi-party-ecdsa]
version = "0.8"
Expand All @@ -44,13 +48,14 @@ zeroize.workspace = true
paillier.workspace = true
round-based.workspace = true
thiserror.workspace = true
rand.workspace = true
rand_chacha.workspace = true
fs-dkr = { path = "fs-dkr", default-features = false }
bincode = "1.3.3"
digest = "0.9"
generic-array = "0.14"
rand_chacha = "0.3.1"
rand = "0.8.5"
getrandom = { version = "0.2", optional = true }
tss-core.workspace = true

[dev-dependencies]
criterion = "0.3"
Expand Down
1 change: 1 addition & 0 deletions fs-dkr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ round-based.workspace = true
serde.workspace = true
zeroize.workspace = true
thiserror.workspace = true
tss-core.workspace = true

[dependencies.multi-party-ecdsa]
workspace = true
Expand Down
127 changes: 48 additions & 79 deletions fs-dkr/src/add_party_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,74 +29,51 @@ use curv::{
elliptic::curves::{Curve, Point, Scalar},
BigInt,
};
use multi_party_ecdsa::gg_2020::party_i::generate_h1_h2_N_tilde;
use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::{
party_i::{Keys, SharedKeys},
state_machine::keygen::LocalKey,
};
use multi_party_ecdsa::utilities::zk_composite_dlog::{
CompositeDLogProof, CompositeDLogStatement, CompositeDLogWitness,
};
use paillier::{Decrypt, EncryptionKey, Paillier};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt::Debug};
use std::{collections::HashMap, fmt::Debug, marker::PhantomData};
use zk_paillier::zkproofs::NiCorrectKeyProof;

use crate::ring_pedersen_proof::{RingPedersenProof, RingPedersenStatement};
use tss_core::utilities::generate_safe_h1_h2_N_tilde;
use tss_core::zkproof::prm::{PiPrmProof, PiPrmStatement, PiPrmWitness};

/// Message used by new parties to join the protocol.
#[derive(Clone, Deserialize, Serialize, Debug)]
#[serde(bound = "E: Curve, H: Digest + Clone")]
pub struct JoinMessage<E: Curve, H: Digest + Clone, const M: usize> {
pub struct JoinMessage<E: Curve, H: Digest + Clone> {
pub(crate) ek: EncryptionKey,
pub(crate) dk_correctness_proof: NiCorrectKeyProof,
pub(crate) party_index: Option<u16>,
pub(crate) dlog_statement: CompositeDLogStatement,
pub(crate) composite_dlog_proof_base_h1: CompositeDLogProof,
pub(crate) composite_dlog_proof_base_h2: CompositeDLogProof,
pub(crate) ring_pedersen_statement: RingPedersenStatement<E, H>,
pub(crate) ring_pedersen_proof: RingPedersenProof<E, H, M>,
pub(crate) dlog_statement: PiPrmStatement,
pub(crate) composite_dlog_proof_base_h1: PiPrmProof,
pub(crate) composite_dlog_proof_base_h2: PiPrmProof,
pub(crate) ring_pedersen_pi_prm_statement: PiPrmStatement,
pub(crate) ring_pedersen_pi_prm_proof: PiPrmProof,
pub phantom: PhantomData<(E, H)>,
}

/// Generates the DlogStatement and CompositeProofs using the parameters
/// generated by [generate_h1_h2_n_tilde]
fn generate_dlog_statement_proofs() -> FsDkrResult<(
CompositeDLogStatement,
CompositeDLogProof,
CompositeDLogProof,
)> {
let (n_tilde, h1, h2, xhi, xhi_inv, phi) = generate_h1_h2_N_tilde();
fn generate_dlog_statement_proofs(
) -> FsDkrResult<(PiPrmStatement, PiPrmProof, PiPrmProof)> {
let (rpparam, rpwitness) = generate_safe_h1_h2_N_tilde();

let dlog_statement_base_h1 = CompositeDLogStatement {
modulus: n_tilde.clone(),
base: h1.clone(),
value: h2.clone(),
};
let dlog_witness_base_h1 = CompositeDLogWitness {
exponent: xhi,
totient: phi.clone(),
};
let dlog_statement_base_h1 = PiPrmStatement::from(&rpparam);
let dlog_witness_base_h1 = PiPrmWitness::from(&rpwitness);

let dlog_statement_base_h2 = CompositeDLogStatement {
modulus: n_tilde,
base: h2,
value: h1,
};
let dlog_witness_base_h2 = CompositeDLogWitness {
exponent: xhi_inv,
totient: phi.clone(),
};
let dlog_statement_base_h2 = PiPrmStatement::inverse_from(&rpparam);
let dlog_witness_base_h2 = PiPrmWitness::inverse_from(&rpwitness);

let composite_dlog_proof_base_h1 = CompositeDLogProof::prove(
&dlog_statement_base_h1,
&dlog_witness_base_h1,
)
.map_err(|_| FsDkrError::CompositeDLogProofGeneration)?;
let composite_dlog_proof_base_h2 = CompositeDLogProof::prove(
&dlog_statement_base_h2,
&dlog_witness_base_h2,
)
.map_err(|_| FsDkrError::CompositeDLogProofGeneration)?;
let composite_dlog_proof_base_h1 =
PiPrmProof::prove(&dlog_statement_base_h1, &dlog_witness_base_h1)
.map_err(|_| FsDkrError::CompositeDLogProofGeneration)?;
let composite_dlog_proof_base_h2 =
PiPrmProof::prove(&dlog_statement_base_h2, &dlog_witness_base_h2)
.map_err(|_| FsDkrError::CompositeDLogProofGeneration)?;

Ok((
dlog_statement_base_h1,
Expand All @@ -105,7 +82,7 @@ fn generate_dlog_statement_proofs() -> FsDkrResult<(
))
}

impl<E: Curve, H: Digest + Clone, const M: usize> JoinMessage<E, H, M> {
impl<E: Curve, H: Digest + Clone> JoinMessage<E, H> {
pub fn set_party_index(&mut self, new_party_index: u16) {
self.party_index = Some(new_party_index);
}
Expand All @@ -121,13 +98,12 @@ impl<E: Curve, H: Digest + Clone, const M: usize> JoinMessage<E, H, M> {
composite_dlog_proof_base_h2,
) = generate_dlog_statement_proofs()?;

let (ring_pedersen_statement, ring_pedersen_witness) =
RingPedersenStatement::generate();

let ring_pedersen_proof = RingPedersenProof::prove(
&ring_pedersen_witness,
&ring_pedersen_statement,
);
let (rpparam, rpwitness) = generate_safe_h1_h2_N_tilde();
let pi_prm_statement = PiPrmStatement::from(&rpparam);
let pi_prm_witness = PiPrmWitness::from(&rpwitness);
let pi_prm_proof =
PiPrmProof::prove(&pi_prm_statement, &pi_prm_witness)
.map_err(|_| FsDkrError::RingPedersenProofError {})?;

let join_message = JoinMessage {
// in a join message, we only care about the ek and the correctness
Expand All @@ -140,9 +116,10 @@ impl<E: Curve, H: Digest + Clone, const M: usize> JoinMessage<E, H, M> {
dlog_statement,
composite_dlog_proof_base_h1,
composite_dlog_proof_base_h2,
ring_pedersen_statement,
ring_pedersen_proof,
ring_pedersen_pi_prm_statement: pi_prm_statement,
ring_pedersen_pi_prm_proof: pi_prm_proof,
party_index: None,
phantom: PhantomData {},
};

Ok((join_message, paillier_key_pair))
Expand All @@ -162,39 +139,31 @@ impl<E: Curve, H: Digest + Clone, const M: usize> JoinMessage<E, H, M> {
/// (multiple parties can be added/replaced at once).
pub fn collect(
&self,
refresh_messages: &[RefreshMessage<E, H, M>],
refresh_messages: &[RefreshMessage<E, H>],
paillier_key: Keys,
join_messages: &[JoinMessage<E, H, M>],
join_messages: &[JoinMessage<E, H>],
new_t: u16,
new_n: u16,
current_t: u16,
) -> FsDkrResult<LocalKey<E>> {
RefreshMessage::validate_collect(refresh_messages, current_t, new_n)?;

for refresh_message in refresh_messages.iter() {
RingPedersenProof::verify(
&refresh_message.ring_pedersen_proof,
&refresh_message.ring_pedersen_statement,
)
.map_err(|_| {
FsDkrError::RingPedersenProofValidation {
refresh_message
.ring_pedersen_pi_prm_proof
.verify(&refresh_message.ring_pedersen_pi_prm_statement)
.map_err(|_| FsDkrError::RingPedersenProofValidation {
party_index: refresh_message.party_index,
}
})?;
})?;
}

for join_message in join_messages.iter() {
RingPedersenProof::verify(
&join_message.ring_pedersen_proof,
&join_message.ring_pedersen_statement,
)
.map_err(|e| {
if let Some(party_index) = join_message.party_index {
FsDkrError::RingPedersenProofValidation { party_index }
} else {
e
}
})?;
join_message
.ring_pedersen_pi_prm_proof
.verify(&join_message.ring_pedersen_pi_prm_statement)
.map_err(|_| FsDkrError::RingPedersenProofValidation {
party_index: join_message.party_index.unwrap_or(0),
})?;
}

// check if a party_index has been assigned to the current party
Expand Down Expand Up @@ -261,7 +230,7 @@ impl<E: Curve, H: Digest + Clone, const M: usize> JoinMessage<E, H, M> {
// TODO: submit the statement the dlog proof as well!
// check what parties are assigned in the current rotation and associate
// their DLogStatements and check their CompositeDlogProofs.
let available_h1_h2_ntilde_vec: HashMap<u16, &CompositeDLogStatement> =
let available_h1_h2_ntilde_vec: HashMap<u16, &PiPrmStatement> =
refresh_messages
.iter()
.map(|msg| (msg.party_index, &msg.dlog_statement))
Expand Down Expand Up @@ -289,7 +258,7 @@ impl<E: Curve, H: Digest + Clone, const M: usize> JoinMessage<E, H, M> {
})
.collect();
// generate the DLogStatement vec needed for the LocalKey generation.
let mut h1_h2_ntilde_vec: Vec<CompositeDLogStatement> =
let mut h1_h2_ntilde_vec: Vec<PiPrmStatement> =
Vec::with_capacity(new_n as usize);
for party in 1..new_n + 1 {
let statement = available_h1_h2_ntilde_vec.get(&party);
Expand Down
1 change: 0 additions & 1 deletion fs-dkr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub mod add_party_message;
pub mod error;
pub mod range_proofs;
pub mod refresh_message;
pub mod ring_pedersen_proof;
pub mod zk_pdl_with_slack;

mod test;
Expand Down
Loading

0 comments on commit 078443b

Please sign in to comment.