From cd0d9ce64c22b2ca5099841c66958a82c477af27 Mon Sep 17 00:00:00 2001 From: omershlo Date: Sun, 31 Mar 2019 19:45:08 +0300 Subject: [PATCH 01/14] keygen + sign --- src/ecdsa/mod.rs | 3 +- src/ecdsa/two_party_gg18/mod.rs | 140 ++++++++ src/ecdsa/two_party_gg18/party1.rs | 317 ++++++++++++++++++ src/ecdsa/two_party_gg18/party2.rs | 315 +++++++++++++++++ src/ecdsa/two_party_gg18/test.rs | 235 +++++++++++++ .../{two_party => two_party_lindell17}/mod.rs | 0 .../party1.rs | 2 +- .../party2.rs | 0 .../test.rs | 0 src/poc.rs | 4 +- 10 files changed, 1012 insertions(+), 4 deletions(-) create mode 100644 src/ecdsa/two_party_gg18/mod.rs create mode 100644 src/ecdsa/two_party_gg18/party1.rs create mode 100644 src/ecdsa/two_party_gg18/party2.rs create mode 100644 src/ecdsa/two_party_gg18/test.rs rename src/ecdsa/{two_party => two_party_lindell17}/mod.rs (100%) rename src/ecdsa/{two_party => two_party_lindell17}/party1.rs (99%) rename src/ecdsa/{two_party => two_party_lindell17}/party2.rs (100%) rename src/ecdsa/{two_party => two_party_lindell17}/test.rs (100%) diff --git a/src/ecdsa/mod.rs b/src/ecdsa/mod.rs index 6cce01d..7f4a886 100644 --- a/src/ecdsa/mod.rs +++ b/src/ecdsa/mod.rs @@ -14,4 +14,5 @@ @license GPL-3.0+ */ -pub mod two_party; +pub mod two_party_gg18; +pub mod two_party_lindell17; diff --git a/src/ecdsa/two_party_gg18/mod.rs b/src/ecdsa/two_party_gg18/mod.rs new file mode 100644 index 0000000..256fa9a --- /dev/null +++ b/src/ecdsa/two_party_gg18/mod.rs @@ -0,0 +1,140 @@ +/* + KMS-ECDSA + Copyright 2018 by Kzen Networks + This file is part of KMS library + (https://github.com/KZen-networks/kms) + Cryptography utilities 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. + @license GPL-3.0+ +*/ + +use curv::cryptographic_primitives::proofs::sigma_correct_homomorphic_elgamal_enc::HomoELGamalProof; +use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; +use curv::BigInt; +use curv::{FE, GE}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, MessageB}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::party_i::*; +use paillier::EncryptionKey; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +pub struct MasterKeyPublic { + pub q: GE, //y_sum + pub vss_scheme_vec: Vec, + pub paillier_key_vec: Vec, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq)] +pub struct MasterKey1 { + pub public: MasterKeyPublic, + private: PartyPrivate, + chain_code: BigInt, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq)] +pub struct MasterKey2 { + pub public: MasterKeyPublic, + private: PartyPrivate, + chain_code: BigInt, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct KeyGenMessage3 { + pub vss_scheme: VerifiableSS, + pub secret_share: FE, +} + +#[derive(Serialize, Deserialize)] +pub struct SignMessage1 { + pub com: SignBroadcastPhase1, + pub m_a_k: MessageA, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct SignMessage2 { + pub m_b_gamma: MessageB, + pub m_b_w: MessageB, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SignMessage3 { + pub delta: FE, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct SignMessage4 { + pub decommit: SignDecommitPhase1, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct SignMessage5 { + pub phase5_com: Phase5Com1, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SignMessage6 { + pub phase_5a_decom: Phase5ADecom1, + pub helgamal_proof: HomoELGamalProof, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SignMessage7 { + pub phase5_com2: Phase5Com2, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SignMessage8 { + pub phase_5d_decom2: Phase5DDecom2, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct SignMessage9 { + pub s_i: FE, +} + +pub mod party1; +pub mod party2; +mod test; + +/* +pub fn hd_key( + mut location_in_hir: Vec, + pubkey: &GE, + chain_code_bi: &BigInt, +) -> (GE, FE, GE) { + let mask = BigInt::from(2).pow(256) - BigInt::one(); + // let public_key = self.public.q.clone(); + + // calc first element: + let first = location_in_hir.remove(0); + let pub_key_bi = pubkey.bytes_compressed_to_big_int(); + let f = hmac_sha512::HMacSha512::create_hmac(&chain_code_bi, &[&pub_key_bi, &first]); + let f_l = &f >> 256; + let f_r = &f & &mask; + let f_l_fe: FE = ECScalar::from(&f_l); + let f_r_fe: FE = ECScalar::from(&f_r); + + let bn_to_slice = BigInt::to_vec(chain_code_bi); + let chain_code = GE::from_bytes(&bn_to_slice[1..33]).unwrap() * &f_r_fe; + let pub_key = pubkey * &f_l_fe; + + let (public_key_new_child, f_l_new, cc_new) = + location_in_hir + .iter() + .fold((pub_key, f_l_fe, chain_code), |acc, index| { + let pub_key_bi = acc.0.bytes_compressed_to_big_int(); + let f = hmac_sha512::HMacSha512::create_hmac( + &acc.2.bytes_compressed_to_big_int(), + &[&pub_key_bi, index], + ); + let f_l = &f >> 256; + let f_r = &f & &mask; + let f_l_fe: FE = ECScalar::from(&f_l); + let f_r_fe: FE = ECScalar::from(&f_r); + + (acc.0 * &f_l_fe, f_l_fe * &acc.1, &acc.2 * &f_r_fe) + }); + (public_key_new_child, f_l_new, cc_new) +} +*/ diff --git a/src/ecdsa/two_party_gg18/party1.rs b/src/ecdsa/two_party_gg18/party1.rs new file mode 100644 index 0000000..4806a31 --- /dev/null +++ b/src/ecdsa/two_party_gg18/party1.rs @@ -0,0 +1,317 @@ +#![allow(non_snake_case)] +/* + KMS-ECDSA + Copyright 2018 by Kzen Networks + This file is part of KMS library + (https://github.com/KZen-networks/kms) + Cryptography utilities 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. + @license GPL-3.0+ +*/ + +use super::*; +use curv::cryptographic_primitives::proofs::sigma_correct_homomorphic_elgamal_enc::HomoELGamalProof; +use curv::cryptographic_primitives::proofs::sigma_dlog::DLogProof; +use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; +use curv::BigInt; +use curv::{FE, GE}; +use ecdsa::two_party_gg18::{MasterKey1, MasterKeyPublic}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, MessageB}; +use paillier::EncryptionKey; + +impl MasterKey1 { + pub fn key_gen_first_message() -> (Keys, KeyGenBroadcastMessage1, KeyGenDecommitMessage1) { + let party_keys = Keys::create(1 as usize); + let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); + (party_keys, bc_i, decom_i) + } + + pub fn key_gen_third_message( + party1_keys: &Keys, + party1_message1: KeyGenBroadcastMessage1, + party2_message1: KeyGenBroadcastMessage1, + party1_message2: KeyGenDecommitMessage1, + party2_message2: KeyGenDecommitMessage1, + ) -> (KeyGenMessage3, FE, Vec, Vec) { + let y_slice = &[party1_keys.y_i, party2_message2.y_i]; + let decom_slice = &[party1_message2, party2_message2]; + let bc1_slice = &[party1_message1.clone(), party2_message1.clone()]; + let paillier_enc_slice = &[party1_message1.e.clone(), party2_message1.e.clone()]; + let parames = Parameters { + threshold: 1 as usize, + share_count: 2 as usize, + }; + let (vss_scheme, secret_shares, _index) = party1_keys + .phase1_verify_com_phase3_verify_correct_key_phase2_distribute( + ¶mes, + &decom_slice.to_vec(), + &bc1_slice.to_vec(), + ) + .expect("invalid key"); + let key_gen_message3 = KeyGenMessage3 { + vss_scheme, + secret_share: secret_shares[1], + }; + ( + key_gen_message3, + secret_shares[0], + y_slice.to_vec(), + paillier_enc_slice.to_vec(), + ) + } + + pub fn key_gen_fourth_message( + party1_keys: &Keys, + vss_scheme_party1: VerifiableSS, + vss_scheme_party2: VerifiableSS, + party1_ss_share_0: FE, + party2_ss_share_0: FE, + y_vec: &Vec, + ) -> (SharedKeys, DLogProof, Vec) { + let parames = Parameters { + threshold: 1 as usize, + share_count: 2 as usize, + }; + let vss_slice = &[vss_scheme_party1, vss_scheme_party2]; + let ss_slice = &[party1_ss_share_0, party2_ss_share_0]; + let (shared_keys, dlog_proof) = party1_keys + .phase2_verify_vss_construct_keypair_phase3_pok_dlog( + ¶mes, + y_vec, + &ss_slice.to_vec(), + &vss_slice.to_vec(), + &(1 as usize), + ) + .expect("invalid vss"); + + (shared_keys, dlog_proof, vss_slice.to_vec()) + } + + pub fn set_master_key( + dlog_proof: Vec, + y_vec: Vec, + party1_keys: Keys, + party1_shared_keys: SharedKeys, + vss_vec: Vec, + paillier_enc_vec: Vec, + chain_code: &BigInt, + ) -> Self { + let parames = Parameters { + threshold: 1 as usize, + share_count: 2 as usize, + }; + Keys::verify_dlog_proofs(¶mes, &dlog_proof, &y_vec).expect("bad dlog proof"); + + let master_key_public = MasterKeyPublic { + q: y_vec[0] + y_vec[1], + vss_scheme_vec: vss_vec, + paillier_key_vec: paillier_enc_vec, + }; + + let master_key_private = PartyPrivate::set_private(party1_keys, party1_shared_keys); + + let master_key1 = MasterKey1 { + public: master_key_public, + private: master_key_private, + chain_code: chain_code.clone(), + }; + master_key1 + } + + pub fn sign_first_message(&self) -> (SignMessage1, SignDecommitPhase1, SignKeys) { + let index: usize = 0; + let index_list = [0 as usize, 1 as usize].to_vec(); + + let sign_keys = SignKeys::create( + &self.private, + &self.public.vss_scheme_vec[0], + index, + &index_list, + ); + + let (com, decommit) = sign_keys.phase1_broadcast(); + let m_a_k = MessageA::a(&sign_keys.k_i, &self.public.paillier_key_vec[0]); + + let sign_message1 = SignMessage1 { com, m_a_k }; + (sign_message1, decommit, sign_keys) + } + + pub fn sign_second_message( + &self, + party2_message1: &SignMessage1, + party1_sign_keys: &SignKeys, + ) -> (SignMessage2, FE, FE) { + let (m_b_gamma, beta) = MessageB::b( + &party1_sign_keys.gamma_i, + &self.public.paillier_key_vec[1], + party2_message1.m_a_k.clone(), + ); + let (m_b_w, ni) = MessageB::b( + &party1_sign_keys.w_i, + &&self.public.paillier_key_vec[1], + party2_message1.m_a_k.clone(), + ); + let party1_message2 = SignMessage2 { m_b_gamma, m_b_w }; + + (party1_message2, beta, ni) + } + + pub fn sign_third_message( + &self, + party2_message2: &SignMessage2, + party1_sign_keys: &SignKeys, + beta: FE, + ni: FE, + ) -> (SignMessage3, FE) { + let alpha = party2_message2 + .m_b_gamma + .verify_proofs_get_alpha_gg18(&self.private, &party1_sign_keys.k_i) + .expect("wrong dlog or m_b");; + let miu = party2_message2 + .m_b_w + .verify_proofs_get_alpha_gg18(&self.private, &party1_sign_keys.k_i) + .expect("wrong dlog or m_b");; + + let index: usize = 1; + let index_list = [0 as usize, 1 as usize].to_vec(); + let xi_com_vec = Keys::get_commitments_to_xi(&self.public.vss_scheme_vec); + let x1_com = xi_com_vec[1]; + let g_w_i = Keys::update_commitments_to_xi( + &x1_com, + &self.public.vss_scheme_vec[1], + index, + &index_list, + ); + assert_eq!(party2_message2.m_b_w.b_proof.pk.clone(), g_w_i); + + let delta = party1_sign_keys.phase2_delta_i(&[alpha].to_vec(), &[beta].to_vec()); + let sigma = party1_sign_keys.phase2_sigma_i(&[miu].to_vec(), &[ni].to_vec()); + + let sign_message3 = SignMessage3 { delta }; + (sign_message3, sigma) + } + + pub fn sign_fourth_message(decommit: SignDecommitPhase1) -> SignMessage4 { + SignMessage4 { decommit } + } + + pub fn sign_fifth_message( + &self, + message: BigInt, + sigma: FE, + party1_sign_keys: &SignKeys, + party1_message4: SignMessage4, + party1_message3: SignMessage3, + party2_message3: SignMessage3, + party2_message4: SignMessage4, + party2_message2: SignMessage2, + party2_message1: SignMessage1, + ) -> ( + SignMessage5, + Phase5ADecom1, + HomoELGamalProof, + LocalSignature, + GE, + ) { + let delta_slice = &[party1_message3.delta, party2_message3.delta]; + let delta_inv = SignKeys::phase3_reconstruct_delta(&delta_slice.to_vec()); + + let b_proof = party2_message2.m_b_gamma.b_proof; + let R = SignKeys::phase4( + &delta_inv, + &[&b_proof].to_vec(), + [party2_message4.decommit.clone()].to_vec(), + &[party2_message1.com].to_vec(), + ) + .expect("bad gamma_i decommit"); + let R = R + party1_message4.decommit.g_gamma_i * &delta_inv; + + let local_sig = LocalSignature::phase5_local_sig( + &party1_sign_keys.k_i, + &message, + &R, + &sigma, + &self.public.q, + ); + + let (phase5_com, phase_5a_decom, helgamal_proof) = local_sig.phase5a_broadcast_5b_zkproof(); + let sign_message5 = SignMessage5 { phase5_com }; + (sign_message5, phase_5a_decom, helgamal_proof, local_sig, R) + } + + pub fn sign_sixth_message( + phase_5a_decom: Phase5ADecom1, + helgamal_proof: HomoELGamalProof, + ) -> SignMessage6 { + SignMessage6 { + phase_5a_decom, + helgamal_proof, + } + } + + pub fn sign_seventh_message( + party1_message6: SignMessage6, + party2_message6: SignMessage6, + party2_message5: SignMessage5, + local_sig: &LocalSignature, + R: GE, + ) -> (SignMessage7, Phase5DDecom2) { + let (phase5_com2, phase_5d_decom2) = local_sig + .phase5c( + &[party2_message6.phase_5a_decom].to_vec(), + &[party2_message5.phase5_com].to_vec(), + &[party2_message6.helgamal_proof].to_vec(), + &party1_message6.phase_5a_decom.V_i, + &R, + ) + .expect("error phase5"); + + let sign_message7 = SignMessage7 { phase5_com2 }; + (sign_message7, phase_5d_decom2) + } + + pub fn sign_eighth_message(phase_5d_decom2: Phase5DDecom2) -> SignMessage8 { + SignMessage8 { phase_5d_decom2 } + } + + pub fn sign_ninth_message( + party1_message6: SignMessage6, + party2_message6: SignMessage6, + party1_message7: SignMessage7, + party2_message7: SignMessage7, + party1_message8: SignMessage8, + party2_message8: SignMessage8, + local_sig: &LocalSignature, + ) -> SignMessage9 { + let phase5a_decom_slice = [ + party1_message6.phase_5a_decom, + party2_message6.phase_5a_decom, + ]; + let phase5d_com_slice = [party1_message7.phase5_com2, party2_message7.phase5_com2]; + let phase5d_decom_slice = [ + party1_message8.phase_5d_decom2, + party2_message8.phase_5d_decom2, + ]; + + let s_i = local_sig + .phase5d( + &phase5d_decom_slice.to_vec(), + &phase5d_com_slice.to_vec(), + &phase5a_decom_slice.to_vec(), + ) + .expect("bad com 5d"); + + let sign_message9 = SignMessage9 { s_i }; + sign_message9 + } + + pub fn output_signature(party2_message9: SignMessage9, local_sig: LocalSignature) -> (FE, FE) { + let message9_vec = [party2_message9.s_i].to_vec(); + let (r, s) = local_sig + .output_signature(&message9_vec) + .expect("verification failed"); + (r, s) + } +} diff --git a/src/ecdsa/two_party_gg18/party2.rs b/src/ecdsa/two_party_gg18/party2.rs new file mode 100644 index 0000000..d4a929e --- /dev/null +++ b/src/ecdsa/two_party_gg18/party2.rs @@ -0,0 +1,315 @@ +#![allow(non_snake_case)] +/* + KMS-ECDSA + Copyright 2018 by Kzen Networks + This file is part of KMS library + (https://github.com/KZen-networks/kms) + Cryptography utilities 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. + @license GPL-3.0+ +*/ + +use super::*; +use curv::cryptographic_primitives::proofs::sigma_correct_homomorphic_elgamal_enc::HomoELGamalProof; +use curv::cryptographic_primitives::proofs::sigma_dlog::DLogProof; +use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; +use curv::BigInt; +use curv::{FE, GE}; +use ecdsa::two_party_gg18::{MasterKey2, MasterKeyPublic}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, MessageB}; +use paillier::EncryptionKey; + +impl MasterKey2 { + pub fn key_gen_first_message() -> (Keys, KeyGenBroadcastMessage1, KeyGenDecommitMessage1) { + let party_keys = Keys::create(2 as usize); + let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); + (party_keys, bc_i, decom_i) + } + + pub fn key_gen_third_message( + party2_keys: &Keys, + party1_message1: KeyGenBroadcastMessage1, + party2_message1: KeyGenBroadcastMessage1, + party1_message2: KeyGenDecommitMessage1, + party2_message2: KeyGenDecommitMessage1, + ) -> (KeyGenMessage3, FE, Vec, Vec) { + let y_slice = &[party1_message2.y_i, party2_keys.y_i]; + let decom_slice = &[party1_message2, party2_message2]; + let bc1_slice = &[party1_message1.clone(), party2_message1.clone()]; + let paillier_enc_slice = &[party1_message1.e.clone(), party2_message1.e.clone()]; + let parames = Parameters { + threshold: 1 as usize, + share_count: 2 as usize, + }; + let (vss_scheme, secret_shares, _index) = party2_keys + .phase1_verify_com_phase3_verify_correct_key_phase2_distribute( + ¶mes, + &decom_slice.to_vec(), + &bc1_slice.to_vec(), + ) + .expect("invalid key"); + let key_gen_message3 = KeyGenMessage3 { + vss_scheme, + secret_share: secret_shares[0], + }; + ( + key_gen_message3, + secret_shares[1], + y_slice.to_vec(), + paillier_enc_slice.to_vec(), + ) + } + + pub fn key_gen_fourth_message( + party2_keys: &Keys, + vss_scheme_party1: VerifiableSS, + vss_scheme_party2: VerifiableSS, + party1_ss_share_1: FE, + party2_ss_share_1: FE, + y_vec: &Vec, + ) -> (SharedKeys, DLogProof, Vec) { + let parames = Parameters { + threshold: 1 as usize, + share_count: 2 as usize, + }; + let vss_slice = &[vss_scheme_party1, vss_scheme_party2]; + let ss_slice = &[party1_ss_share_1, party2_ss_share_1]; + let (shared_keys, dlog_proof) = party2_keys + .phase2_verify_vss_construct_keypair_phase3_pok_dlog( + ¶mes, + y_vec, + &ss_slice.to_vec(), + &vss_slice.to_vec(), + &(2 as usize), + ) + .expect("invalid vss"); + (shared_keys, dlog_proof, vss_slice.to_vec()) + } + + pub fn set_master_key( + dlog_proof: Vec, + y_vec: Vec, + party2_keys: Keys, + party2_shared_keys: SharedKeys, + vss_vec: Vec, + paillier_enc_vec: Vec, + chain_code: &BigInt, + ) -> Self { + let parames = Parameters { + threshold: 1 as usize, + share_count: 2 as usize, + }; + Keys::verify_dlog_proofs(¶mes, &dlog_proof, &y_vec).expect("bad dlog proof"); + let master_key_public = MasterKeyPublic { + q: y_vec[0] + y_vec[1], + vss_scheme_vec: vss_vec, + paillier_key_vec: paillier_enc_vec, + }; + + let master_key_private = PartyPrivate::set_private(party2_keys, party2_shared_keys); + + let master_key2 = MasterKey2 { + public: master_key_public, + private: master_key_private, + chain_code: chain_code.clone(), + }; + master_key2 + } + + pub fn sign_first_message(&self) -> (SignMessage1, SignDecommitPhase1, SignKeys) { + let index: usize = 1; + let index_list = [0 as usize, 1 as usize].to_vec(); + + let sign_keys = SignKeys::create( + &self.private, + &self.public.vss_scheme_vec[1], + index, + &index_list, + ); + + let (com, decommit) = sign_keys.phase1_broadcast(); + let m_a_k = MessageA::a(&sign_keys.k_i, &self.public.paillier_key_vec[1]); + + let sign_message1 = SignMessage1 { com, m_a_k }; + (sign_message1, decommit, sign_keys) + } + + pub fn sign_second_message( + &self, + party1_message1: &SignMessage1, + party2_sign_keys: &SignKeys, + ) -> (SignMessage2, FE, FE) { + let (m_b_gamma, beta) = MessageB::b( + &party2_sign_keys.gamma_i, + &self.public.paillier_key_vec[0], + party1_message1.m_a_k.clone(), + ); + let (m_b_w, ni) = MessageB::b( + &party2_sign_keys.w_i, + &&self.public.paillier_key_vec[0], + party1_message1.m_a_k.clone(), + ); + let party2_message2 = SignMessage2 { m_b_gamma, m_b_w }; + + (party2_message2, beta, ni) + } + + pub fn sign_third_message( + &self, + party1_message2: &SignMessage2, + party2_sign_keys: &SignKeys, + beta: FE, + ni: FE, + ) -> (SignMessage3, FE) { + let alpha = party1_message2 + .m_b_gamma + .verify_proofs_get_alpha_gg18(&self.private, &party2_sign_keys.k_i) + .expect("wrong dlog or m_b");; + let miu = party1_message2 + .m_b_w + .verify_proofs_get_alpha_gg18(&self.private, &party2_sign_keys.k_i) + .expect("wrong dlog or m_b");; + + let index: usize = 0; + let index_list = [0 as usize, 1 as usize].to_vec(); + let xi_com_vec = Keys::get_commitments_to_xi(&self.public.vss_scheme_vec); + let x0_com = xi_com_vec[0]; + let g_w_i = Keys::update_commitments_to_xi( + &x0_com, + &self.public.vss_scheme_vec[0], + index, + &index_list, + ); + assert_eq!(party1_message2.m_b_w.b_proof.pk.clone(), g_w_i); + + let delta = party2_sign_keys.phase2_delta_i(&[alpha].to_vec(), &[beta].to_vec()); + let sigma = party2_sign_keys.phase2_sigma_i(&[miu].to_vec(), &[ni].to_vec()); + + let sign_message3 = SignMessage3 { delta }; + (sign_message3, sigma) + } + + pub fn sign_fourth_message(decommit: SignDecommitPhase1) -> SignMessage4 { + SignMessage4 { decommit } + } + + pub fn sign_fifth_message( + &self, + message: BigInt, + sigma: FE, + party2_sign_keys: &SignKeys, + party2_message4: SignMessage4, + party2_message3: SignMessage3, + party1_message3: SignMessage3, + party1_message4: SignMessage4, + party1_message2: SignMessage2, + party1_message1: SignMessage1, + ) -> ( + SignMessage5, + Phase5ADecom1, + HomoELGamalProof, + LocalSignature, + GE, + ) { + let delta_slice = &[party1_message3.delta, party2_message3.delta]; + let delta_inv = SignKeys::phase3_reconstruct_delta(&delta_slice.to_vec()); + + let b_proof = party1_message2.m_b_gamma.b_proof; + let R = SignKeys::phase4( + &delta_inv, + &[&b_proof].to_vec(), + [party1_message4.decommit.clone()].to_vec(), + &[party1_message1.com].to_vec(), + ) + .expect("bad gamma_i decommit"); + let R = R + party2_message4.decommit.g_gamma_i * &delta_inv; + + let local_sig = LocalSignature::phase5_local_sig( + &party2_sign_keys.k_i, + &message, + &R, + &sigma, + &self.public.q, + ); + + let (phase5_com, phase_5a_decom, helgamal_proof) = local_sig.phase5a_broadcast_5b_zkproof(); + let sign_message5 = SignMessage5 { phase5_com }; + (sign_message5, phase_5a_decom, helgamal_proof, local_sig, R) + } + + pub fn sign_sixth_message( + phase_5a_decom: Phase5ADecom1, + helgamal_proof: HomoELGamalProof, + ) -> SignMessage6 { + SignMessage6 { + phase_5a_decom, + helgamal_proof, + } + } + + pub fn sign_seventh_message( + party2_message6: SignMessage6, + party1_message6: SignMessage6, + party1_message5: SignMessage5, + local_sig: &LocalSignature, + R: GE, + ) -> (SignMessage7, Phase5DDecom2) { + let (phase5_com2, phase_5d_decom2) = local_sig + .phase5c( + &[party1_message6.phase_5a_decom].to_vec(), + &[party1_message5.phase5_com].to_vec(), + &[party1_message6.helgamal_proof].to_vec(), + &party2_message6.phase_5a_decom.V_i, + &R, + ) + .expect("error phase5"); + + let sign_message7 = SignMessage7 { phase5_com2 }; + (sign_message7, phase_5d_decom2) + } + + pub fn sign_eighth_message(phase_5d_decom2: Phase5DDecom2) -> SignMessage8 { + SignMessage8 { phase_5d_decom2 } + } + + pub fn sign_ninth_message( + party1_message6: SignMessage6, + party2_message6: SignMessage6, + party1_message7: SignMessage7, + party2_message7: SignMessage7, + party1_message8: SignMessage8, + party2_message8: SignMessage8, + local_sig: &LocalSignature, + ) -> SignMessage9 { + let phase5a_decom_slice = [ + party1_message6.phase_5a_decom, + party2_message6.phase_5a_decom, + ]; + let phase5d_com_slice = [party1_message7.phase5_com2, party2_message7.phase5_com2]; + let phase5d_decom_slice = [ + party1_message8.phase_5d_decom2, + party2_message8.phase_5d_decom2, + ]; + + let s_i = local_sig + .phase5d( + &phase5d_decom_slice.to_vec(), + &phase5d_com_slice.to_vec(), + &phase5a_decom_slice.to_vec(), + ) + .expect("bad com 5d"); + + let sign_message9 = SignMessage9 { s_i }; + sign_message9 + } + + pub fn output_signature(party2_message9: SignMessage9, local_sig: LocalSignature) -> (FE, FE) { + let message9_vec = [party2_message9.s_i].to_vec(); + let (r, s) = local_sig + .output_signature(&message9_vec) + .expect("verification failed");; + (r, s) + } +} diff --git a/src/ecdsa/two_party_gg18/test.rs b/src/ecdsa/two_party_gg18/test.rs new file mode 100644 index 0000000..b778635 --- /dev/null +++ b/src/ecdsa/two_party_gg18/test.rs @@ -0,0 +1,235 @@ +#![allow(non_snake_case)] +/* + KMS + Copyright 2018 by Kzen Networks + This file is part of KMS library + (https://github.com/KZen-networks/kms) + Cryptography utilities 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. + @license GPL-3.0+ +*/ + +#[cfg(test)] +mod tests { + //use centipede::juggling::segmentation::Msegmentation; + use chain_code::two_party::party1; + use chain_code::two_party::party2; + use curv::BigInt; + use ecdsa::two_party_gg18::{MasterKey1, MasterKey2}; + + #[test] + fn test_sign() { + let (master_key1, master_key2) = key_gen(); + + let message = BigInt::from(100); + + let (party1_message1, party1_decommit_phase1, party1_sign_keys) = + master_key1.sign_first_message(); + let (party2_message1, party2_decommit_phase1, party2_sign_keys) = + master_key2.sign_first_message(); + + let (party1_message2, party1_beta, party1_ni) = + master_key1.sign_second_message(&party2_message1, &party1_sign_keys); + + let (party2_message2, party2_beta, party2_ni) = + master_key2.sign_second_message(&party1_message1, &party2_sign_keys); + + let (party1_message3, party1_sigma) = master_key1.sign_third_message( + &party2_message2, + &party1_sign_keys, + party1_beta, + party1_ni, + ); + + let (party2_message3, party2_sigma) = master_key2.sign_third_message( + &party1_message2, + &party2_sign_keys, + party2_beta, + party2_ni, + ); + + let party1_message4 = MasterKey1::sign_fourth_message(party1_decommit_phase1); + let party2_message4 = MasterKey2::sign_fourth_message(party2_decommit_phase1); + + let ( + party1_message5, + party1_phase5a_decom1, + party1_elgamal_proof, + party1_local_sig, + party1_R, + ) = master_key1.sign_fifth_message( + message.clone(), + party1_sigma, + &party1_sign_keys, + party1_message4.clone(), + party1_message3.clone(), + party2_message3.clone(), + party2_message4.clone(), + party2_message2, + party2_message1, + ); + + let ( + party2_message5, + party2_phase5a_decom1, + party2_elgamal_proof, + party2_local_sig, + party2_R, + ) = master_key2.sign_fifth_message( + message, + party2_sigma, + &party2_sign_keys, + party2_message4, + party2_message3, + party1_message3, + party1_message4, + party1_message2, + party1_message1, + ); + + assert_eq!(party1_R, party2_R); + let party1_message6 = + MasterKey1::sign_sixth_message(party1_phase5a_decom1, party1_elgamal_proof); + let party2_message6 = + MasterKey2::sign_sixth_message(party2_phase5a_decom1, party2_elgamal_proof); + + let (party1_message7, party1_phase5d_decom2) = MasterKey1::sign_seventh_message( + party1_message6.clone(), + party2_message6.clone(), + party2_message5, + &party1_local_sig, + party1_R, + ); + + let (party2_message7, party2_phase5d_decom2) = MasterKey2::sign_seventh_message( + party2_message6.clone(), + party1_message6.clone(), + party1_message5, + &party2_local_sig, + party2_R, + ); + + let party1_message8 = MasterKey1::sign_eighth_message(party1_phase5d_decom2); + let party2_message8 = MasterKey2::sign_eighth_message(party2_phase5d_decom2); + + let party1_message9 = MasterKey1::sign_ninth_message( + party1_message6.clone(), + party2_message6.clone(), + party1_message7.clone(), + party2_message7.clone(), + party1_message8.clone(), + party2_message8.clone(), + &party1_local_sig, + ); + + let party2_message9 = MasterKey2::sign_ninth_message( + party1_message6, + party2_message6, + party1_message7, + party2_message7, + party1_message8, + party2_message8, + &party2_local_sig, + ); + + let (party1_r, party1_s) = MasterKey1::output_signature(party2_message9, party1_local_sig); + let (party2_r, party2_s) = MasterKey2::output_signature(party1_message9, party2_local_sig); + assert_eq!(party1_r, party2_r); + assert_eq!(party1_s, party2_s); + } + + pub fn key_gen() -> (MasterKey1, MasterKey2) { + let (party1_additive_key, party1_message1, party1_message2) = + MasterKey1::key_gen_first_message(); + let (party2_additive_key, party2_message1, party2_message2) = + MasterKey2::key_gen_first_message(); + + let (party1_message3, ss1_to_self, party1_y_vec, party1_ek_vec) = + MasterKey1::key_gen_third_message( + &party1_additive_key, + party1_message1.clone(), + party2_message1.clone(), + party1_message2.clone(), + party2_message2.clone(), + ); + + let (party2_message3, ss2_to_self, party2_y_vec, party2_ek_vec) = + MasterKey2::key_gen_third_message( + &party2_additive_key, + party1_message1, + party2_message1, + party1_message2, + party2_message2, + ); + + let (party1_linear_key, party1_message4, party1_vss_vec) = + MasterKey1::key_gen_fourth_message( + &party1_additive_key, + party1_message3.vss_scheme.clone(), + party2_message3.vss_scheme.clone(), + ss1_to_self, + party2_message3.secret_share.clone(), + &party2_y_vec, + ); + + let (party2_linear_key, party2_message4, party2_vss_vec) = + MasterKey2::key_gen_fourth_message( + &party2_additive_key, + party1_message3.vss_scheme, + party2_message3.vss_scheme, + party1_message3.secret_share, + ss2_to_self, + &party2_y_vec, + ); + + // chain code + let (cc_party_one_first_message, cc_comm_witness, cc_ec_key_pair1) = + party1::ChainCode1::chain_code_first_message(); + let (cc_party_two_first_message, cc_ec_key_pair2) = + party2::ChainCode2::chain_code_first_message(); + let cc_party_one_second_message = party1::ChainCode1::chain_code_second_message( + cc_comm_witness, + &cc_party_two_first_message.d_log_proof, + ); + + let cc_party_two_second_message = party2::ChainCode2::chain_code_second_message( + &cc_party_one_first_message, + &cc_party_one_second_message, + ); + assert!(cc_party_two_second_message.is_ok()); + + let party1_cc = party1::ChainCode1::compute_chain_code( + &cc_ec_key_pair1, + &cc_party_two_first_message.public_share, + ); + + let party2_cc = party2::ChainCode2::compute_chain_code( + &cc_ec_key_pair2, + &cc_party_one_second_message.comm_witness.public_share, + ); + + let master_key2 = MasterKey2::set_master_key( + [party1_message4.clone(), party2_message4.clone()].to_vec(), + party2_y_vec.clone(), + party2_additive_key, + party2_linear_key, + party2_vss_vec, + party2_ek_vec, + &party2_cc.chain_code, + ); + + let master_key1 = MasterKey1::set_master_key( + [party1_message4.clone(), party2_message4.clone()].to_vec(), + party1_y_vec.clone(), + party1_additive_key, + party1_linear_key, + party1_vss_vec, + party1_ek_vec, + &party1_cc.chain_code, + ); + + (master_key1, master_key2) + } +} diff --git a/src/ecdsa/two_party/mod.rs b/src/ecdsa/two_party_lindell17/mod.rs similarity index 100% rename from src/ecdsa/two_party/mod.rs rename to src/ecdsa/two_party_lindell17/mod.rs diff --git a/src/ecdsa/two_party/party1.rs b/src/ecdsa/two_party_lindell17/party1.rs similarity index 99% rename from src/ecdsa/two_party/party1.rs rename to src/ecdsa/two_party_lindell17/party1.rs index 847819d..b25d712 100644 --- a/src/ecdsa/two_party/party1.rs +++ b/src/ecdsa/two_party_lindell17/party1.rs @@ -16,7 +16,7 @@ use curv::{BigInt, FE, GE}; use super::hd_key; use super::{MasterKey1, MasterKey2, Party1Public}; -use ecdsa::two_party::party2::SignMessage; +use ecdsa::two_party_lindell17::party2::SignMessage; use multi_party_ecdsa::protocols::two_party_ecdsa::lindell_2017::party_two::EphKeyGenFirstMsg; use multi_party_ecdsa::protocols::two_party_ecdsa::lindell_2017::party_two::PDLFirstMessage as Party2PDLFirstMsg; use multi_party_ecdsa::protocols::two_party_ecdsa::lindell_2017::party_two::PDLSecondMessage as Party2PDLSecondMsg; diff --git a/src/ecdsa/two_party/party2.rs b/src/ecdsa/two_party_lindell17/party2.rs similarity index 100% rename from src/ecdsa/two_party/party2.rs rename to src/ecdsa/two_party_lindell17/party2.rs diff --git a/src/ecdsa/two_party/test.rs b/src/ecdsa/two_party_lindell17/test.rs similarity index 100% rename from src/ecdsa/two_party/test.rs rename to src/ecdsa/two_party_lindell17/test.rs diff --git a/src/poc.rs b/src/poc.rs index 9c80737..958d1ca 100644 --- a/src/poc.rs +++ b/src/poc.rs @@ -22,8 +22,8 @@ mod tests { use centipede::juggling::segmentation::Msegmentation; use curv::elliptic::curves::traits::{ECPoint, ECScalar}; use curv::{FE, GE}; - use ecdsa::two_party::MasterKey1 as EcdsaMasterKey1; - use ecdsa::two_party::MasterKey2 as EcdsaMasterKey2; + use ecdsa::two_party_lindell17::MasterKey1 as EcdsaMasterKey1; + use ecdsa::two_party_lindell17::MasterKey2 as EcdsaMasterKey2; use schnorr::two_party::party1; use schnorr::two_party::party2; From 1bcbeea72aee7bd2135abf0ad1d8e4bf67a32995 Mon Sep 17 00:00:00 2001 From: omershlo Date: Mon, 1 Apr 2019 10:35:05 +0300 Subject: [PATCH 02/14] more abstraction to keygen --- src/ecdsa/two_party_gg18/mod.rs | 18 ++++++++++- src/ecdsa/two_party_gg18/party1.rs | 48 ++++++++++++++++++------------ src/ecdsa/two_party_gg18/party2.rs | 48 ++++++++++++++++++------------ src/ecdsa/two_party_gg18/test.rs | 27 +++++++++-------- 4 files changed, 90 insertions(+), 51 deletions(-) diff --git a/src/ecdsa/two_party_gg18/mod.rs b/src/ecdsa/two_party_gg18/mod.rs index 256fa9a..8d28cdc 100644 --- a/src/ecdsa/two_party_gg18/mod.rs +++ b/src/ecdsa/two_party_gg18/mod.rs @@ -11,6 +11,7 @@ */ use curv::cryptographic_primitives::proofs::sigma_correct_homomorphic_elgamal_enc::HomoELGamalProof; +use curv::cryptographic_primitives::proofs::sigma_dlog::DLogProof; use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; use curv::BigInt; use curv::{FE, GE}; @@ -39,12 +40,27 @@ pub struct MasterKey2 { chain_code: BigInt, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] +pub struct KeyGenMessage1 { + pub bc_i: KeyGenBroadcastMessage1, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct KeyGenMessage2 { + pub decom_i: KeyGenDecommitMessage1, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct KeyGenMessage3 { pub vss_scheme: VerifiableSS, pub secret_share: FE, } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct KeyGenMessage4 { + pub dlog_proof: DLogProof, +} + #[derive(Serialize, Deserialize)] pub struct SignMessage1 { pub com: SignBroadcastPhase1, diff --git a/src/ecdsa/two_party_gg18/party1.rs b/src/ecdsa/two_party_gg18/party1.rs index 4806a31..e18f3ab 100644 --- a/src/ecdsa/two_party_gg18/party1.rs +++ b/src/ecdsa/two_party_gg18/party1.rs @@ -13,7 +13,6 @@ use super::*; use curv::cryptographic_primitives::proofs::sigma_correct_homomorphic_elgamal_enc::HomoELGamalProof; -use curv::cryptographic_primitives::proofs::sigma_dlog::DLogProof; use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; use curv::BigInt; use curv::{FE, GE}; @@ -22,23 +21,31 @@ use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, Me use paillier::EncryptionKey; impl MasterKey1 { - pub fn key_gen_first_message() -> (Keys, KeyGenBroadcastMessage1, KeyGenDecommitMessage1) { + pub fn key_gen_first_message() -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { let party_keys = Keys::create(1 as usize); let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); - (party_keys, bc_i, decom_i) + let party1_message1 = KeyGenMessage1 { bc_i }; + (party1_message1, party_keys, decom_i) + } + + pub fn keygen_second_message(decom_i: KeyGenDecommitMessage1) -> KeyGenMessage2 { + KeyGenMessage2 { decom_i } } pub fn key_gen_third_message( party1_keys: &Keys, - party1_message1: KeyGenBroadcastMessage1, - party2_message1: KeyGenBroadcastMessage1, - party1_message2: KeyGenDecommitMessage1, - party2_message2: KeyGenDecommitMessage1, + party1_message1: KeyGenMessage1, + party2_message1: KeyGenMessage1, + party1_message2: KeyGenMessage2, + party2_message2: KeyGenMessage2, ) -> (KeyGenMessage3, FE, Vec, Vec) { - let y_slice = &[party1_keys.y_i, party2_message2.y_i]; - let decom_slice = &[party1_message2, party2_message2]; - let bc1_slice = &[party1_message1.clone(), party2_message1.clone()]; - let paillier_enc_slice = &[party1_message1.e.clone(), party2_message1.e.clone()]; + let y_slice = &[party1_keys.y_i, party2_message2.decom_i.y_i]; + let decom_slice = &[party1_message2.decom_i, party2_message2.decom_i]; + let bc1_slice = &[party1_message1.bc_i.clone(), party2_message1.bc_i.clone()]; + let paillier_enc_slice = &[ + party1_message1.bc_i.e.clone(), + party2_message1.bc_i.e.clone(), + ]; let parames = Parameters { threshold: 1 as usize, share_count: 2 as usize, @@ -64,18 +71,17 @@ impl MasterKey1 { pub fn key_gen_fourth_message( party1_keys: &Keys, - vss_scheme_party1: VerifiableSS, - vss_scheme_party2: VerifiableSS, + party1_message3: KeyGenMessage3, + party2_message3: KeyGenMessage3, party1_ss_share_0: FE, - party2_ss_share_0: FE, y_vec: &Vec, - ) -> (SharedKeys, DLogProof, Vec) { + ) -> (KeyGenMessage4, SharedKeys, Vec) { let parames = Parameters { threshold: 1 as usize, share_count: 2 as usize, }; - let vss_slice = &[vss_scheme_party1, vss_scheme_party2]; - let ss_slice = &[party1_ss_share_0, party2_ss_share_0]; + let vss_slice = &[party1_message3.vss_scheme, party2_message3.vss_scheme]; + let ss_slice = &[party1_ss_share_0, party2_message3.secret_share]; let (shared_keys, dlog_proof) = party1_keys .phase2_verify_vss_construct_keypair_phase3_pok_dlog( ¶mes, @@ -86,11 +92,13 @@ impl MasterKey1 { ) .expect("invalid vss"); - (shared_keys, dlog_proof, vss_slice.to_vec()) + let party1_message4 = KeyGenMessage4 { dlog_proof }; + (party1_message4, shared_keys, vss_slice.to_vec()) } pub fn set_master_key( - dlog_proof: Vec, + party1_message4: KeyGenMessage4, + party2_message4: KeyGenMessage4, y_vec: Vec, party1_keys: Keys, party1_shared_keys: SharedKeys, @@ -98,6 +106,8 @@ impl MasterKey1 { paillier_enc_vec: Vec, chain_code: &BigInt, ) -> Self { + let dlog_proof = [party1_message4.dlog_proof, party2_message4.dlog_proof].to_vec(); + let parames = Parameters { threshold: 1 as usize, share_count: 2 as usize, diff --git a/src/ecdsa/two_party_gg18/party2.rs b/src/ecdsa/two_party_gg18/party2.rs index d4a929e..47942fe 100644 --- a/src/ecdsa/two_party_gg18/party2.rs +++ b/src/ecdsa/two_party_gg18/party2.rs @@ -13,7 +13,6 @@ use super::*; use curv::cryptographic_primitives::proofs::sigma_correct_homomorphic_elgamal_enc::HomoELGamalProof; -use curv::cryptographic_primitives::proofs::sigma_dlog::DLogProof; use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; use curv::BigInt; use curv::{FE, GE}; @@ -22,23 +21,31 @@ use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, Me use paillier::EncryptionKey; impl MasterKey2 { - pub fn key_gen_first_message() -> (Keys, KeyGenBroadcastMessage1, KeyGenDecommitMessage1) { + pub fn key_gen_first_message() -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { let party_keys = Keys::create(2 as usize); let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); - (party_keys, bc_i, decom_i) + let party2_message1 = KeyGenMessage1 { bc_i }; + (party2_message1, party_keys, decom_i) + } + + pub fn keygen_second_message(decom_i: KeyGenDecommitMessage1) -> KeyGenMessage2 { + KeyGenMessage2 { decom_i } } pub fn key_gen_third_message( party2_keys: &Keys, - party1_message1: KeyGenBroadcastMessage1, - party2_message1: KeyGenBroadcastMessage1, - party1_message2: KeyGenDecommitMessage1, - party2_message2: KeyGenDecommitMessage1, + party1_message1: KeyGenMessage1, + party2_message1: KeyGenMessage1, + party1_message2: KeyGenMessage2, + party2_message2: KeyGenMessage2, ) -> (KeyGenMessage3, FE, Vec, Vec) { - let y_slice = &[party1_message2.y_i, party2_keys.y_i]; - let decom_slice = &[party1_message2, party2_message2]; - let bc1_slice = &[party1_message1.clone(), party2_message1.clone()]; - let paillier_enc_slice = &[party1_message1.e.clone(), party2_message1.e.clone()]; + let y_slice = &[party1_message2.decom_i.y_i, party2_keys.y_i]; + let decom_slice = &[party1_message2.decom_i, party2_message2.decom_i]; + let bc1_slice = &[party1_message1.bc_i.clone(), party2_message1.bc_i.clone()]; + let paillier_enc_slice = &[ + party1_message1.bc_i.e.clone(), + party2_message1.bc_i.e.clone(), + ]; let parames = Parameters { threshold: 1 as usize, share_count: 2 as usize, @@ -64,18 +71,17 @@ impl MasterKey2 { pub fn key_gen_fourth_message( party2_keys: &Keys, - vss_scheme_party1: VerifiableSS, - vss_scheme_party2: VerifiableSS, - party1_ss_share_1: FE, + party1_message3: KeyGenMessage3, + party2_message3: KeyGenMessage3, party2_ss_share_1: FE, y_vec: &Vec, - ) -> (SharedKeys, DLogProof, Vec) { + ) -> (KeyGenMessage4, SharedKeys, Vec) { let parames = Parameters { threshold: 1 as usize, share_count: 2 as usize, }; - let vss_slice = &[vss_scheme_party1, vss_scheme_party2]; - let ss_slice = &[party1_ss_share_1, party2_ss_share_1]; + let vss_slice = &[party1_message3.vss_scheme, party2_message3.vss_scheme]; + let ss_slice = &[party1_message3.secret_share, party2_ss_share_1]; let (shared_keys, dlog_proof) = party2_keys .phase2_verify_vss_construct_keypair_phase3_pok_dlog( ¶mes, @@ -85,11 +91,13 @@ impl MasterKey2 { &(2 as usize), ) .expect("invalid vss"); - (shared_keys, dlog_proof, vss_slice.to_vec()) + let party2_message4 = KeyGenMessage4 { dlog_proof }; + (party2_message4, shared_keys, vss_slice.to_vec()) } pub fn set_master_key( - dlog_proof: Vec, + party1_message4: KeyGenMessage4, + party2_message4: KeyGenMessage4, y_vec: Vec, party2_keys: Keys, party2_shared_keys: SharedKeys, @@ -97,6 +105,8 @@ impl MasterKey2 { paillier_enc_vec: Vec, chain_code: &BigInt, ) -> Self { + let dlog_proof = [party1_message4.dlog_proof, party2_message4.dlog_proof].to_vec(); + let parames = Parameters { threshold: 1 as usize, share_count: 2 as usize, diff --git a/src/ecdsa/two_party_gg18/test.rs b/src/ecdsa/two_party_gg18/test.rs index b778635..177cc88 100644 --- a/src/ecdsa/two_party_gg18/test.rs +++ b/src/ecdsa/two_party_gg18/test.rs @@ -141,11 +141,14 @@ mod tests { } pub fn key_gen() -> (MasterKey1, MasterKey2) { - let (party1_additive_key, party1_message1, party1_message2) = + let (party1_message1, party1_additive_key, party1_decom1) = MasterKey1::key_gen_first_message(); - let (party2_additive_key, party2_message1, party2_message2) = + let (party2_message1, party2_additive_key, party2_decom1) = MasterKey2::key_gen_first_message(); + let party1_message2 = MasterKey1::keygen_second_message(party1_decom1); + let party2_message2 = MasterKey2::keygen_second_message(party2_decom1); + let (party1_message3, ss1_to_self, party1_y_vec, party1_ek_vec) = MasterKey1::key_gen_third_message( &party1_additive_key, @@ -164,22 +167,20 @@ mod tests { party2_message2, ); - let (party1_linear_key, party1_message4, party1_vss_vec) = + let (party1_message4, party1_linear_key, party1_vss_vec) = MasterKey1::key_gen_fourth_message( &party1_additive_key, - party1_message3.vss_scheme.clone(), - party2_message3.vss_scheme.clone(), + party1_message3.clone(), + party2_message3.clone(), ss1_to_self, - party2_message3.secret_share.clone(), &party2_y_vec, ); - let (party2_linear_key, party2_message4, party2_vss_vec) = + let (party2_message4, party2_linear_key, party2_vss_vec) = MasterKey2::key_gen_fourth_message( &party2_additive_key, - party1_message3.vss_scheme, - party2_message3.vss_scheme, - party1_message3.secret_share, + party1_message3, + party2_message3, ss2_to_self, &party2_y_vec, ); @@ -211,7 +212,8 @@ mod tests { ); let master_key2 = MasterKey2::set_master_key( - [party1_message4.clone(), party2_message4.clone()].to_vec(), + party1_message4.clone(), + party2_message4.clone(), party2_y_vec.clone(), party2_additive_key, party2_linear_key, @@ -221,7 +223,8 @@ mod tests { ); let master_key1 = MasterKey1::set_master_key( - [party1_message4.clone(), party2_message4.clone()].to_vec(), + party1_message4, + party2_message4, party1_y_vec.clone(), party1_additive_key, party1_linear_key, From 6ba1f59234d3efd5f6af110463f7f0f34b783efe Mon Sep 17 00:00:00 2001 From: omershlo Date: Mon, 1 Apr 2019 14:06:05 +0300 Subject: [PATCH 03/14] gg18 rotation --- src/ecdsa/two_party_gg18/mod.rs | 3 + src/ecdsa/two_party_gg18/party1.rs | 77 +++++++++++++++++++++++++- src/ecdsa/two_party_gg18/party2.rs | 79 ++++++++++++++++++++++++++ src/ecdsa/two_party_gg18/test.rs | 89 +++++++++++++++++++++++++++++- 4 files changed, 245 insertions(+), 3 deletions(-) diff --git a/src/ecdsa/two_party_gg18/mod.rs b/src/ecdsa/two_party_gg18/mod.rs index 8d28cdc..b7b30db 100644 --- a/src/ecdsa/two_party_gg18/mod.rs +++ b/src/ecdsa/two_party_gg18/mod.rs @@ -109,6 +109,9 @@ pub struct SignMessage9 { pub s_i: FE, } +#[derive(Debug, Serialize, Deserialize)] +pub struct RotationParty1Message1 {} + pub mod party1; pub mod party2; mod test; diff --git a/src/ecdsa/two_party_gg18/party1.rs b/src/ecdsa/two_party_gg18/party1.rs index e18f3ab..3ea1e41 100644 --- a/src/ecdsa/two_party_gg18/party1.rs +++ b/src/ecdsa/two_party_gg18/party1.rs @@ -19,6 +19,7 @@ use curv::{FE, GE}; use ecdsa::two_party_gg18::{MasterKey1, MasterKeyPublic}; use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, MessageB}; use paillier::EncryptionKey; +use rotation::two_party::Rotation; impl MasterKey1 { pub fn key_gen_first_message() -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { @@ -76,7 +77,7 @@ impl MasterKey1 { party1_ss_share_0: FE, y_vec: &Vec, ) -> (KeyGenMessage4, SharedKeys, Vec) { - let parames = Parameters { + let params = Parameters { threshold: 1 as usize, share_count: 2 as usize, }; @@ -84,7 +85,7 @@ impl MasterKey1 { let ss_slice = &[party1_ss_share_0, party2_message3.secret_share]; let (shared_keys, dlog_proof) = party1_keys .phase2_verify_vss_construct_keypair_phase3_pok_dlog( - ¶mes, + ¶ms, y_vec, &ss_slice.to_vec(), &vss_slice.to_vec(), @@ -324,4 +325,76 @@ impl MasterKey1 { .expect("verification failed"); (r, s) } + + pub fn rotation_first_message( + &self, + cf: &Rotation, + ) -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { + let party1_keys = PartyPrivate::refresh_private_key(&self.private, &cf.rotation, 1); + let (bc_i, decom_i) = party1_keys.phase1_broadcast_phase3_proof_of_correct_key(); + let party1_message1 = KeyGenMessage1 { bc_i }; + (party1_message1, party1_keys, decom_i) + } + + pub fn rotation_second_message(decom_i: KeyGenDecommitMessage1) -> KeyGenMessage2 { + KeyGenMessage2 { decom_i } + } + + pub fn rotation_third_message( + &self, + party1_keys: &Keys, + party1_message1: KeyGenMessage1, + party2_message1: KeyGenMessage1, + party1_message2: KeyGenMessage2, + party2_message2: KeyGenMessage2, + ) -> (KeyGenMessage3, FE, Vec, Vec) { + // make sure rotation of counter party is correct: + let y_sum_new = party1_keys.y_i.clone() + party2_message2.decom_i.y_i.clone(); + assert_eq!(y_sum_new, self.public.q.clone()); + MasterKey1::key_gen_third_message( + party1_keys, + party1_message1, + party2_message1, + party1_message2, + party2_message2, + ) + } + + pub fn rotation_fourth_message( + party1_keys: &Keys, + party1_message3: KeyGenMessage3, + party2_message3: KeyGenMessage3, + party1_ss_share_0: FE, + y_vec: &Vec, + ) -> (KeyGenMessage4, SharedKeys, Vec) { + MasterKey1::key_gen_fourth_message( + party1_keys, + party1_message3, + party2_message3, + party1_ss_share_0, + y_vec, + ) + } + + pub fn rotate_master_key( + &self, + party1_message4: KeyGenMessage4, + party2_message4: KeyGenMessage4, + y_vec: Vec, + party1_keys: Keys, + party1_shared_keys: SharedKeys, + vss_vec: Vec, + paillier_enc_vec: Vec, + ) -> Self { + MasterKey1::set_master_key( + party1_message4, + party2_message4, + y_vec, + party1_keys, + party1_shared_keys, + vss_vec, + paillier_enc_vec, + &self.chain_code, + ) + } } diff --git a/src/ecdsa/two_party_gg18/party2.rs b/src/ecdsa/two_party_gg18/party2.rs index 47942fe..7f9a60e 100644 --- a/src/ecdsa/two_party_gg18/party2.rs +++ b/src/ecdsa/two_party_gg18/party2.rs @@ -14,11 +14,13 @@ use super::*; use curv::cryptographic_primitives::proofs::sigma_correct_homomorphic_elgamal_enc::HomoELGamalProof; use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; +use curv::elliptic::curves::traits::ECScalar; use curv::BigInt; use curv::{FE, GE}; use ecdsa::two_party_gg18::{MasterKey2, MasterKeyPublic}; use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, MessageB}; use paillier::EncryptionKey; +use rotation::two_party::Rotation; impl MasterKey2 { pub fn key_gen_first_message() -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { @@ -322,4 +324,81 @@ impl MasterKey2 { .expect("verification failed");; (r, s) } + + pub fn rotation_first_message( + &self, + cf: &Rotation, + ) -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { + let cf_fe: FE = cf.rotation; + let cf_bn = cf_fe.to_big_int(); + let q = FE::q(); + let negate_cf = q - cf_bn; + let neg_cf_fe: FE = ECScalar::from(&negate_cf); + let party2_keys = PartyPrivate::refresh_private_key(&self.private, &neg_cf_fe, 2); + let (bc_i, decom_i) = party2_keys.phase1_broadcast_phase3_proof_of_correct_key(); + let party2_message1 = KeyGenMessage1 { bc_i }; + (party2_message1, party2_keys, decom_i) + } + + pub fn rotation_second_message(decom_i: KeyGenDecommitMessage1) -> KeyGenMessage2 { + KeyGenMessage2 { decom_i } + } + + pub fn rotation_third_message( + &self, + party2_keys: &Keys, + party1_message1: KeyGenMessage1, + party2_message1: KeyGenMessage1, + party1_message2: KeyGenMessage2, + party2_message2: KeyGenMessage2, + ) -> (KeyGenMessage3, FE, Vec, Vec) { + // make sure rotation of counter party is correct: + let y_sum_new = party2_keys.y_i.clone() + party1_message2.decom_i.y_i.clone(); + assert_eq!(y_sum_new, self.public.q.clone()); + MasterKey2::key_gen_third_message( + party2_keys, + party1_message1, + party2_message1, + party1_message2, + party2_message2, + ) + } + + pub fn rotation_fourth_message( + party2_keys: &Keys, + party1_message3: KeyGenMessage3, + party2_message3: KeyGenMessage3, + party2_ss_share_1: FE, + y_vec: &Vec, + ) -> (KeyGenMessage4, SharedKeys, Vec) { + MasterKey2::key_gen_fourth_message( + party2_keys, + party1_message3, + party2_message3, + party2_ss_share_1, + y_vec, + ) + } + + pub fn rotate_master_key( + &self, + party1_message4: KeyGenMessage4, + party2_message4: KeyGenMessage4, + y_vec: Vec, + party2_keys: Keys, + party2_shared_keys: SharedKeys, + vss_vec: Vec, + paillier_enc_vec: Vec, + ) -> Self { + MasterKey2::set_master_key( + party1_message4, + party2_message4, + y_vec, + party2_keys, + party2_shared_keys, + vss_vec, + paillier_enc_vec, + &self.chain_code, + ) + } } diff --git a/src/ecdsa/two_party_gg18/test.rs b/src/ecdsa/two_party_gg18/test.rs index 177cc88..289d944 100644 --- a/src/ecdsa/two_party_gg18/test.rs +++ b/src/ecdsa/two_party_gg18/test.rs @@ -18,6 +18,93 @@ mod tests { use chain_code::two_party::party2; use curv::BigInt; use ecdsa::two_party_gg18::{MasterKey1, MasterKey2}; + use rotation::two_party::party1::Rotation1; + use rotation::two_party::party2::Rotation2; + + #[test] + fn test_rotate() { + //keygen + let (master_key1, master_key2) = key_gen(); + + //coin flip: + let (party1_first_message, m1, r1) = Rotation1::key_rotate_first_message(); + let party2_first_message = Rotation2::key_rotate_first_message(&party1_first_message); + let (party1_second_message, random1) = + Rotation1::key_rotate_second_message(&party2_first_message, &m1, &r1); + let random2 = Rotation2::key_rotate_second_message( + &party1_second_message, + &party2_first_message, + &party1_first_message, + ); + + assert_eq!(random1.rotation, random2.rotation); + + let (party1_message1, party1_additive_key, party1_decom1) = + master_key1.rotation_first_message(&random1); + let (party2_message1, party2_additive_key, party2_decom1) = + master_key2.rotation_first_message(&random2); + + let party1_message2 = MasterKey1::rotation_second_message(party1_decom1); + let party2_message2 = MasterKey2::rotation_second_message(party2_decom1); + + let (party1_message3, ss1_to_self, party1_y_vec, party1_ek_vec) = master_key1 + .rotation_third_message( + &party1_additive_key, + party1_message1.clone(), + party2_message1.clone(), + party1_message2.clone(), + party2_message2.clone(), + ); + + let (party2_message3, ss2_to_self, party2_y_vec, party2_ek_vec) = master_key2 + .rotation_third_message( + &party2_additive_key, + party1_message1, + party2_message1, + party1_message2, + party2_message2, + ); + + let (party1_message4, party1_linear_key, party1_vss_vec) = + MasterKey1::rotation_fourth_message( + &party1_additive_key, + party1_message3.clone(), + party2_message3.clone(), + ss1_to_self, + &party1_y_vec, + ); + + let (party2_message4, party2_linear_key, party2_vss_vec) = + MasterKey2::rotation_fourth_message( + &party2_additive_key, + party1_message3, + party2_message3, + ss2_to_self, + &party2_y_vec, + ); + + let _master_key2 = master_key2.rotate_master_key( + party1_message4.clone(), + party2_message4.clone(), + party2_y_vec.clone(), + party2_additive_key, + party2_linear_key, + party2_vss_vec, + party2_ek_vec, + ); + + let _master_key1 = master_key1.rotate_master_key( + party1_message4, + party2_message4, + party1_y_vec.clone(), + party1_additive_key, + party1_linear_key, + party1_vss_vec, + party1_ek_vec, + ); + + //(master_key1, master_key2) + } #[test] fn test_sign() { @@ -173,7 +260,7 @@ mod tests { party1_message3.clone(), party2_message3.clone(), ss1_to_self, - &party2_y_vec, + &party1_y_vec, ); let (party2_message4, party2_linear_key, party2_vss_vec) = From e48b882d3fce2dd0852f5966437fe0ae23c27a34 Mon Sep 17 00:00:00 2001 From: omershlo Date: Tue, 2 Apr 2019 15:39:22 +0300 Subject: [PATCH 04/14] gg18: support for get child --- src/ecdsa/two_party_gg18/mod.rs | 16 ++- src/ecdsa/two_party_gg18/party1.rs | 45 +++++- src/ecdsa/two_party_gg18/party2.rs | 41 ++++++ src/ecdsa/two_party_gg18/test.rs | 218 +++++++++++++++++++++++++++++ 4 files changed, 311 insertions(+), 9 deletions(-) diff --git a/src/ecdsa/two_party_gg18/mod.rs b/src/ecdsa/two_party_gg18/mod.rs index b7b30db..b7af8d9 100644 --- a/src/ecdsa/two_party_gg18/mod.rs +++ b/src/ecdsa/two_party_gg18/mod.rs @@ -9,10 +9,13 @@ version 3 of the License, or (at your option) any later version. @license GPL-3.0+ */ - +use curv::arithmetic::traits::Converter; +use curv::cryptographic_primitives::hashing::hmac_sha512; +use curv::cryptographic_primitives::hashing::traits::KeyedHash; use curv::cryptographic_primitives::proofs::sigma_correct_homomorphic_elgamal_enc::HomoELGamalProof; use curv::cryptographic_primitives::proofs::sigma_dlog::DLogProof; use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; +use curv::elliptic::curves::traits::{ECPoint, ECScalar}; use curv::BigInt; use curv::{FE, GE}; use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, MessageB}; @@ -26,14 +29,14 @@ pub struct MasterKeyPublic { pub paillier_key_vec: Vec, } -#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] pub struct MasterKey1 { pub public: MasterKeyPublic, private: PartyPrivate, chain_code: BigInt, } -#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] pub struct MasterKey2 { pub public: MasterKeyPublic, private: PartyPrivate, @@ -116,7 +119,6 @@ pub mod party1; pub mod party2; mod test; -/* pub fn hd_key( mut location_in_hir: Vec, pubkey: &GE, @@ -136,7 +138,8 @@ pub fn hd_key( let bn_to_slice = BigInt::to_vec(chain_code_bi); let chain_code = GE::from_bytes(&bn_to_slice[1..33]).unwrap() * &f_r_fe; - let pub_key = pubkey * &f_l_fe; + let g: GE = ECPoint::generator(); + let pub_key = *pubkey + g * &f_l_fe; let (public_key_new_child, f_l_new, cc_new) = location_in_hir @@ -152,8 +155,7 @@ pub fn hd_key( let f_l_fe: FE = ECScalar::from(&f_l); let f_r_fe: FE = ECScalar::from(&f_r); - (acc.0 * &f_l_fe, f_l_fe * &acc.1, &acc.2 * &f_r_fe) + (acc.0 + g * &f_l_fe, f_l_fe + &acc.1, &acc.2 * &f_r_fe) }); (public_key_new_child, f_l_new, cc_new) } -*/ diff --git a/src/ecdsa/two_party_gg18/party1.rs b/src/ecdsa/two_party_gg18/party1.rs index 3ea1e41..ec18f8a 100644 --- a/src/ecdsa/two_party_gg18/party1.rs +++ b/src/ecdsa/two_party_gg18/party1.rs @@ -11,11 +11,12 @@ @license GPL-3.0+ */ +use super::hd_key; use super::*; use curv::cryptographic_primitives::proofs::sigma_correct_homomorphic_elgamal_enc::HomoELGamalProof; use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; -use curv::BigInt; -use curv::{FE, GE}; +use curv::elliptic::curves::traits::ECPoint; +use curv::{BigInt, FE, GE}; use ecdsa::two_party_gg18::{MasterKey1, MasterKeyPublic}; use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, MessageB}; use paillier::EncryptionKey; @@ -397,4 +398,44 @@ impl MasterKey1 { &self.chain_code, ) } + + pub fn get_child(&self, location_in_hir: Vec) -> MasterKey1 { + let (public_key_new_child, f_l_new, cc_new) = + hd_key(location_in_hir, &self.public.q, &self.chain_code); + + // optimize! + let g: GE = ECPoint::generator(); + let com_zero_new = self.public.vss_scheme_vec[0].commitments[0] + g * f_l_new; + let mut com_iter_unchanged = self.public.vss_scheme_vec[0].commitments.iter(); + let _ = com_iter_unchanged.next().unwrap(); + let com_vec_new = (0..self.public.vss_scheme_vec[1].commitments.len()) + .map(|i| { + if i == 0 { + com_zero_new + } else { + com_iter_unchanged.next().unwrap().clone() + } + }) + .collect::>(); + let new_vss = VerifiableSS { + parameters: self.public.vss_scheme_vec[0].parameters.clone(), + commitments: com_vec_new, + }; + let new_vss_vec = [new_vss, self.public.vss_scheme_vec[1].clone()]; + + let master_key_public = MasterKeyPublic { + q: public_key_new_child, + vss_scheme_vec: new_vss_vec.to_vec(), + paillier_key_vec: self.public.paillier_key_vec.clone(), + }; + + let master_key_private = self.private.update_private_key(&f_l_new, &f_l_new); + + let master_key1 = MasterKey1 { + public: master_key_public, + private: master_key_private, + chain_code: cc_new.bytes_compressed_to_big_int(), + }; + master_key1 + } } diff --git a/src/ecdsa/two_party_gg18/party2.rs b/src/ecdsa/two_party_gg18/party2.rs index 7f9a60e..c26ce02 100644 --- a/src/ecdsa/two_party_gg18/party2.rs +++ b/src/ecdsa/two_party_gg18/party2.rs @@ -401,4 +401,45 @@ impl MasterKey2 { &self.chain_code, ) } + + pub fn get_child(&self, location_in_hir: Vec) -> MasterKey2 { + let (public_key_new_child, f_l_new, cc_new) = + hd_key(location_in_hir, &self.public.q, &self.chain_code); + + // optimize! + let g: GE = ECPoint::generator(); + let com_zero_new = self.public.vss_scheme_vec[0].commitments[0] + g * f_l_new; + let mut com_iter_unchanged = self.public.vss_scheme_vec[0].commitments.iter(); + let _ = com_iter_unchanged.next().unwrap(); + let com_vec_new = (0..self.public.vss_scheme_vec[1].commitments.len()) + .map(|i| { + if i == 0 { + com_zero_new + } else { + com_iter_unchanged.next().unwrap().clone() + } + }) + .collect::>(); + + let new_vss = VerifiableSS { + parameters: self.public.vss_scheme_vec[0].parameters.clone(), + commitments: com_vec_new, + }; + let new_vss_vec = [new_vss, self.public.vss_scheme_vec[1].clone()]; + + let master_key_public = MasterKeyPublic { + q: public_key_new_child, + vss_scheme_vec: new_vss_vec.to_vec(), + paillier_key_vec: self.public.paillier_key_vec.clone(), + }; + + let master_key_private = self.private.update_private_key(&FE::zero(), &f_l_new); + + let master_key2 = MasterKey2 { + public: master_key_public, + private: master_key_private, + chain_code: cc_new.bytes_compressed_to_big_int(), + }; + master_key2 + } } diff --git a/src/ecdsa/two_party_gg18/test.rs b/src/ecdsa/two_party_gg18/test.rs index 289d944..1a8a7a5 100644 --- a/src/ecdsa/two_party_gg18/test.rs +++ b/src/ecdsa/two_party_gg18/test.rs @@ -21,6 +21,27 @@ mod tests { use rotation::two_party::party1::Rotation1; use rotation::two_party::party2::Rotation2; + #[test] + fn test_get_child() { + let (master_key1, master_key2) = key_gen(); + let (master_key1_r, master_key2_r) = rotate(master_key1.clone(), master_key2.clone()); + let master_key1_rc = master_key1_r.get_child(vec![BigInt::from(10), BigInt::from(5)]); + let master_key2_rc = master_key2_r.get_child(vec![BigInt::from(10), BigInt::from(5)]); + sign( + master_key1_rc.clone(), + master_key2_rc.clone(), + BigInt::from(100), + ); + let master_key1_c = master_key1.get_child(vec![BigInt::from(10), BigInt::from(5)]); + let master_key2_c = master_key2.get_child(vec![BigInt::from(10), BigInt::from(5)]); + let (master_key1_cr, master_key2_cr) = rotate(master_key1_c, master_key2_c); + sign( + master_key1_cr.clone(), + master_key2_cr.clone(), + BigInt::from(100), + ); + assert_eq!(master_key1_cr.public.q, master_key2_rc.public.q); + } #[test] fn test_rotate() { //keygen @@ -322,4 +343,201 @@ mod tests { (master_key1, master_key2) } + + pub fn rotate(master_key1: MasterKey1, master_key2: MasterKey2) -> (MasterKey1, MasterKey2) { + //coin flip: + let (party1_first_message, m1, r1) = Rotation1::key_rotate_first_message(); + let party2_first_message = Rotation2::key_rotate_first_message(&party1_first_message); + let (party1_second_message, random1) = + Rotation1::key_rotate_second_message(&party2_first_message, &m1, &r1); + let random2 = Rotation2::key_rotate_second_message( + &party1_second_message, + &party2_first_message, + &party1_first_message, + ); + + assert_eq!(random1.rotation, random2.rotation); + + let (party1_message1, party1_additive_key, party1_decom1) = + master_key1.rotation_first_message(&random1); + let (party2_message1, party2_additive_key, party2_decom1) = + master_key2.rotation_first_message(&random2); + + let party1_message2 = MasterKey1::rotation_second_message(party1_decom1); + let party2_message2 = MasterKey2::rotation_second_message(party2_decom1); + + let (party1_message3, ss1_to_self, party1_y_vec, party1_ek_vec) = master_key1 + .rotation_third_message( + &party1_additive_key, + party1_message1.clone(), + party2_message1.clone(), + party1_message2.clone(), + party2_message2.clone(), + ); + + let (party2_message3, ss2_to_self, party2_y_vec, party2_ek_vec) = master_key2 + .rotation_third_message( + &party2_additive_key, + party1_message1, + party2_message1, + party1_message2, + party2_message2, + ); + + let (party1_message4, party1_linear_key, party1_vss_vec) = + MasterKey1::rotation_fourth_message( + &party1_additive_key, + party1_message3.clone(), + party2_message3.clone(), + ss1_to_self, + &party1_y_vec, + ); + + let (party2_message4, party2_linear_key, party2_vss_vec) = + MasterKey2::rotation_fourth_message( + &party2_additive_key, + party1_message3, + party2_message3, + ss2_to_self, + &party2_y_vec, + ); + + let _master_key2 = master_key2.rotate_master_key( + party1_message4.clone(), + party2_message4.clone(), + party2_y_vec.clone(), + party2_additive_key, + party2_linear_key, + party2_vss_vec, + party2_ek_vec, + ); + + let _master_key1 = master_key1.rotate_master_key( + party1_message4, + party2_message4, + party1_y_vec.clone(), + party1_additive_key, + party1_linear_key, + party1_vss_vec, + party1_ek_vec, + ); + + (master_key1, master_key2) + } + + pub fn sign(master_key1: MasterKey1, master_key2: MasterKey2, message: BigInt) { + let (party1_message1, party1_decommit_phase1, party1_sign_keys) = + master_key1.sign_first_message(); + let (party2_message1, party2_decommit_phase1, party2_sign_keys) = + master_key2.sign_first_message(); + + let (party1_message2, party1_beta, party1_ni) = + master_key1.sign_second_message(&party2_message1, &party1_sign_keys); + + let (party2_message2, party2_beta, party2_ni) = + master_key2.sign_second_message(&party1_message1, &party2_sign_keys); + + let (party1_message3, party1_sigma) = master_key1.sign_third_message( + &party2_message2, + &party1_sign_keys, + party1_beta, + party1_ni, + ); + + let (party2_message3, party2_sigma) = master_key2.sign_third_message( + &party1_message2, + &party2_sign_keys, + party2_beta, + party2_ni, + ); + + let party1_message4 = MasterKey1::sign_fourth_message(party1_decommit_phase1); + let party2_message4 = MasterKey2::sign_fourth_message(party2_decommit_phase1); + + let ( + party1_message5, + party1_phase5a_decom1, + party1_elgamal_proof, + party1_local_sig, + party1_R, + ) = master_key1.sign_fifth_message( + message.clone(), + party1_sigma, + &party1_sign_keys, + party1_message4.clone(), + party1_message3.clone(), + party2_message3.clone(), + party2_message4.clone(), + party2_message2, + party2_message1, + ); + + let ( + party2_message5, + party2_phase5a_decom1, + party2_elgamal_proof, + party2_local_sig, + party2_R, + ) = master_key2.sign_fifth_message( + message, + party2_sigma, + &party2_sign_keys, + party2_message4, + party2_message3, + party1_message3, + party1_message4, + party1_message2, + party1_message1, + ); + + assert_eq!(party1_R, party2_R); + let party1_message6 = + MasterKey1::sign_sixth_message(party1_phase5a_decom1, party1_elgamal_proof); + let party2_message6 = + MasterKey2::sign_sixth_message(party2_phase5a_decom1, party2_elgamal_proof); + + let (party1_message7, party1_phase5d_decom2) = MasterKey1::sign_seventh_message( + party1_message6.clone(), + party2_message6.clone(), + party2_message5, + &party1_local_sig, + party1_R, + ); + + let (party2_message7, party2_phase5d_decom2) = MasterKey2::sign_seventh_message( + party2_message6.clone(), + party1_message6.clone(), + party1_message5, + &party2_local_sig, + party2_R, + ); + + let party1_message8 = MasterKey1::sign_eighth_message(party1_phase5d_decom2); + let party2_message8 = MasterKey2::sign_eighth_message(party2_phase5d_decom2); + + let party1_message9 = MasterKey1::sign_ninth_message( + party1_message6.clone(), + party2_message6.clone(), + party1_message7.clone(), + party2_message7.clone(), + party1_message8.clone(), + party2_message8.clone(), + &party1_local_sig, + ); + + let party2_message9 = MasterKey2::sign_ninth_message( + party1_message6, + party2_message6, + party1_message7, + party2_message7, + party1_message8, + party2_message8, + &party2_local_sig, + ); + + let (party1_r, party1_s) = MasterKey1::output_signature(party2_message9, party1_local_sig); + let (party2_r, party2_s) = MasterKey2::output_signature(party1_message9, party2_local_sig); + assert_eq!(party1_r, party2_r); + assert_eq!(party1_s, party2_s); + } } From 43b940933e79e43b9c7167ec6b2f911e10b1dc12 Mon Sep 17 00:00:00 2001 From: omershlo Date: Wed, 3 Apr 2019 14:09:27 +0300 Subject: [PATCH 05/14] lindell-gg bridge --- src/ecdsa/two_party_gg18/party1.rs | 23 +++ src/ecdsa/two_party_gg18/party2.rs | 17 ++- src/ecdsa/two_party_gg18/test.rs | 200 +++++++++++++++++++++++++++ src/ecdsa/two_party_lindell17/mod.rs | 4 +- 4 files changed, 241 insertions(+), 3 deletions(-) diff --git a/src/ecdsa/two_party_gg18/party1.rs b/src/ecdsa/two_party_gg18/party1.rs index ec18f8a..c7e484f 100644 --- a/src/ecdsa/two_party_gg18/party1.rs +++ b/src/ecdsa/two_party_gg18/party1.rs @@ -18,11 +18,34 @@ use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; use curv::elliptic::curves::traits::ECPoint; use curv::{BigInt, FE, GE}; use ecdsa::two_party_gg18::{MasterKey1, MasterKeyPublic}; +use ecdsa::two_party_lindell17::MasterKey2 as MasterKey2L; use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, MessageB}; use paillier::EncryptionKey; use rotation::two_party::Rotation; +#[derive(Clone, Serialize, Deserialize)] +pub struct KeyGenMessage0Party1Transform { + pub p1m1: KeyGenMessage1, + pub message_b: MessageB, +} + impl MasterKey1 { + pub fn key_gen_zero_message_transform( + lindell_mk2: &MasterKey2L, + ) -> (KeyGenMessage0Party1Transform, Keys, KeyGenDecommitMessage1) { + let (message_b, beta) = lindell_mk2 + .private + .to_mta_message_b(&lindell_mk2.public.paillier_pub, &lindell_mk2.public.c_key); + let party_keys = Keys::create_from(beta, 1 as usize); + let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); + let party1_message1 = KeyGenMessage1 { bc_i }; + let party1_message1 = KeyGenMessage0Party1Transform { + p1m1: party1_message1, + message_b, + }; + (party1_message1, party_keys, decom_i) + } + pub fn key_gen_first_message() -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { let party_keys = Keys::create(1 as usize); let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); diff --git a/src/ecdsa/two_party_gg18/party2.rs b/src/ecdsa/two_party_gg18/party2.rs index c26ce02..50547d2 100644 --- a/src/ecdsa/two_party_gg18/party2.rs +++ b/src/ecdsa/two_party_gg18/party2.rs @@ -17,12 +17,27 @@ use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; use curv::elliptic::curves::traits::ECScalar; use curv::BigInt; use curv::{FE, GE}; +use ecdsa::two_party_gg18::party1::KeyGenMessage0Party1Transform; use ecdsa::two_party_gg18::{MasterKey2, MasterKeyPublic}; +use ecdsa::two_party_lindell17::MasterKey1 as MasterKey1L; use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2018::mta::{MessageA, MessageB}; use paillier::EncryptionKey; use rotation::two_party::Rotation; - impl MasterKey2 { + pub fn key_gen_zero_message_transform( + lindell_mk1: &MasterKey1L, + party1_first_message_t: &KeyGenMessage0Party1Transform, + ) -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { + let alpha = lindell_mk1 + .private + .to_mta_message_b(party1_first_message_t.message_b.clone()) + .expect("wrong dlog or m_b"); + let party_keys = Keys::create_from(alpha, 2 as usize); + let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); + let party1_message1 = KeyGenMessage1 { bc_i }; + (party1_message1, party_keys, decom_i) + } + pub fn key_gen_first_message() -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { let party_keys = Keys::create(2 as usize); let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); diff --git a/src/ecdsa/two_party_gg18/test.rs b/src/ecdsa/two_party_gg18/test.rs index 1a8a7a5..4ae2243 100644 --- a/src/ecdsa/two_party_gg18/test.rs +++ b/src/ecdsa/two_party_gg18/test.rs @@ -18,9 +18,120 @@ mod tests { use chain_code::two_party::party2; use curv::BigInt; use ecdsa::two_party_gg18::{MasterKey1, MasterKey2}; + use ecdsa::two_party_lindell17::MasterKey1 as MK1L; + use ecdsa::two_party_lindell17::MasterKey2 as MK2L; + use rotation::two_party::party1::Rotation1; use rotation::two_party::party2::Rotation2; + #[test] + fn test_lindell_gg_transform() { + // lindell key gen + let (master_key1_lindell, master_key2_lindell) = lindell_key_gen(); + // lindell get child: + let master_key1_lindell_c = + master_key1_lindell.get_child(vec![BigInt::from(10), BigInt::from(5)]); + let master_key2_lindell_c = + master_key2_lindell.get_child(vec![BigInt::from(10), BigInt::from(5)]); + // transform: + let (party1_message1, party1_additive_key, party1_decom1) = + MasterKey1::key_gen_zero_message_transform(&master_key2_lindell_c); + let (party2_message1, party2_additive_key, party2_decom1) = + MasterKey2::key_gen_zero_message_transform(&master_key1_lindell_c, &party1_message1); + + // copy of the rest of gg keygen + + let party1_message2 = MasterKey1::keygen_second_message(party1_decom1); + let party2_message2 = MasterKey2::keygen_second_message(party2_decom1); + + let (party1_message3, ss1_to_self, party1_y_vec, party1_ek_vec) = + MasterKey1::key_gen_third_message( + &party1_additive_key, + party1_message1.p1m1.clone(), + party2_message1.clone(), + party1_message2.clone(), + party2_message2.clone(), + ); + + let (party2_message3, ss2_to_self, party2_y_vec, party2_ek_vec) = + MasterKey2::key_gen_third_message( + &party2_additive_key, + party1_message1.p1m1, + party2_message1, + party1_message2, + party2_message2, + ); + + let (party1_message4, party1_linear_key, party1_vss_vec) = + MasterKey1::key_gen_fourth_message( + &party1_additive_key, + party1_message3.clone(), + party2_message3.clone(), + ss1_to_self, + &party1_y_vec, + ); + + let (party2_message4, party2_linear_key, party2_vss_vec) = + MasterKey2::key_gen_fourth_message( + &party2_additive_key, + party1_message3, + party2_message3, + ss2_to_self, + &party2_y_vec, + ); + + // chain code + let (cc_party_one_first_message, cc_comm_witness, cc_ec_key_pair1) = + party1::ChainCode1::chain_code_first_message(); + let (cc_party_two_first_message, cc_ec_key_pair2) = + party2::ChainCode2::chain_code_first_message(); + let cc_party_one_second_message = party1::ChainCode1::chain_code_second_message( + cc_comm_witness, + &cc_party_two_first_message.d_log_proof, + ); + + let cc_party_two_second_message = party2::ChainCode2::chain_code_second_message( + &cc_party_one_first_message, + &cc_party_one_second_message, + ); + assert!(cc_party_two_second_message.is_ok()); + + let party1_cc = party1::ChainCode1::compute_chain_code( + &cc_ec_key_pair1, + &cc_party_two_first_message.public_share, + ); + + let party2_cc = party2::ChainCode2::compute_chain_code( + &cc_ec_key_pair2, + &cc_party_one_second_message.comm_witness.public_share, + ); + + let master_key2 = MasterKey2::set_master_key( + party1_message4.clone(), + party2_message4.clone(), + party2_y_vec.clone(), + party2_additive_key, + party2_linear_key, + party2_vss_vec, + party2_ek_vec, + &party2_cc.chain_code, + ); + + let master_key1 = MasterKey1::set_master_key( + party1_message4, + party2_message4, + party1_y_vec.clone(), + party1_additive_key, + party1_linear_key, + party1_vss_vec, + party1_ek_vec, + &party1_cc.chain_code, + ); + + sign(master_key1.clone(), master_key2.clone(), BigInt::from(100)); + + assert_eq!(master_key1.public.q, master_key1_lindell_c.public.q); + } #[test] fn test_get_child() { let (master_key1, master_key2) = key_gen(); @@ -540,4 +651,93 @@ mod tests { assert_eq!(party1_r, party2_r); assert_eq!(party1_s, party2_s); } + + pub fn lindell_key_gen() -> (MK1L, MK2L) { + // key gen + let (kg_party_one_first_message, kg_comm_witness, kg_ec_key_pair_party1) = + MK1L::key_gen_first_message(); + let (kg_party_two_first_message, kg_ec_key_pair_party2) = MK2L::key_gen_first_message(); + let (kg_party_one_second_message, party_one_paillier_key_pair, party_one_private) = + MK1L::key_gen_second_message( + kg_comm_witness.clone(), + &kg_ec_key_pair_party1, + &kg_party_two_first_message.d_log_proof, + ); + + let key_gen_second_message = + MK2L::key_gen_second_message(&kg_party_one_first_message, &kg_party_one_second_message); + + assert!(key_gen_second_message.is_ok()); + + let (party_two_second_message, party_two_paillier, party_two_pdl_chal) = + key_gen_second_message.unwrap(); + + let (party_one_third_message, party_one_pdl_decommit) = MK1L::key_gen_third_message( + &party_two_second_message.pdl_first_message, + &party_one_private, + ); + + let party_two_third_message = MK2L::key_gen_third_message(&party_two_pdl_chal); + + let party_one_fourth_message = MK1L::key_gen_fourth_message( + &party_one_third_message, + &party_two_second_message.pdl_first_message, + &party_two_third_message, + party_one_private.clone(), + party_one_pdl_decommit, + ) + .expect("pdl error party 2"); + + MK2L::key_gen_fourth_message( + &party_two_pdl_chal, + &party_one_third_message, + &party_one_fourth_message, + ) + .expect("pdl error party1"); + + // chain code + let (cc_party_one_first_message, cc_comm_witness, cc_ec_key_pair1) = + party1::ChainCode1::chain_code_first_message(); + let (cc_party_two_first_message, cc_ec_key_pair2) = + party2::ChainCode2::chain_code_first_message(); + let cc_party_one_second_message = party1::ChainCode1::chain_code_second_message( + cc_comm_witness, + &cc_party_two_first_message.d_log_proof, + ); + + let cc_party_two_second_message = party2::ChainCode2::chain_code_second_message( + &cc_party_one_first_message, + &cc_party_one_second_message, + ); + assert!(cc_party_two_second_message.is_ok()); + + let party1_cc = party1::ChainCode1::compute_chain_code( + &cc_ec_key_pair1, + &cc_party_two_first_message.public_share, + ); + + let party2_cc = party2::ChainCode2::compute_chain_code( + &cc_ec_key_pair2, + &cc_party_one_second_message.comm_witness.public_share, + ); + // set master keys: + let party_one_master_key = MK1L::set_master_key( + &party1_cc.chain_code, + party_one_private, + &kg_comm_witness.public_share, + &kg_party_two_first_message.public_share, + party_one_paillier_key_pair, + ); + + let party_two_master_key = MK2L::set_master_key( + &party2_cc.chain_code, + &kg_ec_key_pair_party2, + &kg_party_one_second_message + .ecdh_second_message + .comm_witness + .public_share, + &party_two_paillier, + ); + (party_one_master_key, party_two_master_key) + } } diff --git a/src/ecdsa/two_party_lindell17/mod.rs b/src/ecdsa/two_party_lindell17/mod.rs index 521147f..eed537b 100644 --- a/src/ecdsa/two_party_lindell17/mod.rs +++ b/src/ecdsa/two_party_lindell17/mod.rs @@ -30,8 +30,8 @@ pub struct Party1Public { #[derive(Serialize, Deserialize, Debug, PartialEq)] pub struct MasterKey1 { pub public: Party1Public, - private: party_one::Party1Private, - chain_code: BigInt, + pub private: party_one::Party1Private, + pub chain_code: BigInt, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] From aae14abec08e50c8210ca684f35febae1093fcb0 Mon Sep 17 00:00:00 2001 From: omershlo Date: Thu, 4 Apr 2019 12:23:19 +0300 Subject: [PATCH 06/14] gg Signautre struct support --- src/ecdsa/two_party_gg18/party1.rs | 6 +++--- src/ecdsa/two_party_gg18/party2.rs | 6 +++--- src/ecdsa/two_party_gg18/test.rs | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/ecdsa/two_party_gg18/party1.rs b/src/ecdsa/two_party_gg18/party1.rs index c7e484f..3443bf1 100644 --- a/src/ecdsa/two_party_gg18/party1.rs +++ b/src/ecdsa/two_party_gg18/party1.rs @@ -342,12 +342,12 @@ impl MasterKey1 { sign_message9 } - pub fn output_signature(party2_message9: SignMessage9, local_sig: LocalSignature) -> (FE, FE) { + pub fn output_signature(party2_message9: SignMessage9, local_sig: LocalSignature) -> Signature { let message9_vec = [party2_message9.s_i].to_vec(); - let (r, s) = local_sig + let sig = local_sig .output_signature(&message9_vec) .expect("verification failed"); - (r, s) + sig } pub fn rotation_first_message( diff --git a/src/ecdsa/two_party_gg18/party2.rs b/src/ecdsa/two_party_gg18/party2.rs index 50547d2..45971ca 100644 --- a/src/ecdsa/two_party_gg18/party2.rs +++ b/src/ecdsa/two_party_gg18/party2.rs @@ -332,12 +332,12 @@ impl MasterKey2 { sign_message9 } - pub fn output_signature(party2_message9: SignMessage9, local_sig: LocalSignature) -> (FE, FE) { + pub fn output_signature(party2_message9: SignMessage9, local_sig: LocalSignature) -> Signature { let message9_vec = [party2_message9.s_i].to_vec(); - let (r, s) = local_sig + let sig = local_sig .output_signature(&message9_vec) .expect("verification failed");; - (r, s) + sig } pub fn rotation_first_message( diff --git a/src/ecdsa/two_party_gg18/test.rs b/src/ecdsa/two_party_gg18/test.rs index 4ae2243..dd38826 100644 --- a/src/ecdsa/two_party_gg18/test.rs +++ b/src/ecdsa/two_party_gg18/test.rs @@ -353,10 +353,10 @@ mod tests { &party2_local_sig, ); - let (party1_r, party1_s) = MasterKey1::output_signature(party2_message9, party1_local_sig); - let (party2_r, party2_s) = MasterKey2::output_signature(party1_message9, party2_local_sig); - assert_eq!(party1_r, party2_r); - assert_eq!(party1_s, party2_s); + let sig1 = MasterKey1::output_signature(party2_message9, party1_local_sig); + let sig2 = MasterKey2::output_signature(party1_message9, party2_local_sig); + assert_eq!(sig1.r, sig2.r); + assert_eq!(sig1.s, sig2.s); } pub fn key_gen() -> (MasterKey1, MasterKey2) { @@ -646,10 +646,10 @@ mod tests { &party2_local_sig, ); - let (party1_r, party1_s) = MasterKey1::output_signature(party2_message9, party1_local_sig); - let (party2_r, party2_s) = MasterKey2::output_signature(party1_message9, party2_local_sig); - assert_eq!(party1_r, party2_r); - assert_eq!(party1_s, party2_s); + let sig1 = MasterKey1::output_signature(party2_message9, party1_local_sig); + let sig2 = MasterKey2::output_signature(party1_message9, party2_local_sig); + assert_eq!(sig1.r, sig2.r); + assert_eq!(sig1.s, sig2.s); } pub fn lindell_key_gen() -> (MK1L, MK2L) { From 308e46507acf0d50abd95031959cf97a5e1dd6e8 Mon Sep 17 00:00:00 2001 From: omershlo Date: Thu, 4 Apr 2019 13:26:14 +0300 Subject: [PATCH 07/14] clone gg sign message1 --- src/ecdsa/two_party_gg18/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ecdsa/two_party_gg18/mod.rs b/src/ecdsa/two_party_gg18/mod.rs index b7af8d9..db68fde 100644 --- a/src/ecdsa/two_party_gg18/mod.rs +++ b/src/ecdsa/two_party_gg18/mod.rs @@ -64,7 +64,7 @@ pub struct KeyGenMessage4 { pub dlog_proof: DLogProof, } -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub struct SignMessage1 { pub com: SignBroadcastPhase1, pub m_a_k: MessageA, From b31cc0c70516024c185ce9faef77b4da7dd3b4b9 Mon Sep 17 00:00:00 2001 From: omershlo Date: Thu, 4 Apr 2019 15:09:36 +0300 Subject: [PATCH 08/14] derive clone for sign message9 --- src/ecdsa/two_party_gg18/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ecdsa/two_party_gg18/mod.rs b/src/ecdsa/two_party_gg18/mod.rs index db68fde..889222d 100644 --- a/src/ecdsa/two_party_gg18/mod.rs +++ b/src/ecdsa/two_party_gg18/mod.rs @@ -107,7 +107,7 @@ pub struct SignMessage8 { pub phase_5d_decom2: Phase5DDecom2, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct SignMessage9 { pub s_i: FE, } From ee72d58c867d73d4ba6d3343cb2d66cf7c8e6ec7 Mon Sep 17 00:00:00 2001 From: omershlo Date: Fri, 5 Apr 2019 18:19:20 +0300 Subject: [PATCH 09/14] make gg mk fields public --- src/ecdsa/two_party_gg18/mod.rs | 4 ++-- src/ecdsa/two_party_gg18/test.rs | 30 ++---------------------------- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/src/ecdsa/two_party_gg18/mod.rs b/src/ecdsa/two_party_gg18/mod.rs index 889222d..64d8732 100644 --- a/src/ecdsa/two_party_gg18/mod.rs +++ b/src/ecdsa/two_party_gg18/mod.rs @@ -32,8 +32,8 @@ pub struct MasterKeyPublic { #[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] pub struct MasterKey1 { pub public: MasterKeyPublic, - private: PartyPrivate, - chain_code: BigInt, + pub private: PartyPrivate, + pub chain_code: BigInt, } #[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] diff --git a/src/ecdsa/two_party_gg18/test.rs b/src/ecdsa/two_party_gg18/test.rs index dd38826..5914d16 100644 --- a/src/ecdsa/two_party_gg18/test.rs +++ b/src/ecdsa/two_party_gg18/test.rs @@ -80,32 +80,6 @@ mod tests { &party2_y_vec, ); - // chain code - let (cc_party_one_first_message, cc_comm_witness, cc_ec_key_pair1) = - party1::ChainCode1::chain_code_first_message(); - let (cc_party_two_first_message, cc_ec_key_pair2) = - party2::ChainCode2::chain_code_first_message(); - let cc_party_one_second_message = party1::ChainCode1::chain_code_second_message( - cc_comm_witness, - &cc_party_two_first_message.d_log_proof, - ); - - let cc_party_two_second_message = party2::ChainCode2::chain_code_second_message( - &cc_party_one_first_message, - &cc_party_one_second_message, - ); - assert!(cc_party_two_second_message.is_ok()); - - let party1_cc = party1::ChainCode1::compute_chain_code( - &cc_ec_key_pair1, - &cc_party_two_first_message.public_share, - ); - - let party2_cc = party2::ChainCode2::compute_chain_code( - &cc_ec_key_pair2, - &cc_party_one_second_message.comm_witness.public_share, - ); - let master_key2 = MasterKey2::set_master_key( party1_message4.clone(), party2_message4.clone(), @@ -114,7 +88,7 @@ mod tests { party2_linear_key, party2_vss_vec, party2_ek_vec, - &party2_cc.chain_code, + &master_key2_lindell.chain_code, ); let master_key1 = MasterKey1::set_master_key( @@ -125,7 +99,7 @@ mod tests { party1_linear_key, party1_vss_vec, party1_ek_vec, - &party1_cc.chain_code, + &master_key1_lindell.chain_code, ); sign(master_key1.clone(), master_key2.clone(), BigInt::from(100)); From 834e9dc5940cf2f90c7c36f54452b7bbe7b495a0 Mon Sep 17 00:00:00 2001 From: omershlo Date: Sat, 6 Apr 2019 21:27:14 +0300 Subject: [PATCH 10/14] new keygen message 1 --- src/ecdsa/two_party_gg18/party1.rs | 8 ++++++-- src/ecdsa/two_party_gg18/party2.rs | 8 ++++++-- src/ecdsa/two_party_gg18/test.rs | 7 ++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/ecdsa/two_party_gg18/party1.rs b/src/ecdsa/two_party_gg18/party1.rs index 3443bf1..6d8c2ea 100644 --- a/src/ecdsa/two_party_gg18/party1.rs +++ b/src/ecdsa/two_party_gg18/party1.rs @@ -46,8 +46,12 @@ impl MasterKey1 { (party1_message1, party_keys, decom_i) } - pub fn key_gen_first_message() -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { - let party_keys = Keys::create(1 as usize); + pub fn key_gen_first_message(u: FE) -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { + let party_keys = if u == FE::zero() { + Keys::create(1 as usize) + } else { + Keys::create_from(u, 1 as usize) + }; let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); let party1_message1 = KeyGenMessage1 { bc_i }; (party1_message1, party_keys, decom_i) diff --git a/src/ecdsa/two_party_gg18/party2.rs b/src/ecdsa/two_party_gg18/party2.rs index 45971ca..55c2ec2 100644 --- a/src/ecdsa/two_party_gg18/party2.rs +++ b/src/ecdsa/two_party_gg18/party2.rs @@ -38,8 +38,12 @@ impl MasterKey2 { (party1_message1, party_keys, decom_i) } - pub fn key_gen_first_message() -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { - let party_keys = Keys::create(2 as usize); + pub fn key_gen_first_message(u: FE) -> (KeyGenMessage1, Keys, KeyGenDecommitMessage1) { + let party_keys = if u == FE::zero() { + Keys::create(2 as usize) + } else { + Keys::create_from(u, 2 as usize) + }; let (bc_i, decom_i) = party_keys.phase1_broadcast_phase3_proof_of_correct_key(); let party2_message1 = KeyGenMessage1 { bc_i }; (party2_message1, party_keys, decom_i) diff --git a/src/ecdsa/two_party_gg18/test.rs b/src/ecdsa/two_party_gg18/test.rs index 5914d16..c3110d3 100644 --- a/src/ecdsa/two_party_gg18/test.rs +++ b/src/ecdsa/two_party_gg18/test.rs @@ -16,7 +16,8 @@ mod tests { //use centipede::juggling::segmentation::Msegmentation; use chain_code::two_party::party1; use chain_code::two_party::party2; - use curv::BigInt; + use curv::elliptic::curves::traits::ECScalar; + use curv::{BigInt, FE}; use ecdsa::two_party_gg18::{MasterKey1, MasterKey2}; use ecdsa::two_party_lindell17::MasterKey1 as MK1L; use ecdsa::two_party_lindell17::MasterKey2 as MK2L; @@ -335,9 +336,9 @@ mod tests { pub fn key_gen() -> (MasterKey1, MasterKey2) { let (party1_message1, party1_additive_key, party1_decom1) = - MasterKey1::key_gen_first_message(); + MasterKey1::key_gen_first_message(FE::zero()); let (party2_message1, party2_additive_key, party2_decom1) = - MasterKey2::key_gen_first_message(); + MasterKey2::key_gen_first_message(FE::zero()); let party1_message2 = MasterKey1::keygen_second_message(party1_decom1); let party2_message2 = MasterKey2::keygen_second_message(party2_decom1); From 498b75a34afacafbd41c36cc695be0ce3b1935c6 Mon Sep 17 00:00:00 2001 From: omershlo Date: Sun, 7 Apr 2019 06:57:31 +0300 Subject: [PATCH 11/14] sign message5 clone --- src/ecdsa/two_party_gg18/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ecdsa/two_party_gg18/mod.rs b/src/ecdsa/two_party_gg18/mod.rs index 64d8732..5a6872d 100644 --- a/src/ecdsa/two_party_gg18/mod.rs +++ b/src/ecdsa/two_party_gg18/mod.rs @@ -86,7 +86,7 @@ pub struct SignMessage4 { pub decommit: SignDecommitPhase1, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct SignMessage5 { pub phase5_com: Phase5Com1, } From 740dd414fe99a7ed9c41615785de66d2c328c5fd Mon Sep 17 00:00:00 2001 From: omershlo Date: Sun, 7 Apr 2019 07:13:42 +0300 Subject: [PATCH 12/14] sign message2 clone --- src/ecdsa/two_party_gg18/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ecdsa/two_party_gg18/mod.rs b/src/ecdsa/two_party_gg18/mod.rs index 5a6872d..464b0f9 100644 --- a/src/ecdsa/two_party_gg18/mod.rs +++ b/src/ecdsa/two_party_gg18/mod.rs @@ -70,7 +70,7 @@ pub struct SignMessage1 { pub m_a_k: MessageA, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct SignMessage2 { pub m_b_gamma: MessageB, pub m_b_w: MessageB, From bd6374ad4c9ef11649e342ff58eb3a8c1fb61cb6 Mon Sep 17 00:00:00 2001 From: omershlo Date: Sat, 27 Apr 2019 22:37:16 +0300 Subject: [PATCH 13/14] remove debug from privateKeys --- src/ecdsa/two_party_lindell17/mod.rs | 4 ++-- src/ecdsa/two_party_lindell17/test.rs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ecdsa/two_party_lindell17/mod.rs b/src/ecdsa/two_party_lindell17/mod.rs index eed537b..23c36dc 100644 --- a/src/ecdsa/two_party_lindell17/mod.rs +++ b/src/ecdsa/two_party_lindell17/mod.rs @@ -27,7 +27,7 @@ pub struct Party1Public { pub c_key: BigInt, } -#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[derive(Serialize, Deserialize)] pub struct MasterKey1 { pub public: Party1Public, pub private: party_one::Party1Private, @@ -43,7 +43,7 @@ pub struct Party2Public { pub c_key: BigInt, } -#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[derive(Serialize, Deserialize)] pub struct MasterKey2 { pub public: Party2Public, pub private: party_two::Party2Private, diff --git a/src/ecdsa/two_party_lindell17/test.rs b/src/ecdsa/two_party_lindell17/test.rs index 74a6d03..fb4674c 100644 --- a/src/ecdsa/two_party_lindell17/test.rs +++ b/src/ecdsa/two_party_lindell17/test.rs @@ -65,11 +65,12 @@ mod tests { Msegmentation::decrypt(&encryptions_secret_party2, &G, &y, &segment_size); let party_two_master_key_recovered = party_one_master_key .counter_master_key_from_recovered_secret(secret_decrypted_party_two.clone()); + /* assert_eq!( party_two_master_key_recovered.private, party_two_master_key.private ); - + */ // fourth case: party one wants ro self-recover. to do so we first generate "half" party one master key from the recovered secret share // then we run rotation but with coin flip = 1. because our specific rotation includes generating new paillier key with all the zk - proofs. // the result is that both parties will go through rotation and have a new paillier data in the master keys. we show that signing works the same From 96ce1434e6db2e3091efab5c8f9b1ae62b679852 Mon Sep 17 00:00:00 2001 From: omershlo Date: Tue, 21 May 2019 14:33:25 +0300 Subject: [PATCH 14/14] pdl fix --- src/ecdsa/two_party_gg18/test.rs | 4 ++-- src/ecdsa/two_party_lindell17/party1.rs | 12 +++++------ src/ecdsa/two_party_lindell17/test.rs | 27 +++++++++++++------------ src/poc.rs | 6 +++--- src/schnorr/two_party/test.rs | 8 ++++---- 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/ecdsa/two_party_gg18/test.rs b/src/ecdsa/two_party_gg18/test.rs index c3110d3..23e16e2 100644 --- a/src/ecdsa/two_party_gg18/test.rs +++ b/src/ecdsa/two_party_gg18/test.rs @@ -647,7 +647,7 @@ mod tests { let (party_two_second_message, party_two_paillier, party_two_pdl_chal) = key_gen_second_message.unwrap(); - let (party_one_third_message, party_one_pdl_decommit) = MK1L::key_gen_third_message( + let (party_one_third_message, party_one_pdl_decommit, alpha) = MK1L::key_gen_third_message( &party_two_second_message.pdl_first_message, &party_one_private, ); @@ -655,11 +655,11 @@ mod tests { let party_two_third_message = MK2L::key_gen_third_message(&party_two_pdl_chal); let party_one_fourth_message = MK1L::key_gen_fourth_message( - &party_one_third_message, &party_two_second_message.pdl_first_message, &party_two_third_message, party_one_private.clone(), party_one_pdl_decommit, + alpha, ) .expect("pdl error party 2"); diff --git a/src/ecdsa/two_party_lindell17/party1.rs b/src/ecdsa/two_party_lindell17/party1.rs index b25d712..22e13a7 100644 --- a/src/ecdsa/two_party_lindell17/party1.rs +++ b/src/ecdsa/two_party_lindell17/party1.rs @@ -202,7 +202,7 @@ impl MasterKey1 { pub fn key_gen_third_message( party_two_pdl_first_message: &Party2PDLFirstMsg, party_one_private: &party_one::Party1Private, - ) -> (party_one::PDLFirstMessage, party_one::PDLdecommit) { + ) -> (party_one::PDLFirstMessage, party_one::PDLdecommit, BigInt) { party_one::PaillierKeyPair::pdl_first_stage( &party_one_private, &party_two_pdl_first_message, @@ -210,18 +210,18 @@ impl MasterKey1 { } pub fn key_gen_fourth_message( - pdl_party_one_first_message: &party_one::PDLFirstMessage, pdl_party_two_first_message: &Party2PDLFirstMsg, pdl_party_two_second_message: &Party2PDLSecondMsg, party_one_private: party_one::Party1Private, pdl_decommit: party_one::PDLdecommit, + alpha: BigInt, ) -> Result<(party_one::PDLSecondMessage), ()> { party_one::PaillierKeyPair::pdl_second_stage( - pdl_party_one_first_message, pdl_party_two_first_message, pdl_party_two_second_message, party_one_private, pdl_decommit, + alpha, ) } @@ -293,7 +293,7 @@ impl MasterKey1 { pub fn rotation_second_message( rotate_party_two_message_one: &Party2PDLFirstMsg, party_one_private: &party_one::Party1Private, - ) -> (party_one::PDLFirstMessage, party_one::PDLdecommit) { + ) -> (party_one::PDLFirstMessage, party_one::PDLdecommit, BigInt) { party_one::PaillierKeyPair::pdl_first_stage( &party_one_private, &rotate_party_two_message_one, @@ -305,17 +305,17 @@ impl MasterKey1 { rotation_first_message: &RotationParty1Message1, party_one_private_new: party_one::Party1Private, cf: &Rotation, - rotate_party_one_second_message: &party_one::PDLFirstMessage, rotate_party_two_first_message: &Party2PDLFirstMsg, rotate_party_two_second_message: &Party2PDLSecondMsg, pdl_decommit: party_one::PDLdecommit, + alpha: BigInt, ) -> Result<((party_one::PDLSecondMessage, MasterKey1)), ()> { let rotate_party_one_third_message = party_one::PaillierKeyPair::pdl_second_stage( - rotate_party_one_second_message, rotate_party_two_first_message, rotate_party_two_second_message, party_one_private_new.clone(), pdl_decommit, + alpha, ); let master_key_new = self.rotate( cf, diff --git a/src/ecdsa/two_party_lindell17/test.rs b/src/ecdsa/two_party_lindell17/test.rs index fb4674c..7b83a5a 100644 --- a/src/ecdsa/two_party_lindell17/test.rs +++ b/src/ecdsa/two_party_lindell17/test.rs @@ -48,13 +48,13 @@ mod tests { let secret_decrypted_party_one = Msegmentation::decrypt(&encryptions_secret_party1, &G, &y, &segment_size); let _party_one_master_key_recovered = party_two_master_key - .counter_master_key_from_recovered_secret(secret_decrypted_party_one.clone()); + .counter_master_key_from_recovered_secret(secret_decrypted_party_one.unwrap().clone()); // second case: party two wants to self-recover. public data and chain code of party two are assumed to exist locally or sent from party one let secret_decrypted_party_two = Msegmentation::decrypt(&encryptions_secret_party2, &G, &y, &segment_size); let _party_two_master_key_recovered = MasterKey2::recover_master_key( - secret_decrypted_party_two.clone(), + secret_decrypted_party_two.unwrap().clone(), party_two_master_key.public.clone(), party_two_master_key.chain_code.clone(), ); @@ -64,7 +64,7 @@ mod tests { let secret_decrypted_party_two = Msegmentation::decrypt(&encryptions_secret_party2, &G, &y, &segment_size); let party_two_master_key_recovered = party_one_master_key - .counter_master_key_from_recovered_secret(secret_decrypted_party_two.clone()); + .counter_master_key_from_recovered_secret(secret_decrypted_party_two.unwrap().clone()); /* assert_eq!( party_two_master_key_recovered.private, @@ -77,7 +77,7 @@ mod tests { let secret_decrypted_party_one = Msegmentation::decrypt(&encryptions_secret_party1, &G, &y, &segment_size); let party_one_master_key_half_recovered = MasterKey1::recover_master_key( - secret_decrypted_party_one.clone(), + secret_decrypted_party_one.unwrap().clone(), party_one_master_key.public.clone(), party_one_master_key.chain_code.clone(), ); @@ -99,7 +99,7 @@ mod tests { let (rotation_party_two_first_message, party_two_pdl_chal, party_two_paillier) = result_rotate_party_one_first_message.unwrap(); - let (rotation_party_one_second_message, party_one_pdl_decommit) = + let (rotation_party_one_second_message, party_one_pdl_decommit, alpha) = MasterKey1::rotation_second_message( &rotation_party_two_first_message, &party_one_private_new, @@ -111,10 +111,10 @@ mod tests { &rotation_party_one_first_message, party_one_private_new, &random1, - &rotation_party_one_second_message, &rotation_party_two_first_message, &rotation_party_two_second_message, party_one_pdl_decommit, + alpha, ); assert!(result_rotate_party_two_second_message.is_ok()); let (rotation_party_one_third_message, party_one_master_key_rotated) = @@ -381,19 +381,20 @@ mod tests { let (party_two_second_message, party_two_paillier, party_two_pdl_chal) = key_gen_second_message.unwrap(); - let (party_one_third_message, party_one_pdl_decommit) = MasterKey1::key_gen_third_message( - &party_two_second_message.pdl_first_message, - &party_one_private, - ); + let (party_one_third_message, party_one_pdl_decommit, alpha) = + MasterKey1::key_gen_third_message( + &party_two_second_message.pdl_first_message, + &party_one_private, + ); let party_two_third_message = MasterKey2::key_gen_third_message(&party_two_pdl_chal); let party_one_fourth_message = MasterKey1::key_gen_fourth_message( - &party_one_third_message, &party_two_second_message.pdl_first_message, &party_two_third_message, party_one_private.clone(), party_one_pdl_decommit, + alpha, ) .expect("pdl error party 2"); @@ -475,7 +476,7 @@ mod tests { let (rotation_party_two_first_message, party_two_pdl_chal, party_two_paillier) = result_rotate_party_one_first_message.unwrap(); - let (rotation_party_one_second_message, party_one_pdl_decommit) = + let (rotation_party_one_second_message, party_one_pdl_decommit, alpha) = MasterKey1::rotation_second_message( &rotation_party_two_first_message, &party_one_private_new, @@ -486,10 +487,10 @@ mod tests { &rotation_party_one_first_message, party_one_private_new, &random1, - &rotation_party_one_second_message, &rotation_party_two_first_message, &rotation_party_two_second_message, party_one_pdl_decommit, + alpha, ); assert!(result_rotate_party_two_second_message.is_ok()); let (rotation_party_one_third_message, party_one_master_key_rotated) = diff --git a/src/poc.rs b/src/poc.rs index 958d1ca..b789bbe 100644 --- a/src/poc.rs +++ b/src/poc.rs @@ -95,7 +95,7 @@ mod tests { let (party_two_second_message, _party_two_paillier, party_two_pdl_chal) = key_gen_second_message.unwrap(); - let (party_one_third_message, party_one_pdl_commit) = + let (party_one_third_message, party_one_pdl_commit, alpha) = EcdsaMasterKey1::key_gen_third_message( &party_two_second_message.pdl_first_message, &party_one_private, @@ -104,11 +104,11 @@ mod tests { let party_two_third_message = EcdsaMasterKey2::key_gen_third_message(&party_two_pdl_chal); let party_one_fourth_message = EcdsaMasterKey1::key_gen_fourth_message( - &party_one_third_message, &party_two_second_message.pdl_first_message, &party_two_third_message, party_one_private, party_one_pdl_commit, + alpha, ) .expect("pdl error party 2"); @@ -122,6 +122,6 @@ mod tests { let secret_decrypted = Msegmentation::decrypt(&encryptions, &G, &y, &segment_size); // debug test - assert_eq!(ss.get_element(), secret_decrypted.get_element()); + assert_eq!(ss.get_element(), secret_decrypted.unwrap().get_element()); } } diff --git a/src/schnorr/two_party/test.rs b/src/schnorr/two_party/test.rs index 7958110..317d535 100644 --- a/src/schnorr/two_party/test.rs +++ b/src/schnorr/two_party/test.rs @@ -108,13 +108,13 @@ mod tests { let secret_decrypted_party_one = Msegmentation::decrypt(&encryptions_secret_party1, &G, &y, &segment_size); let _party_one_master_key_recovered = party_two_master_key - .counter_master_key_from_recovered_secret(secret_decrypted_party_one.clone()); + .counter_master_key_from_recovered_secret(secret_decrypted_party_one.unwrap().clone()); // second case: party two wants to self-recover. public data and chain code of party two are assumed to exist locally or sent from party one let secret_decrypted_party_two = Msegmentation::decrypt(&encryptions_secret_party2, &G, &y, &segment_size); let _party_two_master_key_recovered = MasterKey2::recover_master_key( - secret_decrypted_party_two.clone(), + secret_decrypted_party_two.unwrap().clone(), party_two_master_key.pubkey.clone(), party_two_master_key.chain_code.clone(), ); @@ -124,7 +124,7 @@ mod tests { let secret_decrypted_party_two = Msegmentation::decrypt(&encryptions_secret_party2, &G, &y, &segment_size); let _party_two_master_key_recovered = party_one_master_key - .counter_master_key_from_recovered_secret(secret_decrypted_party_two.clone()); + .counter_master_key_from_recovered_secret(secret_decrypted_party_two.unwrap().clone()); // fourth case: party one wants ro self-recover. to do so we first generate "half" party one master key from the recovered secret share // then we run rotation but with coin flip = 1. because our specific rotation includes generating new paillier key with all the zk - proofs. @@ -132,7 +132,7 @@ mod tests { let secret_decrypted_party_one = Msegmentation::decrypt(&encryptions_secret_party1, &G, &y, &segment_size); let _party_one_master_key_half_recovered = MasterKey1::recover_master_key( - secret_decrypted_party_one.clone(), + secret_decrypted_party_one.unwrap().clone(), party_one_master_key.pubkey.clone(), party_one_master_key.chain_code.clone(), );