Skip to content

Commit c2f2a24

Browse files
committed
wip
1 parent bc727c4 commit c2f2a24

File tree

6 files changed

+165
-26
lines changed

6 files changed

+165
-26
lines changed

internal/mithril-dmq-node/src/message.rs

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,42 @@ use blake2::{digest::consts::U64, Blake2b, Digest};
55
use pallas_network::miniprotocols::localmsgsubmission::DmqMsg;
66

77
use mithril_cardano_node_chain::chain_observer::ChainObserver;
8-
use mithril_common::StdResult;
8+
use mithril_common::{
9+
crypto_helper::{KesSigner, TryToBytes},
10+
StdResult,
11+
};
912

1013
/// The TTL (Time To Live) for DMQ messages in blocks.
1114
const DMQ_MESSAGE_TTL_IN_BLOCKS: u16 = 100;
1215

1316
/// A builder for creating DMQ messages.
1417
pub struct DmqMessageBuilder {
18+
kes_signer: Arc<dyn KesSigner>,
1519
chain_observer: Arc<dyn ChainObserver>,
1620
ttl_blocks: u16,
1721
}
1822

1923
impl DmqMessageBuilder {
2024
/// Creates a new instance of `DmqMessageBuilder`.
21-
pub fn new(chain_observer: Arc<dyn ChainObserver>, ttl_blocks: u16) -> Self {
25+
pub fn new(
26+
kes_signer: Arc<dyn KesSigner>,
27+
chain_observer: Arc<dyn ChainObserver>,
28+
ttl_blocks: u16,
29+
) -> Self {
2230
Self {
31+
kes_signer,
2332
chain_observer,
2433
ttl_blocks,
2534
}
2635
}
2736

2837
/// Creates a new instance of `DmqMessageBuilder` with default TTL.
29-
pub fn new_with_default_ttl(chain_observer: Arc<dyn ChainObserver>) -> Self {
38+
pub fn new_with_default_ttl(
39+
kes_signer: Arc<dyn KesSigner>,
40+
chain_observer: Arc<dyn ChainObserver>,
41+
) -> Self {
3042
Self {
43+
kes_signer,
3144
chain_observer,
3245
ttl_blocks: DMQ_MESSAGE_TTL_IN_BLOCKS,
3346
}
@@ -57,15 +70,17 @@ impl DmqMessageBuilder {
5770
let block_number = (*block_number)
5871
.try_into()
5972
.map_err(|_| anyhow!("Failed to convert block number to u32"))?;
60-
let kes_signature = vec![]; // TO DO: create a KES signature
61-
let operational_certificate = vec![]; // TO DO: create an operational certificate
73+
let (kes_signature, operational_certificate) = self
74+
.kes_signer
75+
.sign(message_bytes, block_number)
76+
.with_context(|| "Failed to KES sign message while building DMQ message")?;
6277
let mut dmq_message = DmqMsg {
6378
msg_id: vec![],
6479
msg_body: message_bytes.to_vec(),
6580
block_number,
6681
ttl: self.ttl_blocks,
67-
kes_signature,
68-
operational_certificate,
82+
kes_signature: kes_signature.to_bytes_vec()?,
83+
operational_certificate: operational_certificate.to_bytes_vec()?,
6984
};
7085
dmq_message.msg_id = compute_msg_id(&dmq_message);
7186

@@ -77,7 +92,7 @@ impl DmqMessageBuilder {
7792
mod tests {
7893
use mithril_cardano_node_chain::test::double::FakeChainObserver;
7994
use mithril_common::{
80-
crypto_helper::TryToBytes,
95+
crypto_helper::{FakeKesSigner, TryToBytes},
8196
entities::{BlockNumber, ChainPoint, TimePoint},
8297
};
8398

@@ -99,14 +114,19 @@ mod tests {
99114

100115
#[tokio::test]
101116
async fn test_build_dmq_message() {
117+
let (kes_signature, operational_certificate) = FakeKesSigner::dummy_signature();
118+
let kes_signer = Arc::new(FakeKesSigner::new(vec![Ok((
119+
kes_signature.clone(),
120+
operational_certificate.clone(),
121+
))]));
102122
let chain_observer = Arc::new(FakeChainObserver::new(Some(TimePoint {
103123
chain_point: ChainPoint {
104124
block_number: BlockNumber(123),
105125
..ChainPoint::dummy()
106126
},
107127
..TimePoint::dummy()
108128
})));
109-
let builder = DmqMessageBuilder::new(chain_observer, 100);
129+
let builder = DmqMessageBuilder::new(kes_signer, chain_observer, 100);
110130
let message = test_utils::TestMessage {
111131
content: b"test".to_vec(),
112132
};
@@ -118,19 +138,17 @@ mod tests {
118138

119139
assert_eq!(
120140
DmqMsg {
121-
msg_id: vec![
122-
26, 113, 171, 177, 174, 241, 244, 241, 209, 92, 210, 7, 119, 105, 94, 133, 93,
123-
62, 82, 95, 91, 221, 146, 174, 201, 190, 140, 1, 217, 240, 228, 203, 14, 50,
124-
104, 59, 252, 216, 26, 84, 231, 142, 163, 140, 11, 95, 17, 234, 242, 39, 230,
125-
160, 194, 219, 128, 42, 53, 125, 218, 48, 209, 3, 210, 154
126-
],
141+
msg_id: vec![],
127142
msg_body: vec![116, 101, 115, 116],
128143
block_number: 123,
129144
ttl: 100,
130-
kes_signature: vec![],
131-
operational_certificate: vec![],
145+
kes_signature: kes_signature.to_bytes_vec().unwrap(),
146+
operational_certificate: operational_certificate.to_bytes_vec().unwrap(),
132147
},
133-
dmq_message
148+
DmqMsg {
149+
msg_id: vec![],
150+
..dmq_message
151+
}
134152
);
135153
}
136154
}

internal/mithril-dmq-node/src/publisher/pallas.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ mod tests {
9292
use tokio::{net::UnixListener, task::JoinHandle};
9393

9494
use mithril_cardano_node_chain::test::double::FakeChainObserver;
95-
use mithril_common::{current_function, test_utils::TempDir};
95+
use mithril_common::{crypto_helper::FakeKesSigner, current_function, test_utils::TempDir};
9696

9797
use crate::{test::payload::DmqMessageTestPayload, test_tools::TestLogger};
9898

@@ -148,7 +148,20 @@ mod tests {
148148
let publisher = DmqPublisherPallas::new(
149149
socket_path,
150150
CardanoNetwork::TestNet(0),
151-
DmqMessageBuilder::new(Arc::new(FakeChainObserver::default()), 100),
151+
DmqMessageBuilder::new(
152+
{
153+
let (kes_signature, operational_certificate) =
154+
FakeKesSigner::dummy_signature();
155+
let kes_signer = FakeKesSigner::new(vec![Ok((
156+
kes_signature.clone(),
157+
operational_certificate.clone(),
158+
))]);
159+
160+
Arc::new(kes_signer)
161+
},
162+
Arc::new(FakeChainObserver::default()),
163+
100,
164+
),
152165
TestLogger::stdout(),
153166
);
154167

@@ -171,7 +184,20 @@ mod tests {
171184
let publisher = DmqPublisherPallas::new(
172185
socket_path,
173186
CardanoNetwork::TestNet(0),
174-
DmqMessageBuilder::new(Arc::new(FakeChainObserver::default()), 100),
187+
DmqMessageBuilder::new(
188+
{
189+
let (kes_signature, operational_certificate) =
190+
FakeKesSigner::dummy_signature();
191+
let kes_signer = FakeKesSigner::new(vec![Ok((
192+
kes_signature.clone(),
193+
operational_certificate.clone(),
194+
))]);
195+
196+
Arc::new(kes_signer)
197+
},
198+
Arc::new(FakeChainObserver::default()),
199+
100,
200+
),
175201
TestLogger::stdout(),
176202
);
177203

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use std::collections::VecDeque;
2+
3+
use kes_summed_ed25519::kes::Sum6KesSig;
4+
use std::sync::Mutex;
5+
6+
use crate::{
7+
crypto_helper::{
8+
cardano::{create_kes_cryptographic_material, StandardKesSigner},
9+
KESPeriod, KesSigner, OpCert,
10+
},
11+
StdResult,
12+
};
13+
14+
type KesSignatureResult = StdResult<(Sum6KesSig, OpCert)>;
15+
16+
/// Fake KES Signer implementation.
17+
pub struct FakeKesSigner {
18+
results: Mutex<VecDeque<KesSignatureResult>>,
19+
}
20+
21+
impl FakeKesSigner {
22+
/// Creates a new `FakeSignatureConsumer` instance.
23+
pub fn new(results: Vec<KesSignatureResult>) -> Self {
24+
Self {
25+
results: Mutex::new(results.into()),
26+
}
27+
}
28+
29+
/// Returns a dummy signature result that is always successful.
30+
pub fn dummy_signature() -> (Sum6KesSig, OpCert) {
31+
let (_party_id, operational_certificate_file, kes_secret_key_file) =
32+
create_kes_cryptographic_material(
33+
1,
34+
0 as KESPeriod,
35+
"fake_kes_signer_returns_signature_batches_in_expected_order",
36+
);
37+
let message = b"Test message for KES signing";
38+
let kes_signer = StandardKesSigner::new(kes_secret_key_file, operational_certificate_file);
39+
let kes_signing_period = 1;
40+
let (kes_signature, op_cert) = kes_signer
41+
.sign(message, kes_signing_period)
42+
.expect("Signing should not fail");
43+
44+
(kes_signature.clone(), op_cert.clone())
45+
}
46+
47+
/// Returns a dummy signature result that always fails.
48+
pub fn dummy_signature_result_err() -> KesSignatureResult {
49+
Err(anyhow::anyhow!("Dummy error"))
50+
}
51+
}
52+
53+
impl KesSigner for FakeKesSigner {
54+
fn sign(&self, _message: &[u8], _kes_period: KESPeriod) -> KesSignatureResult {
55+
let mut results = self.results.lock().unwrap();
56+
57+
results.pop_front().unwrap()
58+
}
59+
}
60+
61+
#[cfg(test)]
62+
mod tests {
63+
use super::*;
64+
65+
#[test]
66+
fn fake_kes_signer_returns_signature_batches_in_expected_order() {
67+
let (_party_id, operational_certificate_file, kes_secret_key_file) =
68+
create_kes_cryptographic_material(
69+
1,
70+
0 as KESPeriod,
71+
"fake_kes_signer_returns_signature_batches_in_expected_order",
72+
);
73+
let message = b"Test message for KES signing";
74+
let kes_signer = StandardKesSigner::new(kes_secret_key_file, operational_certificate_file);
75+
let kes_signing_period = 1;
76+
let (kes_signature, op_cert) = kes_signer
77+
.sign(message, kes_signing_period)
78+
.expect("Signing should not fail");
79+
let fake_kes_signer = FakeKesSigner::new(vec![
80+
Ok((kes_signature.clone(), op_cert.clone())),
81+
Err(anyhow::anyhow!("Fake error")),
82+
]);
83+
84+
let (kes_signature_1, op_cert_1) = fake_kes_signer
85+
.sign(message, kes_signing_period)
86+
.expect("Signing should not fail");
87+
assert_eq!(kes_signature, kes_signature_1);
88+
assert_eq!(op_cert, op_cert_1);
89+
90+
fake_kes_signer
91+
.sign(message, kes_signing_period)
92+
.expect_err("Signing should fail");
93+
}
94+
}

mithril-common/src/crypto_helper/cardano/kes/interface.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ use crate::{
77

88
/// Trait for KES (Key Evolving Signature) signing operation.
99
#[cfg_attr(test, mockall::automock)]
10-
pub trait KesSigner {
10+
pub trait KesSigner: Send + Sync {
1111
/// Return signed bytes with the KES secret key and the associated Operational Certificate
1212
fn sign(&self, message: &[u8], kes_period: KESPeriod) -> StdResult<(Sum6KesSig, OpCert)>;
1313
}
1414

1515
/// Trait for KES (Key Evolving Signature) verification operation.
1616
#[cfg_attr(test, mockall::automock)]
17-
pub trait KesVerifier {
17+
pub trait KesVerifier: Send + Sync {
1818
/// Verify the signed message and return the original message.
1919
fn verify(
2020
&self,

mithril-common/src/crypto_helper/cardano/kes/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
mod error;
2+
mod fake_signer;
23
mod interface;
34
mod signer_with_key;
45
mod verifier;
56

67
pub use error::*;
8+
pub use fake_signer::*;
79
pub use interface::*;
810
pub use signer_with_key::*;
911
pub use verifier::*;
1012

11-
#[cfg(test)]
1213
pub(crate) use test_utils::*;
1314

14-
#[cfg(test)]
1515
mod test_utils {
1616
use std::path::PathBuf;
1717

@@ -22,6 +22,7 @@ mod test_utils {
2222
use crate::crypto_helper::{KESPeriod, ProtocolPartyId, SerDeShelleyFileFormat, Sum6KesBytes};
2323
use crate::test_utils::TempDir;
2424

25+
/// Create KES cryptographic material for testing purposes.
2526
pub(crate) fn create_kes_cryptographic_material(
2627
party_idx: u64,
2728
kes_period: KESPeriod,

mithril-common/src/crypto_helper/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ cfg_test_tools! {
1616
pub use cardano::ColdKeyGenerator;
1717

1818
pub use cardano::{
19-
KESPeriod, KesError, KesSigner, KesVerifier, KesVerifierStandard, OpCert,
19+
FakeKesSigner, KESPeriod, KesError, KesSigner, KesVerifier, KesVerifierStandard, OpCert,
2020
ProtocolInitializerErrorWrapper, ProtocolRegistrationErrorWrapper, SerDeShelleyFileFormat,
2121
Sum6KesBytes,
2222
};

0 commit comments

Comments
 (0)