Skip to content

Commit

Permalink
Merge pull request input-output-hk#1909 from input-output-hk/djo/1899…
Browse files Browse the repository at this point in the history
…/optional_signed_message_in_register_signature

Optional signed message in registered signatures
  • Loading branch information
Alenar authored Sep 2, 2024
2 parents cbd65d0 + 064aa0a commit 7b39690
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 26 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion mithril-aggregator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-aggregator"
version = "0.5.57"
version = "0.5.58"
description = "A Mithril Aggregator server"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions mithril-aggregator/src/database/record/single_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl TryFrom<SingleSignatureRecord> for SingleSignatures {
party_id: value.signer_id,
won_indexes: value.lottery_indexes,
signature: value.signature.try_into()?,
signed_message: None,
};

Ok(signatures)
Expand Down
12 changes: 10 additions & 2 deletions mithril-aggregator/src/message_adapters/from_register_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ impl TryFromMessageAdapter<RegisterSignatureMessage, SingleSignatures>
"'FromRegisterSingleSignatureAdapter' can not convert the single signature"
})?,
won_indexes: register_single_signature_message.won_indexes,
signed_message: register_single_signature_message.signed_message,
};

Ok(signatures)
Expand All @@ -34,9 +35,16 @@ mod tests {

#[test]
fn test_simple_message() {
let message = RegisterSignatureMessage::dummy();
let signatures = FromRegisterSingleSignatureAdapter::try_adapt(message).unwrap();
let signatures = FromRegisterSingleSignatureAdapter::try_adapt(RegisterSignatureMessage {
signed_message: Some("signed_message".to_string()),
..RegisterSignatureMessage::dummy()
})
.unwrap();

assert_eq!("party_id".to_string(), signatures.party_id);
assert_eq!(
Some("signed_message".to_string()),
signatures.signed_message
);
}
}
2 changes: 1 addition & 1 deletion mithril-common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-common"
version = "0.4.47"
version = "0.4.48"
description = "Common types, interfaces, and utilities for Mithril nodes."
authors = { workspace = true }
edition = { workspace = true }
Expand Down
25 changes: 24 additions & 1 deletion mithril-common/src/entities/single_signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@ pub struct SingleSignatures {
/// The indexes of the won lotteries that lead to the single signatures
#[serde(rename = "indexes")]
pub won_indexes: Vec<LotteryIndex>,

/// Message that is signed by the signer
///
/// Used to buffer the signature for later if the aggregator has yet to create an open message
/// for the signed entity type.
#[serde(skip_serializing_if = "Option::is_none")]
pub signed_message: Option<String>,
}

impl SingleSignatures {
/// SingleSignature factory
/// `SingleSignatures` factory
pub fn new(
party_id: PartyId,
signature: ProtocolSingleSignature,
Expand All @@ -33,6 +40,22 @@ impl SingleSignatures {
party_id,
signature,
won_indexes,
signed_message: None,
}
}

/// `SingleSignatures` factory including the signed message
pub fn new_with_signed_message(
party_id: PartyId,
signature: ProtocolSingleSignature,
won_indexes: Vec<LotteryIndex>,
signed_message: String,
) -> SingleSignatures {
SingleSignatures {
party_id,
signature,
won_indexes,
signed_message: Some(signed_message),
}
}

Expand Down
58 changes: 48 additions & 10 deletions mithril-common/src/messages/register_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ pub struct RegisterSignatureMessage {
/// The indexes of the won lotteries that lead to the single signatures
#[serde(rename = "indexes")]
pub won_indexes: Vec<LotteryIndex>,

/// Message that is signed by the signer
///
/// Used to buffer the signature for later if the aggregator has yet to create an open message
/// for the signed entity type.
#[serde(skip_serializing_if = "Option::is_none")]
pub signed_message: Option<String>,
}

impl RegisterSignatureMessage {
Expand All @@ -32,6 +39,7 @@ impl RegisterSignatureMessage {
party_id: "party_id".to_string(),
signature: fake_keys::single_signature()[0].to_string(),
won_indexes: vec![1, 3],
signed_message: None,
}
}
}
Expand Down Expand Up @@ -62,28 +70,58 @@ mod tests {

use super::*;

fn golden_message() -> RegisterSignatureMessage {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RegisterSignatureMessagePrevious {
#[serde(rename = "entity_type")]
pub signed_entity_type: SignedEntityType,
pub party_id: PartyId,
pub signature: HexEncodedSingleSignature,
#[serde(rename = "indexes")]
pub won_indexes: Vec<LotteryIndex>,
}

fn golden_message_previous() -> RegisterSignatureMessagePrevious {
RegisterSignatureMessagePrevious {
signed_entity_type: SignedEntityType::MithrilStakeDistribution(Epoch(246)),
party_id: "party_id".to_string(),
signature: "7b227369676d61223a5b3133302c3137372c31352c3232392c32342c3235312c3234372c3137312c3139362c3231302c3134332c3131332c38362c3138392c39322c35362c3131322c33332c3139332c3231322c35342c3231342c32382c3231362c3232372c3137332c3130302c3132372c3137382c34302c39382c38372c32392c3138312c3235352c3131312c3135372c3232342c3233352c34362c3130302c3136392c3233322c3138392c3235322c38322c3133392c33365d2c22696e6465786573223a5b302c312c332c342c362c382c392c31302c31312c31322c31342c31382c32312c32322c32332c32352c32362c32372c33302c33332c33342c33382c34312c34332c35302c35382c35392c36302c36312c36322c36372c36392c37312c37332c37352c37362c37372c38312c38322c38332c38342c39302c39312c39322c39332c39372c39385d2c227369676e65725f696e646578223a327d".to_string(),
won_indexes: vec![1, 3],
}
}

fn golden_message_actual() -> RegisterSignatureMessage {
RegisterSignatureMessage {
signed_entity_type: SignedEntityType::MithrilStakeDistribution(Epoch(246)),
party_id: "party_id".to_string(),
signature: "7b227369676d61223a5b3133302c3137372c31352c3232392c32342c3235312c3234372c3137312c3139362c3231302c3134332c3131332c38362c3138392c39322c35362c3131322c33332c3139332c3231322c35342c3231342c32382c3231362c3232372c3137332c3130302c3132372c3137382c34302c39382c38372c32392c3138312c3235352c3131312c3135372c3232342c3233352c34362c3130302c3136392c3233322c3138392c3235322c38322c3133392c33365d2c22696e6465786573223a5b302c312c332c342c362c382c392c31302c31312c31322c31342c31382c32312c32322c32332c32352c32362c32372c33302c33332c33342c33382c34312c34332c35302c35382c35392c36302c36312c36322c36372c36392c37312c37332c37352c37362c37372c38312c38322c38332c38342c39302c39312c39322c39332c39372c39385d2c227369676e65725f696e646578223a327d".to_string(),
won_indexes: vec![1, 3],
signed_message: Some("6a7e737c312972d2346b65ac3075696e04286d046dddaf8004121e3d5e27cc0d".to_string()),
}
}

// Test the retro compatibility with possible future upgrades.
const ACTUAL_JSON: &str = r#"{
"entity_type": { "MithrilStakeDistribution": 246 },
"party_id": "party_id",
"signature": "7b227369676d61223a5b3133302c3137372c31352c3232392c32342c3235312c3234372c3137312c3139362c3231302c3134332c3131332c38362c3138392c39322c35362c3131322c33332c3139332c3231322c35342c3231342c32382c3231362c3232372c3137332c3130302c3132372c3137382c34302c39382c38372c32392c3138312c3235352c3131312c3135372c3232342c3233352c34362c3130302c3136392c3233322c3138392c3235322c38322c3133392c33365d2c22696e6465786573223a5b302c312c332c342c362c382c392c31302c31312c31322c31342c31382c32312c32322c32332c32352c32362c32372c33302c33332c33342c33382c34312c34332c35302c35382c35392c36302c36312c36322c36372c36392c37312c37332c37352c37362c37372c38312c38322c38332c38342c39302c39312c39322c39332c39372c39385d2c227369676e65725f696e646578223a327d",
"indexes": [1, 3],
"signed_message": "6a7e737c312972d2346b65ac3075696e04286d046dddaf8004121e3d5e27cc0d"
}"#;

#[test]
fn test_actual_json_deserialized_into_previous_message() {
let json = ACTUAL_JSON;
let message: RegisterSignatureMessagePrevious = serde_json::from_str(json).unwrap();

assert_eq!(golden_message_previous(), message);
}

#[test]
fn test_v1() {
let json = r#"{
"entity_type": { "MithrilStakeDistribution": 246 },
"party_id": "party_id",
"signature": "7b227369676d61223a5b3133302c3137372c31352c3232392c32342c3235312c3234372c3137312c3139362c3231302c3134332c3131332c38362c3138392c39322c35362c3131322c33332c3139332c3231322c35342c3231342c32382c3231362c3232372c3137332c3130302c3132372c3137382c34302c39382c38372c32392c3138312c3235352c3131312c3135372c3232342c3233352c34362c3130302c3136392c3233322c3138392c3235322c38322c3133392c33365d2c22696e6465786573223a5b302c312c332c342c362c382c392c31302c31312c31322c31342c31382c32312c32322c32332c32352c32362c32372c33302c33332c33342c33382c34312c34332c35302c35382c35392c36302c36312c36322c36372c36392c37312c37332c37352c37362c37372c38312c38322c38332c38342c39302c39312c39322c39332c39372c39385d2c227369676e65725f696e646578223a327d",
"indexes": [1, 3]
}"#;
fn test_actual_json_deserialized_into_actual_message() {
let json = ACTUAL_JSON;
let message: RegisterSignatureMessage = serde_json::from_str(json).expect(
"This JSON is expected to be successfully parsed into a RegisterSignatureMessage instance.",
);

assert_eq!(golden_message(), message);
assert_eq!(golden_message_actual(), message);
}
}
34 changes: 32 additions & 2 deletions mithril-common/src/protocol/single_signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@ impl SingleSigner {
///
/// If no lottery are won None will be returned.
pub fn sign(&self, message: &ProtocolMessage) -> StdResult<Option<SingleSignatures>> {
match self.protocol_signer.sign(message.compute_hash().as_bytes()) {
let signed_message = message.compute_hash();
match self.protocol_signer.sign(signed_message.as_bytes()) {
Some(signature) => {
let won_indexes = signature.indexes.clone();

Ok(Some(SingleSignatures::new(
Ok(Some(SingleSignatures::new_with_signed_message(
self.party_id.to_owned(),
signature.into(),
won_indexes,
signed_message,
)))
}
None => Ok(None),
Expand Down Expand Up @@ -72,4 +74,32 @@ mod test {

assert!(signature.is_some());
}

#[test]
fn embed_signed_message_in_issued_signature() {
let fixture = MithrilFixtureBuilder::default().with_signers(3).build();
let signers = fixture.signers_fixture();
let signer = signers.first().unwrap();

let (single_signer, _) = SignerBuilder::new(
&fixture.signers_with_stake(),
&fixture.protocol_parameters(),
)
.unwrap()
.build_test_single_signer(
signer.signer_with_stake.clone(),
signer.kes_secret_key_path(),
)
.unwrap();

let message = ProtocolMessage::default();
let signature = single_signer
.sign(&message)
.expect("Single signer should be able to issue single signature");

assert_eq!(
Some(message.compute_hash()),
signature.and_then(|s| s.signed_message)
);
}
}
2 changes: 1 addition & 1 deletion mithril-signer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-signer"
version = "0.2.175"
version = "0.2.176"
description = "A Mithril Signer"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ impl TryToMessageAdapter<(SignedEntityType, SingleSignatures), RegisterSignature
"'ToRegisterSignatureMessageAdapter' can not convert the single signature"
})?,
won_indexes: single_signature.won_indexes,
signed_message: single_signature.signed_message,
};

Ok(message)
Expand All @@ -32,13 +33,16 @@ mod tests {

#[test]
fn adapt_ok() {
let single_signature = fake_data::single_signatures([1, 3].to_vec());
let message: RegisterSignatureMessage = ToRegisterSignatureMessageAdapter::try_adapt((
SignedEntityType::dummy(),
single_signature,
SingleSignatures {
signed_message: Some("signed_message".to_string()),
..fake_data::single_signatures([1, 3].to_vec())
},
))
.unwrap();

assert_eq!("party_id".to_string(), message.party_id);
assert_eq!(Some("signed_message".to_string()), message.signed_message);
}
}
2 changes: 1 addition & 1 deletion mithril-test-lab/mithril-end-to-end/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-end-to-end"
version = "0.4.29"
version = "0.4.30"
authors = { workspace = true }
edition = { workspace = true }
documentation = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub fn generate_register_signature_message(
party_id: s.party_id.clone(),
signature: s.signature.clone().to_json_hex().unwrap(),
won_indexes: s.won_indexes.clone(),
signed_message: None,
})
.collect::<Vec<_>>()
}
Expand Down
11 changes: 10 additions & 1 deletion openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1068,12 +1068,21 @@ components:
items:
type: integer
format: int64
signed_message:
description: |
Hash of the protocol message that is signed by the signer
Optional, allows the aggregator to store this signature for later if it has yet to start aggregating
signatures for the message.
type: string
format: bytes
example:
{
"entity_type": { "MithrilStakeDistribution": 246 },
"party_id": "1234567890",
"signature": "7b2c36322c3130352c3232322c31302c3131302c33312c37312c39372c22766b223a5b3136342c2c31393137352c313834",
"indexes": [25, 35]
"indexes": [25, 35],
"signed_message": "07ed7c9e128744c1a4797b7eb34c54823cc7a21fc95c19876122ab4bb0fe796d6bba2bc"
}

ProtocolMessageParts:
Expand Down

0 comments on commit 7b39690

Please sign in to comment.