use crate::{pubkey::PubKeyError, seckey::SecKeyError, CurvePoint, PubKey, ScalarField, SecKey};
use core::fmt;
use rand::{self, CryptoRng, RngCore};
use thiserror::Error;
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum KeypairError {
#[error(transparent)]
SecretKey(#[from] SecKeyError),
#[error(transparent)]
PublicKey(#[from] PubKeyError),
#[error("point not on curve")]
NonCurvePoint,
}
pub type Result<T> = std::result::Result<T, KeypairError>;
#[derive(Clone, PartialEq, Eq)]
pub struct Keypair {
pub(crate) secret: SecKey,
pub public: PubKey,
}
impl Keypair {
pub fn from_parts_unsafe(secret: ScalarField, public: CurvePoint) -> Self {
Self {
secret: SecKey::new(secret),
public: PubKey::from_point_unsafe(public),
}
}
pub fn from_secret_key(secret_key: SecKey) -> Result<Self> {
let public = PubKey::from_secret_key(secret_key.clone())?;
Ok(Self::from_parts_unsafe(
secret_key.into_scalar(),
public.into_point(),
))
}
pub fn rand(rng: &mut (impl RngCore + CryptoRng)) -> Result<Self> {
let sec_key: SecKey = SecKey::rand(rng);
Keypair::from_secret_key(sec_key)
}
pub fn from_bytes(secret_bytes: &[u8]) -> Result<Self> {
let secret = SecKey::from_bytes(secret_bytes)?;
Keypair::from_secret_key(secret)
}
pub fn from_hex(secret_hex: &str) -> Result<Self> {
let secret = SecKey::from_hex(secret_hex)?;
Keypair::from_secret_key(secret)
}
pub fn get_address(self) -> String {
self.public.into_address()
}
pub fn to_bytes(&self) -> Vec<u8> {
self.secret.to_bytes()
}
pub fn to_hex(&self) -> String {
hex::encode(self.to_bytes())
}
}
impl fmt::Debug for Keypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.public)
}
}
impl fmt::Display for Keypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.public)
}
}