1#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
69#![warn(missing_docs)]
70
71#[cfg(all(not(feature = "picnic"), not(feature = "picnic3")))]
73compile_error!("One of the features \"picnic\" and \"picnic3\" is required.");
74
75#[cfg(not(feature = "std"))]
76extern crate alloc;
77
78#[cfg(not(feature = "std"))]
79use alloc::{format, vec, vec::Vec};
80
81use core::fmt::{self, Debug};
82use core::marker::PhantomData;
83use libpicnic_sys::*;
84use paste::paste;
85pub use signature::{self, Error, Signer, Verifier};
86
87#[cfg(feature = "serialization")]
88use serde::{Deserialize, Deserializer, Serialize, Serializer};
89
90#[cfg(feature = "zeroize")]
91use zeroize::{Zeroize, ZeroizeOnDrop};
92
93#[cfg(feature = "subtle")]
94use subtle::{Choice, ConstantTimeEq};
95
96mod wrapper;
97use crate::wrapper::*;
98
99#[cfg(feature = "serialization")]
100mod serialization;
101
102#[cfg(feature = "serialization")]
103use serialization::{deserialize, serialize};
104
105pub trait Parameters: Clone {
107 const PARAM: picnic_params_t;
109 const MAX_SIGNATURE_SIZE: usize;
111 const PRIVATE_KEY_SIZE: usize;
113 const PUBLIC_KEY_SIZE: usize;
115
116 fn parameter_name() -> &'static str;
118}
119
120pub trait RawVerifier {
125 fn verify_raw(&self, msg: &[u8], signature: &[u8]) -> Result<(), Error>;
127}
128
129macro_rules! define_params {
131 ($name:ident, $param:ident) => {
132 paste! {
133 #[doc = $name " parameters"]
134 #[derive(Clone, Debug, PartialEq, Eq)]
135 #[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
136 pub struct $name {}
137
138 impl Parameters for $name {
139 const PARAM: picnic_params_t = picnic_params_t::$param;
140 const MAX_SIGNATURE_SIZE: usize = [<PICNIC_SIGNATURE_SIZE_ $param>];
141 const PRIVATE_KEY_SIZE: usize = [<PICNIC_PRIVATE_KEY_SIZE_ $param>];
142 const PUBLIC_KEY_SIZE: usize = [<PICNIC_PUBLIC_KEY_SIZE_ $param>];
143
144 #[inline(always)]
145 fn parameter_name() -> &'static str {
146 "$param"
147 }
148 }
149
150 #[doc = "Signing key for " $name]
151 pub type [<$name SigningKey>] = SigningKey<$name>;
152 #[doc = "Verification key for " $name]
153 pub type [<$name VerificationKey>] = VerificationKey<$name>;
154 }
155 };
156}
157
158#[cfg(feature = "picnic")]
159define_params!(PicnicL1FS, Picnic_L1_FS);
160#[cfg(feature = "unruh-transform")]
161define_params!(PicnicL1UR, Picnic_L1_UR);
162#[cfg(feature = "picnic")]
163define_params!(PicnicL1Full, Picnic_L1_full);
164#[cfg(feature = "picnic3")]
165define_params!(Picnic3L1, Picnic3_L1);
166
167#[cfg(feature = "picnic")]
168define_params!(PicnicL3FS, Picnic_L3_FS);
169#[cfg(feature = "unruh-transform")]
170define_params!(PicnicL3UR, Picnic_L3_UR);
171#[cfg(feature = "picnic")]
172define_params!(PicnicL3Full, Picnic_L3_full);
173#[cfg(feature = "picnic3")]
174define_params!(Picnic3L3, Picnic3_L3);
175
176#[cfg(feature = "picnic")]
177define_params!(PicnicL5FS, Picnic_L5_FS);
178#[cfg(feature = "unruh-transform")]
179define_params!(PicnicL5UR, Picnic_L5_UR);
180#[cfg(feature = "picnic")]
181define_params!(PicnicL5Full, Picnic_L5_full);
182#[cfg(feature = "picnic3")]
183define_params!(Picnic3L5, Picnic3_L5);
184
185#[derive(Debug, Clone, Eq, PartialEq)]
190#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
191pub struct DynamicSignature(
192 #[cfg_attr(feature = "serialization", serde(with = "serde_bytes"))] Vec<u8>,
193);
194
195impl AsRef<[u8]> for DynamicSignature {
196 fn as_ref(&self) -> &[u8] {
197 self.0.as_ref()
198 }
199}
200
201impl From<&[u8]> for DynamicSignature {
202 fn from(bytes: &[u8]) -> Self {
203 Self(bytes.into())
204 }
205}
206
207#[derive(Clone)]
209#[cfg_attr(feature = "zeroize", derive(Zeroize, ZeroizeOnDrop))]
210pub struct SigningKey<P: Parameters> {
211 data: PrivateKey,
212 #[cfg_attr(feature = "zeroize", zeroize(skip))]
213 phantom_data: PhantomData<P>,
214}
215
216impl<P> SigningKey<P>
217where
218 P: Parameters,
219{
220 pub fn random() -> Result<(Self, VerificationKey<P>), Error> {
224 PrivateKey::random(P::PARAM).map(|(sk, vk)| {
225 (
226 Self {
227 data: sk,
228 phantom_data: PhantomData,
229 },
230 VerificationKey {
231 data: vk,
232 phantom_data: PhantomData,
233 },
234 )
235 })
236 }
237}
238
239impl<P> Signer<DynamicSignature> for SigningKey<P>
240where
241 P: Parameters,
242{
243 fn try_sign(&self, msg: &[u8]) -> Result<DynamicSignature, Error> {
244 let mut signature = vec![0; P::MAX_SIGNATURE_SIZE];
245
246 let length = self.data.try_sign(msg, signature.as_mut_slice())?;
247 signature.resize(length, 0);
248 Ok(DynamicSignature(signature))
249 }
250}
251
252impl<P> Verifier<DynamicSignature> for SigningKey<P>
253where
254 P: Parameters,
255{
256 fn verify(&self, msg: &[u8], signature: &DynamicSignature) -> Result<(), Error> {
257 self.data
258 .public_key()
259 .and_then(|pk| pk.verify(msg, signature.as_ref()))
260 }
261}
262
263impl<P> PicnicKey for SigningKey<P>
264where
265 P: Parameters,
266{
267 #[inline(always)]
268 fn param(&self) -> picnic_params_t {
269 P::PARAM
270 }
271
272 #[inline(always)]
273 fn serialized_size(&self) -> usize {
274 P::PRIVATE_KEY_SIZE
275 }
276}
277
278impl<P> AsRef<[u8]> for SigningKey<P>
279where
280 P: Parameters,
281{
282 fn as_ref(&self) -> &[u8] {
283 &self.data.as_ref().data[0..P::PRIVATE_KEY_SIZE]
285 }
286}
287
288impl<P> TryFrom<&[u8]> for SigningKey<P>
289where
290 P: Parameters,
291{
292 type Error = Error;
293
294 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
295 let sk = PrivateKey::try_from(value)?;
296 match sk.param() == P::PARAM {
297 true => Ok(Self {
298 data: sk,
299 phantom_data: PhantomData,
300 }),
301 false => Err(Self::Error::new()),
302 }
303 }
304}
305
306impl<P> Debug for SigningKey<P>
307where
308 P: Parameters,
309{
310 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
311 fmt.debug_struct(&format!("SigningKey<{}>", P::parameter_name()))
312 .field("data", &"[...]")
313 .finish()
314 }
315}
316
317impl<P> PartialEq for SigningKey<P>
318where
319 P: Parameters,
320{
321 fn eq(&self, other: &Self) -> bool {
322 self.as_ref() == other.as_ref()
323 }
324}
325
326impl<P> Eq for SigningKey<P> where P: Parameters {}
327
328#[cfg(feature = "subtle")]
329impl<P> ConstantTimeEq for SigningKey<P>
330where
331 P: Parameters,
332{
333 fn ct_eq(&self, other: &Self) -> Choice {
334 self.as_ref().ct_eq(other.as_ref())
335 }
336}
337
338#[cfg(feature = "serialization")]
339impl<P> Serialize for SigningKey<P>
340where
341 P: Parameters,
342{
343 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
344 where
345 S: Serializer,
346 {
347 serialize(self, serializer)
348 }
349}
350
351#[cfg(feature = "serialization")]
352impl<'de, P> Deserialize<'de> for SigningKey<P>
353where
354 P: Parameters,
355{
356 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
357 where
358 D: Deserializer<'de>,
359 {
360 deserialize(deserializer)
361 }
362}
363
364#[derive(Clone)]
366pub struct VerificationKey<P: Parameters> {
367 data: PublicKey,
368 phantom_data: PhantomData<P>,
369}
370
371impl<P> Verifier<DynamicSignature> for VerificationKey<P>
372where
373 P: Parameters,
374{
375 fn verify(&self, msg: &[u8], signature: &DynamicSignature) -> Result<(), Error> {
376 self.verify_raw(msg, &signature.0)
377 }
378}
379
380impl<P> RawVerifier for VerificationKey<P>
381where
382 P: Parameters,
383{
384 fn verify_raw(&self, msg: &[u8], signature: &[u8]) -> Result<(), Error> {
385 self.data.verify(msg, signature)
386 }
387}
388
389impl<P> PicnicKey for VerificationKey<P>
390where
391 P: Parameters,
392{
393 #[inline(always)]
394 fn param(&self) -> picnic_params_t {
395 P::PARAM
396 }
397
398 #[inline(always)]
399 fn serialized_size(&self) -> usize {
400 P::PUBLIC_KEY_SIZE
401 }
402}
403
404impl<P> AsRef<[u8]> for VerificationKey<P>
405where
406 P: Parameters,
407{
408 fn as_ref(&self) -> &[u8] {
409 &self.data.as_ref().data[0..P::PUBLIC_KEY_SIZE]
411 }
412}
413
414impl<P> TryFrom<&[u8]> for VerificationKey<P>
415where
416 P: Parameters,
417{
418 type Error = Error;
419
420 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
421 let vk = PublicKey::try_from(value)?;
422 match vk.param() == P::PARAM {
423 true => Ok(Self {
424 data: vk,
425 phantom_data: PhantomData,
426 }),
427 false => Err(Self::Error::new()),
428 }
429 }
430}
431
432impl<P> TryFrom<&SigningKey<P>> for VerificationKey<P>
433where
434 P: Parameters,
435{
436 type Error = Error;
437
438 fn try_from(sk: &SigningKey<P>) -> Result<Self, Self::Error> {
439 sk.data.public_key().map(|vk| Self {
440 data: vk,
441 phantom_data: PhantomData,
442 })
443 }
444}
445
446impl<P> Debug for VerificationKey<P>
447where
448 P: Parameters,
449{
450 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
451 fmt.debug_struct(&format!("VerificationKey<{}>", P::parameter_name()))
452 .field("data", &self.data)
453 .finish()
454 }
455}
456
457impl<P> PartialEq for VerificationKey<P>
458where
459 P: Parameters,
460{
461 fn eq(&self, other: &Self) -> bool {
462 self.as_ref() == other.as_ref()
463 }
464}
465
466impl<P> Eq for VerificationKey<P> where P: Parameters {}
467
468#[cfg(feature = "serialization")]
469impl<P> Serialize for VerificationKey<P>
470where
471 P: Parameters,
472{
473 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
474 where
475 S: Serializer,
476 {
477 serialize(self, serializer)
478 }
479}
480
481#[cfg(feature = "serialization")]
482impl<'de, P> Deserialize<'de> for VerificationKey<P>
483where
484 P: Parameters,
485{
486 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
487 where
488 D: Deserializer<'de>,
489 {
490 deserialize(deserializer)
491 }
492}
493
494#[derive(Clone)]
496#[cfg_attr(feature = "zeroize", derive(Zeroize, ZeroizeOnDrop))]
497pub struct DynamicSigningKey {
498 data: PrivateKey,
499}
500
501impl Debug for DynamicSigningKey {
502 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
503 fmt.debug_struct("DynamicSigningKey")
504 .field("param", &self.param())
505 .field("data", &"[...]")
506 .finish()
507 }
508}
509
510impl DynamicSigningKey {
511 pub fn random(params: picnic_params_t) -> Result<(Self, DynamicVerificationKey), Error> {
515 PrivateKey::random(params)
516 .map(|(sk, vk)| (Self { data: sk }, DynamicVerificationKey { data: vk }))
517 }
518}
519
520impl Signer<DynamicSignature> for DynamicSigningKey {
521 fn try_sign(&self, msg: &[u8]) -> Result<DynamicSignature, Error> {
522 let mut signature = vec![0; signature_size(self.param())];
523 let length = self.data.try_sign(msg, signature.as_mut_slice())?;
524 signature.resize(length, 0);
525 Ok(DynamicSignature(signature))
526 }
527}
528
529impl Verifier<DynamicSignature> for DynamicSigningKey {
530 fn verify(&self, msg: &[u8], signature: &DynamicSignature) -> Result<(), Error> {
531 self.data
532 .public_key()
533 .and_then(|pk| pk.verify(msg, signature.as_ref()))
534 }
535}
536
537impl PicnicKey for DynamicSigningKey {
538 #[inline(always)]
539 fn param(&self) -> picnic_params_t {
540 self.data.param()
541 }
542
543 #[inline(always)]
544 fn serialized_size(&self) -> usize {
545 self.data.serialized_size()
546 }
547}
548
549impl AsRef<[u8]> for DynamicSigningKey {
550 fn as_ref(&self) -> &[u8] {
551 &self.data.as_ref().data[0..self.serialized_size()]
553 }
554}
555
556impl TryFrom<&[u8]> for DynamicSigningKey {
557 type Error = Error;
558
559 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
560 let sk = PrivateKey::try_from(value)?;
561 match sk.param() != picnic_params_t::PARAMETER_SET_INVALID {
562 true => Ok(DynamicSigningKey { data: sk }),
563 false => Err(Self::Error::new()),
564 }
565 }
566}
567
568impl PartialEq for DynamicSigningKey {
569 fn eq(&self, other: &Self) -> bool {
570 self.param() == other.param() && {
571 let size = self.serialized_size();
572 self.data.as_ref().data[..size] == other.data.as_ref().data[..size]
573 }
574 }
575}
576
577impl Eq for DynamicSigningKey {}
578
579#[cfg(feature = "serialization")]
580impl Serialize for DynamicSigningKey {
581 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
582 where
583 S: Serializer,
584 {
585 serialize(self, serializer)
586 }
587}
588
589#[cfg(feature = "serialization")]
590impl<'de> Deserialize<'de> for DynamicSigningKey {
591 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
592 where
593 D: Deserializer<'de>,
594 {
595 deserialize(deserializer)
596 }
597}
598
599#[derive(Clone, Debug)]
601pub struct DynamicVerificationKey {
602 data: PublicKey,
603}
604
605impl Verifier<DynamicSignature> for DynamicVerificationKey {
606 fn verify(&self, msg: &[u8], signature: &DynamicSignature) -> Result<(), Error> {
607 self.verify_raw(msg, &signature.0)
608 }
609}
610
611impl RawVerifier for DynamicVerificationKey {
612 fn verify_raw(&self, msg: &[u8], signature: &[u8]) -> Result<(), Error> {
613 self.data.verify(msg, signature)
614 }
615}
616
617impl PicnicKey for DynamicVerificationKey {
618 #[inline(always)]
619 fn param(&self) -> picnic_params_t {
620 self.data.param()
621 }
622
623 #[inline(always)]
624 fn serialized_size(&self) -> usize {
625 self.data.serialized_size()
626 }
627}
628
629impl AsRef<[u8]> for DynamicVerificationKey {
630 fn as_ref(&self) -> &[u8] {
631 &self.data.as_ref().data[0..self.serialized_size()]
633 }
634}
635
636impl TryFrom<&[u8]> for DynamicVerificationKey {
637 type Error = Error;
638
639 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
640 let vk = PublicKey::try_from(value)?;
641 match vk.param() != picnic_params_t::PARAMETER_SET_INVALID {
642 true => Ok(DynamicVerificationKey { data: vk }),
643 false => Err(Self::Error::new()),
644 }
645 }
646}
647
648impl TryFrom<&DynamicSigningKey> for DynamicVerificationKey {
649 type Error = Error;
650
651 fn try_from(sk: &DynamicSigningKey) -> Result<Self, Self::Error> {
652 sk.data.public_key().map(|vk| Self { data: vk })
653 }
654}
655
656impl PartialEq for DynamicVerificationKey {
657 fn eq(&self, other: &Self) -> bool {
658 self.param() == other.param() && {
659 let size = self.serialized_size();
660 self.data.as_ref().data[..size] == other.data.as_ref().data[..size]
661 }
662 }
663}
664
665impl Eq for DynamicVerificationKey {}
666
667#[cfg(feature = "serialization")]
668impl Serialize for DynamicVerificationKey {
669 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
670 where
671 S: Serializer,
672 {
673 serialize(self, serializer)
674 }
675}
676
677#[cfg(feature = "serialization")]
678impl<'de> Deserialize<'de> for DynamicVerificationKey {
679 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
680 where
681 D: Deserializer<'de>,
682 {
683 deserialize(deserializer)
684 }
685}
686
687#[cfg(test)]
688mod test {
689 #[cfg(feature = "picnic")]
690 use crate::{PicnicL1FSSigningKey, PicnicL1FullSigningKey, PicnicL1FullVerificationKey};
691
692 #[cfg(feature = "picnic")]
693 #[test]
694 fn serialization_param_mismatch() {
695 let (sk1, vk1) = PicnicL1FSSigningKey::random().expect("unable to generate keys");
696 PicnicL1FullSigningKey::try_from(sk1.as_ref()).expect_err("deserialization did not fail");
697 PicnicL1FullVerificationKey::try_from(vk1.as_ref())
698 .expect_err("deserialization did not fail");
699 }
700}