Skip to content

Commit

Permalink
dkg v1 - verify that confirmations were computed from the same proces…
Browse files Browse the repository at this point in the history
…sed messages
  • Loading branch information
benr-ml committed Jun 20, 2024
1 parent f410858 commit c02f0ee
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 18 deletions.
9 changes: 0 additions & 9 deletions fastcrypto-tbls/src/dkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,6 @@ pub struct Complaint<EG: GroupElement> {
pub(crate) proof: RecoveryPackage<EG>,
}

/// A [Confirmation] is sent during the second phase of the protocol. It includes complaints
/// created by receiver of invalid encrypted shares (if any).
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Confirmation<EG: GroupElement> {
pub sender: PartyId,
/// List of complaints against other parties. Empty if there are none.
pub complaints: Vec<Complaint<EG>>,
}

// Upper bound on the size of binary serialized incoming messages assuming <=3333 shares, <=400
// parties, and using G2Element for encryption. This is a safe upper bound since:
// - Message is O(96*t + 32*n) bytes.
Expand Down
11 changes: 10 additions & 1 deletion fastcrypto-tbls/src/dkg_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use itertools::Itertools;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::collections::{HashMap, HashSet};

use crate::dkg::{Complaint, Confirmation, Output, Party};
use crate::dkg::{Complaint, Output, Party};
use crate::ecies::RecoveryPackage;
use crate::ecies_v0::MultiRecipientEncryption;
use tap::prelude::*;
Expand Down Expand Up @@ -95,6 +95,15 @@ impl<G: GroupElement, EG: GroupElement> VerifiedProcessedMessages<G, EG> {
}
}

/// A [Confirmation] is sent during the second phase of the protocol. It includes complaints
/// created by receiver of invalid encrypted shares (if any).
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Confirmation<EG: GroupElement> {
pub sender: PartyId,
/// List of complaints against other parties. Empty if there are none.
pub complaints: Vec<Complaint<EG>>,
}

/// A dealer in the DKG ceremony.
///
/// Can be instantiated with G1Curve or G2Curve.
Expand Down
29 changes: 26 additions & 3 deletions fastcrypto-tbls/src/dkg_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use itertools::Itertools;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::collections::{HashMap, HashSet};

use crate::dkg::{Complaint, Confirmation, Output, Party};
use crate::dkg::{Complaint, Output, Party};
use crate::{ecies, ecies_v1};

use tap::prelude::*;
Expand Down Expand Up @@ -96,6 +96,17 @@ impl<G: GroupElement, EG: GroupElement> VerifiedProcessedMessages<G, EG> {
}
}

/// A [Confirmation] is sent during the second phase of the protocol. It includes complaints
/// created by receiver of invalid encrypted shares (if any).
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Confirmation<EG: GroupElement> {
pub sender: PartyId,
/// List of complaints against other parties. Empty if there are none.
pub complaints: Vec<Complaint<EG>>,
/// List of senders of the processed messages.
pub processed_senders: Vec<PartyId>,
}

/// A dealer in the DKG ceremony.
///
/// Can be instantiated with G1Curve or G2Curve.
Expand Down Expand Up @@ -375,6 +386,12 @@ where
let mut conf = Confirmation {
sender: self.id,
complaints: Vec::new(),
processed_senders: filtered_messages
.0
.iter()
.map(|m| m.message.sender)
.sorted()
.collect::<Vec<_>>(),
};
for m in &filtered_messages.0 {
if let Some(complaint) = &m.complaint {
Expand Down Expand Up @@ -407,14 +424,20 @@ where
) -> FastCryptoResult<VerifiedProcessedMessages<G, EG>> {
debug!("Processing {} confirmations", confirmations.len());
let required_threshold = 2 * (self.t as u32) - 1; // guarantee that at least t honest nodes have valid shares.
let used_parties = messages
.0
.iter()
.map(|m| m.message.sender)
.sorted()
.collect::<Vec<_>>();

// Ignore confirmations with invalid sender or zero weights
// Ignore confirmations with invalid sender, zero weights, or different view of messages.
let confirmations = confirmations
.iter()
.filter(|c| {
self.nodes
.node_id_to_node(c.sender)
.is_ok_and(|n| n.weight > 0)
.is_ok_and(|n| n.weight > 0 && used_parties == c.processed_senders)
})
.unique_by(|m| m.sender)
.collect::<Vec<_>>();
Expand Down
4 changes: 2 additions & 2 deletions fastcrypto-tbls/src/tests/dkg_v0_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use fastcrypto::error::FastCryptoError;
use fastcrypto::groups::bls12381::G2Element;
use fastcrypto::groups::GroupElement;

use crate::dkg::{Confirmation, Output, Party, DKG_MESSAGES_MAX_SIZE};
use crate::dkg_v0::{create_fake_complaint, Message, ProcessedMessage};
use crate::dkg::{Output, Party, DKG_MESSAGES_MAX_SIZE};
use crate::dkg_v0::{create_fake_complaint, Confirmation, Message, ProcessedMessage};
use crate::ecies::{PrivateKey, PublicKey};
use crate::ecies_v0::MultiRecipientEncryption;
use crate::mocked_dkg::generate_mocked_output;
Expand Down
27 changes: 24 additions & 3 deletions fastcrypto-tbls/src/tests/dkg_v1_tests.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Copyright (c) 2022, Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use crate::dkg::{Confirmation, Party, DKG_MESSAGES_MAX_SIZE};
use crate::dkg::{Party, DKG_MESSAGES_MAX_SIZE};
use crate::dkg_v0::create_fake_complaint;
use crate::dkg_v1::{Message, ProcessedMessage};
use crate::dkg_v1::{Confirmation, Message, ProcessedMessage};
use crate::ecies::{PrivateKey, PublicKey};
use crate::ecies_v1::MultiRecipientEncryption;
use crate::nodes::{Node, Nodes, PartyId};
Expand Down Expand Up @@ -526,6 +526,8 @@ fn test_test_process_confirmations() {
.map(|m| d0.process_message_v1(m.clone(), &mut thread_rng()).unwrap())
.collect::<Vec<_>>();
let (conf0, used_msgs0) = d0.merge_v1(proc_msg0).unwrap();
let mut invalid_conf0 = conf0.clone();
invalid_conf0.processed_senders.remove(0); // remove d0 from the list of processed senders

let proc_msg1 = &all_messages
.iter()
Expand All @@ -545,6 +547,24 @@ fn test_test_process_confirmations() {
.collect::<Vec<_>>();
let (conf3, _used_msgs3) = d3.merge_v1(proc_msg3).unwrap();

// check that invalid conf is ignored (with different processed senders)
assert!(d1
.process_confirmations_v1(
&used_msgs0,
&[conf0.clone(), conf1.clone()],
&mut thread_rng(),
)
.is_ok());
assert_eq!(
d1.process_confirmations_v1(
&used_msgs0,
&[invalid_conf0.clone(), conf1.clone()],
&mut thread_rng(),
)
.err(),
Some(FastCryptoError::NotEnoughInputs)
);

// sanity check that with the current confirmations, all messages are in
let ver_msg = d1
.process_confirmations_v1(
Expand Down Expand Up @@ -661,6 +681,7 @@ fn test_size_limits() {
let conf = Confirmation {
sender: 0,
complaints,
processed_senders: (0..k).collect(),
};
assert!(bcs::to_bytes(&conf).unwrap().len() <= DKG_MESSAGES_MAX_SIZE);
}
Expand Down Expand Up @@ -732,7 +753,7 @@ fn test_serialized_message_regression() {
// );

let expected_msg0 = "000003acee6249d2cf89903c516b3a29410e25da2c7aea52d59e3c12397198397ce35c6a8fd64bda4963d2daac6adf2cf94d22061c663f859dbdc19af4aebb6657e5c8f565ec6f56464a6610d547d59147f06390922fd0b8a7e1aa1a89ac9b2370d90196cfd197b6a5af7bc932c4831541be2dc896e40b47592f4be223bcee68227c4cd19ef1083f2bdc89401f7afd68a46bed17ac2669c5a246737bcc4fde95fb44eee18b2c0175ce4f7bea9300e6f3d66d388c7df4919ffe8f95a919b3436b4938a2b1b5539bebf257db7185189bc0cdc98cbb3fd163a96b1d180bb5fa34d12693d18e07c2d5723d5c65ca3b25e75817fdbb0837d5985ef1c9af57492b74f7fd6f45f30bf6c176fba2e9df61e07114505984a4189b8c6eb585fcce4da3518b509893b6b2ae04078eb54aa79efff5358d4a6aac16bb15c1389eb863e40847703094ad79621e3992031409dab281803419b16b0ae98c8cc1e1fc58a8c78a3d4397b83914109c5e3a49d5e54c730cd81c2626abd0bde41f8c2b3cff521855361e5f4dcd8831787968259a34d70c6179eab5eb85abdc054ecc45c3fb8a5367de2f4c701d19466fcfbeab2180741e04969fa3600714728ae5c0cc03b027b85df69b2412f1dc61e165250de6e1bce717af1f2b55e070e4bc0317652d23f7ced9ac03b8260806419b3811e60da868a4a9937dff11b4936babda4114ecce78aa903f36fc937fde0ed6776175f38d8cc1d4f3e8284f6d723f6b02423a946c5021a520067a9e8b3698ca61e6c7d761435b0b3cbfd1d1edb19239aff4f39c4c5b5a89cae37073683d731d1e19b2252d569b1f09768aa406bd3fb05bba04f0d0062d607938a3b4be2ce35e9da880f69666fe99e5ed23afe7730f123578b417a8823f025bbfa89afbf9d78667c60195a1014848562feae33283b542f4515e3a8860afd7534278dd6d2a7db30d56754d98f13d9fd6c447060fc62cdf610a8ef2934a2baf2310c4a5918160c7e4499bbd56f081319cc62591ea5e12ee13b74b3bf23211523b0539d5b1f674203bdf34e5cba5fd18961edddf17a73c31f9b61eb7f781ccddf24f83a692414f0f587d2403e0a06efc86f8e27061bdcb4b959ab71524e1bfe3b85607a314734b992370ecad71b320c101525249fd661eb67b243b232d3caebc20cddf24a00fdf3ed45cadfe438b0846dc26765d10427d8334569a6f9226c3c80ad6f773401ab2bc1e4ff0883eed0a071d33255a0c30c6a0e69a3abc4a8719d6c18956c31cbcf8694b10969a36a308137d9dc2b7dede7272fe901f0445d476741050fe9ecb190204b2f427c8b19914e2c32a03554ea689c24cc839fb91ada2af6bfc0b740537005bdcd47b0708d79b3f4552b55823c170b35a99e75a2804a6d78f507cdae72d515e523501cd43ee13222e7ce1014c76eaae067b4f5c3147b3604e5c9b2ce83e7cb89960433f909631574986481426ccfd007a75a00a3cd0fcb0ca447cd4ec9799a244dfd4c21836776fd480183d4ec43d31af47d8761764855209d5c1bc1c8e2b26aa297370214a34d553e8abbb4bacde684237756a9b0118a34e190cc1dff7e447150187c4b0aa85cb1e3b2602520b29e5abef4dfaa238ad548059aeb0802c89943409c74c45b790c8edb88ef4ff0fff58866e1432ab2fdd8c18708d1af798fba0698b3a983a7ea381ecfa6ccc48cfb3b38f613117f75f1701ec92b3dfaa9ecad82301b84adb61be835c90011ef0b3cca4530f925fd4a871314266a0839db3dfb9beecc7bd8c46ae9a3a2cb1c0cfcd8e9b5044b6ef40857bc11296ebc50617966249a1e8ebf8bd44e31892806f0dc1d55b9d9e7cb56f54b7dd5e537b5d197fddb3cff267000cf72dc556b3e957de96f856c6c7cd926c00698fae41ed7c12541d7656cf15352fe249616205ed2fdb0fd12ba1ef04e13ef338f4bd379b4c5f0d2f2b6b7848f768b040a54fc1c846edd9456164e282e50bee9d3fc40907be6840139c476bd7cdb2441cd15ae7ac3d0e150d1ca5e8116373fe9d5c3e4d5596643d7aa497c2550be3007f16779719593e";
let expected_conf0 = "00000103009242c26a0ef926f97ff4eb739a6ee2fed88efbacb79392cff978cad2b66a07c0b9e20333aad7a2fc1567a2b27b1b777e0fd52d8525ef903b43c828a5894d8f110479f0422ddd69a893fc4abce54dda795532de21303d072b164d601bac0d111b98db3bd4924d5ca3cf5c031f790ace67834ad4aa592cd93060b092e2db540e01e436182aad5d6ad21e458d0ee217970018a28cb7c0c7174e2d0667fd4093ad214c94169a53bd0a159c8cd62657efce03e215d31daec89a67ef79b34cfab0dca1a141e9fe2fd6d9b627c2bb8df63f4738e2a810b27bf6514162c89c641a7bee56358ff9624f087940b01ae54aaa06999016237bb392d54891e564925324dc4da99cd9f1145d50ba447c4b36eac8ff60caac14c94d5b595c6a830746b12fa34c9c026d4688a438c233e2bd93c124405f03ce1ce7de4b18a1caa5a6d6c5b386309b";
let expected_conf0 = "00000103009242c26a0ef926f97ff4eb739a6ee2fed88efbacb79392cff978cad2b66a07c0b9e20333aad7a2fc1567a2b27b1b777e0fd52d8525ef903b43c828a5894d8f110479f0422ddd69a893fc4abce54dda795532de21303d072b164d601bac0d111b98db3bd4924d5ca3cf5c031f790ace67834ad4aa592cd93060b092e2db540e01e436182aad5d6ad21e458d0ee217970018a28cb7c0c7174e2d0667fd4093ad214c94169a53bd0a159c8cd62657efce03e215d31daec89a67ef79b34cfab0dca1a141e9fe2fd6d9b627c2bb8df63f4738e2a810b27bf6514162c89c641a7bee56358ff9624f087940b01ae54aaa06999016237bb392d54891e564925324dc4da99cd9f1145d50ba447c4b36eac8ff60caac14c94d5b595c6a830746b12fa34c9c026d4688a438c233e2bd93c124405f03ce1ce7de4b18a1caa5a6d6c5b386309b03000001000300";
assert_eq!(hex::encode(bcs::to_bytes(&msg0).unwrap()), expected_msg0);
assert_eq!(hex::encode(bcs::to_bytes(&conf0).unwrap()), expected_conf0);
}

0 comments on commit c02f0ee

Please sign in to comment.