77 lines
2.4 KiB
Rust
77 lines
2.4 KiB
Rust
//! 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<Self, CryptoError> {
|
|
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<Self, CryptoError> {
|
|
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<u8> {
|
|
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<Vec<u8>, 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<Self, CryptoError> {
|
|
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)
|
|
}
|
|
}
|