//! An implementation of digitial signatures using secp256k1 ECDSA. use k256::ecdsa::{ Signature, SigningKey, VerifyingKey, signature::{Signer, Verifier}, }; use crate::error::CryptoError; pub struct SigningKeypair { sk: SigningKey, vk: VerifyingKey, } pub struct PublicKey(VerifyingKey); impl SigningKeypair { /// Generates a new random keypair pub fn new() -> Result { let mut raw_private = [0u8; 32]; rand::fill(&mut raw_private); let sk = SigningKey::from_slice(&raw_private) .expect("Key is provided generated with fixed valid size"); let vk = sk.verifying_key().to_owned(); Ok(Self { sk, vk }) } /// Create a new key from existing bytes. pub(crate) fn from_bytes(bytes: &[u8]) -> Result { if bytes.len() == 32 { let sk = SigningKey::from_slice(&bytes).expect("Key was checked to be a valid size"); let vk = sk.verifying_key().to_owned(); Ok(Self { sk, vk }) } else { Err(CryptoError::InvalidKeySize) } } /// View the raw bytes of the private key of this keypair. pub(crate) fn as_raw_private_key(&self) -> Vec { self.sk.as_nonzero_scalar().to_bytes().to_vec() } /// Get the public part of this keypair. pub fn public_key(&self) -> PublicKey { PublicKey(self.vk) } /// Sign data with the private key of this `SigningKeypair`. Other parties can use the public /// key to verify the signature. The generated signature is a detached signature. pub fn sign(&self, message: &[u8]) -> Result, CryptoError> { let sig: Signature = self.sk.sign(message); Ok(sig.to_vec()) } } impl PublicKey { /// Import a public key from raw bytes pub fn from_bytes(bytes: &[u8]) -> Result { if bytes.len() == 64 { Ok(Self( VerifyingKey::from_sec1_bytes(bytes).expect("Key is of valid size"), )) } else { Err(CryptoError::InvalidKeySize) } } pub fn verify_signature(&self, message: &[u8], sig: &[u8]) -> Result<(), CryptoError> { let sig = Signature::from_slice(sig).map_err(|_| CryptoError::InvalidKeySize)?; self.0 .verify(message, &sig) .map_err(|_| CryptoError::SignatureFailed) } }