1use crate::error::Error;
6use crate::mayo_signature::Signature;
7use crate::params::MayoParameter;
8use crate::signing_key::SigningKey;
9use crate::verify::{
10 VerifyScratch, expand_public_key, mayo_verify, mayo_verify_with_expanded_pk,
11 mayo_verify_with_expanded_pk_and_scratch,
12};
13use core::marker::PhantomData;
14
15#[derive(Clone)]
17pub struct VerifyingKey<P: MayoParameter> {
18 pub(crate) bytes: Vec<u8>,
19 pub(crate) _marker: PhantomData<P>,
20}
21
22impl<P: MayoParameter> AsRef<[u8]> for VerifyingKey<P> {
23 fn as_ref(&self) -> &[u8] {
24 &self.bytes
25 }
26}
27
28impl<P: MayoParameter> TryFrom<&[u8]> for VerifyingKey<P> {
29 type Error = Error;
30
31 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
32 if bytes.len() != P::CPK_BYTES {
33 return Err(Error::InvalidKeyLength {
34 expected: P::CPK_BYTES,
35 got: bytes.len(),
36 });
37 }
38 Ok(Self::from_bytes_unchecked(bytes.to_vec()))
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::from_bytes_unchecked(bytes))
53 }
54}
55
56impl<P: MayoParameter> TryFrom<&Vec<u8>> for VerifyingKey<P> {
57 type Error = Error;
58
59 fn try_from(bytes: &Vec<u8>) -> Result<Self, Self::Error> {
60 Self::try_from(bytes.as_slice())
61 }
62}
63
64impl<P: MayoParameter> TryFrom<Box<[u8]>> for VerifyingKey<P> {
65 type Error = Error;
66
67 fn try_from(bytes: Box<[u8]>) -> Result<Self, Self::Error> {
68 if bytes.len() != P::CPK_BYTES {
69 return Err(Error::InvalidKeyLength {
70 expected: P::CPK_BYTES,
71 got: bytes.len(),
72 });
73 }
74 Ok(Self::from_bytes_unchecked(bytes.into_vec()))
75 }
76}
77
78impl<P: MayoParameter> PartialEq for VerifyingKey<P> {
79 fn eq(&self, other: &Self) -> bool {
80 self.bytes == other.bytes
81 }
82}
83
84impl<P: MayoParameter> Eq for VerifyingKey<P> {}
85
86impl<P: MayoParameter> core::fmt::Debug for VerifyingKey<P> {
87 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88 f.debug_struct("VerifyingKey")
89 .field("variant", &P::NAME)
90 .field("bytes", &hex::encode(&self.bytes))
91 .finish()
92 }
93}
94
95impl<P: MayoParameter> From<&SigningKey<P>> for VerifyingKey<P> {
96 fn from(sk: &SigningKey<P>) -> Self {
97 Self::from_bytes_unchecked(sk.cpk.clone())
98 }
99}
100
101impl<P: MayoParameter> signature::Verifier<Signature<P>> for VerifyingKey<P> {
102 fn verify(&self, msg: &[u8], signature: &Signature<P>) -> Result<(), signature::Error> {
103 mayo_verify::<P>(msg, signature.as_ref(), &self.bytes).map_err(Into::into)
104 }
105}
106
107impl<P: MayoParameter> VerifyingKey<P> {
108 pub(crate) fn from_bytes_unchecked(bytes: Vec<u8>) -> Self {
109 Self {
110 bytes,
111 _marker: PhantomData,
112 }
113 }
114
115 pub fn expand(&self) -> ExpandedVerifyingKey<P> {
117 ExpandedVerifyingKey::from_bytes_unchecked(self.bytes.clone())
118 }
119}
120
121#[derive(Clone)]
126pub struct ExpandedVerifyingKey<P: MayoParameter> {
127 bytes: Vec<u8>,
128 expanded_pk: Vec<u64>,
129 p3: Vec<u64>,
130 _marker: PhantomData<P>,
131}
132
133pub struct VerificationContext<P: MayoParameter> {
138 key: ExpandedVerifyingKey<P>,
139 scratch: VerifyScratch,
140}
141
142impl<P: MayoParameter> AsRef<[u8]> for ExpandedVerifyingKey<P> {
143 fn as_ref(&self) -> &[u8] {
144 &self.bytes
145 }
146}
147
148impl<P: MayoParameter> TryFrom<&[u8]> for ExpandedVerifyingKey<P> {
149 type Error = Error;
150
151 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
152 VerifyingKey::<P>::try_from(bytes).map(|vk| vk.expand())
153 }
154}
155
156impl<P: MayoParameter> TryFrom<Vec<u8>> for ExpandedVerifyingKey<P> {
157 type Error = Error;
158
159 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
160 if bytes.len() != P::CPK_BYTES {
161 return Err(Error::InvalidKeyLength {
162 expected: P::CPK_BYTES,
163 got: bytes.len(),
164 });
165 }
166 Ok(Self::from_bytes_unchecked(bytes))
167 }
168}
169
170impl<P: MayoParameter> TryFrom<&Vec<u8>> for ExpandedVerifyingKey<P> {
171 type Error = Error;
172
173 fn try_from(bytes: &Vec<u8>) -> Result<Self, Self::Error> {
174 Self::try_from(bytes.as_slice())
175 }
176}
177
178impl<P: MayoParameter> TryFrom<Box<[u8]>> for ExpandedVerifyingKey<P> {
179 type Error = Error;
180
181 fn try_from(bytes: Box<[u8]>) -> Result<Self, Self::Error> {
182 Self::try_from(bytes.into_vec())
183 }
184}
185
186impl<P: MayoParameter> From<&VerifyingKey<P>> for ExpandedVerifyingKey<P> {
187 fn from(vk: &VerifyingKey<P>) -> Self {
188 vk.expand()
189 }
190}
191
192impl<P: MayoParameter> From<&SigningKey<P>> for ExpandedVerifyingKey<P> {
193 fn from(sk: &SigningKey<P>) -> Self {
194 Self::from_bytes_unchecked(sk.cpk.clone())
195 }
196}
197
198impl<P: MayoParameter> PartialEq for ExpandedVerifyingKey<P> {
199 fn eq(&self, other: &Self) -> bool {
200 self.bytes == other.bytes
201 }
202}
203
204impl<P: MayoParameter> Eq for ExpandedVerifyingKey<P> {}
205
206impl<P: MayoParameter> PartialEq for VerificationContext<P> {
207 fn eq(&self, other: &Self) -> bool {
208 self.key == other.key
209 }
210}
211
212impl<P: MayoParameter> Eq for VerificationContext<P> {}
213
214impl<P: MayoParameter> core::fmt::Debug for ExpandedVerifyingKey<P> {
215 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
216 f.debug_struct("ExpandedVerifyingKey")
217 .field("variant", &P::NAME)
218 .field("bytes", &hex::encode(&self.bytes))
219 .finish()
220 }
221}
222
223impl<P: MayoParameter> core::fmt::Debug for VerificationContext<P> {
224 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
225 f.debug_struct("VerificationContext")
226 .field("variant", &P::NAME)
227 .field("key", &self.key)
228 .finish_non_exhaustive()
229 }
230}
231
232impl<P: MayoParameter> signature::Verifier<Signature<P>> for ExpandedVerifyingKey<P> {
233 fn verify(&self, msg: &[u8], signature: &Signature<P>) -> Result<(), signature::Error> {
234 mayo_verify_with_expanded_pk::<P>(msg, signature.as_ref(), &self.expanded_pk, &self.p3)
235 .map_err(Into::into)
236 }
237}
238
239impl<P: MayoParameter> ExpandedVerifyingKey<P> {
240 fn from_bytes_unchecked(bytes: Vec<u8>) -> Self {
241 let (expanded_pk, p3) = expand_public_key::<P>(&bytes);
242 Self {
243 bytes,
244 expanded_pk,
245 p3,
246 _marker: PhantomData,
247 }
248 }
249
250 pub fn compact(&self) -> VerifyingKey<P> {
252 VerifyingKey::from_bytes_unchecked(self.bytes.clone())
253 }
254
255 pub fn context(&self) -> VerificationContext<P> {
257 VerificationContext::from(self)
258 }
259}
260
261impl<P: MayoParameter> VerificationContext<P> {
262 pub fn verify(&mut self, msg: &[u8], signature: &Signature<P>) -> Result<(), signature::Error> {
264 mayo_verify_with_expanded_pk_and_scratch::<P>(
265 msg,
266 signature.as_ref(),
267 &self.key.expanded_pk,
268 &self.key.p3,
269 &mut self.scratch,
270 )
271 .map_err(Into::into)
272 }
273
274 pub fn verifying_key(&self) -> &ExpandedVerifyingKey<P> {
276 &self.key
277 }
278}
279
280impl<P: MayoParameter> From<&ExpandedVerifyingKey<P>> for VerificationContext<P> {
281 fn from(key: &ExpandedVerifyingKey<P>) -> Self {
282 Self {
283 key: key.clone(),
284 scratch: VerifyScratch::new::<P>(),
285 }
286 }
287}
288
289impl<P: MayoParameter> From<&VerifyingKey<P>> for VerificationContext<P> {
290 fn from(key: &VerifyingKey<P>) -> Self {
291 Self::from(&key.expand())
292 }
293}
294
295#[cfg(feature = "serde")]
296impl<P: MayoParameter> serde::Serialize for VerifyingKey<P> {
297 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
298 where
299 S: serde::Serializer,
300 {
301 serdect::slice::serialize_hex_lower_or_bin(&self.bytes, serializer)
302 }
303}
304
305#[cfg(feature = "serde")]
306impl<'de, P: MayoParameter> serde::Deserialize<'de> for VerifyingKey<P> {
307 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
308 where
309 D: serde::Deserializer<'de>,
310 {
311 let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?;
312 Self::try_from(bytes).map_err(serde::de::Error::custom)
313 }
314}
315
316#[cfg(feature = "serde")]
317impl<P: MayoParameter> serde::Serialize for ExpandedVerifyingKey<P> {
318 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
319 where
320 S: serde::Serializer,
321 {
322 serdect::slice::serialize_hex_lower_or_bin(&self.bytes, serializer)
323 }
324}
325
326#[cfg(feature = "serde")]
327impl<'de, P: MayoParameter> serde::Deserialize<'de> for ExpandedVerifyingKey<P> {
328 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
329 where
330 D: serde::Deserializer<'de>,
331 {
332 let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?;
333 Self::try_from(bytes).map_err(serde::de::Error::custom)
334 }
335}