use crate::{
crypto::{secp256k1::Signature, PublicKey},
ErrorReport, Result,
};
use ecdsa::signature::{Keypair, Signer};
use k256::ecdsa::VerifyingKey;
#[cfg(feature = "getrandom")]
use rand_core::OsRng;
pub struct SigningKey {
inner: Box<dyn EcdsaSigner>,
}
impl SigningKey {
pub fn new(signer: Box<dyn EcdsaSigner>) -> Self {
Self { inner: signer }
}
pub fn from_slice(bytes: &[u8]) -> Result<Self> {
let signing_key = k256::ecdsa::SigningKey::from_slice(bytes)?;
Ok(Self::new(Box::new(signing_key)))
}
#[cfg(feature = "getrandom")]
pub fn random() -> Self {
Self::new(Box::new(k256::ecdsa::SigningKey::random(&mut OsRng)))
}
#[cfg(feature = "bip32")]
pub fn derive_from_path(
seed: impl AsRef<[u8]>,
path: &bip32::DerivationPath,
) -> bip32::Result<Self> {
bip32::XPrv::derive_from_path(seed, path).map(Into::into)
}
pub fn sign(&self, msg: &[u8]) -> Result<Signature> {
Ok(self.inner.try_sign(msg)?)
}
pub fn public_key(&self) -> PublicKey {
self.inner.verifying_key().into()
}
}
impl From<Box<dyn EcdsaSigner>> for SigningKey {
fn from(signer: Box<dyn EcdsaSigner>) -> Self {
Self::new(signer)
}
}
impl TryFrom<&[u8]> for SigningKey {
type Error = ErrorReport;
fn try_from(bytes: &[u8]) -> Result<Self> {
Self::from_slice(bytes)
}
}
#[cfg(feature = "bip32")]
impl From<bip32::XPrv> for SigningKey {
fn from(xprv: bip32::XPrv) -> SigningKey {
SigningKey::from(&xprv)
}
}
#[cfg(feature = "bip32")]
impl From<&bip32::XPrv> for SigningKey {
fn from(xprv: &bip32::XPrv) -> SigningKey {
Self {
inner: Box::new(xprv.private_key().clone()),
}
}
}
pub trait EcdsaSigner:
Signer<Signature> + Keypair<VerifyingKey = VerifyingKey> + Sync + Send
{
}
impl<T> EcdsaSigner for T where
T: Signer<Signature> + Keypair<VerifyingKey = VerifyingKey> + Sync + Send
{
}