use std::cmp::Ordering;
use std::ops::Deref;
use crate::*;
impl MultiDisplay<Encoding> for ec25519::x25519::PublicKey {
type Display = String;
fn display_fmt(&self, f: &Encoding) -> String { f.encode(self.as_slice()) }
}
impl EcPk for ec25519::x25519::PublicKey {
const COMPRESSED_LEN: usize = 32;
const CURVE_NAME: &'static str = "Curve25519";
type Compressed = [u8; 32];
fn base_point() -> Self { ec25519::x25519::PublicKey::base_point() }
fn to_pk_compressed(&self) -> Self::Compressed { *self.deref() }
fn from_pk_compressed(pk: Self::Compressed) -> Result<Self, EcPkInvalid> {
Ok(ec25519::x25519::PublicKey::new(pk))
}
fn from_pk_compressed_slice(slice: &[u8]) -> Result<Self, EcPkInvalid> {
if slice.len() != Self::COMPRESSED_LEN {
return Err(EcPkInvalid {});
}
let mut buf = [0u8; 32];
buf.copy_from_slice(slice);
Self::from_pk_compressed(buf)
}
}
impl EcSk for ec25519::x25519::SecretKey {
type Pk = ec25519::x25519::PublicKey;
fn generate_keypair() -> (Self, Self::Pk)
where Self: Sized {
let pair = ec25519::x25519::KeyPair::generate();
(pair.sk, pair.pk)
}
fn to_pk(&self) -> Result<Self::Pk, EcSkInvalid> {
self.recover_public_key().map_err(EcSkInvalid::from)
}
}
#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)]
#[wrapper(Deref)]
pub struct SharedSecret([u8; 32]);
impl AsRef<[u8]> for SharedSecret {
fn as_ref(&self) -> &[u8] { &self.0 }
}
impl SharedSecret {
pub fn empty() -> Self { SharedSecret([0u8; 32]) }
pub fn is_empty(self) -> bool { self == Self::empty() }
}
#[derive(Wrapper, Copy, Clone, PartialEq, Eq, Hash, Debug, From)]
#[wrapper(Deref)]
pub struct PublicKey(#[from] ec25519::x25519::PublicKey);
impl PartialOrd for PublicKey {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.0.as_ref().partial_cmp(other.0.as_ref())
}
}
impl Ord for PublicKey {
fn cmp(&self, other: &Self) -> Ordering { self.0.as_ref().cmp(other.0.as_ref()) }
}
impl EcPk for PublicKey {
const COMPRESSED_LEN: usize = 32;
const CURVE_NAME: &'static str = "Curve25519";
type Compressed = [u8; 32];
fn base_point() -> Self { Self(ec25519::x25519::PublicKey::base_point()) }
fn to_pk_compressed(&self) -> Self::Compressed { self.0.to_pk_compressed() }
fn from_pk_compressed(pk: Self::Compressed) -> Result<Self, EcPkInvalid> {
ec25519::x25519::PublicKey::from_pk_compressed(pk).map(Self)
}
fn from_pk_compressed_slice(slice: &[u8]) -> Result<Self, EcPkInvalid> {
ec25519::x25519::PublicKey::from_pk_compressed_slice(slice).map(Self)
}
}
impl MultiDisplay<Encoding> for PublicKey {
type Display = String;
fn display_fmt(&self, f: &Encoding) -> Self::Display { self.0.display_fmt(f) }
}
#[derive(Wrapper, Clone, PartialEq, Eq, Hash, Debug, From)]
#[wrapper(Deref)]
pub struct PrivateKey(#[from] ec25519::x25519::SecretKey);
impl PartialOrd for PrivateKey {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
}
impl Ord for PrivateKey {
fn cmp(&self, other: &Self) -> Ordering { self.0.cmp(&other.0) }
}
impl EcSk for PrivateKey {
type Pk = PublicKey;
fn generate_keypair() -> (Self, Self::Pk)
where Self: Sized {
let (sk, pk) = ec25519::x25519::SecretKey::generate_keypair();
(sk.into(), pk.into())
}
fn to_pk(&self) -> Result<PublicKey, EcSkInvalid> { self.0.to_pk().map(PublicKey::from) }
}
impl Ecdh for ec25519::x25519::SecretKey {
type SharedSecret = [u8; 32];
fn ecdh(&self, pk: &Self::Pk) -> Result<Self::SharedSecret, EcdhError> { Ok(*pk.dh(self)?) }
}
impl Ecdh for PrivateKey {
type SharedSecret = SharedSecret;
fn ecdh(&self, pk: &PublicKey) -> Result<SharedSecret, EcdhError> {
self.0.ecdh(&pk.0).map(SharedSecret::from)
}
}