Skip to content

Commit 240b527

Browse files
committed
fix(common): KES period used to sign must be current
1 parent 79f99d4 commit 240b527

File tree

7 files changed

+32
-39
lines changed

7 files changed

+32
-39
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub enum KesVerifyError {
1818
#[derive(Error, Debug)]
1919
pub enum KesSignError {
2020
/// Error raised when a KES update error occurs
21-
#[error("KES key cannot be updated for period {0}")]
21+
#[error("KES key cannot be updated for evolution {0}")]
2222
UpdateKey(KesPeriod),
2323

2424
/// Period of key file does not match with period provided by user

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ use crate::{
1111
#[cfg_attr(test, mockall::automock)]
1212
pub trait KesSigner: Send + Sync {
1313
/// Return signed bytes with the KES secret key and the associated Operational Certificate
14-
fn sign(&self, message: &[u8], kes_period: KesPeriod) -> StdResult<(Sum6KesSig, OpCert)>;
14+
///
15+
/// current_kes_period: The KES period used to sign the message (absolute period computed from the chain at the moment of signature)
16+
fn sign(
17+
&self,
18+
message: &[u8],
19+
current_kes_period: KesPeriod,
20+
) -> StdResult<(Sum6KesSig, OpCert)>;
1521
}
1622

1723
/// Trait for KES (Key Evolving Signature) verification operation.

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

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,27 +31,32 @@ impl KesSignerStandard {
3131
}
3232

3333
impl KesSigner for KesSignerStandard {
34-
fn sign(&self, message: &[u8], kes_period: KesPeriod) -> StdResult<(Sum6KesSig, OpCert)> {
34+
fn sign(
35+
&self,
36+
message: &[u8],
37+
current_kes_period: KesPeriod,
38+
) -> StdResult<(Sum6KesSig, OpCert)> {
3539
let mut kes_sk_bytes = Sum6KesBytes::from_file(&self.kes_sk_path)
3640
.with_context(|| "StandardKesSigner can not read KES secret key from file")?;
3741
let mut kes_sk = Sum6Kes::try_from(&mut kes_sk_bytes)
3842
.with_context(|| "StandardKesSigner can not use KES secret key")?;
43+
let operational_certificate = OpCert::from_file(&self.operational_certificate_path)
44+
.with_context(|| "StandardKesSigner can not read operational certificate from file")?;
45+
let kes_period_start = operational_certificate.get_start_kes_period() as u32;
3946
let kes_sk_period = kes_sk.get_period();
40-
if kes_sk_period > kes_period {
47+
let kes_evolutions = kes_period.saturating_sub(kes_period_start);
48+
if kes_sk_period > kes_evolutions {
4149
return Err(anyhow!(KesSignError::PeriodMismatch(
4250
kes_sk_period,
4351
kes_period
4452
)));
4553
}
4654

4755
// We need to perform the evolutions
48-
for period in kes_sk_period..kes_period {
49-
kes_sk.update().map_err(|_| KesSignError::UpdateKey(period))?;
56+
for evolution in kes_sk_period..kes_evolutions {
57+
kes_sk.update().map_err(|_| KesSignError::UpdateKey(evolution))?;
5058
}
5159

52-
let operational_certificate = OpCert::from_file(&self.operational_certificate_path)
53-
.with_context(|| "StandardKesSigner can not read operational certificate from file")?;
54-
5560
Ok((kes_sk.sign(message), operational_certificate))
5661
}
5762
}
@@ -119,7 +124,8 @@ mod tests {
119124
}
120125

121126
#[test]
122-
fn create_invalid_signature_for_invalid_kes_period() {
127+
fn create_invalid_signature_for_invalid_kes_evolution() {
128+
const MAX_KES_EVOLUTIONS: KesPeriod = 63;
123129
let kes_period_start = 5 as KesPeriod;
124130
let KesCryptographicMaterialForTest {
125131
party_id: _,
@@ -132,11 +138,7 @@ mod tests {
132138
);
133139
let message = b"Test message for KES signing";
134140
let kes_signer = KesSignerStandard::new(kes_secret_key_file, operational_certificate_file);
135-
let kes_signing_period = 2;
136-
assert!(
137-
kes_signing_period < kes_period_start,
138-
"KES signing period should be less than the KES period of the key"
139-
);
141+
let kes_signing_period = kes_period_start + MAX_KES_EVOLUTIONS + 1;
140142

141143
kes_signer
142144
.sign(message, kes_signing_period)

mithril-common/src/crypto_helper/cardano/key_certification.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub enum ProtocolInitializerErrorWrapper {
8888
ProtocolInitializer(#[source] StdError),
8989

9090
/// Error raised when a KES update error occurs
91-
#[error("KES key cannot be updated for period {0}")]
91+
#[error("KES key cannot be updated for evolution {0}")]
9292
KesUpdate(KesPeriod),
9393

9494
/// Period of key file does not match with period provided by user

mithril-common/src/test/crypto_helper/cardano/kes/setup.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub(crate) struct KesCryptographicMaterialForTest {
2121
/// Create KES cryptographic material for testing purposes.
2222
pub fn create_kes_cryptographic_material(
2323
party_idx: KesPartyIndexForTest,
24-
kes_period: KesPeriod,
24+
start_kes_period: KesPeriod,
2525
test_directory: &str,
2626
) -> KesCryptographicMaterialForTest {
2727
let temp_dir = std::env::temp_dir()
@@ -31,16 +31,12 @@ pub fn create_kes_cryptographic_material(
3131
let keypair = ColdKeyGenerator::create_deterministic_keypair([party_idx as u8; 32]);
3232
let mut dummy_buffer = [0u8; Sum6Kes::SIZE + 4];
3333
let mut dummy_seed = [party_idx as u8; 32];
34-
let (mut kes_secret_key, kes_verification_key) =
34+
let (kes_secret_key, kes_verification_key) =
3535
Sum6Kes::keygen(&mut dummy_buffer, &mut dummy_seed);
36-
for _ in 0..kes_period {
37-
kes_secret_key
38-
.update()
39-
.expect("KES secret key update should not fail");
40-
}
4136
let mut kes_bytes = Sum6KesBytes([0u8; Sum6Kes::SIZE + 4]);
4237
kes_bytes.0.copy_from_slice(&kes_secret_key.clone_sk());
43-
let operational_certificate = OpCert::new(kes_verification_key, 0, 0, keypair);
38+
let operational_certificate =
39+
OpCert::new(kes_verification_key, 0, start_kes_period as u64, keypair);
4440
let kes_secret_key_file = temp_dir.join(format!("kes{party_idx}.skey"));
4541
kes_bytes
4642
.to_file(&kes_secret_key_file)

mithril-common/src/test/crypto_helper/cardano/kes/signer_fake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl KesSignerFake {
6363
}
6464

6565
impl KesSigner for KesSignerFake {
66-
fn sign(&self, message: &[u8], _kes_period: KesPeriod) -> KesSignatureResult {
66+
fn sign(&self, message: &[u8], _current_kes_period: KesPeriod) -> KesSignatureResult {
6767
let mut messages = self.signed_messages.lock().unwrap();
6868
messages.push_back(message.to_vec());
6969

mithril-signer/src/runtime/runner.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use thiserror::Error;
55
use tokio::sync::RwLockReadGuard;
66

77
use mithril_common::StdResult;
8-
use mithril_common::crypto_helper::{KesPeriod, OpCert, ProtocolOpCert, SerDeShelleyFileFormat};
8+
use mithril_common::crypto_helper::{OpCert, ProtocolOpCert, SerDeShelleyFileFormat};
99
use mithril_common::entities::{
1010
Epoch, PartyId, ProtocolMessage, SignedEntityType, Signer, TimePoint,
1111
};
@@ -184,7 +184,7 @@ impl Runner for SignerRunner {
184184
let stake = stake_distribution
185185
.get(&self.services.single_signer.get_party_id())
186186
.ok_or_else(RunnerError::NoStakeForSelf)?;
187-
let (operational_certificate, protocol_operational_certificate) = match &self
187+
let (_operational_certificate, protocol_operational_certificate) = match &self
188188
.config
189189
.operational_certificate_path
190190
{
@@ -198,18 +198,7 @@ impl Runner for SignerRunner {
198198
}
199199
_ => (None, None),
200200
};
201-
202-
let kes_period = match operational_certificate {
203-
Some(operational_certificate) => Some(
204-
self.services
205-
.chain_observer
206-
.get_current_kes_period()
207-
.await?
208-
.unwrap_or_default()
209-
- operational_certificate.get_start_kes_period() as KesPeriod,
210-
),
211-
None => None,
212-
};
201+
let kes_period = self.services.chain_observer.get_current_kes_period().await?;
213202

214203
let protocol_initializer = self
215204
.services

0 commit comments

Comments
 (0)