pub mod serialized_public_key;
pub use serialized_public_key::SerializedPublicKey;
use core::convert::TryFrom;
use core::fmt;
use secp256k1::Secp256k1;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum KeyFormat {
Compressed,
Uncompressed,
}
impl KeyFormat {
#[inline]
pub fn is_compressed(self) -> bool {
self == KeyFormat::Compressed
}
#[inline]
pub fn is_uncompressed(self) -> bool {
self == KeyFormat::Uncompressed
}
}
impl core::ops::Not for KeyFormat {
type Output = Self;
#[inline]
fn not(self) -> Self::Output {
match self {
KeyFormat::Compressed => KeyFormat::Uncompressed,
KeyFormat::Uncompressed => KeyFormat::Compressed,
}
}
}
mod sealed {
use secp256k1::Secp256k1;
pub trait Key: Copy + Eq {}
impl Key for secp256k1::PublicKey {}
impl Key for secp256k1::SecretKey {}
impl Key for secp256k1::KeyPair {}
pub trait PublicKey: Key {
fn public_key(self) -> secp256k1::PublicKey;
}
impl PublicKey for secp256k1::PublicKey {
#[inline]
fn public_key(self) -> secp256k1::PublicKey {
self
}
}
impl PublicKey for secp256k1::KeyPair {
#[inline]
fn public_key(self) -> secp256k1::PublicKey {
self.into()
}
}
pub trait PrivateKey: Key {
fn private_key(self) -> secp256k1::SecretKey;
#[inline]
fn compute_public_key<C: secp256k1::Signing>(self, context: &Secp256k1<C>) -> secp256k1::PublicKey {
secp256k1::PublicKey::from_secret_key(context, &self.private_key())
}
}
impl PrivateKey for secp256k1::SecretKey {
#[inline]
fn private_key(self) -> secp256k1::SecretKey {
self
}
}
impl PrivateKey for secp256k1::KeyPair {
#[inline]
fn private_key(self) -> secp256k1::SecretKey {
self.into()
}
#[inline]
fn compute_public_key<C: secp256k1::Signing>(self, _context: &Secp256k1<C>) -> secp256k1::PublicKey {
self.into()
}
}
}
pub trait Key: sealed::Key {
}
pub trait PublicKey: Key + sealed::PublicKey {
}
pub trait PrivateKey: Key + sealed::PrivateKey {
}
impl Key for secp256k1::PublicKey {}
impl Key for secp256k1::SecretKey {}
impl Key for secp256k1::KeyPair {}
impl PublicKey for secp256k1::PublicKey {}
impl PrivateKey for secp256k1::SecretKey {}
impl PublicKey for secp256k1::KeyPair {}
impl PrivateKey for secp256k1::KeyPair {}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct Legacy<K: Key> {
key: K,
format: KeyFormat,
}
impl<K: Key> Legacy<K> {
#[inline]
pub fn from_raw(key: K, format: KeyFormat) -> Self {
Legacy {
key,
format,
}
}
#[inline]
pub fn format(self) -> KeyFormat {
self.format
}
#[inline]
pub fn raw_key(self) -> K {
self.key
}
#[inline]
pub fn force_set_format(&mut self, format: KeyFormat) {
self.format = format;
}
#[inline]
pub fn force_to_compressed(self) -> Compressed<K> {
Compressed::from_raw(self.key)
}
#[inline]
pub fn eq_key(self, rhs: Self) -> bool {
self.key == rhs.key
}
}
impl<K: PublicKey> Legacy<K> {
#[inline]
pub fn serialize_public_key(self) -> SerializedPublicKey {
SerializedPublicKey::new(self.key.public_key(), self.format)
}
}
impl<K: PrivateKey> Legacy<K> {
pub fn compute_public_key<C: secp256k1::Signing>(self, context: &Secp256k1<C>) -> Legacy<secp256k1::PublicKey> {
Legacy::from_raw(self.key.compute_public_key(context), self.format)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Compressed<K: Key> {
key: K,
}
impl<K: Key> Compressed<K> {
pub fn from_raw(key: K) -> Self {
Compressed {
key,
}
}
pub fn raw_key(self) -> K {
self.key
}
}
impl<K: PublicKey> Compressed<K> {
#[inline]
pub fn serialize_public_key(self) -> [u8; 33] {
self.key.public_key().serialize()
}
}
impl<K: PrivateKey> Compressed<K> {
pub fn compute_public_key<C: secp256k1::Signing>(self, context: &Secp256k1<C>) -> Compressed<secp256k1::PublicKey> {
Compressed::from_raw(self.key.compute_public_key(context))
}
}
impl From<Legacy<secp256k1::KeyPair>> for Legacy<secp256k1::PublicKey> {
fn from(value: Legacy<secp256k1::KeyPair>) -> Self {
Legacy::from_raw(value.raw_key().into(), value.format())
}
}
impl From<Legacy<secp256k1::KeyPair>> for Legacy<secp256k1::SecretKey> {
fn from(value: Legacy<secp256k1::KeyPair>) -> Self {
Legacy::from_raw(value.raw_key().into(), value.format())
}
}
impl From<Compressed<secp256k1::KeyPair>> for Compressed<secp256k1::PublicKey> {
fn from(value: Compressed<secp256k1::KeyPair>) -> Self {
Compressed::from_raw(value.raw_key().into())
}
}
impl From<Compressed<secp256k1::KeyPair>> for Compressed<secp256k1::SecretKey> {
fn from(value: Compressed<secp256k1::KeyPair>) -> Self {
Compressed::from_raw(value.raw_key().into())
}
}
impl<K: Key> From<Compressed<K>> for Legacy<K> {
fn from(value: Compressed<K>) -> Self {
Self::from_raw(value.raw_key(), KeyFormat::Compressed)
}
}
impl<K: Key> TryFrom<Legacy<K>> for Compressed<K> {
type Error = KeyNotCompressedError;
fn try_from(value: Legacy<K>) -> Result<Self, Self::Error> {
match value.format() {
KeyFormat::Compressed => Ok(Self::from_raw(value.raw_key())),
KeyFormat::Uncompressed => Err(KeyNotCompressedError {}),
}
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct KeyNotCompressedError {
}
impl fmt::Display for KeyNotCompressedError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("an uncompressed key type is used in a context requiring compressed keys only")
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for KeyNotCompressedError {}