use crate::types::*;
use crate::PublicKey;
use crate::Result;
pub use secp256k1::SecretKey;
use secp256k1::{scalar::Scalar, Secp256k1, SignOnly};
pub trait PrivateKey: Sized {
type PublicKey: PublicKey;
fn from_bytes(bytes: &PrivateKeyBytes) -> Result<Self>;
fn to_bytes(&self) -> PrivateKeyBytes;
fn derive_child(&self, other: PrivateKeyBytes) -> Result<Self>;
fn public_key(&self) -> Self::PublicKey;
}
impl PrivateKey for SecretKey {
type PublicKey = secp256k1::PublicKey;
fn from_bytes(bytes: &PrivateKeyBytes) -> Result<Self> {
Ok(SecretKey::from_slice(bytes)?)
}
fn to_bytes(&self) -> PrivateKeyBytes {
*self.as_ref()
}
fn derive_child(&self, other: PrivateKeyBytes) -> Result<Self> {
Ok((*self).add_tweak(&Scalar::from_be_bytes(other)?)?)
}
fn public_key(&self) -> Self::PublicKey {
let engine = Secp256k1::<SignOnly>::signing_only();
secp256k1::PublicKey::from_secret_key(&engine, self)
}
}