From 5556a645f63921c28b4b032de36c9abcf89f2983 Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Mon, 23 Jun 2025 11:38:49 +0200 Subject: [PATCH 01/10] Signing_keys.rs errors updated --- Cargo.lock | 1 + crates/keys/Cargo.toml | 1 + crates/keys/src/signing_keys.rs | 112 ++++++++++++++++++++------------ 3 files changed, 73 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d81c4d7f..90d067044 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7050,6 +7050,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.8", + "thiserror 2.0.12", "utoipa", ] diff --git a/crates/keys/Cargo.toml b/crates/keys/Cargo.toml index 7e35722dc..fc8de78ba 100644 --- a/crates/keys/Cargo.toml +++ b/crates/keys/Cargo.toml @@ -29,6 +29,7 @@ ripemd.workspace = true # misc anyhow.workspace = true sha2.workspace = true +thiserror.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] rand = { version = "0.8.5", features = ["std"] } diff --git a/crates/keys/src/signing_keys.rs b/crates/keys/src/signing_keys.rs index db3816b44..6ff77b939 100644 --- a/crates/keys/src/signing_keys.rs +++ b/crates/keys/src/signing_keys.rs @@ -1,5 +1,4 @@ use alloy_primitives::eip191_hash_message; -use anyhow::{Result, anyhow}; use ed25519::{ PublicKeyBytes as Ed25519PublicKeyBytes, pkcs8::KeypairBytes as Ed25519KeypairBytes, }; @@ -13,7 +12,8 @@ use pkcs8::{ Document, EncodePrivateKey, LineEnding, PrivateKeyInfo, SecretDocument, der::{Decode, pem::PemLabel}, }; -use std::path::Path; +use std::{path::Path, result::Result}; +use thiserror::Error; use sha2::Digest as _; @@ -66,7 +66,7 @@ impl SigningKey { SigningKey::CosmosAdr36(Secp256k1SigningKey::random(&mut get_rng())) } - pub fn new_with_algorithm(algorithm: CryptoAlgorithm) -> Result { + pub fn new_with_algorithm(algorithm: CryptoAlgorithm) -> Result { match algorithm { CryptoAlgorithm::Ed25519 => Ok(SigningKey::new_ed25519()), CryptoAlgorithm::Secp256k1 => Ok(SigningKey::new_secp256k1()), @@ -90,7 +90,7 @@ impl SigningKey { } } - fn to_pkcs8_der_doc(&self) -> Result { + fn to_pkcs8_der_doc(&self) -> Result { match self { SigningKey::Ed25519(sk) => { let keypair_bytes = Ed25519KeypairBytes { @@ -104,75 +104,80 @@ impl SigningKey { SigningKey::Eip191(sk) => sk.to_pkcs8_der(), SigningKey::CosmosAdr36(sk) => sk.to_pkcs8_der(), } - .map_err(|_| anyhow!("Creating PKCS8 DER failed")) + .map_err(|_| KeysError::DerCreationError) } - pub fn to_pkcs8_der(&self) -> Result> { + pub fn to_pkcs8_der(&self) -> Result, KeysError> { Ok(self.to_pkcs8_der_doc()?.as_bytes().to_vec()) } - pub fn to_pkcs8_pem_file(&self, filename: impl AsRef) -> Result<()> { + pub fn to_pkcs8_pem_file(&self, filename: impl AsRef) -> Result<(), KeysError> { self.to_pkcs8_der_doc()? .write_pem_file(filename, PrivateKeyInfo::PEM_LABEL, LineEnding::LF) - .map_err(|_| anyhow!("Creating PKCS8 PEM file failed")) + .map_err(|_| KeysError::PemCreationError) } - pub fn from_algorithm_and_bytes(algorithm: CryptoAlgorithm, bytes: &[u8]) -> Result { + pub fn from_algorithm_and_bytes( + algorithm: CryptoAlgorithm, + bytes: &[u8], + ) -> Result { match algorithm { - CryptoAlgorithm::Ed25519 => { - Ed25519SigningKey::try_from(bytes).map(SigningKey::Ed25519).map_err(|e| e.into()) - } + CryptoAlgorithm::Ed25519 => Ed25519SigningKey::try_from(bytes) + .map(SigningKey::Ed25519) + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), CryptoAlgorithm::Secp256k1 => Secp256k1SigningKey::from_slice(bytes) .map(SigningKey::Secp256k1) - .map_err(|e| e.into()), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), CryptoAlgorithm::Secp256r1 => Secp256r1SigningKey::from_slice(bytes) .map(SigningKey::Secp256r1) - .map_err(|e| e.into()), - CryptoAlgorithm::Eip191 => { - Secp256k1SigningKey::from_slice(bytes).map(SigningKey::Eip191).map_err(|e| e.into()) - } + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + CryptoAlgorithm::Eip191 => Secp256k1SigningKey::from_slice(bytes) + .map(SigningKey::Eip191) + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), CryptoAlgorithm::CosmosAdr36 => Secp256k1SigningKey::from_slice(bytes) .map(SigningKey::CosmosAdr36) - .map_err(|e| e.into()), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), } } - pub fn from_pkcs8_der_doc(doc: &Document) -> Result { + pub fn from_pkcs8_der_doc(doc: &Document) -> Result { let value = doc.as_bytes(); - let pk_info = PrivateKeyInfo::try_from(value)?; - let algorithm = CryptoAlgorithm::try_from(pk_info.algorithm) - .map_err(|_| anyhow!("Unable to parse key algorithm from PKCS#8 der"))?; + let pk_info = PrivateKeyInfo::try_from(value).map_err(|_| KeysError::ParseError)?; + let algorithm = + CryptoAlgorithm::try_from(pk_info.algorithm).map_err(|_| KeysError::ParseError)?; match algorithm { CryptoAlgorithm::Ed25519 => { - let ed25519_key_pair_bytes = Ed25519KeypairBytes::try_from(pk_info)?; + let ed25519_key_pair_bytes = Ed25519KeypairBytes::try_from(pk_info) + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()))?; let ed25519_signing_key = Ed25519SigningKey::from(ed25519_key_pair_bytes.secret_key); Ok(SigningKey::Ed25519(ed25519_signing_key)) } CryptoAlgorithm::Secp256k1 => Secp256k1SigningKey::try_from(pk_info) .map(SigningKey::Secp256k1) - .map_err(|e| e.into()), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), CryptoAlgorithm::Secp256r1 => Secp256r1SigningKey::try_from(pk_info) .map(SigningKey::Secp256r1) - .map_err(|e| e.into()), - CryptoAlgorithm::Eip191 => { - Secp256k1SigningKey::try_from(pk_info).map(SigningKey::Eip191).map_err(|e| e.into()) - } + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + CryptoAlgorithm::Eip191 => Secp256k1SigningKey::try_from(pk_info) + .map(SigningKey::Eip191) + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), CryptoAlgorithm::CosmosAdr36 => Secp256k1SigningKey::try_from(pk_info) .map(SigningKey::CosmosAdr36) - .map_err(|e| e.into()), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), } } - pub fn from_pkcs8_der(bytes: &[u8]) -> Result { - let document = pkcs8::Document::from_der(bytes)?; + pub fn from_pkcs8_der(bytes: &[u8]) -> Result { + let document = pkcs8::Document::from_der(bytes).map_err(|_| KeysError::ParseError)?; Self::from_pkcs8_der_doc(&document) } - pub fn from_pkcs8_pem_file(file_path: impl AsRef) -> Result { - let (label, document) = pkcs8::Document::read_pem_file(file_path)?; - PrivateKeyInfo::validate_pem_label(&label).map_err(|_| anyhow!("Incorrect PEM label"))?; + pub fn from_pkcs8_pem_file(file_path: impl AsRef) -> Result { + let (label, document) = + pkcs8::Document::read_pem_file(file_path).map_err(|_| KeysError::ParseError)?; + PrivateKeyInfo::validate_pem_label(&label).map_err(|_| KeysError::PemLabelError)?; Self::from_pkcs8_der_doc(&document) } @@ -187,29 +192,38 @@ impl SigningKey { } } - pub fn sign(&self, message: impl AsRef<[u8]>) -> Result { + pub fn sign(&self, message: impl AsRef<[u8]>) -> Result { match self { SigningKey::Ed25519(sk) => Ok(Signature::Ed25519(sk.sign(message.as_ref()))), SigningKey::Secp256k1(sk) => { let mut digest = sha2::Sha256::new(); digest.update(message); - let sig: Secp256k1Signature = sk.try_sign_digest(digest)?; + let sig: Secp256k1Signature = sk + .try_sign_digest(digest) + .map_err(|e| KeysError::SigningError(e.to_string()))?; Ok(Signature::Secp256k1(sig)) } SigningKey::Secp256r1(sk) => { let mut digest = sha2::Sha256::new(); digest.update(message); - let sig: Secp256r1Signature = sk.try_sign_digest(digest)?; + let sig: Secp256r1Signature = sk + .try_sign_digest(digest) + .map_err(|e| KeysError::SigningError(e.to_string()))?; Ok(Signature::Secp256r1(sig)) } SigningKey::Eip191(sk) => { let message = eip191_hash_message(message); - let sig: Secp256k1Signature = sk.sign_prehash(message.as_slice())?; + let sig: Secp256k1Signature = sk + .sign_prehash(message.as_slice()) + .map_err(|e| KeysError::SigningError(e.to_string()))?; Ok(Signature::Secp256k1(sig)) } SigningKey::CosmosAdr36(sk) => { - let message = cosmos_adr36_hash_message(message, sk.verifying_key())?; - let sig: Secp256k1Signature = sk.sign_prehash(message.as_slice())?; + let message = cosmos_adr36_hash_message(message, sk.verifying_key()) + .map_err(|e| KeysError::SigningError(e.to_string()))?; + let sig: Secp256k1Signature = sk + .sign_prehash(message.as_slice()) + .map_err(|e| KeysError::SigningError(e.to_string()))?; Ok(Signature::Secp256k1(sig)) } } @@ -230,7 +244,7 @@ impl PartialEq for SigningKey { } impl TryFrom for SigningKey { - type Error = anyhow::Error; + type Error = KeysError; fn try_from(value: CryptoPayload) -> std::result::Result { SigningKey::from_algorithm_and_bytes(value.algorithm, &value.bytes) @@ -245,3 +259,19 @@ impl From for CryptoPayload { } } } + +#[derive(Error, Clone, Debug)] +pub enum KeysError { + #[error("creating PKCS8 DER failed")] + DerCreationError, + #[error("creating PKCS8 PEM failed")] + PemCreationError, + #[error("parsing key algorithm from PKCS#8 DER failed")] + ParseError, + #[error("invalid PEM label")] + PemLabelError, + #[error("invalid key bytes for algorithm {0}")] + InvalidKeyBytes(String), + #[error("signing operation failed {0}")] + SigningError(String), +} From 3b2dcfc820b939c8d99b8a56d13836cea3f0fccf Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Mon, 23 Jun 2025 15:15:04 +0200 Subject: [PATCH 02/10] Signatures error enums added --- crates/keys/src/signatures.rs | 63 ++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/crates/keys/src/signatures.rs b/crates/keys/src/signatures.rs index 32017e783..2733bf795 100644 --- a/crates/keys/src/signatures.rs +++ b/crates/keys/src/signatures.rs @@ -1,4 +1,3 @@ -use anyhow::{Result, bail}; use ed25519_consensus::Signature as Ed25519Signature; use k256::ecdsa::Signature as Secp256k1Signature; use p256::ecdsa::Signature as Secp256r1Signature; @@ -11,7 +10,9 @@ use serde::{Deserialize, Serialize}; use std::{ borrow::Cow, fmt::{Display, Formatter}, + result::Result, }; +use thiserror::Error; use utoipa::{ PartialSchema, ToSchema, openapi::{RefOr, Schema}, @@ -39,21 +40,22 @@ impl Signature { } } - pub fn from_algorithm_and_bytes(algorithm: CryptoAlgorithm, bytes: &[u8]) -> Result { + pub fn from_algorithm_and_bytes( + algorithm: CryptoAlgorithm, + bytes: &[u8], + ) -> Result { match algorithm { - CryptoAlgorithm::Ed25519 => { - Ed25519Signature::try_from(bytes).map(Signature::Ed25519).map_err(|e| e.into()) - } + CryptoAlgorithm::Ed25519 => Ed25519Signature::try_from(bytes) + .map(Signature::Ed25519) + .map_err(|e| SignatureError::AlgorithmError(e.to_string())), CryptoAlgorithm::Secp256k1 => Secp256k1Signature::from_slice(bytes) .map(Signature::Secp256k1) - .map_err(|e| e.into()), + .map_err(|e| SignatureError::AlgorithmError(e.to_string())), CryptoAlgorithm::Secp256r1 => Secp256r1Signature::from_slice(bytes) .map(Signature::Secp256r1) - .map_err(|e| e.into()), - CryptoAlgorithm::Eip191 => bail!("No EIP-191 specific signatures implemented"), - CryptoAlgorithm::CosmosAdr36 => { - bail!("No cosmos ADR-36 specific signatures implemented") - } + .map_err(|e| SignatureError::AlgorithmError(e.to_string())), + CryptoAlgorithm::Eip191 => Err(SignatureError::EipSignatureError), + CryptoAlgorithm::CosmosAdr36 => Err(SignatureError::AdrSignatureError), } } @@ -82,27 +84,36 @@ impl Signature { } } - pub fn to_prism_der(&self) -> Result> { + pub fn to_prism_der(&self) -> Result, SignatureError> { let signature_bytes = self.to_bytes(); let mut der_bytes = Vec::with_capacity(2 + signature_bytes.len()); der_bytes.push(0x04); // octet stream - der_bytes.push(signature_bytes.len().try_into()?); // length of signature bytes + der_bytes.push( + signature_bytes + .len() + .try_into() + .map_err(|_| SignatureError::AlgorithmError("Map conversion failed".to_string()))?, + ); // length of signature bytes der_bytes.extend_from_slice(&signature_bytes); let signature_info = SignatureInfoRef { algorithm: self.algorithm_identifier(), - signature: OctetStringRef::new(&der_bytes)?, + signature: OctetStringRef::new(&der_bytes) + .map_err(|e| SignatureError::AlgorithmError(e.to_string()))?, }; - let doc = SecretDocument::encode_msg(&signature_info)?; + let doc = SecretDocument::encode_msg(&signature_info) + .map_err(|e| SignatureError::AlgorithmError(e.to_string()))?; der_bytes.zeroize(); Ok(doc.as_bytes().to_vec()) } - pub fn from_prism_der(bytes: &[u8]) -> Result { - let signature_info = SignatureInfoRef::from_der(bytes)?; - let algorithm = CryptoAlgorithm::try_from(signature_info.algorithm)?; + pub fn from_prism_der(bytes: &[u8]) -> Result { + let signature_info = SignatureInfoRef::from_der(bytes) + .map_err(|e| SignatureError::AlgorithmError(e.to_string()))?; + let algorithm = CryptoAlgorithm::try_from(signature_info.algorithm) + .map_err(|e| SignatureError::AlgorithmError(e.to_string()))?; // Signature byte representation: // 1st byte: 0x04 (type OCTET STRING) @@ -112,13 +123,13 @@ impl Signature { [0x04, _, signature_bytes @ ..] => { Signature::from_algorithm_and_bytes(algorithm, signature_bytes) } - _ => bail!("Malformed signature"), + _ => Err(SignatureError::MalformedSignError), } } } impl TryFrom for Signature { - type Error = anyhow::Error; + type Error = SignatureError; fn try_from(value: CryptoPayload) -> std::result::Result { Signature::from_algorithm_and_bytes(value.algorithm, &value.bytes) @@ -159,3 +170,15 @@ impl PartialSchema for Signature { CryptoPayload::schema() } } + +#[derive(Error, Clone, Debug)] +pub enum SignatureError { + #[error("No EIP-191 specific signatures implemented")] + EipSignatureError, + #[error("No ADR-36 specific signatures implemented")] + AdrSignatureError, + #[error("malformed signature")] + MalformedSignError, + #[error("Algorithm Error {0}")] + AlgorithmError(String), +} From e6aea3a850529256add160f6f56d351ee9aeb328 Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Tue, 24 Jun 2025 12:06:38 +0200 Subject: [PATCH 03/10] verifiying_keys.rs error enums created --- crates/keys/src/verifying_keys.rs | 182 +++++++++++++++++++++--------- 1 file changed, 129 insertions(+), 53 deletions(-) diff --git a/crates/keys/src/verifying_keys.rs b/crates/keys/src/verifying_keys.rs index 109203551..bc22db585 100644 --- a/crates/keys/src/verifying_keys.rs +++ b/crates/keys/src/verifying_keys.rs @@ -1,5 +1,4 @@ use alloy_primitives::eip191_hash_message; -use anyhow::{Result, anyhow, bail}; use ed25519::PublicKeyBytes as Ed25519PublicKeyBytes; use ed25519_consensus::VerificationKey as Ed25519VerifyingKey; use k256::ecdsa::VerifyingKey as Secp256k1VerifyingKey; @@ -21,7 +20,9 @@ use std::{ borrow::Cow, hash::{Hash, Hasher}, path::Path, + result::Result, }; +use thiserror::Error; use utoipa::{ PartialSchema, ToSchema, openapi::{RefOr, Schema}, @@ -88,23 +89,32 @@ impl VerifyingKey { } } - pub fn from_algorithm_and_bytes(algorithm: CryptoAlgorithm, bytes: &[u8]) -> Result { + pub fn from_algorithm_and_bytes( + algorithm: CryptoAlgorithm, + bytes: &[u8], + ) -> Result { match algorithm { CryptoAlgorithm::Ed25519 => Ed25519VerifyingKey::try_from(bytes) .map(VerifyingKey::Ed25519) - .map_err(|e| e.into()), - CryptoAlgorithm::Secp256k1 => Secp256k1VerifyingKey::from_sec1_bytes(bytes) - .map(VerifyingKey::Secp256k1) - .map_err(|e| e.into()), - CryptoAlgorithm::Secp256r1 => Secp256r1VerifyingKey::from_sec1_bytes(bytes) - .map(VerifyingKey::Secp256r1) - .map_err(|e| e.into()), + .map_err(|e| VerificationError::VerifyError("ed25519".to_string(), e.to_string())), + CryptoAlgorithm::Secp256k1 => { + Secp256k1VerifyingKey::from_sec1_bytes(bytes).map(VerifyingKey::Secp256k1).map_err( + |e| VerificationError::VerifyError("secp256k1".to_string(), e.to_string()), + ) + } + CryptoAlgorithm::Secp256r1 => { + Secp256r1VerifyingKey::from_sec1_bytes(bytes).map(VerifyingKey::Secp256r1).map_err( + |e| VerificationError::VerifyError("secp256r1".to_string(), e.to_string()), + ) + } CryptoAlgorithm::Eip191 => Secp256k1VerifyingKey::from_sec1_bytes(bytes) .map(VerifyingKey::Eip191) - .map_err(|e| e.into()), + .map_err(|e| VerificationError::VerifyError("eip191".to_string(), e.to_string())), CryptoAlgorithm::CosmosAdr36 => Secp256k1VerifyingKey::from_sec1_bytes(bytes) .map(VerifyingKey::CosmosAdr36) - .map_err(|e| e.into()), + .map_err(|e| { + VerificationError::VerifyError("cosmos adr36".to_string(), e.to_string()) + }), } } @@ -118,117 +128,160 @@ impl VerifyingKey { } } - pub fn verify_signature(&self, message: impl AsRef<[u8]>, signature: &Signature) -> Result<()> { + pub fn verify_signature( + &self, + message: impl AsRef<[u8]>, + signature: &Signature, + ) -> Result<(), VerificationError> { match self { VerifyingKey::Ed25519(vk) => { let Signature::Ed25519(signature) = signature else { - bail!("Invalid signature type"); + return Err(VerificationError::InvalidSignError); }; - vk.verify(signature, message.as_ref()) - .map_err(|e| anyhow!("Failed to verify ed25519 signature: {}", e)) + vk.verify(signature, message.as_ref()).map_err(|e| { + VerificationError::VerifyError("ed25519".to_string(), e.to_string()) + }) } VerifyingKey::Secp256k1(vk) => { let Signature::Secp256k1(signature) = signature else { - bail!("Invalid signature type"); + return Err(VerificationError::InvalidSignError); }; let mut digest = sha2::Sha256::new(); digest.update(message); vk.verify_digest(digest, signature) - .map_err(|e| anyhow!("Failed to verify secp256k1 signature: {}", e)) + // .map_err(|e| anyhow!("Failed to verify secp256k1 signature: {}", e)) + .map_err(|e| { + VerificationError::VerifyError("secp256k1".to_string(), e.to_string()) + }) } VerifyingKey::Secp256r1(vk) => { let Signature::Secp256r1(signature) = signature else { - bail!("Invalid signature type"); + return Err(VerificationError::InvalidSignError); }; let mut digest = sha2::Sha256::new(); digest.update(message); vk.verify_digest(digest, signature) - .map_err(|e| anyhow!("Failed to verify secp256r1 signature: {}", e)) + // .map_err(|e| anyhow!("Failed to verify secp256r1 signature: {}", e)) + .map_err(|e| { + VerificationError::VerifyError("secp256r1".to_string(), e.to_string()) + }) } VerifyingKey::Eip191(vk) => { let Signature::Secp256k1(signature) = signature else { - bail!("Verifying key for EIP-191 can only verify secp256k1 signatures"); + return Err(VerificationError::SignatureError("EIP-191".to_string())); }; let prehash = eip191_hash_message(message); - vk.verify_prehash(prehash.as_slice(), signature) - .map_err(|e| anyhow!("Failed to verify EIP-191 signature: {}", e)) + vk.verify_prehash(prehash.as_slice(), signature).map_err(|e| { + VerificationError::VerifyError("EIP-191".to_string(), e.to_string()) + }) } VerifyingKey::CosmosAdr36(vk) => { let Signature::Secp256k1(signature) = signature else { - bail!("Verifying key for cosmos ADR-36 can only verify secp256k1 signatures"); + return Err(VerificationError::SignatureError( + "cosmos ADR-36".to_string(), + )); }; - let prehash = cosmos_adr36_hash_message(message, vk)?; - vk.verify_prehash(&prehash, signature) - .map_err(|e| anyhow!("Failed to verify cosmos ADR-36 signature: {}", e)) + let prehash = cosmos_adr36_hash_message(message, vk) + .map_err(|e| VerificationError::GeneralError(e.to_string()))?; + vk.verify_prehash(&prehash, signature).map_err(|e| { + VerificationError::VerifyError("cosmos ADR-36".to_string(), e.to_string()) + }) } } } - fn to_spki_der_doc(&self) -> Result { + fn to_spki_der_doc(&self) -> Result { match self { VerifyingKey::Ed25519(vk) => Ed25519PublicKeyBytes(vk.to_bytes()).to_public_key_der(), VerifyingKey::Secp256k1(vk) => vk.to_public_key_der(), VerifyingKey::Secp256r1(vk) => vk.to_public_key_der(), - VerifyingKey::Eip191(_) => bail!("EIP-191 vk to DER format is not implemented"), + VerifyingKey::Eip191(_) => { + return Err(VerificationError::NotImplementedError( + "EIP-191".to_string(), + "to".to_string(), + )); + } VerifyingKey::CosmosAdr36(_) => { - bail!("Cosmos ADR-36 vk to DER format is not implemented") + return Err(VerificationError::NotImplementedError( + "cosmos ADR-36".to_string(), + "to".to_string(), + )); } } - .map_err(|_| anyhow!("Creating SPKI DER failed")) + .map_err(|_| VerificationError::GeneralError("creating SPKI DER failed".to_string())) } - pub fn to_spki_der(&self) -> Result> { + pub fn to_spki_der(&self) -> Result, VerificationError> { Ok(self.to_spki_der_doc()?.as_bytes().to_vec()) } - pub fn to_spki_pem_file(&self, filename: impl AsRef) -> Result<()> { + pub fn to_spki_pem_file(&self, filename: impl AsRef) -> Result<(), VerificationError> { self.to_spki_der_doc()? .write_pem_file(filename, SubjectPublicKeyInfoRef::PEM_LABEL, LineEnding::LF) - .map_err(|_| anyhow!("Creating PKCS8 PEM file failed")) + .map_err(|_| VerificationError::CreationError("PKCS8 PEM file".to_string())) } - fn from_spki(spki: SubjectPublicKeyInfoRef) -> Result { - let algorithm = CryptoAlgorithm::try_from(spki.algorithm)?; + fn from_spki(spki: SubjectPublicKeyInfoRef) -> Result { + let algorithm = CryptoAlgorithm::try_from(spki.algorithm) + .map_err(|e| VerificationError::GeneralError(e.to_string()))?; match algorithm { CryptoAlgorithm::Ed25519 => { - let ed25519_spki = Ed25519PublicKeyBytes::try_from(spki)?; - let ed25519_key = Ed25519VerifyingKey::try_from(ed25519_spki.as_ref() as &[u8])?; + let ed25519_spki = Ed25519PublicKeyBytes::try_from(spki) + .map_err(|e| VerificationError::GeneralError(e.to_string()))?; + let ed25519_key = Ed25519VerifyingKey::try_from(ed25519_spki.as_ref() as &[u8]) + .map_err(|e| { + VerificationError::IntoRefError("ed25519".to_string(), e.to_string()) + })?; Ok(VerifyingKey::Ed25519(ed25519_key)) } CryptoAlgorithm::Secp256k1 => { - let secp256k1_key = Secp256k1VerifyingKey::try_from(spki)?; + let secp256k1_key = Secp256k1VerifyingKey::try_from(spki).map_err(|e| { + VerificationError::IntoRefError("secp256k1".to_string(), e.to_string()) + })?; Ok(VerifyingKey::Secp256k1(secp256k1_key)) } CryptoAlgorithm::Secp256r1 => { - let secp256r1_key = Secp256r1VerifyingKey::try_from(spki)?; + let secp256r1_key = Secp256r1VerifyingKey::try_from(spki).map_err(|e| { + VerificationError::IntoRefError("secp256r1".to_string(), e.to_string()) + })?; Ok(VerifyingKey::Secp256r1(secp256r1_key)) } - CryptoAlgorithm::Eip191 => bail!("Eth vk from DER format is not implemented"), + CryptoAlgorithm::Eip191 => { + return Err(VerificationError::NotImplementedError( + "Eth".to_string(), + "from".to_string(), + )); + } CryptoAlgorithm::CosmosAdr36 => { - bail!("Cosmos ADR-36 vk from DER format is not implemented") + return Err(VerificationError::NotImplementedError( + "Cosmos ADR-36".to_string(), + "from".to_string(), + )); } } } - pub fn from_spki_der(bytes: &[u8]) -> Result { - let spki = SubjectPublicKeyInfoRef::from_der(bytes)?; + pub fn from_spki_der(bytes: &[u8]) -> Result { + let spki = SubjectPublicKeyInfoRef::from_der(bytes) + .map_err(|e| VerificationError::GeneralError(e.to_string()))?; Self::from_spki(spki) } - pub fn from_spki_pem_file(filename: impl AsRef) -> Result { - let (label, doc) = Document::read_pem_file(filename)?; + pub fn from_spki_pem_file(filename: impl AsRef) -> Result { + let (label, doc) = Document::read_pem_file(filename) + .map_err(|e| VerificationError::GeneralError(e.to_string()))?; SubjectPublicKeyInfoRef::validate_pem_label(&label) - .map_err(|_| anyhow!("Incorrect PEM label"))?; + .map_err(|_| VerificationError::GeneralError("Incorrect PEM label".to_string()))?; Self::from_spki_der(doc.as_bytes()) } } impl TryFrom for VerifyingKey { - type Error = anyhow::Error; + type Error = VerificationError; fn try_from(value: CryptoPayload) -> std::result::Result { VerifyingKey::from_algorithm_and_bytes(value.algorithm, &value.bytes) @@ -257,24 +310,28 @@ impl From for VerifyingKey { } impl FromBase64 for VerifyingKey { - type Error = anyhow::Error; + type Error = VerificationError; fn from_base64>(base64: T) -> Result { - let bytes = Vec::::from_base64(base64)?; + let bytes = Vec::::from_base64(base64) + .map_err(|e| (VerificationError::GeneralError(e.to_string())))?; match bytes.len() { 32 => { - let vk = Ed25519VerifyingKey::try_from(bytes.as_slice()) - .map_err(|e| anyhow!("Invalid Ed25519 key: {}", e))?; + let vk = Ed25519VerifyingKey::try_from(bytes.as_slice()).map_err(|e| { + VerificationError::GeneralError(format!("invalid ed25519 key: {}", e)) + })?; Ok(VerifyingKey::Ed25519(vk)) } - _ => Err(anyhow!("Only Ed25519 keys can be initialized from base64")), + _ => Err(VerificationError::GeneralError( + "Only Ed25519 keys can be initialized from base64".to_string(), + )), } } } impl TryFrom for VerifyingKey { - type Error = anyhow::Error; + type Error = VerificationError; fn try_from(s: String) -> std::result::Result { Self::from_base64(s) @@ -306,3 +363,22 @@ impl PartialSchema for VerifyingKey { CryptoPayload::schema() } } + +#[derive(Error, Clone, Debug)] +pub enum VerificationError { + #[error("invalid signature type")] + InvalidSignError, + #[error("failed to verify {0} signature: {1}")] + VerifyError(String, String), + #[error("verifying key for {0} can only verify secp256k1 signatures")] + SignatureError(String), + #[error("creating {0} failed")] + CreationError(String), + #[error("{0} vk from DER format failed: {1}")] + IntoRefError(String, String), + #[error("{0} vk {1} DER format is not implemented")] + NotImplementedError(String, String), + + #[error("something went wrong {0}")] + GeneralError(String), +} From 8aa684657eff18d7771eb5828c4c8a1d5d85a3bd Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Tue, 24 Jun 2025 12:39:37 +0200 Subject: [PATCH 04/10] cleaned-up and removed anyhow from keys --- Cargo.lock | 1 - crates/keys/Cargo.toml | 1 - crates/keys/src/algorithm.rs | 22 +++++++++++++++++----- crates/keys/src/cosmos.rs | 28 +++++++++++++++++++++------- crates/keys/src/verifying_keys.rs | 21 ++++++++------------- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 90d067044..d99cf38d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7037,7 +7037,6 @@ name = "prism-keys" version = "0.1.0" dependencies = [ "alloy-primitives", - "anyhow", "ed25519", "ed25519-consensus", "getrandom 0.2.16", diff --git a/crates/keys/Cargo.toml b/crates/keys/Cargo.toml index fc8de78ba..44cd2b997 100644 --- a/crates/keys/Cargo.toml +++ b/crates/keys/Cargo.toml @@ -27,7 +27,6 @@ alloy-primitives.workspace = true ripemd.workspace = true # misc -anyhow.workspace = true sha2.workspace = true thiserror.workspace = true diff --git a/crates/keys/src/algorithm.rs b/crates/keys/src/algorithm.rs index 49181198c..2d55443a3 100644 --- a/crates/keys/src/algorithm.rs +++ b/crates/keys/src/algorithm.rs @@ -1,6 +1,6 @@ -use anyhow::bail; use pkcs8::{AlgorithmIdentifierRef, ObjectIdentifier}; use serde::{Deserialize, Serialize}; +use thiserror::Error; use utoipa::ToSchema; #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, ToSchema)] @@ -60,7 +60,7 @@ pub const SECP256K1_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.13 pub const SECP256R1_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7"); impl<'a> TryFrom> for CryptoAlgorithm { - type Error = anyhow::Error; + type Error = AlgorithmError; fn try_from(algorithm_identifier: AlgorithmIdentifierRef<'a>) -> Result { let oid = algorithm_identifier.oid; @@ -68,16 +68,28 @@ impl<'a> TryFrom> for CryptoAlgorithm { if oid == ED25519_OID { Ok(CryptoAlgorithm::Ed25519) } else if oid == ELLIPTIC_CURVE_OID || oid == ECDSA_SHA256_OID { - let parameter_oid = algorithm_identifier.parameters_oid()?; + let parameter_oid = algorithm_identifier + .parameters_oid() + .map_err(|e| AlgorithmError::GeneralError(e.to_string()))?; if parameter_oid == SECP256K1_OID { Ok(CryptoAlgorithm::Secp256k1) } else if parameter_oid == SECP256R1_OID { Ok(CryptoAlgorithm::Secp256r1) } else { - bail!("Unsupported elliptic curve OID") + return Err(AlgorithmError::GeneralError( + "Unsupported elliptic curve OID".to_string(), + )); } } else { - bail!("Unsupported algorithm OID") + return Err(AlgorithmError::GeneralError( + "Unsupported algorithm OID".to_string(), + )); } } } + +#[derive(Error, Clone, Debug)] +pub enum AlgorithmError { + #[error("error: {0}")] + GeneralError(String), +} diff --git a/crates/keys/src/cosmos.rs b/crates/keys/src/cosmos.rs index 3e557d805..6381438e9 100644 --- a/crates/keys/src/cosmos.rs +++ b/crates/keys/src/cosmos.rs @@ -1,9 +1,10 @@ -use anyhow::Result; use k256::ecdsa::VerifyingKey as Secp256k1VerifyingKey; use prism_serde::{bech32::ToBech32, raw_or_b64}; use ripemd::Ripemd160; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; +use std::result::Result; +use thiserror::Error; #[derive(Serialize, Deserialize)] struct CosmosSignDoc { @@ -68,14 +69,15 @@ impl CosmosSignDoc { pub fn cosmos_adr36_hash_message( message: impl AsRef<[u8]>, verifying_key: &Secp256k1VerifyingKey, -) -> Result> { +) -> Result, CosmosError> { // TODO: Support arbitrary address prefixes // At the moment we expect users to use "cosmoshub-4" as chainId when // signing prism data via `signArbitrary(..)`, resulting in "cosmos" as address prefix const ADDRESS_PREFIX: &str = "cosmos"; let signer = signer_from_key(ADDRESS_PREFIX, verifying_key)?; - let serialized_sign_doc = create_serialized_adr36_sign_doc(message.as_ref().to_vec(), signer)?; + let serialized_sign_doc = create_serialized_adr36_sign_doc(message.as_ref().to_vec(), signer) + .map_err(|e| CosmosError::GeneralError(e.to_string()))?; let hashed_sign_doc = Sha256::digest(&serialized_sign_doc).to_vec(); Ok(hashed_sign_doc) } @@ -92,10 +94,11 @@ pub fn cosmos_adr36_hash_message( /// /// # Returns /// * `Result>` - The serialized sign document as bytes or an error -fn create_serialized_adr36_sign_doc(data: Vec, signer: String) -> Result> { +fn create_serialized_adr36_sign_doc(data: Vec, signer: String) -> Result, CosmosError> { let adr36_sign_doc = CosmosSignDoc::new(signer, data); - let sign_doc_str = serde_json::to_string(&adr36_sign_doc)? + let sign_doc_str = serde_json::to_string(&adr36_sign_doc) + .map_err(|e| CosmosError::GeneralError(e.to_string()))? .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("&", "\\u0026"); @@ -116,11 +119,22 @@ fn create_serialized_adr36_sign_doc(data: Vec, signer: String) -> Result` - The bech32-encoded address or an error -fn signer_from_key(address_prefix: &str, verifying_key: &Secp256k1VerifyingKey) -> Result { +fn signer_from_key( + address_prefix: &str, + verifying_key: &Secp256k1VerifyingKey, +) -> Result { let verifying_key_bytes = verifying_key.to_sec1_bytes(); let hashed_key_bytes = Sha256::digest(verifying_key_bytes); let cosmos_address = Ripemd160::digest(hashed_key_bytes); - let signer = cosmos_address.to_bech32(address_prefix)?; + let signer = cosmos_address + .to_bech32(address_prefix) + .map_err(|e| CosmosError::GeneralError(e.to_string()))?; Ok(signer) } + +#[derive(Error, Clone, Debug)] +pub enum CosmosError { + #[error("something went wrong: {0}")] + GeneralError(String), +} diff --git a/crates/keys/src/verifying_keys.rs b/crates/keys/src/verifying_keys.rs index bc22db585..868bd7617 100644 --- a/crates/keys/src/verifying_keys.rs +++ b/crates/keys/src/verifying_keys.rs @@ -250,18 +250,14 @@ impl VerifyingKey { })?; Ok(VerifyingKey::Secp256r1(secp256r1_key)) } - CryptoAlgorithm::Eip191 => { - return Err(VerificationError::NotImplementedError( - "Eth".to_string(), - "from".to_string(), - )); - } - CryptoAlgorithm::CosmosAdr36 => { - return Err(VerificationError::NotImplementedError( - "Cosmos ADR-36".to_string(), - "from".to_string(), - )); - } + CryptoAlgorithm::Eip191 => Err(VerificationError::NotImplementedError( + "Eth".to_string(), + "from".to_string(), + )), + CryptoAlgorithm::CosmosAdr36 => Err(VerificationError::NotImplementedError( + "Cosmos ADR-36".to_string(), + "from".to_string(), + )), } } @@ -378,7 +374,6 @@ pub enum VerificationError { IntoRefError(String, String), #[error("{0} vk {1} DER format is not implemented")] NotImplementedError(String, String), - #[error("something went wrong {0}")] GeneralError(String), } From 49c14a55c418ec7cec43d40b36d4d064378a0154 Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Wed, 25 Jun 2025 11:58:04 +0200 Subject: [PATCH 05/10] Added errors.rs file to keys --- Cargo.lock | 2 +- crates/keys/src/algorithm.rs | 16 ++++------ crates/keys/src/cosmos.rs | 24 +++++++-------- crates/keys/src/errors.rs | 49 +++++++++++++++++++++++++++++++ crates/keys/src/lib.rs | 1 + crates/keys/src/signatures.rs | 14 +-------- crates/keys/src/signing_keys.rs | 18 +----------- crates/keys/src/verifying_keys.rs | 36 +++++------------------ 8 files changed, 76 insertions(+), 84 deletions(-) create mode 100644 crates/keys/src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index d99cf38d9..2dca99033 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2311,7 +2311,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.102", ] [[package]] diff --git a/crates/keys/src/algorithm.rs b/crates/keys/src/algorithm.rs index 2d55443a3..c9b1546d1 100644 --- a/crates/keys/src/algorithm.rs +++ b/crates/keys/src/algorithm.rs @@ -1,6 +1,6 @@ +use crate::errors::SignatureError; use pkcs8::{AlgorithmIdentifierRef, ObjectIdentifier}; use serde::{Deserialize, Serialize}; -use thiserror::Error; use utoipa::ToSchema; #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, ToSchema)] @@ -60,7 +60,7 @@ pub const SECP256K1_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.13 pub const SECP256R1_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7"); impl<'a> TryFrom> for CryptoAlgorithm { - type Error = AlgorithmError; + type Error = SignatureError; fn try_from(algorithm_identifier: AlgorithmIdentifierRef<'a>) -> Result { let oid = algorithm_identifier.oid; @@ -70,26 +70,20 @@ impl<'a> TryFrom> for CryptoAlgorithm { } else if oid == ELLIPTIC_CURVE_OID || oid == ECDSA_SHA256_OID { let parameter_oid = algorithm_identifier .parameters_oid() - .map_err(|e| AlgorithmError::GeneralError(e.to_string()))?; + .map_err(|e| SignatureError::AlgorithmError(e.to_string()))?; if parameter_oid == SECP256K1_OID { Ok(CryptoAlgorithm::Secp256k1) } else if parameter_oid == SECP256R1_OID { Ok(CryptoAlgorithm::Secp256r1) } else { - return Err(AlgorithmError::GeneralError( + return Err(SignatureError::AlgorithmError( "Unsupported elliptic curve OID".to_string(), )); } } else { - return Err(AlgorithmError::GeneralError( + return Err(SignatureError::AlgorithmError( "Unsupported algorithm OID".to_string(), )); } } } - -#[derive(Error, Clone, Debug)] -pub enum AlgorithmError { - #[error("error: {0}")] - GeneralError(String), -} diff --git a/crates/keys/src/cosmos.rs b/crates/keys/src/cosmos.rs index 6381438e9..de41d5782 100644 --- a/crates/keys/src/cosmos.rs +++ b/crates/keys/src/cosmos.rs @@ -4,7 +4,8 @@ use ripemd::Ripemd160; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use std::result::Result; -use thiserror::Error; + +use crate::errors::SignatureError; #[derive(Serialize, Deserialize)] struct CosmosSignDoc { @@ -69,7 +70,7 @@ impl CosmosSignDoc { pub fn cosmos_adr36_hash_message( message: impl AsRef<[u8]>, verifying_key: &Secp256k1VerifyingKey, -) -> Result, CosmosError> { +) -> Result, SignatureError> { // TODO: Support arbitrary address prefixes // At the moment we expect users to use "cosmoshub-4" as chainId when // signing prism data via `signArbitrary(..)`, resulting in "cosmos" as address prefix @@ -77,7 +78,7 @@ pub fn cosmos_adr36_hash_message( let signer = signer_from_key(ADDRESS_PREFIX, verifying_key)?; let serialized_sign_doc = create_serialized_adr36_sign_doc(message.as_ref().to_vec(), signer) - .map_err(|e| CosmosError::GeneralError(e.to_string()))?; + .map_err(|e| SignatureError::CosmosError(e.to_string()))?; let hashed_sign_doc = Sha256::digest(&serialized_sign_doc).to_vec(); Ok(hashed_sign_doc) } @@ -94,11 +95,14 @@ pub fn cosmos_adr36_hash_message( /// /// # Returns /// * `Result>` - The serialized sign document as bytes or an error -fn create_serialized_adr36_sign_doc(data: Vec, signer: String) -> Result, CosmosError> { +fn create_serialized_adr36_sign_doc( + data: Vec, + signer: String, +) -> Result, SignatureError> { let adr36_sign_doc = CosmosSignDoc::new(signer, data); let sign_doc_str = serde_json::to_string(&adr36_sign_doc) - .map_err(|e| CosmosError::GeneralError(e.to_string()))? + .map_err(|e| SignatureError::CosmosError(e.to_string()))? .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("&", "\\u0026"); @@ -122,19 +126,13 @@ fn create_serialized_adr36_sign_doc(data: Vec, signer: String) -> Result Result { +) -> Result { let verifying_key_bytes = verifying_key.to_sec1_bytes(); let hashed_key_bytes = Sha256::digest(verifying_key_bytes); let cosmos_address = Ripemd160::digest(hashed_key_bytes); let signer = cosmos_address .to_bech32(address_prefix) - .map_err(|e| CosmosError::GeneralError(e.to_string()))?; + .map_err(|e| SignatureError::CosmosError(e.to_string()))?; Ok(signer) } - -#[derive(Error, Clone, Debug)] -pub enum CosmosError { - #[error("something went wrong: {0}")] - GeneralError(String), -} diff --git a/crates/keys/src/errors.rs b/crates/keys/src/errors.rs new file mode 100644 index 000000000..6e72191c3 --- /dev/null +++ b/crates/keys/src/errors.rs @@ -0,0 +1,49 @@ +use thiserror::Error; + +#[derive(Error, Clone, Debug)] +pub enum SignatureError { + #[error("No EIP-191 specific signatures implemented")] + EipSignatureError, + #[error("No ADR-36 specific signatures implemented")] + AdrSignatureError, + #[error("Malformed signature")] + MalformedSignError, + #[error("Algorithm Error: {0}")] + AlgorithmError(String), + #[error("something went wrong: {0}")] + CosmosError(String), +} + +#[derive(Error, Clone, Debug)] +pub enum KeysError { + #[error("Creating PKCS8 DER failed")] + DerCreationError, + #[error("Creating PKCS8 PEM failed")] + PemCreationError, + #[error("Parsing key algorithm from PKCS#8 DER failed")] + ParseError, + #[error("Invalid PEM label")] + PemLabelError, + #[error("Invalid key bytes for algorithm: {0}")] + InvalidKeyBytes(String), + #[error("Signing operation failed: {0}")] + SigningError(String), +} + +#[derive(Error, Clone, Debug)] +pub enum VerificationError { + #[error("Invalid signature type")] + InvalidSignError, + #[error("Failed to verify {0} signature: {1}")] + VerifyError(String, String), + #[error("Verifying key for {0} can only verify secp256k1 signatures")] + SignatureError(String), + #[error("Creating {0} failed")] + CreationError(String), + #[error("{0} vk from DER format failed: {1}")] + IntoRefError(String, String), + #[error("{0} vk {1} DER format is not implemented")] + NotImplementedError(String, String), + #[error("Something went wrong: {0}")] + GeneralError(String), +} diff --git a/crates/keys/src/lib.rs b/crates/keys/src/lib.rs index 68667829a..55c8f1908 100644 --- a/crates/keys/src/lib.rs +++ b/crates/keys/src/lib.rs @@ -1,6 +1,7 @@ mod algorithm; mod cosmos; mod der; +pub mod errors; mod payload; mod signatures; mod signing_keys; diff --git a/crates/keys/src/signatures.rs b/crates/keys/src/signatures.rs index 2733bf795..513979530 100644 --- a/crates/keys/src/signatures.rs +++ b/crates/keys/src/signatures.rs @@ -1,3 +1,4 @@ +use crate::errors::SignatureError; use ed25519_consensus::Signature as Ed25519Signature; use k256::ecdsa::Signature as Secp256k1Signature; use p256::ecdsa::Signature as Secp256r1Signature; @@ -12,7 +13,6 @@ use std::{ fmt::{Display, Formatter}, result::Result, }; -use thiserror::Error; use utoipa::{ PartialSchema, ToSchema, openapi::{RefOr, Schema}, @@ -170,15 +170,3 @@ impl PartialSchema for Signature { CryptoPayload::schema() } } - -#[derive(Error, Clone, Debug)] -pub enum SignatureError { - #[error("No EIP-191 specific signatures implemented")] - EipSignatureError, - #[error("No ADR-36 specific signatures implemented")] - AdrSignatureError, - #[error("malformed signature")] - MalformedSignError, - #[error("Algorithm Error {0}")] - AlgorithmError(String), -} diff --git a/crates/keys/src/signing_keys.rs b/crates/keys/src/signing_keys.rs index 6ff77b939..1af1bc995 100644 --- a/crates/keys/src/signing_keys.rs +++ b/crates/keys/src/signing_keys.rs @@ -1,3 +1,4 @@ +use crate::errors::KeysError; use alloy_primitives::eip191_hash_message; use ed25519::{ PublicKeyBytes as Ed25519PublicKeyBytes, pkcs8::KeypairBytes as Ed25519KeypairBytes, @@ -13,7 +14,6 @@ use pkcs8::{ der::{Decode, pem::PemLabel}, }; use std::{path::Path, result::Result}; -use thiserror::Error; use sha2::Digest as _; @@ -259,19 +259,3 @@ impl From for CryptoPayload { } } } - -#[derive(Error, Clone, Debug)] -pub enum KeysError { - #[error("creating PKCS8 DER failed")] - DerCreationError, - #[error("creating PKCS8 PEM failed")] - PemCreationError, - #[error("parsing key algorithm from PKCS#8 DER failed")] - ParseError, - #[error("invalid PEM label")] - PemLabelError, - #[error("invalid key bytes for algorithm {0}")] - InvalidKeyBytes(String), - #[error("signing operation failed {0}")] - SigningError(String), -} diff --git a/crates/keys/src/verifying_keys.rs b/crates/keys/src/verifying_keys.rs index 868bd7617..38a96726f 100644 --- a/crates/keys/src/verifying_keys.rs +++ b/crates/keys/src/verifying_keys.rs @@ -1,3 +1,4 @@ +use crate::errors::VerificationError; use alloy_primitives::eip191_hash_message; use ed25519::PublicKeyBytes as Ed25519PublicKeyBytes; use ed25519_consensus::VerificationKey as Ed25519VerifyingKey; @@ -22,7 +23,6 @@ use std::{ path::Path, result::Result, }; -use thiserror::Error; use utoipa::{ PartialSchema, ToSchema, openapi::{RefOr, Schema}, @@ -150,11 +150,9 @@ impl VerifyingKey { let mut digest = sha2::Sha256::new(); digest.update(message); - vk.verify_digest(digest, signature) - // .map_err(|e| anyhow!("Failed to verify secp256k1 signature: {}", e)) - .map_err(|e| { - VerificationError::VerifyError("secp256k1".to_string(), e.to_string()) - }) + vk.verify_digest(digest, signature).map_err(|e| { + VerificationError::VerifyError("secp256k1".to_string(), e.to_string()) + }) } VerifyingKey::Secp256r1(vk) => { let Signature::Secp256r1(signature) = signature else { @@ -163,11 +161,9 @@ impl VerifyingKey { let mut digest = sha2::Sha256::new(); digest.update(message); - vk.verify_digest(digest, signature) - // .map_err(|e| anyhow!("Failed to verify secp256r1 signature: {}", e)) - .map_err(|e| { - VerificationError::VerifyError("secp256r1".to_string(), e.to_string()) - }) + vk.verify_digest(digest, signature).map_err(|e| { + VerificationError::VerifyError("secp256r1".to_string(), e.to_string()) + }) } VerifyingKey::Eip191(vk) => { let Signature::Secp256k1(signature) = signature else { @@ -359,21 +355,3 @@ impl PartialSchema for VerifyingKey { CryptoPayload::schema() } } - -#[derive(Error, Clone, Debug)] -pub enum VerificationError { - #[error("invalid signature type")] - InvalidSignError, - #[error("failed to verify {0} signature: {1}")] - VerifyError(String, String), - #[error("verifying key for {0} can only verify secp256k1 signatures")] - SignatureError(String), - #[error("creating {0} failed")] - CreationError(String), - #[error("{0} vk from DER format failed: {1}")] - IntoRefError(String, String), - #[error("{0} vk {1} DER format is not implemented")] - NotImplementedError(String, String), - #[error("something went wrong {0}")] - GeneralError(String), -} From d9c350e6169fb4f2c791fa6186825762d44b1d79 Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Thu, 26 Jun 2025 10:53:25 +0200 Subject: [PATCH 06/10] CryptoErrors setup and verifying_keys implemented it --- crates/keys/src/errors.rs | 17 +++- crates/keys/src/lib.rs | 1 + crates/keys/src/verifying_keys.rs | 134 ++++++++++++++++-------------- 3 files changed, 88 insertions(+), 64 deletions(-) diff --git a/crates/keys/src/errors.rs b/crates/keys/src/errors.rs index 6e72191c3..3a038e823 100644 --- a/crates/keys/src/errors.rs +++ b/crates/keys/src/errors.rs @@ -1,5 +1,20 @@ use thiserror::Error; +pub type Result = std::result::Result; + +// Top-level error type +#[derive(Error, Debug, Clone)] +pub enum CryptoError { + #[error("signature error: {0}")] + SignatureError(#[from] SignatureError), + + #[error("keys error: {0}")] + KeysError(#[from] KeysError), + + #[error("verification error: {0}")] + VerificationError(#[from] VerificationError), +} + #[derive(Error, Clone, Debug)] pub enum SignatureError { #[error("No EIP-191 specific signatures implemented")] @@ -10,7 +25,7 @@ pub enum SignatureError { MalformedSignError, #[error("Algorithm Error: {0}")] AlgorithmError(String), - #[error("something went wrong: {0}")] + #[error("Something went wrong: {0}")] CosmosError(String), } diff --git a/crates/keys/src/lib.rs b/crates/keys/src/lib.rs index 55c8f1908..1ea7ad238 100644 --- a/crates/keys/src/lib.rs +++ b/crates/keys/src/lib.rs @@ -2,6 +2,7 @@ mod algorithm; mod cosmos; mod der; pub mod errors; +pub use errors::{CryptoError, KeysError, Result, SignatureError, VerificationError}; mod payload; mod signatures; mod signing_keys; diff --git a/crates/keys/src/verifying_keys.rs b/crates/keys/src/verifying_keys.rs index 38a96726f..4f435461d 100644 --- a/crates/keys/src/verifying_keys.rs +++ b/crates/keys/src/verifying_keys.rs @@ -1,4 +1,7 @@ -use crate::errors::VerificationError; +use crate::{ + CryptoError, Result, + errors::{KeysError, VerificationError}, +}; use alloy_primitives::eip191_hash_message; use ed25519::PublicKeyBytes as Ed25519PublicKeyBytes; use ed25519_consensus::VerificationKey as Ed25519VerifyingKey; @@ -21,7 +24,6 @@ use std::{ borrow::Cow, hash::{Hash, Hasher}, path::Path, - result::Result, }; use utoipa::{ PartialSchema, ToSchema, @@ -89,31 +91,32 @@ impl VerifyingKey { } } - pub fn from_algorithm_and_bytes( - algorithm: CryptoAlgorithm, - bytes: &[u8], - ) -> Result { + pub fn from_algorithm_and_bytes(algorithm: CryptoAlgorithm, bytes: &[u8]) -> Result { match algorithm { - CryptoAlgorithm::Ed25519 => Ed25519VerifyingKey::try_from(bytes) - .map(VerifyingKey::Ed25519) - .map_err(|e| VerificationError::VerifyError("ed25519".to_string(), e.to_string())), - CryptoAlgorithm::Secp256k1 => { - Secp256k1VerifyingKey::from_sec1_bytes(bytes).map(VerifyingKey::Secp256k1).map_err( - |e| VerificationError::VerifyError("secp256k1".to_string(), e.to_string()), - ) + CryptoAlgorithm::Ed25519 => { + Ed25519VerifyingKey::try_from(bytes).map(VerifyingKey::Ed25519).map_err(|e| { + VerificationError::VerifyError("ed25519".to_string(), e.to_string()).into() + }) } - CryptoAlgorithm::Secp256r1 => { - Secp256r1VerifyingKey::from_sec1_bytes(bytes).map(VerifyingKey::Secp256r1).map_err( - |e| VerificationError::VerifyError("secp256r1".to_string(), e.to_string()), + CryptoAlgorithm::Secp256k1 => Secp256k1VerifyingKey::from_sec1_bytes(bytes) + .map(VerifyingKey::Secp256k1) + .map_err(|e| { + VerificationError::VerifyError("secp256k1".to_string(), e.to_string()).into() + }), + CryptoAlgorithm::Secp256r1 => Secp256r1VerifyingKey::from_sec1_bytes(bytes) + .map(VerifyingKey::Secp256r1) + .map_err(|e| { + VerificationError::VerifyError("secp256r1".to_string(), e.to_string()).into() + }), + CryptoAlgorithm::Eip191 => { + Secp256k1VerifyingKey::from_sec1_bytes(bytes).map(VerifyingKey::Eip191).map_err( + |e| VerificationError::VerifyError("eip191".to_string(), e.to_string()).into(), ) } - CryptoAlgorithm::Eip191 => Secp256k1VerifyingKey::from_sec1_bytes(bytes) - .map(VerifyingKey::Eip191) - .map_err(|e| VerificationError::VerifyError("eip191".to_string(), e.to_string())), CryptoAlgorithm::CosmosAdr36 => Secp256k1VerifyingKey::from_sec1_bytes(bytes) .map(VerifyingKey::CosmosAdr36) .map_err(|e| { - VerificationError::VerifyError("cosmos adr36".to_string(), e.to_string()) + VerificationError::VerifyError("cosmos adr36".to_string(), e.to_string()).into() }), } } @@ -128,99 +131,97 @@ impl VerifyingKey { } } - pub fn verify_signature( - &self, - message: impl AsRef<[u8]>, - signature: &Signature, - ) -> Result<(), VerificationError> { + pub fn verify_signature(&self, message: impl AsRef<[u8]>, signature: &Signature) -> Result<()> { match self { VerifyingKey::Ed25519(vk) => { let Signature::Ed25519(signature) = signature else { - return Err(VerificationError::InvalidSignError); + return Err(VerificationError::InvalidSignError.into()); }; vk.verify(signature, message.as_ref()).map_err(|e| { - VerificationError::VerifyError("ed25519".to_string(), e.to_string()) + VerificationError::VerifyError("ed25519".to_string(), e.to_string()).into() }) } VerifyingKey::Secp256k1(vk) => { let Signature::Secp256k1(signature) = signature else { - return Err(VerificationError::InvalidSignError); + return Err(VerificationError::InvalidSignError.into()); }; let mut digest = sha2::Sha256::new(); digest.update(message); vk.verify_digest(digest, signature).map_err(|e| { - VerificationError::VerifyError("secp256k1".to_string(), e.to_string()) + VerificationError::VerifyError("secp256k1".to_string(), e.to_string()).into() }) } VerifyingKey::Secp256r1(vk) => { let Signature::Secp256r1(signature) = signature else { - return Err(VerificationError::InvalidSignError); + return Err(VerificationError::InvalidSignError.into()); }; let mut digest = sha2::Sha256::new(); digest.update(message); vk.verify_digest(digest, signature).map_err(|e| { - VerificationError::VerifyError("secp256r1".to_string(), e.to_string()) + VerificationError::VerifyError("secp256r1".to_string(), e.to_string()).into() }) } VerifyingKey::Eip191(vk) => { let Signature::Secp256k1(signature) = signature else { - return Err(VerificationError::SignatureError("EIP-191".to_string())); + return Err(VerificationError::SignatureError("EIP-191".to_string()).into()); }; let prehash = eip191_hash_message(message); vk.verify_prehash(prehash.as_slice(), signature).map_err(|e| { - VerificationError::VerifyError("EIP-191".to_string(), e.to_string()) + VerificationError::VerifyError("EIP-191".to_string(), e.to_string()).into() }) } VerifyingKey::CosmosAdr36(vk) => { let Signature::Secp256k1(signature) = signature else { - return Err(VerificationError::SignatureError( - "cosmos ADR-36".to_string(), - )); + return Err( + VerificationError::SignatureError("cosmos ADR-36".to_string()).into(), + ); }; let prehash = cosmos_adr36_hash_message(message, vk) .map_err(|e| VerificationError::GeneralError(e.to_string()))?; vk.verify_prehash(&prehash, signature).map_err(|e| { VerificationError::VerifyError("cosmos ADR-36".to_string(), e.to_string()) + .into() }) } } } - fn to_spki_der_doc(&self) -> Result { + fn to_spki_der_doc(&self) -> Result { match self { VerifyingKey::Ed25519(vk) => Ed25519PublicKeyBytes(vk.to_bytes()).to_public_key_der(), VerifyingKey::Secp256k1(vk) => vk.to_public_key_der(), VerifyingKey::Secp256r1(vk) => vk.to_public_key_der(), VerifyingKey::Eip191(_) => { - return Err(VerificationError::NotImplementedError( - "EIP-191".to_string(), - "to".to_string(), + return Err(CryptoError::VerificationError( + VerificationError::NotImplementedError("EIP-191".to_string(), "to".to_string()), )); } VerifyingKey::CosmosAdr36(_) => { - return Err(VerificationError::NotImplementedError( - "cosmos ADR-36".to_string(), - "to".to_string(), + return Err(CryptoError::VerificationError( + VerificationError::NotImplementedError( + "cosmos ADR-36".to_string(), + "to".to_string(), + ), )); } } - .map_err(|_| VerificationError::GeneralError("creating SPKI DER failed".to_string())) + .map_err(|_| CryptoError::KeysError(KeysError::DerCreationError)) } - pub fn to_spki_der(&self) -> Result, VerificationError> { + pub fn to_spki_der(&self) -> Result> { Ok(self.to_spki_der_doc()?.as_bytes().to_vec()) } - pub fn to_spki_pem_file(&self, filename: impl AsRef) -> Result<(), VerificationError> { + pub fn to_spki_pem_file(&self, filename: impl AsRef) -> Result<()> { self.to_spki_der_doc()? .write_pem_file(filename, SubjectPublicKeyInfoRef::PEM_LABEL, LineEnding::LF) - .map_err(|_| VerificationError::CreationError("PKCS8 PEM file".to_string())) + .map_err(|_| VerificationError::CreationError("PKCS8 PEM file".to_string()).into()) } - fn from_spki(spki: SubjectPublicKeyInfoRef) -> Result { + fn from_spki(spki: SubjectPublicKeyInfoRef) -> Result { let algorithm = CryptoAlgorithm::try_from(spki.algorithm) .map_err(|e| VerificationError::GeneralError(e.to_string()))?; @@ -246,24 +247,30 @@ impl VerifyingKey { })?; Ok(VerifyingKey::Secp256r1(secp256r1_key)) } - CryptoAlgorithm::Eip191 => Err(VerificationError::NotImplementedError( - "Eth".to_string(), - "from".to_string(), - )), - CryptoAlgorithm::CosmosAdr36 => Err(VerificationError::NotImplementedError( - "Cosmos ADR-36".to_string(), - "from".to_string(), - )), + CryptoAlgorithm::Eip191 => { + return Err(VerificationError::NotImplementedError( + "Eth".to_string(), + "from".to_string(), + ) + .into()); + } + CryptoAlgorithm::CosmosAdr36 => { + return Err(VerificationError::NotImplementedError( + "Cosmos ADR-36".to_string(), + "from".to_string(), + ) + .into()); + } } } - pub fn from_spki_der(bytes: &[u8]) -> Result { + pub fn from_spki_der(bytes: &[u8]) -> Result { let spki = SubjectPublicKeyInfoRef::from_der(bytes) .map_err(|e| VerificationError::GeneralError(e.to_string()))?; Self::from_spki(spki) } - pub fn from_spki_pem_file(filename: impl AsRef) -> Result { + pub fn from_spki_pem_file(filename: impl AsRef) -> Result { let (label, doc) = Document::read_pem_file(filename) .map_err(|e| VerificationError::GeneralError(e.to_string()))?; SubjectPublicKeyInfoRef::validate_pem_label(&label) @@ -273,7 +280,7 @@ impl VerifyingKey { } impl TryFrom for VerifyingKey { - type Error = VerificationError; + type Error = CryptoError; fn try_from(value: CryptoPayload) -> std::result::Result { VerifyingKey::from_algorithm_and_bytes(value.algorithm, &value.bytes) @@ -302,9 +309,9 @@ impl From for VerifyingKey { } impl FromBase64 for VerifyingKey { - type Error = VerificationError; + type Error = CryptoError; - fn from_base64>(base64: T) -> Result { + fn from_base64>(base64: T) -> Result { let bytes = Vec::::from_base64(base64) .map_err(|e| (VerificationError::GeneralError(e.to_string())))?; @@ -317,13 +324,14 @@ impl FromBase64 for VerifyingKey { } _ => Err(VerificationError::GeneralError( "Only Ed25519 keys can be initialized from base64".to_string(), - )), + ) + .into()), } } } impl TryFrom for VerifyingKey { - type Error = VerificationError; + type Error = CryptoError; fn try_from(s: String) -> std::result::Result { Self::from_base64(s) From 401675d95bfd1913e0a13a0a7ca6f53299e0e199 Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Thu, 26 Jun 2025 12:05:31 +0200 Subject: [PATCH 07/10] CryptoError fully immplemented in keys --- crates/keys/src/algorithm.rs | 21 ++++++------- crates/keys/src/cosmos.rs | 16 +++------- crates/keys/src/errors.rs | 7 ++--- crates/keys/src/signatures.rs | 30 +++++++++---------- crates/keys/src/signing_keys.rs | 49 +++++++++++++++---------------- crates/keys/src/verifying_keys.rs | 24 +++++++-------- 6 files changed, 65 insertions(+), 82 deletions(-) diff --git a/crates/keys/src/algorithm.rs b/crates/keys/src/algorithm.rs index c9b1546d1..0fed879d8 100644 --- a/crates/keys/src/algorithm.rs +++ b/crates/keys/src/algorithm.rs @@ -1,4 +1,4 @@ -use crate::errors::SignatureError; +use crate::{CryptoError, Result, errors::SignatureError}; use pkcs8::{AlgorithmIdentifierRef, ObjectIdentifier}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; @@ -33,16 +33,16 @@ impl CryptoAlgorithm { } impl std::str::FromStr for CryptoAlgorithm { - type Err = (); + type Err = CryptoError; - fn from_str(input: &str) -> Result { + fn from_str(input: &str) -> Result { match input.to_lowercase().as_str() { "ed25519" => Ok(CryptoAlgorithm::Ed25519), "secp256k1" => Ok(CryptoAlgorithm::Secp256k1), "secp256r1" => Ok(CryptoAlgorithm::Secp256r1), "eip191" => Ok(CryptoAlgorithm::Eip191), "cosmos_adr36" => Ok(CryptoAlgorithm::CosmosAdr36), - _ => Err(()), + _ => Err(SignatureError::AlgorithmError(input.to_string()).into()), } } } @@ -60,9 +60,9 @@ pub const SECP256K1_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.13 pub const SECP256R1_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7"); impl<'a> TryFrom> for CryptoAlgorithm { - type Error = SignatureError; + type Error = CryptoError; - fn try_from(algorithm_identifier: AlgorithmIdentifierRef<'a>) -> Result { + fn try_from(algorithm_identifier: AlgorithmIdentifierRef<'a>) -> Result { let oid = algorithm_identifier.oid; if oid == ED25519_OID { @@ -78,12 +78,13 @@ impl<'a> TryFrom> for CryptoAlgorithm { } else { return Err(SignatureError::AlgorithmError( "Unsupported elliptic curve OID".to_string(), - )); + ) + .into()); } } else { - return Err(SignatureError::AlgorithmError( - "Unsupported algorithm OID".to_string(), - )); + return Err( + SignatureError::AlgorithmError("Unsupported algorithm OID".to_string()).into(), + ); } } } diff --git a/crates/keys/src/cosmos.rs b/crates/keys/src/cosmos.rs index de41d5782..6afe69c9b 100644 --- a/crates/keys/src/cosmos.rs +++ b/crates/keys/src/cosmos.rs @@ -1,11 +1,9 @@ +use crate::{Result, errors::SignatureError}; use k256::ecdsa::VerifyingKey as Secp256k1VerifyingKey; use prism_serde::{bech32::ToBech32, raw_or_b64}; use ripemd::Ripemd160; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; -use std::result::Result; - -use crate::errors::SignatureError; #[derive(Serialize, Deserialize)] struct CosmosSignDoc { @@ -70,7 +68,7 @@ impl CosmosSignDoc { pub fn cosmos_adr36_hash_message( message: impl AsRef<[u8]>, verifying_key: &Secp256k1VerifyingKey, -) -> Result, SignatureError> { +) -> Result> { // TODO: Support arbitrary address prefixes // At the moment we expect users to use "cosmoshub-4" as chainId when // signing prism data via `signArbitrary(..)`, resulting in "cosmos" as address prefix @@ -95,10 +93,7 @@ pub fn cosmos_adr36_hash_message( /// /// # Returns /// * `Result>` - The serialized sign document as bytes or an error -fn create_serialized_adr36_sign_doc( - data: Vec, - signer: String, -) -> Result, SignatureError> { +fn create_serialized_adr36_sign_doc(data: Vec, signer: String) -> Result> { let adr36_sign_doc = CosmosSignDoc::new(signer, data); let sign_doc_str = serde_json::to_string(&adr36_sign_doc) @@ -123,10 +118,7 @@ fn create_serialized_adr36_sign_doc( /// /// # Returns /// * `Result` - The bech32-encoded address or an error -fn signer_from_key( - address_prefix: &str, - verifying_key: &Secp256k1VerifyingKey, -) -> Result { +fn signer_from_key(address_prefix: &str, verifying_key: &Secp256k1VerifyingKey) -> Result { let verifying_key_bytes = verifying_key.to_sec1_bytes(); let hashed_key_bytes = Sha256::digest(verifying_key_bytes); let cosmos_address = Ripemd160::digest(hashed_key_bytes); diff --git a/crates/keys/src/errors.rs b/crates/keys/src/errors.rs index 3a038e823..6d5295961 100644 --- a/crates/keys/src/errors.rs +++ b/crates/keys/src/errors.rs @@ -2,7 +2,6 @@ use thiserror::Error; pub type Result = std::result::Result; -// Top-level error type #[derive(Error, Debug, Clone)] pub enum CryptoError { #[error("signature error: {0}")] @@ -17,10 +16,8 @@ pub enum CryptoError { #[derive(Error, Clone, Debug)] pub enum SignatureError { - #[error("No EIP-191 specific signatures implemented")] - EipSignatureError, - #[error("No ADR-36 specific signatures implemented")] - AdrSignatureError, + #[error("No {0} specific signatures implemented")] + UnsupportedFormatError(String), #[error("Malformed signature")] MalformedSignError, #[error("Algorithm Error: {0}")] diff --git a/crates/keys/src/signatures.rs b/crates/keys/src/signatures.rs index 513979530..1aa7f96f2 100644 --- a/crates/keys/src/signatures.rs +++ b/crates/keys/src/signatures.rs @@ -1,4 +1,4 @@ -use crate::errors::SignatureError; +use crate::{CryptoError, Result, errors::SignatureError}; use ed25519_consensus::Signature as Ed25519Signature; use k256::ecdsa::Signature as Secp256k1Signature; use p256::ecdsa::Signature as Secp256r1Signature; @@ -11,7 +11,6 @@ use serde::{Deserialize, Serialize}; use std::{ borrow::Cow, fmt::{Display, Formatter}, - result::Result, }; use utoipa::{ PartialSchema, ToSchema, @@ -40,22 +39,23 @@ impl Signature { } } - pub fn from_algorithm_and_bytes( - algorithm: CryptoAlgorithm, - bytes: &[u8], - ) -> Result { + pub fn from_algorithm_and_bytes(algorithm: CryptoAlgorithm, bytes: &[u8]) -> Result { match algorithm { CryptoAlgorithm::Ed25519 => Ed25519Signature::try_from(bytes) .map(Signature::Ed25519) - .map_err(|e| SignatureError::AlgorithmError(e.to_string())), + .map_err(|e| SignatureError::AlgorithmError(e.to_string()).into()), CryptoAlgorithm::Secp256k1 => Secp256k1Signature::from_slice(bytes) .map(Signature::Secp256k1) - .map_err(|e| SignatureError::AlgorithmError(e.to_string())), + .map_err(|e| SignatureError::AlgorithmError(e.to_string()).into()), CryptoAlgorithm::Secp256r1 => Secp256r1Signature::from_slice(bytes) .map(Signature::Secp256r1) - .map_err(|e| SignatureError::AlgorithmError(e.to_string())), - CryptoAlgorithm::Eip191 => Err(SignatureError::EipSignatureError), - CryptoAlgorithm::CosmosAdr36 => Err(SignatureError::AdrSignatureError), + .map_err(|e| SignatureError::AlgorithmError(e.to_string()).into()), + CryptoAlgorithm::Eip191 => { + Err(SignatureError::UnsupportedFormatError("EIP-191".to_string()).into()) + } + CryptoAlgorithm::CosmosAdr36 => { + Err(SignatureError::UnsupportedFormatError("ADR-36".to_string()).into()) + } } } @@ -84,7 +84,7 @@ impl Signature { } } - pub fn to_prism_der(&self) -> Result, SignatureError> { + pub fn to_prism_der(&self) -> Result> { let signature_bytes = self.to_bytes(); let mut der_bytes = Vec::with_capacity(2 + signature_bytes.len()); @@ -109,7 +109,7 @@ impl Signature { Ok(doc.as_bytes().to_vec()) } - pub fn from_prism_der(bytes: &[u8]) -> Result { + pub fn from_prism_der(bytes: &[u8]) -> Result { let signature_info = SignatureInfoRef::from_der(bytes) .map_err(|e| SignatureError::AlgorithmError(e.to_string()))?; let algorithm = CryptoAlgorithm::try_from(signature_info.algorithm) @@ -123,13 +123,13 @@ impl Signature { [0x04, _, signature_bytes @ ..] => { Signature::from_algorithm_and_bytes(algorithm, signature_bytes) } - _ => Err(SignatureError::MalformedSignError), + _ => Err(SignatureError::MalformedSignError.into()), } } } impl TryFrom for Signature { - type Error = SignatureError; + type Error = CryptoError; fn try_from(value: CryptoPayload) -> std::result::Result { Signature::from_algorithm_and_bytes(value.algorithm, &value.bytes) diff --git a/crates/keys/src/signing_keys.rs b/crates/keys/src/signing_keys.rs index 1af1bc995..23616ce16 100644 --- a/crates/keys/src/signing_keys.rs +++ b/crates/keys/src/signing_keys.rs @@ -1,4 +1,4 @@ -use crate::errors::KeysError; +use crate::{CryptoError, Result, errors::KeysError}; use alloy_primitives::eip191_hash_message; use ed25519::{ PublicKeyBytes as Ed25519PublicKeyBytes, pkcs8::KeypairBytes as Ed25519KeypairBytes, @@ -13,7 +13,7 @@ use pkcs8::{ Document, EncodePrivateKey, LineEnding, PrivateKeyInfo, SecretDocument, der::{Decode, pem::PemLabel}, }; -use std::{path::Path, result::Result}; +use std::path::Path; use sha2::Digest as _; @@ -66,7 +66,7 @@ impl SigningKey { SigningKey::CosmosAdr36(Secp256k1SigningKey::random(&mut get_rng())) } - pub fn new_with_algorithm(algorithm: CryptoAlgorithm) -> Result { + pub fn new_with_algorithm(algorithm: CryptoAlgorithm) -> Result { match algorithm { CryptoAlgorithm::Ed25519 => Ok(SigningKey::new_ed25519()), CryptoAlgorithm::Secp256k1 => Ok(SigningKey::new_secp256k1()), @@ -90,7 +90,7 @@ impl SigningKey { } } - fn to_pkcs8_der_doc(&self) -> Result { + fn to_pkcs8_der_doc(&self) -> Result { match self { SigningKey::Ed25519(sk) => { let keypair_bytes = Ed25519KeypairBytes { @@ -104,43 +104,40 @@ impl SigningKey { SigningKey::Eip191(sk) => sk.to_pkcs8_der(), SigningKey::CosmosAdr36(sk) => sk.to_pkcs8_der(), } - .map_err(|_| KeysError::DerCreationError) + .map_err(|_| KeysError::DerCreationError.into()) } - pub fn to_pkcs8_der(&self) -> Result, KeysError> { + pub fn to_pkcs8_der(&self) -> Result> { Ok(self.to_pkcs8_der_doc()?.as_bytes().to_vec()) } - pub fn to_pkcs8_pem_file(&self, filename: impl AsRef) -> Result<(), KeysError> { + pub fn to_pkcs8_pem_file(&self, filename: impl AsRef) -> Result<()> { self.to_pkcs8_der_doc()? .write_pem_file(filename, PrivateKeyInfo::PEM_LABEL, LineEnding::LF) - .map_err(|_| KeysError::PemCreationError) + .map_err(|_| KeysError::PemCreationError.into()) } - pub fn from_algorithm_and_bytes( - algorithm: CryptoAlgorithm, - bytes: &[u8], - ) -> Result { + pub fn from_algorithm_and_bytes(algorithm: CryptoAlgorithm, bytes: &[u8]) -> Result { match algorithm { CryptoAlgorithm::Ed25519 => Ed25519SigningKey::try_from(bytes) .map(SigningKey::Ed25519) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Secp256k1 => Secp256k1SigningKey::from_slice(bytes) .map(SigningKey::Secp256k1) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Secp256r1 => Secp256r1SigningKey::from_slice(bytes) .map(SigningKey::Secp256r1) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Eip191 => Secp256k1SigningKey::from_slice(bytes) .map(SigningKey::Eip191) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::CosmosAdr36 => Secp256k1SigningKey::from_slice(bytes) .map(SigningKey::CosmosAdr36) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), } } - pub fn from_pkcs8_der_doc(doc: &Document) -> Result { + pub fn from_pkcs8_der_doc(doc: &Document) -> Result { let value = doc.as_bytes(); let pk_info = PrivateKeyInfo::try_from(value).map_err(|_| KeysError::ParseError)?; let algorithm = @@ -156,25 +153,25 @@ impl SigningKey { } CryptoAlgorithm::Secp256k1 => Secp256k1SigningKey::try_from(pk_info) .map(SigningKey::Secp256k1) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Secp256r1 => Secp256r1SigningKey::try_from(pk_info) .map(SigningKey::Secp256r1) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Eip191 => Secp256k1SigningKey::try_from(pk_info) .map(SigningKey::Eip191) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::CosmosAdr36 => Secp256k1SigningKey::try_from(pk_info) .map(SigningKey::CosmosAdr36) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string())), + .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), } } - pub fn from_pkcs8_der(bytes: &[u8]) -> Result { + pub fn from_pkcs8_der(bytes: &[u8]) -> Result { let document = pkcs8::Document::from_der(bytes).map_err(|_| KeysError::ParseError)?; Self::from_pkcs8_der_doc(&document) } - pub fn from_pkcs8_pem_file(file_path: impl AsRef) -> Result { + pub fn from_pkcs8_pem_file(file_path: impl AsRef) -> Result { let (label, document) = pkcs8::Document::read_pem_file(file_path).map_err(|_| KeysError::ParseError)?; PrivateKeyInfo::validate_pem_label(&label).map_err(|_| KeysError::PemLabelError)?; @@ -192,7 +189,7 @@ impl SigningKey { } } - pub fn sign(&self, message: impl AsRef<[u8]>) -> Result { + pub fn sign(&self, message: impl AsRef<[u8]>) -> Result { match self { SigningKey::Ed25519(sk) => Ok(Signature::Ed25519(sk.sign(message.as_ref()))), SigningKey::Secp256k1(sk) => { @@ -244,7 +241,7 @@ impl PartialEq for SigningKey { } impl TryFrom for SigningKey { - type Error = KeysError; + type Error = CryptoError; fn try_from(value: CryptoPayload) -> std::result::Result { SigningKey::from_algorithm_and_bytes(value.algorithm, &value.bytes) diff --git a/crates/keys/src/verifying_keys.rs b/crates/keys/src/verifying_keys.rs index 4f435461d..9e16baead 100644 --- a/crates/keys/src/verifying_keys.rs +++ b/crates/keys/src/verifying_keys.rs @@ -247,20 +247,16 @@ impl VerifyingKey { })?; Ok(VerifyingKey::Secp256r1(secp256r1_key)) } - CryptoAlgorithm::Eip191 => { - return Err(VerificationError::NotImplementedError( - "Eth".to_string(), - "from".to_string(), - ) - .into()); - } - CryptoAlgorithm::CosmosAdr36 => { - return Err(VerificationError::NotImplementedError( - "Cosmos ADR-36".to_string(), - "from".to_string(), - ) - .into()); - } + CryptoAlgorithm::Eip191 => Err(VerificationError::NotImplementedError( + "Eth".to_string(), + "from".to_string(), + ) + .into()), + CryptoAlgorithm::CosmosAdr36 => Err(VerificationError::NotImplementedError( + "Cosmos ADR-36".to_string(), + "from".to_string(), + ) + .into()), } } From 9e06ce84e6a72e7ae7da8f6ca8e0edea0cdb0dac Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Thu, 26 Jun 2025 14:14:42 +0200 Subject: [PATCH 08/10] Reorganized CryptoErrors enums to be more accurate --- crates/keys/src/cosmos.rs | 9 ++++--- crates/keys/src/errors.rs | 43 +++++++++++++++++++++---------- crates/keys/src/verifying_keys.rs | 20 +++++++------- 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/crates/keys/src/cosmos.rs b/crates/keys/src/cosmos.rs index 6afe69c9b..8927927b8 100644 --- a/crates/keys/src/cosmos.rs +++ b/crates/keys/src/cosmos.rs @@ -1,4 +1,7 @@ -use crate::{Result, errors::SignatureError}; +use crate::{ + Result, + errors::{ParseError, SignatureError}, +}; use k256::ecdsa::VerifyingKey as Secp256k1VerifyingKey; use prism_serde::{bech32::ToBech32, raw_or_b64}; use ripemd::Ripemd160; @@ -76,7 +79,7 @@ pub fn cosmos_adr36_hash_message( let signer = signer_from_key(ADDRESS_PREFIX, verifying_key)?; let serialized_sign_doc = create_serialized_adr36_sign_doc(message.as_ref().to_vec(), signer) - .map_err(|e| SignatureError::CosmosError(e.to_string()))?; + .map_err(|e| ParseError::GeneralError(e.to_string()))?; let hashed_sign_doc = Sha256::digest(&serialized_sign_doc).to_vec(); Ok(hashed_sign_doc) } @@ -97,7 +100,7 @@ fn create_serialized_adr36_sign_doc(data: Vec, signer: String) -> Result", "\\u003e") .replace("&", "\\u0026"); diff --git a/crates/keys/src/errors.rs b/crates/keys/src/errors.rs index 6d5295961..c0347d1b9 100644 --- a/crates/keys/src/errors.rs +++ b/crates/keys/src/errors.rs @@ -4,13 +4,13 @@ pub type Result = std::result::Result; #[derive(Error, Debug, Clone)] pub enum CryptoError { - #[error("signature error: {0}")] + #[error("Signature error: {0}")] SignatureError(#[from] SignatureError), - #[error("keys error: {0}")] - KeysError(#[from] KeysError), + #[error("Parse error: {0}")] + ParseError(#[from] ParseError), - #[error("verification error: {0}")] + #[error("Verification error: {0}")] VerificationError(#[from] VerificationError), } @@ -18,44 +18,61 @@ pub enum CryptoError { pub enum SignatureError { #[error("No {0} specific signatures implemented")] UnsupportedFormatError(String), + #[error("Malformed signature")] MalformedSignError, + #[error("Algorithm Error: {0}")] AlgorithmError(String), - #[error("Something went wrong: {0}")] + + #[error("Invalid signature type")] + InvalidSignError, + + #[error("Signing operation failed: {0}")] + SigningError(String), + + #[error("Cosmos Error: {0}")] CosmosError(String), } #[derive(Error, Clone, Debug)] -pub enum KeysError { +pub enum ParseError { #[error("Creating PKCS8 DER failed")] DerCreationError, + #[error("Creating PKCS8 PEM failed")] PemCreationError, + #[error("Parsing key algorithm from PKCS#8 DER failed")] - ParseError, + DerParseError, + #[error("Invalid PEM label")] PemLabelError, + #[error("Invalid key bytes for algorithm: {0}")] InvalidKeyBytes(String), - #[error("Signing operation failed: {0}")] - SigningError(String), + + #[error("A parsing error occured: {0}")] + GeneralError(String), } #[derive(Error, Clone, Debug)] pub enum VerificationError { - #[error("Invalid signature type")] - InvalidSignError, #[error("Failed to verify {0} signature: {1}")] VerifyError(String, String), + #[error("Verifying key for {0} can only verify secp256k1 signatures")] SignatureError(String), + #[error("Creating {0} failed")] - CreationError(String), + VKCreationError(String), + #[error("{0} vk from DER format failed: {1}")] IntoRefError(String, String), + #[error("{0} vk {1} DER format is not implemented")] NotImplementedError(String, String), - #[error("Something went wrong: {0}")] + + #[error("A verification error occured: {0}")] GeneralError(String), } diff --git a/crates/keys/src/verifying_keys.rs b/crates/keys/src/verifying_keys.rs index 9e16baead..8d6c3b0ff 100644 --- a/crates/keys/src/verifying_keys.rs +++ b/crates/keys/src/verifying_keys.rs @@ -1,6 +1,6 @@ use crate::{ CryptoError, Result, - errors::{KeysError, VerificationError}, + errors::{ParseError, SignatureError, VerificationError}, }; use alloy_primitives::eip191_hash_message; use ed25519::PublicKeyBytes as Ed25519PublicKeyBytes; @@ -135,7 +135,7 @@ impl VerifyingKey { match self { VerifyingKey::Ed25519(vk) => { let Signature::Ed25519(signature) = signature else { - return Err(VerificationError::InvalidSignError.into()); + return Err(SignatureError::InvalidSignError.into()); }; vk.verify(signature, message.as_ref()).map_err(|e| { @@ -144,7 +144,7 @@ impl VerifyingKey { } VerifyingKey::Secp256k1(vk) => { let Signature::Secp256k1(signature) = signature else { - return Err(VerificationError::InvalidSignError.into()); + return Err(SignatureError::InvalidSignError.into()); }; let mut digest = sha2::Sha256::new(); digest.update(message); @@ -155,7 +155,7 @@ impl VerifyingKey { } VerifyingKey::Secp256r1(vk) => { let Signature::Secp256r1(signature) = signature else { - return Err(VerificationError::InvalidSignError.into()); + return Err(SignatureError::InvalidSignError.into()); }; let mut digest = sha2::Sha256::new(); digest.update(message); @@ -208,7 +208,7 @@ impl VerifyingKey { )); } } - .map_err(|_| CryptoError::KeysError(KeysError::DerCreationError)) + .map_err(|_| ParseError::DerCreationError.into()) } pub fn to_spki_der(&self) -> Result> { @@ -218,17 +218,17 @@ impl VerifyingKey { pub fn to_spki_pem_file(&self, filename: impl AsRef) -> Result<()> { self.to_spki_der_doc()? .write_pem_file(filename, SubjectPublicKeyInfoRef::PEM_LABEL, LineEnding::LF) - .map_err(|_| VerificationError::CreationError("PKCS8 PEM file".to_string()).into()) + .map_err(|_| VerificationError::VKCreationError("PKCS8 PEM file".to_string()).into()) } fn from_spki(spki: SubjectPublicKeyInfoRef) -> Result { let algorithm = CryptoAlgorithm::try_from(spki.algorithm) - .map_err(|e| VerificationError::GeneralError(e.to_string()))?; + .map_err(|e| ParseError::GeneralError(e.to_string()))?; match algorithm { CryptoAlgorithm::Ed25519 => { let ed25519_spki = Ed25519PublicKeyBytes::try_from(spki) - .map_err(|e| VerificationError::GeneralError(e.to_string()))?; + .map_err(|e| ParseError::GeneralError(e.to_string()))?; let ed25519_key = Ed25519VerifyingKey::try_from(ed25519_spki.as_ref() as &[u8]) .map_err(|e| { VerificationError::IntoRefError("ed25519".to_string(), e.to_string()) @@ -262,7 +262,7 @@ impl VerifyingKey { pub fn from_spki_der(bytes: &[u8]) -> Result { let spki = SubjectPublicKeyInfoRef::from_der(bytes) - .map_err(|e| VerificationError::GeneralError(e.to_string()))?; + .map_err(|e| ParseError::GeneralError(e.to_string()))?; Self::from_spki(spki) } @@ -309,7 +309,7 @@ impl FromBase64 for VerifyingKey { fn from_base64>(base64: T) -> Result { let bytes = Vec::::from_base64(base64) - .map_err(|e| (VerificationError::GeneralError(e.to_string())))?; + .map_err(|e| (ParseError::GeneralError(e.to_string())))?; match bytes.len() { 32 => { From 8f0c53159aff3c7d29059b8b9a935baa63803fff Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Thu, 26 Jun 2025 14:41:16 +0200 Subject: [PATCH 09/10] Fixed key lib --- crates/keys/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/keys/src/lib.rs b/crates/keys/src/lib.rs index 1ea7ad238..2e18fc5ab 100644 --- a/crates/keys/src/lib.rs +++ b/crates/keys/src/lib.rs @@ -2,7 +2,7 @@ mod algorithm; mod cosmos; mod der; pub mod errors; -pub use errors::{CryptoError, KeysError, Result, SignatureError, VerificationError}; +pub use errors::{CryptoError, ParseError, Result, SignatureError, VerificationError}; mod payload; mod signatures; mod signing_keys; From b8fb92cb4ed04f5667a994da4f81b57a918144e4 Mon Sep 17 00:00:00 2001 From: Scott Ford Date: Thu, 26 Jun 2025 14:50:00 +0200 Subject: [PATCH 10/10] Fixed signing keys --- crates/keys/src/signing_keys.rs | 46 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/crates/keys/src/signing_keys.rs b/crates/keys/src/signing_keys.rs index 23616ce16..1347a6ec0 100644 --- a/crates/keys/src/signing_keys.rs +++ b/crates/keys/src/signing_keys.rs @@ -1,4 +1,4 @@ -use crate::{CryptoError, Result, errors::KeysError}; +use crate::{CryptoError, Result, SignatureError, errors::ParseError}; use alloy_primitives::eip191_hash_message; use ed25519::{ PublicKeyBytes as Ed25519PublicKeyBytes, pkcs8::KeypairBytes as Ed25519KeypairBytes, @@ -104,7 +104,7 @@ impl SigningKey { SigningKey::Eip191(sk) => sk.to_pkcs8_der(), SigningKey::CosmosAdr36(sk) => sk.to_pkcs8_der(), } - .map_err(|_| KeysError::DerCreationError.into()) + .map_err(|_| ParseError::DerCreationError.into()) } pub fn to_pkcs8_der(&self) -> Result> { @@ -114,67 +114,67 @@ impl SigningKey { pub fn to_pkcs8_pem_file(&self, filename: impl AsRef) -> Result<()> { self.to_pkcs8_der_doc()? .write_pem_file(filename, PrivateKeyInfo::PEM_LABEL, LineEnding::LF) - .map_err(|_| KeysError::PemCreationError.into()) + .map_err(|_| ParseError::PemCreationError.into()) } pub fn from_algorithm_and_bytes(algorithm: CryptoAlgorithm, bytes: &[u8]) -> Result { match algorithm { CryptoAlgorithm::Ed25519 => Ed25519SigningKey::try_from(bytes) .map(SigningKey::Ed25519) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Secp256k1 => Secp256k1SigningKey::from_slice(bytes) .map(SigningKey::Secp256k1) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Secp256r1 => Secp256r1SigningKey::from_slice(bytes) .map(SigningKey::Secp256r1) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Eip191 => Secp256k1SigningKey::from_slice(bytes) .map(SigningKey::Eip191) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::CosmosAdr36 => Secp256k1SigningKey::from_slice(bytes) .map(SigningKey::CosmosAdr36) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()).into()), } } pub fn from_pkcs8_der_doc(doc: &Document) -> Result { let value = doc.as_bytes(); - let pk_info = PrivateKeyInfo::try_from(value).map_err(|_| KeysError::ParseError)?; + let pk_info = PrivateKeyInfo::try_from(value).map_err(|_| ParseError::DerParseError)?; let algorithm = - CryptoAlgorithm::try_from(pk_info.algorithm).map_err(|_| KeysError::ParseError)?; + CryptoAlgorithm::try_from(pk_info.algorithm).map_err(|_| ParseError::DerParseError)?; match algorithm { CryptoAlgorithm::Ed25519 => { let ed25519_key_pair_bytes = Ed25519KeypairBytes::try_from(pk_info) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()))?; + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()))?; let ed25519_signing_key = Ed25519SigningKey::from(ed25519_key_pair_bytes.secret_key); Ok(SigningKey::Ed25519(ed25519_signing_key)) } CryptoAlgorithm::Secp256k1 => Secp256k1SigningKey::try_from(pk_info) .map(SigningKey::Secp256k1) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Secp256r1 => Secp256r1SigningKey::try_from(pk_info) .map(SigningKey::Secp256r1) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::Eip191 => Secp256k1SigningKey::try_from(pk_info) .map(SigningKey::Eip191) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()).into()), CryptoAlgorithm::CosmosAdr36 => Secp256k1SigningKey::try_from(pk_info) .map(SigningKey::CosmosAdr36) - .map_err(|e| KeysError::InvalidKeyBytes(e.to_string()).into()), + .map_err(|e| ParseError::InvalidKeyBytes(e.to_string()).into()), } } pub fn from_pkcs8_der(bytes: &[u8]) -> Result { - let document = pkcs8::Document::from_der(bytes).map_err(|_| KeysError::ParseError)?; + let document = pkcs8::Document::from_der(bytes).map_err(|_| ParseError::DerParseError)?; Self::from_pkcs8_der_doc(&document) } pub fn from_pkcs8_pem_file(file_path: impl AsRef) -> Result { let (label, document) = - pkcs8::Document::read_pem_file(file_path).map_err(|_| KeysError::ParseError)?; - PrivateKeyInfo::validate_pem_label(&label).map_err(|_| KeysError::PemLabelError)?; + pkcs8::Document::read_pem_file(file_path).map_err(|_| ParseError::DerParseError)?; + PrivateKeyInfo::validate_pem_label(&label).map_err(|_| ParseError::PemLabelError)?; Self::from_pkcs8_der_doc(&document) } @@ -197,7 +197,7 @@ impl SigningKey { digest.update(message); let sig: Secp256k1Signature = sk .try_sign_digest(digest) - .map_err(|e| KeysError::SigningError(e.to_string()))?; + .map_err(|e| SignatureError::SigningError(e.to_string()))?; Ok(Signature::Secp256k1(sig)) } SigningKey::Secp256r1(sk) => { @@ -205,22 +205,22 @@ impl SigningKey { digest.update(message); let sig: Secp256r1Signature = sk .try_sign_digest(digest) - .map_err(|e| KeysError::SigningError(e.to_string()))?; + .map_err(|e| SignatureError::SigningError(e.to_string()))?; Ok(Signature::Secp256r1(sig)) } SigningKey::Eip191(sk) => { let message = eip191_hash_message(message); let sig: Secp256k1Signature = sk .sign_prehash(message.as_slice()) - .map_err(|e| KeysError::SigningError(e.to_string()))?; + .map_err(|e| SignatureError::SigningError(e.to_string()))?; Ok(Signature::Secp256k1(sig)) } SigningKey::CosmosAdr36(sk) => { let message = cosmos_adr36_hash_message(message, sk.verifying_key()) - .map_err(|e| KeysError::SigningError(e.to_string()))?; + .map_err(|e| SignatureError::SigningError(e.to_string()))?; let sig: Secp256k1Signature = sk .sign_prehash(message.as_slice()) - .map_err(|e| KeysError::SigningError(e.to_string()))?; + .map_err(|e| SignatureError::SigningError(e.to_string()))?; Ok(Signature::Secp256k1(sig)) } }