zerotier_crypto/
public_key.rsuse arrayref::array_ref;
use hex::{FromHex, FromHexError};
use std::convert::TryFrom;
use std::str::FromStr;
use crate::SecretKey;
pub const PUBLIC_KEY_LENGTH: usize = 64;
#[derive(Clone, Debug)]
pub struct PublicKey {
pub x25519: x25519_dalek::PublicKey,
pub ed25519: ed25519_dalek::VerifyingKey,
}
pub type PublicKeyError = ed25519_dalek::SignatureError;
impl From<&SecretKey> for PublicKey {
fn from(secret_key: &SecretKey) -> Self {
Self {
x25519: x25519_dalek::PublicKey::from(&secret_key.x25519),
ed25519: ed25519_dalek::VerifyingKey::from(&secret_key.ed25519),
}
}
}
impl Into<[u8; PUBLIC_KEY_LENGTH]> for &PublicKey {
fn into(self) -> [u8; PUBLIC_KEY_LENGTH] {
let mut buf = [0u8; PUBLIC_KEY_LENGTH];
buf[..32].copy_from_slice(self.x25519.as_bytes());
buf[32..].copy_from_slice(self.ed25519.as_bytes());
buf
}
}
impl TryFrom<&[u8; PUBLIC_KEY_LENGTH]> for PublicKey {
type Error = PublicKeyError;
fn try_from(bytes: &[u8; PUBLIC_KEY_LENGTH]) -> Result<Self, Self::Error> {
let x25519_bytes = array_ref![bytes, 0, 32];
let ed25519_bytes = array_ref![bytes, 32, 32];
Ok(Self {
x25519: x25519_dalek::PublicKey::from(x25519_bytes.clone()),
ed25519: ed25519_dalek::VerifyingKey::from_bytes(ed25519_bytes)?,
})
}
}
#[derive(Debug)]
pub enum FromSlicePublicKeyError {
InvalidLength(usize),
PublicKeyError(PublicKeyError),
}
impl From<PublicKeyError> for FromSlicePublicKeyError {
fn from(err: PublicKeyError) -> Self {
Self::PublicKeyError(err)
}
}
impl TryFrom<&[u8]> for PublicKey {
type Error = FromSlicePublicKeyError;
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
let length = bytes.len();
if length == PUBLIC_KEY_LENGTH {
Ok(Self::try_from(array_ref![bytes, 0, PUBLIC_KEY_LENGTH])?)
} else {
Err(Self::Error::InvalidLength(length))
}
}
}
#[derive(Debug)]
pub enum FromStrPublicKeyError {
DecodeError(FromHexError),
InvalidByteLength(usize),
PublicKeyError(PublicKeyError),
}
impl From<FromHexError> for FromStrPublicKeyError {
fn from(err: FromHexError) -> Self {
Self::DecodeError(err)
}
}
impl From<PublicKeyError> for FromStrPublicKeyError {
fn from(err: PublicKeyError) -> Self {
Self::PublicKeyError(err)
}
}
impl From<FromSlicePublicKeyError> for FromStrPublicKeyError {
fn from(err: FromSlicePublicKeyError) -> Self {
match err {
FromSlicePublicKeyError::InvalidLength(len) => Self::InvalidByteLength(len),
FromSlicePublicKeyError::PublicKeyError(err) => err.into(),
}
}
}
impl FromHex for PublicKey {
type Error = FromStrPublicKeyError;
fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
Ok(Self::try_from(&<[u8; PUBLIC_KEY_LENGTH]>::from_hex(hex)?)?)
}
}
impl FromStr for PublicKey {
type Err = FromStrPublicKeyError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::from_hex(s)
}
}