diff --git a/examples/gg20_sign_client.rs b/examples/gg20_sign_client.rs index 12308449..66e7fdb5 100644 --- a/examples/gg20_sign_client.rs +++ b/examples/gg20_sign_client.rs @@ -301,6 +301,9 @@ fn main() { index: (party_num_int - 1) as usize, sign_keys: res_stage1.sign_keys.clone(), s_ttag: signers_vec.len(), + m_a:, + e_k:, + h1_h2_N_tilde_vec:, }; let res_stage5 = sign_stage5(&input_stage5).expect("Sign Stage 5 failed."); assert!(broadcast( diff --git a/src/protocols/multi_party_ecdsa/gg_2020/orchestrate.rs b/src/protocols/multi_party_ecdsa/gg_2020/orchestrate.rs index 25f236f0..49eb44cf 100644 --- a/src/protocols/multi_party_ecdsa/gg_2020/orchestrate.rs +++ b/src/protocols/multi_party_ecdsa/gg_2020/orchestrate.rs @@ -404,11 +404,16 @@ pub struct SignStage5Input { pub index: usize, pub sign_keys: SignKeys, pub s_ttag: usize, + pub m_a: (MessageA, BigInt), + pub e_k: EncryptionKey, + pub h1_h2_N_tilde_vec: DLogStatement, } +use crate::utilities::zk_pdl_with_slack::{PDLwSlackProof, PDLwSlackStatement, PDLwSlackWitness}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SignStage5Result { pub R: GE, pub R_dash: GE, + pub phase5_proof: PDLwSlackProof, } pub fn sign_stage5(input: &SignStage5Input) -> Result { let b_proof_vec = (0..input.s_ttag - 1) @@ -428,18 +433,28 @@ pub fn sign_stage5(input: &SignStage5Input) -> Result, - pub R: GE, - pub m_a: MessageA, - pub randomness: BigInt, - pub e_k: EncryptionKey, + pub R_vec: Vec, + pub m_a_vec: Vec, + pub e_k_vec: Vec, pub k_i: FE, pub h1_h2_N_tilde_vec: Vec, pub s: Vec, @@ -448,6 +463,7 @@ pub struct SignStage6Input { pub message_bn: BigInt, pub sigma: FE, pub ysum: GE, + pub phase5_proof_vec: Vec, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -455,33 +471,24 @@ pub struct SignStage6Result { pub local_sig: LocalSignature, } pub fn sign_stage6(input: &SignStage6Input) -> Result { - let mut proof_vec = vec![]; for j in 0..input.s.len() - 1 { + if j == input.index { + continue; + } let ind = if j < input.index { j } else { j + 1 }; - let proof = LocalSignature::phase5_proof_pdl( + let phase5_verify_zk = LocalSignature::phase5_verify_pdl( + &input.phase5_proof_vec, &input.R_dash_vec[input.index], - &input.R, - &input.m_a.c, - &input.e_k, - &input.k_i, - &input.randomness, - &input.h1_h2_N_tilde_vec[input.s[ind]], + &input.R_vec[input.index], + &input.m_a_vec[input.index].c, + &input.e_k_vec[input.s[ind]], + &input.h1_h2_N_tilde_vec[..], + &input.s, + input.index, ); - - proof_vec.push(proof); - } - let phase5_verify_zk = LocalSignature::phase5_verify_pdl( - &proof_vec, - &input.R_dash_vec[input.index], - &input.R, - &input.m_a.c, - &input.e_k, - &input.h1_h2_N_tilde_vec[..], - &input.s, - input.index, - ); - if phase5_verify_zk.is_err() { - return Err(phase5_verify_zk.err().unwrap()); + if phase5_verify_zk.is_err() { + return Err(phase5_verify_zk.err().unwrap()); + } } let phase5_check = LocalSignature::phase5_check_R_dash_sum(&input.R_dash_vec); @@ -495,7 +502,7 @@ pub fn sign_stage6(input: &SignStage6Input) -> Result>, Store>, )>, - msgs4: Option>>, + msgs4: Option<( + Store>, + Store>, + Store>, + )>, msgs_com: Option>>, msgs_queue: MsgQueue, @@ -136,7 +141,13 @@ impl OfflineStage { .as_ref() .map(|(s1, s2)| s1.wants_more() || s2.wants_more()) .unwrap_or(false); - let store4_wants_more = self.msgs4.as_ref().map(|s| s.wants_more()).unwrap_or(false); + let store4_wants_more = self + .msgs4 + .as_ref() + .map(|(s1, s2, s3)| { + s1.wants_more() || s2.wants_more() || s3.wants_more() + }) + .unwrap_or(false); let next_state: OfflineR; let try_again: bool = match replace(&mut self.round, OfflineR::Gone) { @@ -217,12 +228,19 @@ impl OfflineStage { false } OfflineR::R4(round) if !store4_wants_more && (!round.is_expensive() || may_block) => { - let store = self.msgs4.take().ok_or(InternalError::StoreGone)?; - let msgs = store + let (store1, store2, store3) = + self.msgs4.take().ok_or(InternalError::StoreGone)?; + let msgs1 = store1 + .finish() + .map_err(InternalError::RetrieveMessagesFromStore)?; + let msgs2 = store2 + .finish() + .map_err(InternalError::RetrieveMessagesFromStore)?; + let msgs3 = store3 .finish() .map_err(InternalError::RetrieveMessagesFromStore)?; next_state = round - .proceed(msgs) + .proceed(msgs1, msgs2, msgs3) .map(OfflineR::Finished) .map_err(Error::ProceedRound)?; false @@ -383,14 +401,46 @@ impl StateMachine for OfflineStage { }) .map_err(Error::HandleMessage)?; } - OfflineProtocolMessage(OfflineM::M4(m)) => { - let store = self - .msgs4 - .as_mut() - .ok_or(Error::ReceivedOutOfOrderMessage { - current_round, - msg_round: 4, - })?; + OfflineProtocolMessage(OfflineM::M4A(m)) => { + let (store, _, _) = + self.msgs4 + .as_mut() + .ok_or(Error::ReceivedOutOfOrderMessage { + current_round, + msg_round: 4, + })?; + store + .push_msg(Msg { + sender: msg.sender, + receiver: msg.receiver, + body: m, + }) + .map_err(Error::HandleMessage)?; + } + OfflineProtocolMessage(OfflineM::M4B(m)) => { + let (_, store, _) = + self.msgs4 + .as_mut() + .ok_or(Error::ReceivedOutOfOrderMessage { + current_round, + msg_round: 4, + })?; + store + .push_msg(Msg { + sender: msg.sender, + receiver: msg.receiver, + body: m, + }) + .map_err(Error::HandleMessage)?; + } + OfflineProtocolMessage(OfflineM::M4C(m)) => { + let (_, _, store) = + self.msgs4 + .as_mut() + .ok_or(Error::ReceivedOutOfOrderMessage { + current_round, + msg_round: 4, + })?; store .push_msg(Msg { sender: msg.sender, @@ -435,7 +485,13 @@ impl StateMachine for OfflineStage { .as_ref() .map(|(s1, s2)| s1.wants_more() || s2.wants_more()) .unwrap_or(false); - let store4_wants_more = self.msgs4.as_ref().map(|s| s.wants_more()).unwrap_or(false); + let store4_wants_more = self + .msgs4 + .as_ref() + .map(|(s1, s2, s3)| { + s1.wants_more() || s2.wants_more() || s3.wants_more() + }) + .unwrap_or(false); let store_com_wants_more = self .msgs_com .as_ref() @@ -555,8 +611,9 @@ enum OfflineM { M2B((GammaI, WI)), M3A(SignDecommitPhase1), M3B(DeltaI), - M4(RDash), - + M4A(RDash), + M4B(PDLwSlackProof), + M4C(RVal), MD(SignBroadcastPhase1), } @@ -584,7 +641,9 @@ make_pushable! { M2B (GammaI, WI), M3A SignDecommitPhase1, M3B DeltaI, - M4 RDash, + M4A RDash, + M4B PDLwSlackProof, + M4C RVal, MD SignBroadcastPhase1, } diff --git a/src/protocols/multi_party_ecdsa/gg_2020/state_machine/sign/fmt.rs b/src/protocols/multi_party_ecdsa/gg_2020/state_machine/sign/fmt.rs index 7feceb82..ff7626ba 100644 --- a/src/protocols/multi_party_ecdsa/gg_2020/state_machine/sign/fmt.rs +++ b/src/protocols/multi_party_ecdsa/gg_2020/state_machine/sign/fmt.rs @@ -17,7 +17,7 @@ pub struct OfflineStageProgress { round1_msgs: ReceivedMessages, round2_msgs: (ReceivedMessages, ReceivedMessages), round3_msgs: (ReceivedMessages, ReceivedMessages), - round4_msgs: ReceivedMessages, + round4_msgs: (ReceivedMessages, ReceivedMessages, ReceivedMessages), decom_round_msgs: ReceivedMessages, msgs_queue: OutgoingMessages, @@ -53,7 +53,11 @@ impl From<&super::OfflineStage> for OfflineStageProgress { ReceivedMessages::from_broadcast(state.msgs3.as_ref().map(|s| &s.0)), ReceivedMessages::from_broadcast(state.msgs3.as_ref().map(|s| &s.1)), ), - round4_msgs: ReceivedMessages::from_broadcast(state.msgs4.as_ref()), + round4_msgs: ( + ReceivedMessages::from_broadcast(state.msgs4.as_ref().map(|s| &s.0)), + ReceivedMessages::from_broadcast(state.msgs4.as_ref().map(|s| &s.1)), + ReceivedMessages::from_broadcast(state.msgs4.as_ref().map(|s| &s.2)), + ), decom_round_msgs: ReceivedMessages::from_broadcast(state.msgs_com.as_ref()), msgs_queue: OutgoingMessages { diff --git a/src/protocols/multi_party_ecdsa/gg_2020/state_machine/sign/rounds.rs b/src/protocols/multi_party_ecdsa/gg_2020/state_machine/sign/rounds.rs index ff442d72..478d5bad 100644 --- a/src/protocols/multi_party_ecdsa/gg_2020/state_machine/sign/rounds.rs +++ b/src/protocols/multi_party_ecdsa/gg_2020/state_machine/sign/rounds.rs @@ -13,6 +13,8 @@ use round_based::Msg; use crate::utilities::mta::{MessageA, MessageB}; use crate::protocols::multi_party_ecdsa::gg_2020 as gg20; + +use crate::utilities::zk_pdl_with_slack::PDLwSlackProof; use gg20::orchestrate::*; use gg20::party_i::{ LocalSignature, SignBroadcastPhase1, SignDecommitPhase1, SignKeys, SignatureRecid, @@ -32,6 +34,8 @@ pub struct WI(pub MessageB); pub struct DeltaI(FE); #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RDash(GE); +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct RVal(GE); pub struct Round0 { /// Index of this party @@ -120,7 +124,7 @@ impl Round1 { { let m_a_vec = input.into_vec_including_me(self.stage1.m_a.0.clone()); let input = SignStage2Input { - m_a_vec, + m_a_vec: m_a_vec.clone(), gamma_i: self.stage1.sign_keys.gamma_i, w_i: self.stage1.sign_keys.w_i, ek_vec: self.local_key.paillier_key_vec.clone(), @@ -161,6 +165,7 @@ impl Round1 { stage1: self.stage1, stage2, + m_a_vec, }) } @@ -180,6 +185,7 @@ pub struct Round2 { stage1: SignStage1Result, stage2: SignStage2Result, + m_a_vec: Vec, } impl Round2 { @@ -258,6 +264,7 @@ impl Round2 { stage2: self.stage2, stage3, stage4, + m_a_vec: self.m_a_vec.clone(), }) } @@ -282,7 +289,7 @@ pub struct CompletedRound2 { local_key: LocalKey, mb_gamma_s: Vec, - + m_a_vec: Vec, stage1: SignStage1Result, stage2: SignStage2Result, stage3: SignStage3Result, @@ -298,7 +305,7 @@ pub struct Round3 { commitments: Vec, mb_gamma_s: Vec, - + m_a_vec: Vec, stage1: SignStage1Result, stage2: SignStage2Result, stage3: SignStage3Result, @@ -314,7 +321,7 @@ impl Round3 { commitments: commitments.commitments, mb_gamma_s: round2.mb_gamma_s, - + m_a_vec: round2.m_a_vec.clone(), stage1: round2.stage1, stage2: round2.stage2, stage3: round2.stage3, @@ -329,7 +336,7 @@ impl Round3 { mut output: O, ) -> Result where - O: Push>, + O: Push> + Push>, { let decom_vec1 = input_decom.into_vec_including_me(self.stage1.decom1.clone()); let deltas: Vec<_> = input_delta @@ -347,6 +354,10 @@ impl Round3 { index: usize::from(self.i) - 1, sign_keys: self.stage1.sign_keys.clone(), s_ttag: self.s_l.len(), + h1_h2_N_tilde_vec: self.local_key.h1_h2_n_tilde_vec[(self.local_key.i - 1) as usize] + .clone(), + m_a: self.stage1.m_a.clone(), + e_k: self.local_key.paillier_key_vec[(self.local_key.i - 1) as usize].clone(), }; write_input(self.i, 5, &input); @@ -359,11 +370,16 @@ impl Round3 { body: RDash(stage5.R_dash), }); + output.push(Msg { + sender: self.i, + receiver: None, + body: RVal(stage5.R), + }); Ok(Round4 { i: self.i, s_l: self.s_l, local_key: self.local_key, - + m_a_vec: self.m_a_vec.clone(), stage1: self.stage1, stage2: self.stage2, stage3: self.stage3, @@ -394,7 +410,7 @@ pub struct Round4 { i: u16, s_l: Vec, local_key: LocalKey, - + m_a_vec: Vec, stage1: SignStage1Result, stage2: SignStage2Result, stage3: SignStage3Result, @@ -403,9 +419,18 @@ pub struct Round4 { } impl Round4 { - pub fn proceed(self, input: BroadcastMsgs) -> Result { + pub fn proceed( + self, + input: BroadcastMsgs, + input_phase5_proof: BroadcastMsgs, + input_r: BroadcastMsgs, + ) -> Result { let r_dash = input.into_vec_including_me(RDash(self.stage5.R_dash.clone())); let r_dash = r_dash.into_iter().map(|RDash(r)| r).collect(); + let r = input_r.into_vec_including_me(RVal(self.stage5.R.clone())); + let r = r.into_iter().map(|a| a.0.clone()).collect(); + let phase_5_proof_vec = + input_phase5_proof.into_vec_including_me(self.stage5.phase5_proof.clone()); Ok(CompletedOfflineStage { i: self.i, s_l: self.s_l, @@ -418,11 +443,25 @@ impl Round4 { stage5: self.stage5, r_dash, + r_vec: r, + m_a_vec: self.m_a_vec.clone(), + phase_5_proof_vec, }) } - pub fn expects_messages(i: u16, n: u16) -> Store> { - containers::BroadcastMsgsStore::new(i, n) + pub fn expects_messages( + i: u16, + n: u16, + ) -> ( + Store>, + Store>, + Store>, + ) { + ( + containers::BroadcastMsgsStore::new(i, n), + containers::BroadcastMsgsStore::new(i, n), + containers::BroadcastMsgsStore::new(i, n), + ) } pub fn is_expensive(&self) -> bool { @@ -443,6 +482,9 @@ pub struct CompletedOfflineStage { stage5: SignStage5Result, r_dash: Vec, + r_vec: Vec, + m_a_vec: Vec, + phase_5_proof_vec: Vec, } impl CompletedOfflineStage { @@ -472,13 +514,11 @@ impl Round5 { ); let input = SignStage6Input { R_dash_vec: self.offline.r_dash, - R: self.offline.stage5.R, - m_a: self.offline.stage1.m_a.0, - e_k: self.offline.local_key.paillier_key_vec - [usize::from(self.offline.s_l[usize::from(self.offline.i) - 1]) - 1] - .clone(), + R_vec: self.offline.r_vec, + m_a_vec: self.offline.m_a_vec, + e_k_vec: self.offline.local_key.paillier_key_vec.clone(), k_i: self.offline.stage1.sign_keys.k_i, - randomness: self.offline.stage1.m_a.1, + phase5_proof_vec: self.offline.phase_5_proof_vec, h1_h2_N_tilde_vec: self.offline.local_key.h1_h2_n_tilde_vec, index: usize::from(self.offline.i) - 1, s: self