use asn1_der::{DerObject, FromDerObject};
use rand::RngCore;
use secp256k1::{Message, Signature};
use sha2::{Digest as ShaDigestTrait, Sha256};
use zeroize::Zeroize;
use std::fmt;
use crate::{Error, Result};
#[derive(Clone)]
pub struct Keypair {
secret_key: SecretKey,
public_key: PublicKey,
}
impl Keypair {
pub fn generate() -> Keypair {
Keypair::from(SecretKey::generate())
}
pub fn as_public_key(&self) -> &PublicKey {
&self.public_key
}
pub fn to_public_key(&self) -> PublicKey {
self.public_key.clone()
}
pub fn as_secret_key(&self) -> &SecretKey {
&self.secret_key
}
}
impl fmt::Debug for Keypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Keypair")
.field("public", &self.public_key)
.finish()
}
}
impl From<SecretKey> for Keypair {
fn from(val: SecretKey) -> Keypair {
let public_key = PublicKey {
public_key: secp256k1::PublicKey::from_secret_key(&val.secret_key),
};
Keypair {
secret_key: SecretKey {
secret_key: val.secret_key,
},
public_key,
}
}
}
impl From<Keypair> for SecretKey {
fn from(val: Keypair) -> SecretKey {
val.secret_key
}
}
#[derive(Clone)]
pub struct SecretKey {
secret_key: secp256k1::SecretKey,
}
impl fmt::Debug for SecretKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SecretKey")
}
}
impl SecretKey {
pub fn generate() -> SecretKey {
let mut r = rand::thread_rng();
let mut b = [0; secp256k1::util::SECRET_KEY_SIZE];
loop {
r.fill_bytes(&mut b);
if let Ok(secret_key) = secp256k1::SecretKey::parse(&b) {
break SecretKey { secret_key };
}
}
}
pub fn from_bytes(mut sk: impl AsMut<[u8]>) -> Result<SecretKey> {
let sk_bytes = sk.as_mut();
let secret_key = match secp256k1::SecretKey::parse_slice(&*sk_bytes) {
Ok(secret_key) => Ok(secret_key),
err @ Err(_) => {
let msg = format!("failed to parse secp256k1 secret key");
err_at!(DecodeError, err, msg)
}
}?;
sk_bytes.zeroize();
Ok(SecretKey { secret_key })
}
pub fn from_der(mut der: impl AsMut<[u8]>) -> Result<SecretKey> {
let val: Vec<DerObject> = {
match FromDerObject::deserialize(der.as_mut().iter()) {
Ok(val) => Ok(val),
err @ Err(_) => {
let msg = format!("Secp256k1 DER ECPrivateKey");
err_at!(DecodeError, err, msg)
}
}?
};
der.as_mut().zeroize();
let sk_val = match val.into_iter().nth(1) {
Some(val) => val,
None => {
let msg = format!("Not enough elements in DER");
err_at!(DecodeError, msg: msg)?
}
};
let mut sk_bytes: Vec<u8> = {
let res = FromDerObject::from_der_object(sk_val);
err_at!(DecodeError, res)?
};
let sk = SecretKey::from_bytes(&mut sk_bytes)?;
sk_bytes.zeroize();
Ok(sk)
}
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>> {
self.sign_hash(Sha256::digest(msg).as_ref())
}
pub fn to_bytes(&self) -> [u8; 32] {
self.secret_key.serialize()
}
fn sign_hash(&self, msg: &[u8]) -> Result<Vec<u8>> {
let m = match Message::parse_slice(msg) {
Ok(m) => Ok(m),
err @ Err(_) => {
let msg = format!("failed to parse secp256k1 digest");
err_at!(SigningError, err, msg)
}
}?;
Ok(secp256k1::sign(&m, &self.secret_key)
.0
.serialize_der()
.as_ref()
.into())
}
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct PublicKey {
public_key: secp256k1::PublicKey,
}
impl PublicKey {
pub fn verify(&self, msg: &[u8], signature: &[u8]) -> bool {
let msg = Sha256::digest(msg);
Message::parse_slice(msg.as_ref())
.and_then(|m| {
Signature::parse_der(signature).map(|s| secp256k1::verify(&m, &s, &self.public_key))
})
.unwrap_or(false)
}
pub fn encode(&self) -> [u8; 33] {
self.public_key.serialize_compressed()
}
pub fn encode_uncompressed(&self) -> [u8; 65] {
self.public_key.serialize()
}
pub fn decode(k: &[u8]) -> Result<PublicKey> {
let format = Some(secp256k1::PublicKeyFormat::Compressed);
match secp256k1::PublicKey::parse_slice(k, format) {
Ok(public_key) => Ok(PublicKey { public_key }),
Err(err) => {
let msg = format!("failed to parse secp256k1 public key");
err_at!(DecodeError, Err(err), msg)
}
}
}
}
#[cfg(test)]
#[path = "secp256k1_test.rs"]
mod secp256k1_test;