Skip to content

Commit

Permalink
Merge pull request #674 from input-output-hk/iquerejeta/update-kes
Browse files Browse the repository at this point in the history
Update kes dependency
  • Loading branch information
iquerejeta committed Jan 4, 2023
2 parents cab17fa + b592b22 commit 697b10e
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 21 deletions.
7 changes: 4 additions & 3 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions mithril-common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-common"
version = "0.2.0"
version = "0.2.1"
authors = { workspace = true }
edition = { workspace = true }
documentation = { workspace = true }
Expand All @@ -27,7 +27,7 @@ glob = "0.3"
hex = "0.4.3"
http = "0.2.6"
jsonschema = "0.16.0"
kes-summed-ed25519 = { git = "https://github.com/input-output-hk/kes", rev = "1418efa", features = ["serde_enabled"] }
kes-summed-ed25519 = { version = "0.1.1", features = ["serde_enabled"] }
mockall = "0.11.0"
nom = "7.1"
rand-chacha-dalek-compat = { package = "rand_chacha", version = "0.2" }
Expand Down
56 changes: 54 additions & 2 deletions mithril-common/src/crypto_helper/cardano/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ pub trait SerDeShelleyFileFormat: Serialize + DeserializeOwned {
/// The description of the Cardano key
const DESCRIPTION: &'static str;

/// Deserialize a Cardano key from file
/// Deserialize a type `T: Serialize + DeserializeOwned` from file following Cardano
/// Shelley file format.
fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, ParseError> {
let data = fs::read_to_string(path)?;
let file: ShelleyFileFormat = serde_json::from_str(&data)?;
Expand All @@ -65,7 +66,8 @@ pub trait SerDeShelleyFileFormat: Serialize + DeserializeOwned {
Ok(a)
}

/// Serialize a Cardano Key to file
/// Serialize a type `T: Serialize + DeserializeOwned` to file following Cardano
/// Shelley file format.
fn to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), ParseError> {
let cbor_string = hex::encode(serde_cbor::to_vec(&self)?);

Expand All @@ -86,4 +88,54 @@ pub trait SerDeShelleyFileFormat: Serialize + DeserializeOwned {
impl SerDeShelleyFileFormat for Sum6Kes {
const TYPE: &'static str = "KesSigningKey_ed25519_kes_2^6";
const DESCRIPTION: &'static str = "KES Signing Key";

/// Deserialize a Cardano key from file. Cardano KES key Shelley format does not
/// contain the period (it is always zero). Therefore we need to include it in the
/// deserialisation.
fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, ParseError> {
let data = fs::read_to_string(path)?;
let file: ShelleyFileFormat = serde_json::from_str(&data)?;
let mut hex_vector = Vec::from_hex(file.cbor_hex)?;

// We check whether the serialisation was performed by the haskell library or the rust library
if (hex_vector[2] & 4u8) == 0 {
// First we need to change the cbor format to notify about the extra 4 bytes:
hex_vector[2] |= 4u8;
// Then we append the bytes representing the period = 0
hex_vector.extend_from_slice(&[0u8; 4]);
}

let a: Self = serde_cbor::from_slice(&hex_vector)?;
Ok(a)
}
}

#[cfg(all(test))]
mod test {
use super::*;

#[test]
fn compat_with_shelly_format() {
let temp_dir = std::env::temp_dir().join("testing");
fs::create_dir_all(&temp_dir).expect("temp dir creation should not fail");
let sk_dir = temp_dir.join("dummy.skey");
let cbor_string = "590260fe77acdfa56281e4b05198f5136018057a65f425411f0990cac4aca0f2917aa00a3d51e191f6f425d870aca3c6a2a41833621f5729d7bc0e3dfc3ae77d057e5e1253b71def7a54157b9f98973ca3c49edd9f311e5f4b23ac268b56a6ac040c14c6d2217925492e42f00dc89a2a01ff363571df0ca0db5ba37001cee56790cc01cd69c6aa760fca55a65a110305ea3c11da0a27be345a589329a584ebfc499c43c55e8c6db5d9c0b014692533ee78abd7ac1e79f7ec9335c7551d31668369b4d5111db78072f010043e35e5ca7f11acc3c05b26b9c7fe56f02aa41544f00cb7685e87f34c73b617260ade3c7b8d8c4df46693694998f85ad80d2cbab0b575b6ccd65d90574e84368169578bff57f751bc94f7eec5c0d7055ec88891a69545eedbfbd3c5f1b1c1fe09c14099f6b052aa215efdc5cb6cdc84aa810db41dbe8cb7d28f7c4beb75cc53915d3ac75fc9d0bf1c734a46e401e15150c147d013a938b7e07cc4f25a582b914e94783d15896530409b8acbe31ef471de8a1988ac78dfb7510729eff008084885f07df870b65e4f382ca15908e1dcda77384b5c724350de90cec22b1dcbb1cdaed88da08bb4772a82266ec154f5887f89860d0920dba705c45957ef6d93e42f6c9509c966277d368dd0eefa67c8147aa15d40a222f7953a4f34616500b310d00aa1b5b73eb237dc4f76c0c16813d321b2fc5ac97039be25b22509d1201d61f4ccc11cd4ff40fffe39f0e937b4722074d8e073a775d7283b715d46f79ce128e3f1362f35615fa72364d20b6db841193d96e58d9d8e86b516bbd1f05e45b39823a93f6e9f29d9e01acf2c12c072d1c64e0afbbabf6903ef542e".to_string();

let file_format = ShelleyFileFormat {
file_type: Sum6Kes::TYPE.to_string(),
description: Sum6Kes::DESCRIPTION.to_string(),
cbor_hex: cbor_string,
};

let mut file =
fs::File::create(sk_dir.clone()).expect("Unexpected error with file creation.");
let json_str =
serde_json::to_string(&file_format).expect("Unexpected error with serialisation.");

write!(file, "{}", json_str).expect("Unexpected error writing to file.");

let kes_sk = Sum6Kes::from_file(&sk_dir);

assert!(kes_sk.is_ok(), "Failure parsing Shelley file format.");
}
}
30 changes: 20 additions & 10 deletions mithril-common/src/crypto_helper/cardano/key_certification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use thiserror::Error;
type D = Blake2b<U32>;

/// The KES period that is used to check if the KES keys is expired
pub type KESPeriod = usize;
pub type KESPeriod = u32;

/// New registration error
#[derive(Error, Debug, PartialEq, Eq)]
Expand All @@ -53,7 +53,7 @@ pub enum ProtocolRegistrationErrorWrapper {

/// Error raised when a KES Signature verification fails
#[error("KES signature verification error: CurrentKesPeriod={0}, StartKesPeriod={1}")]
KesSignatureInvalid(usize, u64),
KesSignatureInvalid(u32, u64),

/// Error raised when a KES Signature is needed but not provided
#[error("missing KES signature")]
Expand Down Expand Up @@ -82,6 +82,10 @@ pub enum ProtocolInitializerErrorWrapper {
/// Error raised when a KES update error occurs
#[error("KES key cannot be updated for period {0}")]
KesUpdate(KESPeriod),

/// Period of key file does not match with period provided by user
#[error("Period of key file, {0}, does not match with period provided by user, {1}")]
KesMismatch(KESPeriod, KESPeriod),
}
/// Wrapper structure for [MithrilStm:StmInitializer](mithril_stm::stm::StmInitializer).
/// It now obtains a KES signature over the Mithril key. This allows the signers prove
Expand Down Expand Up @@ -119,17 +123,23 @@ impl StmInitializerWrapper {
let kes_signature = if let Some(kes_sk_path) = kes_sk_path {
let mut kes_sk: Sum6Kes = Sum6Kes::from_file(kes_sk_path)?;

// We need to perform the evolutions, as the key is stored in evolution 0 in `kes.skey`
for period in 0..kes_period.unwrap_or_default() {
let kes_sk_period = kes_sk.get_period();
let provided_period = kes_period.unwrap_or_default();
if kes_sk_period > provided_period {
return Err(ProtocolInitializerErrorWrapper::KesMismatch(
kes_sk_period,
provided_period,
));
}

// We need to perform the evolutions
for period in kes_sk_period..provided_period {
kes_sk
.update(period)
.update()
.map_err(|_| ProtocolInitializerErrorWrapper::KesUpdate(period))?;
}

Some(kes_sk.sign(
kes_period.unwrap_or_default(),
&stm_initializer.verification_key().to_bytes(),
))
Some(kes_sk.sign(&stm_initializer.verification_key().to_bytes()))
} else {
println!("WARNING: Non certified signer registration by providing only a Pool Id is decommissionned and must be used for tests only!");
None
Expand All @@ -148,7 +158,7 @@ impl StmInitializerWrapper {

/// Extract the verification key signature.
pub fn verification_key_signature(&self) -> Option<ProtocolSignerVerificationKeySignature> {
self.kes_signature.clone()
self.kes_signature
}

/// Extract the stake of the party
Expand Down
2 changes: 1 addition & 1 deletion mithril-common/src/crypto_helper/cardano/opcert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use blake2::{digest::consts::U28, Blake2b, Digest};
#[cfg(any(test, feature = "test_only"))]
use ed25519_dalek::{Keypair as EdKeypair, Signer};
use ed25519_dalek::{PublicKey as EdPublicKey, Signature as EdSignature, Verifier};
use kes_summed_ed25519::common::PublicKey as KesPublicKey;
use kes_summed_ed25519::PublicKey as KesPublicKey;
use serde::de::Error;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use sha2::Sha256;
Expand Down
7 changes: 4 additions & 3 deletions mithril-signer/src/single_signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ use std::path::PathBuf;
use thiserror::Error;

use mithril_common::crypto_helper::{
key_decode_hex, key_encode_hex, ProtocolClerk, ProtocolInitializer, ProtocolKeyRegistration,
ProtocolPartyId, ProtocolRegistrationError, ProtocolSigner, ProtocolStakeDistribution,
key_decode_hex, key_encode_hex, KESPeriod, ProtocolClerk, ProtocolInitializer,
ProtocolKeyRegistration, ProtocolPartyId, ProtocolRegistrationError, ProtocolSigner,
ProtocolStakeDistribution,
};
use mithril_common::entities::{
PartyId, ProtocolMessage, ProtocolParameters, SignerWithStake, SingleSignatures, Stake,
Expand Down Expand Up @@ -38,7 +39,7 @@ impl MithrilProtocolInitializerBuilder {
stake: &Stake,
protocol_parameters: &ProtocolParameters,
kes_secret_key_path: Option<PathBuf>,
kes_period: Option<usize>,
kes_period: Option<KESPeriod>,
) -> Result<ProtocolInitializer, MithrilProtocolInitializerBuilderError> {
let mut rng = rand_core::OsRng;
let protocol_initializer = ProtocolInitializer::setup(
Expand Down

0 comments on commit 697b10e

Please sign in to comment.