mithril_common/crypto_helper/cardano/kes/
verifier_standard.rs

1use kes_summed_ed25519::{kes::Sum6KesSig, traits::KesSig};
2
3use crate::{
4    crypto_helper::{
5        cardano::{KesVerifier, KesVerifyError},
6        KesPeriod, OpCert,
7    },
8    StdResult,
9};
10
11/// A standard KES signature verifier.
12#[derive(Debug)]
13pub struct KesVerifierStandard;
14
15impl KesVerifier for KesVerifierStandard {
16    /// Verify the signed message and return the original message.
17    fn verify(
18        &self,
19        message: &[u8],
20        signature: &Sum6KesSig,
21        operational_certificate: &OpCert,
22        kes_period: KesPeriod,
23    ) -> StdResult<()> {
24        operational_certificate
25            .validate()
26            .map_err(|_| KesVerifyError::OpCertInvalid)?;
27
28        // Check if the KES period in the operational certificate matches the provided KES period +/- 1
29        let kes_period_try_min = std::cmp::max(0, kes_period.saturating_sub(1));
30        let kes_period_try_max = std::cmp::min(64, kes_period.saturating_add(1));
31        for kes_period_try in kes_period_try_min..kes_period_try_max {
32            if signature
33                .verify(kes_period_try, &operational_certificate.kes_vk, message)
34                .is_ok()
35            {
36                return Ok(());
37            }
38        }
39
40        Err(KesVerifyError::SignatureInvalid(
41            kes_period,
42            operational_certificate.start_kes_period as u32,
43        )
44        .into())
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use crate::crypto_helper::cardano::{
51        kes::tests_setup::create_kes_cryptographic_material,
52        tests_setup::KesCryptographicMaterialForTest, KesSigner, KesSignerStandard,
53    };
54
55    use super::*;
56
57    #[test]
58    fn verify_valid_signature_succeeds() {
59        let KesCryptographicMaterialForTest {
60            party_id: _,
61            operational_certificate_file,
62            kes_secret_key_file,
63        } = create_kes_cryptographic_material(1, 0 as KesPeriod, "verify_valid_signature_succeeds");
64        let message = b"Test message for KES signing";
65        let kes_signer = KesSignerStandard::new(kes_secret_key_file, operational_certificate_file);
66        let kes_signing_period = 1;
67        let (signature, op_cert) = kes_signer
68            .sign(message, kes_signing_period)
69            .expect("Signing should not fail");
70
71        KesVerifierStandard
72            .verify(message, &signature, &op_cert, kes_signing_period)
73            .expect("Signature verification should not fail");
74    }
75
76    #[test]
77    fn verify_invalid_signature_fails() {
78        let KesCryptographicMaterialForTest {
79            party_id: _,
80            operational_certificate_file,
81            kes_secret_key_file,
82        } = create_kes_cryptographic_material(1, 0 as KesPeriod, "verify_invalid_signature_fails");
83        let message = b"Test message for KES signing";
84        let kes_signer = KesSignerStandard::new(kes_secret_key_file, operational_certificate_file);
85        let kes_signing_period = 1;
86        let (signature, op_cert) = kes_signer
87            .sign(message, kes_signing_period)
88            .expect("Signing should not fail");
89
90        KesVerifierStandard
91            .verify(
92                b"Different message",
93                &signature,
94                &op_cert,
95                kes_signing_period,
96            )
97            .expect_err("Signature verification should fail");
98    }
99}