use crate::error::{DecodingError, SigningError, VerificationError};
use asn1_der::{DerObject, FromDerObject};
use core::fmt;
use libsecp256k1::Message;
use rand::RngCore;
use serde::de::Error as SerdeError;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes};
use sha2::{Digest as ShaDigestTrait, Sha256};
use zeroize::Zeroize;
#[derive(Clone)]
pub struct Keypair {
secret: SecretKey,
public: PublicKey,
}
impl Keypair {
pub fn generate() -> Self {
Keypair::from(SecretKey::generate())
}
pub fn public(&self) -> &PublicKey {
&self.public
}
pub fn secret(&self) -> &SecretKey {
&self.secret
}
}
impl fmt::Debug for Keypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Keypair")
.field("public", &self.public)
.finish()
}
}
impl From<SecretKey> for Keypair {
fn from(secret: SecretKey) -> Self {
let public = PublicKey(libsecp256k1::PublicKey::from_secret_key(&secret.0));
Keypair { secret, public }
}
}
impl From<Keypair> for SecretKey {
fn from(kp: Keypair) -> Self {
kp.secret
}
}
#[derive(Clone)]
pub struct SecretKey(libsecp256k1::SecretKey);
impl fmt::Debug for SecretKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SecretKey")
}
}
impl SecretKey {
pub fn generate() -> Self {
let mut r = rand::thread_rng();
let mut b = [0; libsecp256k1::util::SECRET_KEY_SIZE];
loop {
r.fill_bytes(&mut b);
if let Ok(k) = libsecp256k1::SecretKey::parse(&b) {
return SecretKey(k);
}
}
}
pub fn from_bytes(mut sk: impl AsMut<[u8]>) -> Result<Self, DecodingError> {
let sk_bytes = sk.as_mut();
let secret = libsecp256k1::SecretKey::parse_slice(&*sk_bytes)
.map_err(|_| DecodingError::Secp256k1)?;
sk_bytes.zeroize();
Ok(SecretKey(secret))
}
pub fn from_der(mut der: impl AsMut<[u8]>) -> Result<SecretKey, DecodingError> {
let der_obj = der.as_mut();
let obj: Vec<DerObject> =
FromDerObject::deserialize((*der_obj).iter()).map_err(|_| DecodingError::Secp256k1)?;
der_obj.zeroize();
let sk_obj = obj.into_iter().nth(1).ok_or(DecodingError::Secp256k1)?;
let mut sk_bytes: Vec<u8> =
FromDerObject::from_der_object(sk_obj).map_err(|_| DecodingError::Secp256k1)?;
let sk = SecretKey::from_bytes(&mut sk_bytes)?;
sk_bytes.zeroize();
Ok(sk)
}
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
self.sign_hashed(Sha256::digest(msg).as_ref())
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0.serialize()
}
pub fn sign_hashed(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
let m = Message::parse_slice(msg).map_err(SigningError::Secp256k1)?;
Ok(libsecp256k1::sign(&m, &self.0)
.0
.serialize_der()
.as_ref()
.into())
}
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct PublicKey(libsecp256k1::PublicKey);
impl PublicKey {
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> {
self.verify_hashed(Sha256::digest(msg).as_ref(), sig)
}
pub fn verify_hashed(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> {
Message::parse_slice(msg)
.and_then(|m| {
libsecp256k1::Signature::parse_der(sig)
.map(|s| libsecp256k1::verify(&m, &s, &self.0))
})
.map_err(|e| {
VerificationError::Secp256k1(
e,
bs58::encode(sig).into_string(),
bs58::encode(self.0.serialize_compressed()).into_string(),
)
})
.map(|_| ())
}
pub fn encode(&self) -> [u8; 33] {
self.0.serialize_compressed()
}
pub fn encode_uncompressed(&self) -> [u8; 65] {
self.0.serialize()
}
pub fn decode(bytes: &[u8]) -> Result<Self, DecodingError> {
libsecp256k1::PublicKey::parse_slice(bytes, Some(libsecp256k1::PublicKeyFormat::Compressed))
.map_err(|_| DecodingError::Secp256k1)
.map(PublicKey)
}
}
impl Serialize for PublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
SerdeBytes::new(self.encode().to_vec().as_slice()).serialize(serializer)
}
}
impl<'d> Deserialize<'d> for PublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'d>,
{
let bytes = <SerdeByteBuf>::deserialize(deserializer)?;
PublicKey::decode(bytes.as_slice()).map_err(SerdeError::custom)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Signature(pub Vec<u8>);
#[cfg(test)]
mod tests {
use super::*;
use crate::{key_pair, KeyFormat};
use quickcheck::QuickCheck;
fn eq_keypairs(kp1: key_pair::KeyPair, kp2: key_pair::KeyPair) -> bool {
kp1.public() == kp2.public() && kp1.secret().unwrap() == kp2.secret().unwrap()
}
#[test]
fn secp256k1_secret_from_bytes() {
let sk1 = SecretKey::generate();
let mut sk_bytes = [0; 32];
sk_bytes.copy_from_slice(&sk1.0.serialize()[..]);
let sk2 = SecretKey::from_bytes(&mut sk_bytes).unwrap();
assert_eq!(sk1.0.serialize(), sk2.0.serialize());
assert_eq!(sk_bytes, [0; 32]);
}
#[test]
fn secp256k1_keypair_encode_decode() {
fn prop() -> bool {
let kp1 = key_pair::KeyPair::generate(KeyFormat::Secp256k1);
let kp1_enc = libp2p_identity::Keypair::from(kp1.clone());
let kp2 = key_pair::KeyPair::from(kp1_enc);
eq_keypairs(kp1, kp2)
}
QuickCheck::new().tests(10).quickcheck(prop as fn() -> _);
}
}