signatory/ed25519/
verify.rs

1//! Ed25519 keys.
2
3use super::{Signature, ALGORITHM_ID, ALGORITHM_OID};
4use crate::{Error, Result};
5use core::cmp::Ordering;
6use pkcs8::{der::asn1, EncodePublicKey};
7use signature::Verifier;
8
9/// Ed25519 verifying key.
10#[derive(Copy, Clone, Debug, Eq, PartialEq)]
11pub struct VerifyingKey {
12    inner: ed25519_dalek::VerifyingKey,
13}
14
15impl VerifyingKey {
16    /// Size of a serialized Ed25519 verifying key in bytes.
17    pub const BYTE_SIZE: usize = 32;
18
19    /// Parse an Ed25519 public key from raw bytes
20    /// (i.e. compressed Edwards-y coordinate)
21    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
22        ed25519_dalek::VerifyingKey::try_from(bytes)
23            .map(|inner| VerifyingKey { inner })
24            .map_err(|_| Error::Parse)
25    }
26
27    /// Serialize this key as a byte array.
28    pub fn to_bytes(self) -> [u8; Self::BYTE_SIZE] {
29        self.inner.to_bytes()
30    }
31}
32
33impl AsRef<[u8; Self::BYTE_SIZE]> for VerifyingKey {
34    fn as_ref(&self) -> &[u8; Self::BYTE_SIZE] {
35        self.inner.as_bytes()
36    }
37}
38
39impl From<&ed25519_dalek::SigningKey> for VerifyingKey {
40    fn from(signing_key: &ed25519_dalek::SigningKey) -> VerifyingKey {
41        Self {
42            inner: signing_key.verifying_key(),
43        }
44    }
45}
46
47impl EncodePublicKey for VerifyingKey {
48    fn to_public_key_der(&self) -> pkcs8::spki::Result<pkcs8::Document> {
49        pkcs8::SubjectPublicKeyInfoRef {
50            algorithm: ALGORITHM_ID,
51            subject_public_key: asn1::BitStringRef::new(0, self.inner.as_bytes())?,
52        }
53        .try_into()
54    }
55}
56
57impl TryFrom<pkcs8::SubjectPublicKeyInfoRef<'_>> for VerifyingKey {
58    type Error = pkcs8::spki::Error;
59
60    fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> pkcs8::spki::Result<Self> {
61        spki.algorithm.assert_algorithm_oid(ALGORITHM_OID)?;
62
63        if spki.algorithm.parameters.is_some() {
64            return Err(pkcs8::spki::Error::OidUnknown {
65                oid: spki.algorithm.parameters_oid()?,
66            });
67        }
68
69        spki.subject_public_key
70            .as_bytes()
71            .and_then(|bytes| Self::from_bytes(bytes).ok())
72            .ok_or(pkcs8::spki::Error::KeyMalformed)
73    }
74}
75
76impl TryFrom<&[u8]> for VerifyingKey {
77    type Error = Error;
78
79    fn try_from(bytes: &[u8]) -> Result<Self> {
80        Self::from_bytes(bytes)
81    }
82}
83
84impl Verifier<Signature> for VerifyingKey {
85    fn verify(&self, msg: &[u8], sig: &Signature) -> signature::Result<()> {
86        self.inner.verify(msg, sig)
87    }
88}
89
90impl Ord for VerifyingKey {
91    fn cmp(&self, other: &Self) -> Ordering {
92        self.inner.as_bytes().cmp(other.inner.as_bytes())
93    }
94}
95
96impl PartialOrd for VerifyingKey {
97    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
98        Some(self.cmp(other))
99    }
100}