use crate::{asymmetric, ecdsa::algorithm::CurveAlgorithm, ed25519};
use ::ecdsa::elliptic_curve::{
bigint::Encoding as _, generic_array::GenericArray, sec1, FieldSize, PointCompression,
PrimeCurve,
};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct PublicKey {
pub algorithm: asymmetric::Algorithm,
pub bytes: Vec<u8>,
}
#[allow(clippy::len_without_is_empty)]
impl PublicKey {
pub fn into_vec(self) -> Vec<u8> {
self.into()
}
pub fn len(&self) -> usize {
self.bytes.len()
}
pub fn as_slice(&self) -> &[u8] {
self.as_ref()
}
pub fn ecdsa<C>(&self) -> Option<sec1::EncodedPoint<C>>
where
C: PrimeCurve + CurveAlgorithm + PointCompression,
FieldSize<C>: sec1::ModulusSize,
{
if self.algorithm != C::asymmetric_algorithm() || self.bytes.len() != C::UInt::BYTE_SIZE * 2
{
return None;
}
let mut bytes = GenericArray::default();
bytes.copy_from_slice(&self.bytes);
let result = sec1::EncodedPoint::<C>::from_untagged_bytes(&bytes);
if C::COMPRESS_POINTS {
Some(result.compress())
} else {
Some(result)
}
}
pub fn ed25519(&self) -> Option<ed25519::PublicKey> {
if self.algorithm == asymmetric::Algorithm::Ed25519 {
ed25519::PublicKey::from_bytes(&self.bytes)
} else {
None
}
}
}
impl AsRef<[u8]> for PublicKey {
fn as_ref(&self) -> &[u8] {
self.bytes.as_ref()
}
}
impl Into<Vec<u8>> for PublicKey {
fn into(self) -> Vec<u8> {
self.bytes
}
}