Skip to content

Set indices to be represented as vectors instead of unique #351

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 19 additions & 31 deletions demo/protocol-demo/src/demonstrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct PlayerArtifact {
struct SingleSignatureArtifact {
party_id: ProtocolPartyId,
message: String,
lottery: u64,
lotteries: Vec<u64>,
signature: String,
}

Expand Down Expand Up @@ -112,34 +112,27 @@ impl Party {
}

/// Individually sign a message through lottery
pub fn sign_message(&mut self, message: &Bytes) -> Vec<(ProtocolSingleSignature, u64)> {
let mut signatures = Vec::new();
pub fn sign_message(&mut self, message: &Bytes) -> ProtocolSingleSignature {
println!(
"Party #{}: sign message {}",
self.party_id,
message.encode_hex::<String>()
);
for i in 1..self.params.unwrap().m {
if let Some(signature) = self.signer.as_ref().unwrap().sign(message, i) {
println!("Party #{}: lottery #{} won", self.party_id, i,);
signatures.push((signature, i));
}
}
signatures
let signature = self.signer.as_ref().unwrap().sign(message).unwrap();
println!(
"Party #{}: lottery #{:?} won",
self.party_id, &signature.indexes
);
signature
}

/// Aggregate signatures
pub fn sign_aggregate(
&mut self,
message: &Bytes,
signatures: &[(ProtocolSingleSignature, u64)],
signatures: &[ProtocolSingleSignature],
) -> Option<&ProtocolMultiSignature> {
let unzipped_signatures: (Vec<_>, Vec<_>) = signatures.iter().cloned().unzip();
let msig = self
.clerk
.as_ref()
.unwrap()
.aggregate(&unzipped_signatures.0, message);
let msig = self.clerk.as_ref().unwrap().aggregate(signatures, message);
match msig {
Ok(aggregate_signature) => {
println!("Party #{}: aggregate signature computed", self.party_id);
Expand Down Expand Up @@ -409,21 +402,16 @@ impl ProtocolDemonstrator for Demonstrator {
for (i, message) in self.messages.iter().enumerate() {
// Issue certificates
println!("Message #{} to sign: {:?}", i, message);
let mut signatures = Vec::<(ProtocolSingleSignature, u64)>::new();
let mut signatures = Vec::<ProtocolSingleSignature>::new();
for party in self.parties.iter_mut() {
let party_signatures = party.sign_message(message);
single_signature_artifacts.extend(
party_signatures
.iter()
.map(|sig| SingleSignatureArtifact {
party_id: party.party_id.to_owned(),
message: message.encode_hex::<String>(),
lottery: sig.1,
signature: key_encode_hex(&sig.0).unwrap(),
})
.collect::<Vec<SingleSignatureArtifact>>(),
);
signatures.extend(party_signatures);
let party_signature = party.sign_message(message);
single_signature_artifacts.push(SingleSignatureArtifact {
party_id: party.party_id.to_owned(),
message: message.encode_hex::<String>(),
lotteries: party_signature.indexes.clone(),
signature: key_encode_hex(&party_signature).unwrap(),
});
signatures.push(party_signature);
}
for party in self.parties.iter_mut() {
let party_id = party.party_id.to_owned();
Expand Down
47 changes: 20 additions & 27 deletions mithril-aggregator/src/multi_signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,13 +532,11 @@ impl MultiSigner for MultiSignerImpl {
.ok_or_else(ProtocolError::UnavailableClerk)?
.compute_avk();

for sig in signatures
.to_protocol_signatures()
signatures
.to_protocol_signature()
.map_err(ProtocolError::Codec)?
{
sig.verify(protocol_parameters, avk, message.compute_hash().as_bytes())
.map_err(|e| ProtocolError::Core(e.to_string()))?;
}
.verify(protocol_parameters, avk, message.compute_hash().as_bytes())
.map_err(|e| ProtocolError::Core(e.to_string()))?;

// Register single signature
let beacon = self
Expand Down Expand Up @@ -595,15 +593,20 @@ impl MultiSigner for MultiSignerImpl {
.await?
.unwrap_or_default()
.iter()
.flat_map(|(_party_id, single_signature)| {
.filter_map(|(_party_id, single_signature)| {
single_signature
.to_protocol_signatures()
.to_protocol_signature()
.map_err(ProtocolError::Codec)
.ok()
})
.flatten()
.collect::<Vec<_>>();
if self.protocol_parameters.unwrap().k > signatures.len() as u64 {
if self.protocol_parameters.unwrap().k
> signatures
.iter()
.map(|s| s.indexes.len())
.reduce(|s1, s2| s1 + s2)
.unwrap_or(0) as u64
{
// Quorum is not reached
debug!(
"Quorum is not reached {} signatures vs {} needed",
Expand Down Expand Up @@ -943,22 +946,12 @@ mod tests {

let mut signatures = Vec::new();
for (party_id, _, _, protocol_signer, _) in &signers {
let mut first_sig = None;
let mut won_indexes = vec![];
for i in 1..=protocol_parameters.m {
if let Some(signature) = protocol_signer.sign(message.compute_hash().as_bytes(), i)
{
if first_sig.is_none() {
first_sig = Some(key_encode_hex(signature).unwrap());
}
won_indexes.push(i);
}
}
if let Some(signature) = protocol_signer.sign(message.compute_hash().as_bytes()) {
let won_indexes = signature.indexes.clone();

if let Some(signature) = first_sig {
signatures.push(entities::SingleSignatures::new(
party_id.to_owned(),
signature,
key_encode_hex(signature).unwrap(),
won_indexes,
));
}
Expand Down Expand Up @@ -988,14 +981,14 @@ mod tests {
.await
.expect("create_certificate should not fail")
.is_none());

// Add some signatures but not enough to reach the quorum: multi-signer should not create the multi-signature
for signature in signatures_to_almost_reach_quorum {
multi_signer
.register_single_signature(&signature)
.await
.expect("register single signature should not fail");
}

// Some signatures but quorum still not reached: multi-signer can't create the multi-signature
multi_signer
.create_multi_signature()
.await
Expand All @@ -1010,14 +1003,14 @@ mod tests {
.await
.expect("create_certificate should not fail")
.is_none());

// Add the remaining signatures to reach the quorum: multi-signer should create a multi-signature
for signature in &signatures {
multi_signer
.register_single_signature(signature)
.await
.expect("register single signature should not fail");
}

// Enough signatures to reach the quorum: multi-signer should create a multi-signature
multi_signer
.create_multi_signature()
.await
Expand Down
9 changes: 3 additions & 6 deletions mithril-client/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,13 @@ mod tests {

let mut single_signatures = Vec::new();
signers.iter().for_each(|(_, _, _, protocol_signer, _)| {
for i in 1..=protocol_parameters.m {
if let Some(signature) = protocol_signer.sign(&message.compute_hash().as_bytes(), i)
{
single_signatures.push(signature);
}
if let Some(signature) = protocol_signer.sign(message.compute_hash().as_bytes()) {
single_signatures.push(signature);
}
});

let first_signer = &signers.first().unwrap().3;
let clerk = ProtocolClerk::from_signer(&first_signer);
let clerk = ProtocolClerk::from_signer(first_signer);
let aggregate_verification_key = clerk.compute_avk();
let multi_signature = clerk
.aggregate(&single_signatures, &message.compute_hash().as_bytes())
Expand Down
36 changes: 6 additions & 30 deletions mithril-common/src/entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,17 +543,9 @@ impl SingleSignatures {
}
}

pub fn to_protocol_signatures(&self) -> Result<Vec<ProtocolSingleSignature>, String> {
pub fn to_protocol_signature(&self) -> Result<ProtocolSingleSignature, String> {
match key_decode_hex::<ProtocolSingleSignature>(&self.signature) {
Ok(signature) => Ok(self
.won_indexes
.iter()
.map(|idx| {
let mut sig = signature.clone();
sig.index = *idx;
sig
})
.collect()),
Ok(signature) => Ok(signature),
Err(error) => Err(format!(
"Could not decode signature: {}, signature: {}",
error, self.signature
Expand Down Expand Up @@ -723,31 +715,15 @@ mod tests {
let message = setup_message();
let signers = setup_signers(1);
let (party_id, _, _, signer, _) = signers.first().unwrap();
let protocol_sigs = (1..30)
.into_iter()
.filter_map(|i| signer.sign(message.compute_hash().as_bytes(), i))
.collect::<Vec<_>>();
assert!(!protocol_sigs.is_empty());
let protocol_sigs = signer.sign(message.compute_hash().as_bytes()).unwrap();

let signature = SingleSignatures::new(
party_id.to_owned(),
key_encode_hex(&protocol_sigs.first().unwrap()).unwrap(),
protocol_sigs.iter().map(|p| p.index).collect(),
key_encode_hex(&protocol_sigs).unwrap(),
protocol_sigs.indexes.clone(),
);

// Note: the 'path' of the ProtocolSignature doesn't derive PartialCmp so we can't include it here:
assert_eq!(
protocol_sigs
.iter()
.map(|s| (s.index, s.stake, s.sigma, s.pk))
.collect::<Vec<_>>(),
signature
.to_protocol_signatures()
.unwrap()
.iter()
.map(|s| (s.index, s.stake, s.sigma, s.pk))
.collect::<Vec<_>>(),
);
assert_eq!(protocol_sigs, signature.to_protocol_signature().unwrap());
}

#[test]
Expand Down
21 changes: 2 additions & 19 deletions mithril-core/benches/size_benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,27 +55,10 @@ where
.map(|p| p.new_signer(closed_reg.clone()))
.collect::<Vec<StmSigner<H>>>();

let p_results = ps
let sigs = ps
.par_iter()
.map(|p| {
let mut sigs = Vec::new();
let mut ixs = Vec::new();
for ix in 1..params.m {
if let Some(sig) = p.sign(&msg, ix) {
sigs.push(sig);
ixs.push(ix);
}
}

(ixs, sigs)
})
.filter_map(|p| p.sign(&msg))
.collect::<Vec<_>>();
let mut sigs = Vec::new();
let mut ixs = Vec::new();
for res in p_results {
ixs.extend(res.0);
sigs.extend(res.1);
}

let clerk = StmClerk::from_signer(&ps[0]);
if let Ok(msig) = clerk.aggregate(&sigs, &msg) {
Expand Down
38 changes: 8 additions & 30 deletions mithril-core/benches/stm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,14 @@ where
.map(|p| p.new_signer(closed_reg.clone()))
.collect::<Vec<StmSigner<H>>>();

group.bench_with_input(
BenchmarkId::new("Play all lotteries", &param_string),
&m,
|b, &m| {
b.iter(|| {
for ix in 1..m {
ps[0].sign(&msg, ix);
}
})
},
);
group.bench_function(BenchmarkId::new("Play all lotteries", &param_string), |b| {
b.iter(|| {
ps[0].sign(&msg);
})
});
}

let mut sigs = Vec::new();
let sigs = Vec::new();

for &k in NR_K.iter() {
m = 50;
Expand Down Expand Up @@ -140,27 +134,11 @@ where
.map(|p| p.new_signer(closed_reg.clone()))
.collect::<Vec<StmSigner<H>>>();

let p_results = ps
let sigs = ps
.par_iter()
.map(|p| {
let mut sigs = Vec::new();
for ix in 1..params.m {
if let Some(sig) = p.sign(&msg, ix) {
sigs.push(sig);
}
}

sigs
})
.filter_map(|p| p.sign(&msg))
.collect::<Vec<_>>();

sigs = Vec::new();

// todo: probably can be optimized
for res in p_results {
sigs.extend(res);
}

party_dummy = ps[0].clone();
let clerk = StmClerk::from_signer(&party_dummy);

Expand Down
Loading