Skip to main content

pq_mayo/
verifying_key.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3//! MAYO verifying (public) key.
4
5use crate::error::Error;
6use crate::mayo_signature::Signature;
7use crate::params::MayoParameter;
8use crate::signing_key::SigningKey;
9use crate::verify::mayo_verify;
10use core::marker::PhantomData;
11
12/// A MAYO verifying key (compact public key).
13#[derive(Clone)]
14pub struct VerifyingKey<P: MayoParameter> {
15    pub(crate) bytes: Vec<u8>,
16    pub(crate) _marker: PhantomData<P>,
17}
18
19impl<P: MayoParameter> AsRef<[u8]> for VerifyingKey<P> {
20    fn as_ref(&self) -> &[u8] {
21        &self.bytes
22    }
23}
24
25impl<P: MayoParameter> TryFrom<&[u8]> for VerifyingKey<P> {
26    type Error = Error;
27
28    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
29        if bytes.len() != P::CPK_BYTES {
30            return Err(Error::InvalidKeyLength {
31                expected: P::CPK_BYTES,
32                got: bytes.len(),
33            });
34        }
35        Ok(Self {
36            bytes: bytes.to_vec(),
37            _marker: PhantomData,
38        })
39    }
40}
41
42impl<P: MayoParameter> TryFrom<Vec<u8>> for VerifyingKey<P> {
43    type Error = Error;
44
45    fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
46        if bytes.len() != P::CPK_BYTES {
47            return Err(Error::InvalidKeyLength {
48                expected: P::CPK_BYTES,
49                got: bytes.len(),
50            });
51        }
52        Ok(Self {
53            bytes,
54            _marker: PhantomData,
55        })
56    }
57}
58
59impl<P: MayoParameter> TryFrom<&Vec<u8>> for VerifyingKey<P> {
60    type Error = Error;
61
62    fn try_from(bytes: &Vec<u8>) -> Result<Self, Self::Error> {
63        Self::try_from(bytes.as_slice())
64    }
65}
66
67impl<P: MayoParameter> TryFrom<Box<[u8]>> for VerifyingKey<P> {
68    type Error = Error;
69
70    fn try_from(bytes: Box<[u8]>) -> Result<Self, Self::Error> {
71        if bytes.len() != P::CPK_BYTES {
72            return Err(Error::InvalidKeyLength {
73                expected: P::CPK_BYTES,
74                got: bytes.len(),
75            });
76        }
77        Ok(Self {
78            bytes: bytes.into_vec(),
79            _marker: PhantomData,
80        })
81    }
82}
83
84impl<P: MayoParameter> PartialEq for VerifyingKey<P> {
85    fn eq(&self, other: &Self) -> bool {
86        self.bytes == other.bytes
87    }
88}
89
90impl<P: MayoParameter> Eq for VerifyingKey<P> {}
91
92impl<P: MayoParameter> core::fmt::Debug for VerifyingKey<P> {
93    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
94        f.debug_struct("VerifyingKey")
95            .field("variant", &P::NAME)
96            .field("bytes", &hex::encode(&self.bytes))
97            .finish()
98    }
99}
100
101impl<P: MayoParameter> From<&SigningKey<P>> for VerifyingKey<P> {
102    fn from(sk: &SigningKey<P>) -> Self {
103        Self {
104            bytes: sk.cpk.clone(),
105            _marker: PhantomData,
106        }
107    }
108}
109
110impl<P: MayoParameter> signature::Verifier<Signature<P>> for VerifyingKey<P> {
111    fn verify(&self, msg: &[u8], signature: &Signature<P>) -> Result<(), signature::Error> {
112        mayo_verify::<P>(msg, signature.as_ref(), &self.bytes).map_err(Into::into)
113    }
114}
115
116#[cfg(feature = "serde")]
117impl<P: MayoParameter> serde::Serialize for VerifyingKey<P> {
118    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
119    where
120        S: serde::Serializer,
121    {
122        serdect::slice::serialize_hex_lower_or_bin(&self.bytes, serializer)
123    }
124}
125
126#[cfg(feature = "serde")]
127impl<'de, P: MayoParameter> serde::Deserialize<'de> for VerifyingKey<P> {
128    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
129    where
130        D: serde::Deserializer<'de>,
131    {
132        let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?;
133        Self::try_from(bytes).map_err(serde::de::Error::custom)
134    }
135}