From 6b17fc0b0df3f15969770970369ffbfe5179e3aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 16:31:58 +0100 Subject: [PATCH 01/12] Create `kairos-crypto` workspace. --- Cargo.lock | 4 ++++ Cargo.toml | 1 + kairos-crypto/Cargo.toml | 6 ++++++ kairos-crypto/src/lib.rs | 0 4 files changed, 11 insertions(+) create mode 100644 kairos-crypto/Cargo.toml create mode 100644 kairos-crypto/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index b03a31ad..b698aee7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1054,6 +1054,10 @@ dependencies = [ "thiserror", ] +[[package]] +name = "kairos-crypto" +version = "0.1.0" + [[package]] name = "kairos-server" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index d19bb8a6..9de41ea8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "2" members = [ "kairos-cli", + "kairos-crypto", "kairos-server", ] diff --git a/kairos-crypto/Cargo.toml b/kairos-crypto/Cargo.toml new file mode 100644 index 00000000..919cbf2a --- /dev/null +++ b/kairos-crypto/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "kairos-crypto" +version.workspace = true +edition.workspace = true + +[lib] diff --git a/kairos-crypto/src/lib.rs b/kairos-crypto/src/lib.rs new file mode 100644 index 00000000..e69de29b From 0a507d7cd285d46be370199b0b9cdc6acb5be5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 16:37:07 +0100 Subject: [PATCH 02/12] Add `thiserror` dependency. --- Cargo.lock | 3 +++ kairos-crypto/Cargo.toml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index b698aee7..1f097796 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1057,6 +1057,9 @@ dependencies = [ [[package]] name = "kairos-crypto" version = "0.1.0" +dependencies = [ + "thiserror", +] [[package]] name = "kairos-server" diff --git a/kairos-crypto/Cargo.toml b/kairos-crypto/Cargo.toml index 919cbf2a..b6ffb34b 100644 --- a/kairos-crypto/Cargo.toml +++ b/kairos-crypto/Cargo.toml @@ -4,3 +4,6 @@ version.workspace = true edition.workspace = true [lib] + +[dependencies] +thiserror = "1" From df652c0ba7c13cf9ef33096fcc9a060e0b33290c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 16:46:16 +0100 Subject: [PATCH 03/12] Define `CryptoError`. --- kairos-crypto/src/error.rs | 20 ++++++++++++++++++++ kairos-crypto/src/lib.rs | 1 + 2 files changed, 21 insertions(+) create mode 100644 kairos-crypto/src/error.rs diff --git a/kairos-crypto/src/error.rs b/kairos-crypto/src/error.rs new file mode 100644 index 00000000..885720af --- /dev/null +++ b/kairos-crypto/src/error.rs @@ -0,0 +1,20 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum CryptoError { + /// Failed to parse a public key from a raw data. + #[error("failed to parse private key: {error}")] + FailedToParseKey { error: String }, + /// Encoding related error. + #[error("failed to serialize '{context}'")] + Serialization { context: &'static str }, + /// Invalid public key (hexdigest) or other decoding related error. + #[error("failed to deserialize '{context}'")] + Deserialization { context: &'static str }, + /// Signature verification failure. + #[error("signature verification failed")] + InvalidSignature, + /// Private key is not provided. + #[error("private key is not provided")] + MissingPrivateKey, +} diff --git a/kairos-crypto/src/lib.rs b/kairos-crypto/src/lib.rs index e69de29b..a91e7351 100644 --- a/kairos-crypto/src/lib.rs +++ b/kairos-crypto/src/lib.rs @@ -0,0 +1 @@ +pub mod error; From f91232f6dd361743944420a9a22f1f65aa7854d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 16:50:21 +0100 Subject: [PATCH 04/12] Define `CryptoSigner`. --- kairos-crypto/src/lib.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/kairos-crypto/src/lib.rs b/kairos-crypto/src/lib.rs index a91e7351..08f69c5f 100644 --- a/kairos-crypto/src/lib.rs +++ b/kairos-crypto/src/lib.rs @@ -1 +1,19 @@ pub mod error; + +use std::path::Path; + +use error::CryptoError; + +pub trait CryptoSigner { + fn from_private_key_file>(file: P) -> Result + where + Self: Sized; + fn from_public_key(bytes: &[u8]) -> Result + where + Self: Sized; + + fn sign(&self, data: &[u8]) -> Result, CryptoError>; + fn verify(&self, data: &[u8], signature_bytes: &[u8]) -> Result<(), CryptoError>; + + fn to_public_key(&self) -> Result, CryptoError>; +} From 306080f752acaa747ff02147a11603e1d6623a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 16:58:59 +0100 Subject: [PATCH 05/12] Add `casper-types` dependency - optionally enabled via feature. --- Cargo.lock | 1 + kairos-crypto/Cargo.toml | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 1f097796..95c29789 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1058,6 +1058,7 @@ dependencies = [ name = "kairos-crypto" version = "0.1.0" dependencies = [ + "casper-types", "thiserror", ] diff --git a/kairos-crypto/Cargo.toml b/kairos-crypto/Cargo.toml index b6ffb34b..fe14bcfe 100644 --- a/kairos-crypto/Cargo.toml +++ b/kairos-crypto/Cargo.toml @@ -3,7 +3,14 @@ name = "kairos-crypto" version.workspace = true edition.workspace = true +[features] +default = ["crypto-casper"] +crypto-casper = ["casper-types"] + [lib] [dependencies] thiserror = "1" + +# Casper signer implementation. +casper-types = { version = "4", optional = true, features = ["std"] } # TODO: Change `std` -> `std-fs-io` in the future version. From 63dde1d3258000b37053c6c51006545cd4b727ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 17:04:58 +0100 Subject: [PATCH 06/12] Implement Casper signer. --- kairos-crypto/src/implementations/casper.rs | 84 +++++++++++++++++++++ kairos-crypto/src/implementations/mod.rs | 9 +++ kairos-crypto/src/lib.rs | 1 + 3 files changed, 94 insertions(+) create mode 100644 kairos-crypto/src/implementations/casper.rs create mode 100644 kairos-crypto/src/implementations/mod.rs diff --git a/kairos-crypto/src/implementations/casper.rs b/kairos-crypto/src/implementations/casper.rs new file mode 100644 index 00000000..3ab71097 --- /dev/null +++ b/kairos-crypto/src/implementations/casper.rs @@ -0,0 +1,84 @@ +use casper_types::bytesrepr::{FromBytes, ToBytes}; +use casper_types::{crypto, PublicKey, SecretKey, Signature}; +use std::path::Path; + +use crate::CryptoError; +use crate::CryptoSigner; + +pub struct Signer { + private_key: Option, + public_key: PublicKey, +} + +impl CryptoSigner for Signer { + fn from_private_key_file>(file: P) -> Result + where + Self: Sized, + { + let private_key = + SecretKey::from_file(file).map_err(|e| CryptoError::FailedToParseKey { + error: e.to_string(), + })?; + let public_key = PublicKey::from(&private_key); + + Ok(Self { + private_key: Some(private_key), + public_key, + }) + } + + fn from_public_key(bytes: &[u8]) -> Result + where + Self: Sized, + { + let (public_key, _remainder) = + casper_types::PublicKey::from_bytes(bytes).map_err(|_e| { + CryptoError::Deserialization { + context: "public key", + } + })?; + + Ok(Self { + private_key: None, + public_key, + }) + } + + fn sign(&self, data: &[u8]) -> Result, CryptoError> { + let private_key = self + .private_key + .as_ref() + .ok_or(CryptoError::MissingPrivateKey)?; + let signature = crypto::sign(data, private_key, &self.public_key); + let signature_bytes = signature + .to_bytes() + .map_err(|_e| CryptoError::Serialization { + context: "signature", + })?; + + Ok(signature_bytes) + } + + fn verify(&self, data: &[u8], signature_bytes: &[u8]) -> Result<(), CryptoError> { + let (signature, _remainder) = + Signature::from_bytes(signature_bytes).map_err(|_e| CryptoError::Deserialization { + context: "signature", + })?; + crypto::verify(data, &signature, &self.public_key) + .map_err(|_e| CryptoError::InvalidSignature)?; + + Ok(()) + } + + fn to_public_key(&self) -> Result, CryptoError> { + let public_key = + self.public_key + .clone() + .into_bytes() + .map_err(|_e| CryptoError::Serialization { + context: "public_key", + })?; + + Ok(public_key) + } +} diff --git a/kairos-crypto/src/implementations/mod.rs b/kairos-crypto/src/implementations/mod.rs new file mode 100644 index 00000000..c2e0d82e --- /dev/null +++ b/kairos-crypto/src/implementations/mod.rs @@ -0,0 +1,9 @@ +mod casper; + +#[cfg(feature = "crypto-casper")] +pub type Signer = casper::Signer; + +// Alternative crypto implementations can be provided, for example: +// +//#[cfg(feature = "crypto-kairos-a")] +//pub type Signer = kairos_a::Signer; diff --git a/kairos-crypto/src/lib.rs b/kairos-crypto/src/lib.rs index 08f69c5f..38dab94f 100644 --- a/kairos-crypto/src/lib.rs +++ b/kairos-crypto/src/lib.rs @@ -1,4 +1,5 @@ pub mod error; +pub mod implementations; use std::path::Path; From e16f185dafe854e3d102837e5711b9c579716436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 17:06:54 +0100 Subject: [PATCH 07/12] Add `hex` dependency. --- Cargo.lock | 1 + kairos-crypto/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 95c29789..40986fbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1059,6 +1059,7 @@ name = "kairos-crypto" version = "0.1.0" dependencies = [ "casper-types", + "hex", "thiserror", ] diff --git a/kairos-crypto/Cargo.toml b/kairos-crypto/Cargo.toml index fe14bcfe..e7b26536 100644 --- a/kairos-crypto/Cargo.toml +++ b/kairos-crypto/Cargo.toml @@ -10,6 +10,7 @@ crypto-casper = ["casper-types"] [lib] [dependencies] +hex = "0.4" thiserror = "1" # Casper signer implementation. From eb1fcbcfa748de2e89a588af3846fb189aa07665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 17:07:54 +0100 Subject: [PATCH 08/12] Add tests for Casper signer. --- kairos-crypto/src/implementations/casper.rs | 44 +++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/kairos-crypto/src/implementations/casper.rs b/kairos-crypto/src/implementations/casper.rs index 3ab71097..f154433c 100644 --- a/kairos-crypto/src/implementations/casper.rs +++ b/kairos-crypto/src/implementations/casper.rs @@ -82,3 +82,47 @@ impl CryptoSigner for Signer { Ok(public_key) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_casper_ed25519_public_key() { + // This public key has a 01 prefix indicating Ed25519. + let bytes = + hex::decode("01c377281132044bd3278b039925eeb3efdb9d99dd5f46d9ec6a764add34581af7") + .unwrap(); + let result = Signer::from_public_key(&bytes); + assert!( + result.is_ok(), + "Ed25519 public key should be parsed correctly" + ); + } + + #[test] + fn test_casper_secp256k1_public_key() { + // This public key has a 02 prefix indicating Secp256k1. + let bytes = + hex::decode("0202e99759649fa63a72c685b72e696b30c90f1deabb02d0d9b1de45eb371a73e5bb") + .unwrap(); + let result = Signer::from_public_key(&bytes); + assert!( + result.is_ok(), + "Secp256k1 public key should be parsed correctly" + ); + } + + #[test] + fn test_casper_unrecognized_prefix() { + // Using a 99 prefix which is not recognized. + let bytes = + hex::decode("99c377281132044bd3278b039925eeb3efdb9d99dd5f46d9ec6a764add34581af7") + .unwrap(); + let result = Signer::from_public_key(&bytes); + assert!( + result.is_err(), + "Unrecognized prefix should result in an error" + ); + } +} From 5335312f1ea60cc72bda21bd323168b366acf0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 17:25:27 +0100 Subject: [PATCH 09/12] Use `kairos-crypto` in CLI parsing. --- Cargo.lock | 1 + kairos-cli/Cargo.toml | 1 + kairos-cli/src/commands/deposit.rs | 8 +++++--- kairos-cli/src/commands/transfer.rs | 11 ++++++----- kairos-cli/src/commands/withdraw.rs | 8 +++++--- kairos-cli/src/error.rs | 2 +- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 40986fbf..2d2a37e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1050,6 +1050,7 @@ dependencies = [ "casper-types", "clap", "hex", + "kairos-crypto", "predicates", "thiserror", ] diff --git a/kairos-cli/Cargo.toml b/kairos-cli/Cargo.toml index abf507c8..7fcd037c 100644 --- a/kairos-cli/Cargo.toml +++ b/kairos-cli/Cargo.toml @@ -17,6 +17,7 @@ casper-types = { version = "4.0.1", features = ["std"] } # TODO: Change `std` -> clap = { version = "4.4.18", features = ["derive"] } hex = "0.4.3" thiserror = "1.0.56" +kairos-crypto = { path = "../kairos-crypto" } [dev-dependencies] assert_cmd = "2.0.13" diff --git a/kairos-cli/src/commands/deposit.rs b/kairos-cli/src/commands/deposit.rs index a90650ff..b4b95c99 100644 --- a/kairos-cli/src/commands/deposit.rs +++ b/kairos-cli/src/commands/deposit.rs @@ -1,8 +1,10 @@ use crate::common::args::{AmountArg, PrivateKeyPathArg}; -use crate::crypto::error::CryptoError; -use crate::crypto::signer::CasperSigner; use crate::error::CliError; +use kairos_crypto::error::CryptoError; +use kairos_crypto::implementations::Signer; +use kairos_crypto::CryptoSigner; + use clap::Parser; #[derive(Parser, Debug)] @@ -16,7 +18,7 @@ pub struct Args { pub fn run(args: Args) -> Result { let _amount: u64 = args.amount.field; let _signer = - CasperSigner::from_file(args.private_key_path.field).map_err(CryptoError::from)?; + Signer::from_private_key_file(args.private_key_path.field).map_err(CryptoError::from)?; // TODO: Create transaction and sign it with `signer`. diff --git a/kairos-cli/src/commands/transfer.rs b/kairos-cli/src/commands/transfer.rs index 508057eb..605d3821 100644 --- a/kairos-cli/src/commands/transfer.rs +++ b/kairos-cli/src/commands/transfer.rs @@ -1,10 +1,11 @@ use crate::common::args::{AmountArg, PrivateKeyPathArg}; -use crate::crypto::error::CryptoError; -use crate::crypto::public_key::CasperPublicKey; -use crate::crypto::signer::CasperSigner; use crate::error::CliError; use crate::utils::parse_hex_string; +use kairos_crypto::error::CryptoError; +use kairos_crypto::implementations::Signer; +use kairos_crypto::CryptoSigner; + use clap::Parser; #[derive(Parser)] @@ -18,10 +19,10 @@ pub struct Args { } pub fn run(args: Args) -> Result { - let _recipient = CasperPublicKey::from_bytes(args.recipient.as_ref())?; + let _recipient = Signer::from_public_key(args.recipient.as_ref())?.to_public_key()?; let _amount: u64 = args.amount.field; let _signer = - CasperSigner::from_file(args.private_key_path.field).map_err(CryptoError::from)?; + Signer::from_private_key_file(args.private_key_path.field).map_err(CryptoError::from)?; // TODO: Create transaction and sign it with `signer`. diff --git a/kairos-cli/src/commands/withdraw.rs b/kairos-cli/src/commands/withdraw.rs index 45a6b130..13490eb2 100644 --- a/kairos-cli/src/commands/withdraw.rs +++ b/kairos-cli/src/commands/withdraw.rs @@ -1,8 +1,10 @@ use crate::common::args::{AmountArg, PrivateKeyPathArg}; -use crate::crypto::error::CryptoError; -use crate::crypto::signer::CasperSigner; use crate::error::CliError; +use kairos_crypto::error::CryptoError; +use kairos_crypto::implementations::Signer; +use kairos_crypto::CryptoSigner; + use clap::Parser; #[derive(Parser)] @@ -16,7 +18,7 @@ pub struct Args { pub fn run(args: Args) -> Result { let _amount: u64 = args.amount.field; let _signer = - CasperSigner::from_file(args.private_key_path.field).map_err(CryptoError::from)?; + Signer::from_private_key_file(args.private_key_path.field).map_err(CryptoError::from)?; // TODO: Create transaction and sign it with `signer`. diff --git a/kairos-cli/src/error.rs b/kairos-cli/src/error.rs index 9338ee2b..19558e20 100644 --- a/kairos-cli/src/error.rs +++ b/kairos-cli/src/error.rs @@ -1,7 +1,7 @@ use hex::FromHexError; use thiserror::Error; -use crate::crypto::error::CryptoError; +use kairos_crypto::error::CryptoError; #[derive(Error, Debug)] pub enum CliError { From d12f91ebfee71cc912b2788fbf2b9adb4d1d8ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Sun, 17 Mar 2024 17:26:14 +0100 Subject: [PATCH 10/12] Remove unused crypto part of CLI. --- kairos-cli/src/crypto/error.rs | 15 ------ kairos-cli/src/crypto/mod.rs | 4 -- kairos-cli/src/crypto/private_key.rs | 11 ----- kairos-cli/src/crypto/public_key.rs | 68 ---------------------------- kairos-cli/src/crypto/signer.rs | 38 ---------------- kairos-cli/src/lib.rs | 1 - 6 files changed, 137 deletions(-) delete mode 100644 kairos-cli/src/crypto/error.rs delete mode 100644 kairos-cli/src/crypto/mod.rs delete mode 100644 kairos-cli/src/crypto/private_key.rs delete mode 100644 kairos-cli/src/crypto/public_key.rs delete mode 100644 kairos-cli/src/crypto/signer.rs diff --git a/kairos-cli/src/crypto/error.rs b/kairos-cli/src/crypto/error.rs deleted file mode 100644 index 789afa5d..00000000 --- a/kairos-cli/src/crypto/error.rs +++ /dev/null @@ -1,15 +0,0 @@ -use casper_types::ErrorExt; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum CryptoError { - /// Failed to parse a public key from a raw data. - #[error("failed to parse private key: {error}")] - FailedToParseKey { - #[from] - error: ErrorExt, - }, - /// Invalid public key (hexdigest) or other encoding related error. - #[error("failed to serialize/deserialize '{context}'")] - Serialization { context: &'static str }, -} diff --git a/kairos-cli/src/crypto/mod.rs b/kairos-cli/src/crypto/mod.rs deleted file mode 100644 index b68afd01..00000000 --- a/kairos-cli/src/crypto/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod error; -pub mod private_key; -pub mod public_key; -pub mod signer; diff --git a/kairos-cli/src/crypto/private_key.rs b/kairos-cli/src/crypto/private_key.rs deleted file mode 100644 index 9cfd7902..00000000 --- a/kairos-cli/src/crypto/private_key.rs +++ /dev/null @@ -1,11 +0,0 @@ -use std::path::Path; - -use casper_types::ErrorExt; - -pub struct CasperPrivateKey(pub casper_types::SecretKey); - -impl CasperPrivateKey { - pub fn from_file>(file_path: P) -> Result { - casper_types::SecretKey::from_file(file_path).map(Self) - } -} diff --git a/kairos-cli/src/crypto/public_key.rs b/kairos-cli/src/crypto/public_key.rs deleted file mode 100644 index 9bf0d571..00000000 --- a/kairos-cli/src/crypto/public_key.rs +++ /dev/null @@ -1,68 +0,0 @@ -use crate::crypto::error::CryptoError; -use casper_types::bytesrepr::{FromBytes, ToBytes}; - -#[derive(Clone)] -pub struct CasperPublicKey(pub casper_types::PublicKey); - -impl CasperPublicKey { - pub fn from_bytes(bytes: &[u8]) -> Result { - let (public_key, _remainder) = - casper_types::PublicKey::from_bytes(bytes).map_err(|_e| { - CryptoError::Serialization { - context: "public key serialization", - } - })?; - Ok(Self(public_key)) - } - - #[allow(unused)] - fn to_bytes(&self) -> Result, CryptoError> { - self.0.to_bytes().map_err(|_e| CryptoError::Serialization { - context: "public key deserialization", - }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_casper_ed25519_public_key() { - // This public key has a 01 prefix indicating Ed25519. - let bytes = - hex::decode("01c377281132044bd3278b039925eeb3efdb9d99dd5f46d9ec6a764add34581af7") - .unwrap(); - let result = CasperPublicKey::from_bytes(&bytes); - assert!( - result.is_ok(), - "Ed25519 public key should be parsed correctly" - ); - } - - #[test] - fn test_casper_secp256k1_public_key() { - // This public key has a 02 prefix indicating Secp256k1. - let bytes = - hex::decode("0202e99759649fa63a72c685b72e696b30c90f1deabb02d0d9b1de45eb371a73e5bb") - .unwrap(); - let result = CasperPublicKey::from_bytes(&bytes); - assert!( - result.is_ok(), - "Secp256k1 public key should be parsed correctly" - ); - } - - #[test] - fn test_casper_unrecognized_prefix() { - // Using a 99 prefix which is not recognized. - let bytes = - hex::decode("99c377281132044bd3278b039925eeb3efdb9d99dd5f46d9ec6a764add34581af7") - .unwrap(); - let result = CasperPublicKey::from_bytes(&bytes); - assert!( - result.is_err(), - "Unrecognized prefix should result in an error" - ); - } -} diff --git a/kairos-cli/src/crypto/signer.rs b/kairos-cli/src/crypto/signer.rs deleted file mode 100644 index 7ce62e5f..00000000 --- a/kairos-cli/src/crypto/signer.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::path::Path; - -use super::private_key::CasperPrivateKey; -use super::public_key::CasperPublicKey; -use crate::crypto::error::CryptoError; -use casper_types::bytesrepr::ToBytes; -use casper_types::{crypto, ErrorExt, PublicKey}; - -pub struct CasperSigner { - secret_key: CasperPrivateKey, - pub public_key: CasperPublicKey, -} - -#[allow(unused)] -impl CasperSigner { - pub fn from_file>(file_path: P) -> Result { - let secret_key = CasperPrivateKey::from_file(file_path)?; - - // Derive the public key. - let public_key = CasperPublicKey(PublicKey::from(&secret_key.0)); - - Ok(CasperSigner { - secret_key, - public_key, - }) - } - - pub fn sign_message(&self, message: &[u8]) -> Result, CryptoError> { - let signature = crypto::sign(message, &self.secret_key.0, &self.public_key.0); - let bytes = signature - .to_bytes() - .map_err(|_e| CryptoError::Serialization { - context: "signature", - })?; - - Ok(bytes) - } -} diff --git a/kairos-cli/src/lib.rs b/kairos-cli/src/lib.rs index 86f168d4..80647025 100644 --- a/kairos-cli/src/lib.rs +++ b/kairos-cli/src/lib.rs @@ -1,5 +1,4 @@ pub mod commands; pub mod common; -pub mod crypto; pub mod error; pub mod utils; From 9792ee33cc357f3798cca652a76e89cc4ff51755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Wed, 20 Mar 2024 11:23:32 +0100 Subject: [PATCH 11/12] Use `AsRef<[u8]>` instead of `&[u8]`. --- kairos-cli/src/commands/transfer.rs | 2 +- kairos-crypto/src/implementations/casper.rs | 30 ++++++++++++--------- kairos-crypto/src/lib.rs | 10 ++++--- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/kairos-cli/src/commands/transfer.rs b/kairos-cli/src/commands/transfer.rs index 605d3821..d45cd954 100644 --- a/kairos-cli/src/commands/transfer.rs +++ b/kairos-cli/src/commands/transfer.rs @@ -19,7 +19,7 @@ pub struct Args { } pub fn run(args: Args) -> Result { - let _recipient = Signer::from_public_key(args.recipient.as_ref())?.to_public_key()?; + let _recipient = Signer::from_public_key(args.recipient)?.to_public_key()?; let _amount: u64 = args.amount.field; let _signer = Signer::from_private_key_file(args.private_key_path.field).map_err(CryptoError::from)?; diff --git a/kairos-crypto/src/implementations/casper.rs b/kairos-crypto/src/implementations/casper.rs index f154433c..9b0fcc57 100644 --- a/kairos-crypto/src/implementations/casper.rs +++ b/kairos-crypto/src/implementations/casper.rs @@ -27,15 +27,13 @@ impl CryptoSigner for Signer { }) } - fn from_public_key(bytes: &[u8]) -> Result + fn from_public_key>(bytes: T) -> Result where Self: Sized, { - let (public_key, _remainder) = - casper_types::PublicKey::from_bytes(bytes).map_err(|_e| { - CryptoError::Deserialization { - context: "public key", - } + let (public_key, _remainder) = casper_types::PublicKey::from_bytes(bytes.as_ref()) + .map_err(|_e| CryptoError::Deserialization { + context: "public key", })?; Ok(Self { @@ -44,7 +42,7 @@ impl CryptoSigner for Signer { }) } - fn sign(&self, data: &[u8]) -> Result, CryptoError> { + fn sign>(&self, data: T) -> Result, CryptoError> { let private_key = self .private_key .as_ref() @@ -59,10 +57,16 @@ impl CryptoSigner for Signer { Ok(signature_bytes) } - fn verify(&self, data: &[u8], signature_bytes: &[u8]) -> Result<(), CryptoError> { + fn verify, U: AsRef<[u8]>>( + &self, + data: T, + signature_bytes: U, + ) -> Result<(), CryptoError> { let (signature, _remainder) = - Signature::from_bytes(signature_bytes).map_err(|_e| CryptoError::Deserialization { - context: "signature", + Signature::from_bytes(signature_bytes.as_ref()).map_err(|_e| { + CryptoError::Deserialization { + context: "signature", + } })?; crypto::verify(data, &signature, &self.public_key) .map_err(|_e| CryptoError::InvalidSignature)?; @@ -93,7 +97,7 @@ mod tests { let bytes = hex::decode("01c377281132044bd3278b039925eeb3efdb9d99dd5f46d9ec6a764add34581af7") .unwrap(); - let result = Signer::from_public_key(&bytes); + let result = Signer::from_public_key(bytes); assert!( result.is_ok(), "Ed25519 public key should be parsed correctly" @@ -106,7 +110,7 @@ mod tests { let bytes = hex::decode("0202e99759649fa63a72c685b72e696b30c90f1deabb02d0d9b1de45eb371a73e5bb") .unwrap(); - let result = Signer::from_public_key(&bytes); + let result = Signer::from_public_key(bytes); assert!( result.is_ok(), "Secp256k1 public key should be parsed correctly" @@ -119,7 +123,7 @@ mod tests { let bytes = hex::decode("99c377281132044bd3278b039925eeb3efdb9d99dd5f46d9ec6a764add34581af7") .unwrap(); - let result = Signer::from_public_key(&bytes); + let result = Signer::from_public_key(bytes); assert!( result.is_err(), "Unrecognized prefix should result in an error" diff --git a/kairos-crypto/src/lib.rs b/kairos-crypto/src/lib.rs index 38dab94f..a8f31aeb 100644 --- a/kairos-crypto/src/lib.rs +++ b/kairos-crypto/src/lib.rs @@ -9,12 +9,16 @@ pub trait CryptoSigner { fn from_private_key_file>(file: P) -> Result where Self: Sized; - fn from_public_key(bytes: &[u8]) -> Result + fn from_public_key>(bytes: T) -> Result where Self: Sized; - fn sign(&self, data: &[u8]) -> Result, CryptoError>; - fn verify(&self, data: &[u8], signature_bytes: &[u8]) -> Result<(), CryptoError>; + fn sign>(&self, data: T) -> Result, CryptoError>; + fn verify, U: AsRef<[u8]>>( + &self, + data: T, + signature_bytes: U, + ) -> Result<(), CryptoError>; fn to_public_key(&self) -> Result, CryptoError>; } From 56fad27dbbd2641f3c6f3ff9ecf7dc6883443d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Wed, 27 Mar 2024 22:05:16 +0100 Subject: [PATCH 12/12] Update `cargo.lock`. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index d3ecda5d..edfd16a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1705,7 +1705,7 @@ dependencies = [ name = "kairos-crypto" version = "0.1.0" dependencies = [ - "casper-types", + "casper-types 4.0.1", "hex", "thiserror", ]