1#![cfg_attr(not(feature = "std"), no_std)]
19
20#[cfg(not(feature = "std"))]
21extern crate alloc;
22
23#[cfg(not(feature = "std"))]
24use alloc::vec::Vec;
25
26use core::{marker::PhantomData, mem};
27use paste::paste;
28pub use picnic_bindings::{self, Parameters};
29use picnic_bindings::{
30 signature::{Signer, Verifier},
31 DynamicSignature, RawVerifier, SigningKey, VerificationKey,
32};
33pub use pqcrypto_traits::{
34 sign::{self, VerificationError},
35 Error,
36};
37
38#[cfg(feature = "serialization")]
39use serde::{Deserialize, Serialize};
40
41#[cfg(feature = "zeroize")]
42use zeroize::{Zeroize, ZeroizeOnDrop};
43
44const LENGTH_SIZE: usize = mem::size_of::<u32>();
45
46#[derive(Debug, Clone, Eq, PartialEq)]
48#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
49#[cfg_attr(feature = "zeroize", derive(Zeroize, ZeroizeOnDrop))]
50#[repr(transparent)]
51pub struct SecretKey<P>(SigningKey<P>)
52where
53 P: Parameters;
54
55impl<P> sign::SecretKey for SecretKey<P>
56where
57 P: Parameters,
58{
59 #[inline(always)]
60 fn as_bytes(&self) -> &[u8] {
61 self.0.as_ref()
62 }
63
64 fn from_bytes(bytes: &[u8]) -> pqcrypto_traits::Result<Self>
65 where
66 Self: Sized,
67 {
68 match SigningKey::<P>::try_from(bytes) {
69 Ok(sk) => Ok(Self(sk)),
70 Err(_) => Err(Error::BadLength {
71 name: "SecretKey",
72 actual: bytes.len(),
73 expected: P::PRIVATE_KEY_SIZE,
74 }),
75 }
76 }
77}
78
79#[derive(Debug, Clone, Eq, PartialEq)]
81#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
82#[repr(transparent)]
83pub struct PublicKey<P>(VerificationKey<P>)
84where
85 P: Parameters;
86
87impl<P> sign::PublicKey for PublicKey<P>
88where
89 P: Parameters,
90{
91 #[inline]
92 fn as_bytes(&self) -> &[u8] {
93 self.0.as_ref()
94 }
95
96 fn from_bytes(bytes: &[u8]) -> pqcrypto_traits::Result<Self>
97 where
98 Self: Sized,
99 {
100 match VerificationKey::<P>::try_from(bytes) {
101 Ok(pk) => Ok(Self(pk)),
102 Err(_) => Err(Error::BadLength {
103 name: "PublicKey",
104 actual: bytes.len(),
105 expected: P::PUBLIC_KEY_SIZE,
106 }),
107 }
108 }
109}
110
111#[derive(Debug, Clone, Eq, PartialEq)]
116#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
117#[repr(transparent)]
118pub struct SignedMessage<P>(
119 #[cfg_attr(feature = "serialization", serde(with = "serde_bytes"))] Vec<u8>,
120 #[cfg_attr(feature = "serialization", serde(skip))] PhantomData<P>,
121)
122where
123 P: Parameters;
124
125fn pack(msg: &[u8], sig: DynamicSignature) -> Vec<u8> {
127 let sig_data = sig.as_ref();
128
129 let mut data = Vec::with_capacity(LENGTH_SIZE + msg.len() + sig_data.len());
130 data.extend_from_slice(&(sig_data.len() as u32).to_le_bytes());
131 data.extend_from_slice(msg);
132 data.extend_from_slice(sig_data);
133 data
134}
135
136fn unpack(data: &[u8]) -> pqcrypto_traits::Result<(&[u8], &[u8])> {
138 let sm_len = data.len();
139 if sm_len < LENGTH_SIZE {
140 return Err(Error::BadLength {
141 name: "signature (signature length)",
142 actual: sm_len,
143 expected: LENGTH_SIZE,
144 });
145 }
146
147 let len = u32::from_le_bytes(data[..4].try_into().unwrap()) as usize;
148 if sm_len < len + LENGTH_SIZE {
149 return Err(Error::BadLength {
150 name: "signature (signature length and signature)",
151 actual: sm_len,
152 expected: len + LENGTH_SIZE,
153 });
154 }
155
156 let sig_offset = sm_len - len;
157 let message = &data[LENGTH_SIZE..sig_offset];
158 let signature = &data[sig_offset..];
159
160 Ok((message, signature))
161}
162
163impl<P> sign::SignedMessage for SignedMessage<P>
164where
165 P: Parameters,
166{
167 #[inline]
168 fn as_bytes(&self) -> &[u8] {
169 self.0.as_slice()
170 }
171
172 #[inline]
173 fn from_bytes(bytes: &[u8]) -> pqcrypto_traits::Result<Self> {
174 unpack(bytes).map(|_| SignedMessage(bytes.to_vec(), PhantomData))
175 }
176}
177
178#[derive(Debug, Clone, Eq, PartialEq)]
180#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
181#[repr(transparent)]
182pub struct DetachedSignature<P>(
183 DynamicSignature,
184 #[cfg_attr(feature = "serialization", serde(skip))] PhantomData<P>,
185)
186where
187 P: Parameters;
188
189impl<P> sign::DetachedSignature for DetachedSignature<P>
190where
191 P: Parameters,
192{
193 #[inline]
194 fn as_bytes(&self) -> &[u8] {
195 self.0.as_ref()
196 }
197
198 #[inline]
199 fn from_bytes(bytes: &[u8]) -> pqcrypto_traits::Result<Self>
200 where
201 Self: Sized,
202 {
203 Ok(DetachedSignature(
204 DynamicSignature::from(bytes),
205 PhantomData,
206 ))
207 }
208}
209
210#[inline]
212pub(crate) fn keypair<P>() -> (SecretKey<P>, PublicKey<P>)
213where
214 P: Parameters,
215{
216 SigningKey::<P>::random()
219 .map(|(sk, pk)| (SecretKey(sk), PublicKey(pk)))
220 .expect("parameters not supported")
221}
222
223#[inline]
225pub(crate) fn sign<P>(msg: &[u8], sk: &SecretKey<P>) -> SignedMessage<P>
226where
227 P: Parameters,
228{
229 let sig = sk.0.sign(msg);
230 SignedMessage(pack(msg, sig), PhantomData)
231}
232
233#[inline]
235pub(crate) fn open<'a, P>(
236 sm: &'a SignedMessage<P>,
237 pk: &PublicKey<P>,
238) -> Result<&'a [u8], VerificationError>
239where
240 P: Parameters,
241{
242 let (message, signature) = unpack(&sm.0).map_err(|_| VerificationError::InvalidSignature)?;
243 match pk.0.verify_raw(message, signature) {
244 Ok(_) => Ok(message),
245 Err(_) => Err(VerificationError::InvalidSignature),
246 }
247}
248
249#[inline]
251pub(crate) fn detached_sign<P>(msg: &[u8], sk: &SecretKey<P>) -> DetachedSignature<P>
252where
253 P: Parameters,
254{
255 DetachedSignature(sk.0.sign(msg), PhantomData)
256}
257
258#[inline]
260pub(crate) fn verify_detached_signature<P>(
261 sig: &DetachedSignature<P>,
262 msg: &[u8],
263 pk: &PublicKey<P>,
264) -> Result<(), VerificationError>
265where
266 P: Parameters,
267{
268 pk.0.verify(msg, &sig.0)
269 .map_err(|_| VerificationError::InvalidSignature)
270}
271
272#[inline(always)]
274pub(crate) fn public_key_bytes<P>() -> usize
275where
276 P: Parameters,
277{
278 P::PUBLIC_KEY_SIZE
279}
280
281#[inline(always)]
283pub(crate) fn secret_key_bytes<P>() -> usize
284where
285 P: Parameters,
286{
287 P::PRIVATE_KEY_SIZE
288}
289
290#[inline(always)]
292pub(crate) fn signature_bytes<P>() -> usize
293where
294 P: Parameters,
295{
296 P::MAX_SIGNATURE_SIZE
297}
298
299macro_rules! define_implementation {
300 ($name:ident, $parameters:ident) => {
301 paste! {
302 #[doc = "Implementations of [pqcrypto_traits] for Picnic parameter set " $parameters]
303 pub mod $name {
304 pub use crate::{Error, VerificationError};
305 use picnic_bindings::$parameters;
306
307 pub type SecretKey = crate::SecretKey<$parameters>;
309 pub type PublicKey = crate::PublicKey<$parameters>;
311 pub type SignedMessage = crate::SignedMessage<$parameters>;
313 pub type DetachedSignature = crate::DetachedSignature<$parameters>;
315
316 #[inline(always)]
318 pub fn keypair() -> (SecretKey, PublicKey) {
319 crate::keypair::<$parameters>()
320 }
321
322 #[inline(always)]
324 pub fn sign(msg: &[u8], sk: &SecretKey) -> SignedMessage {
325 crate::sign(msg, sk)
326 }
327
328 #[inline(always)]
330 pub fn open<'a>(sm: &'a SignedMessage, pk: &PublicKey) -> Result<&'a [u8], VerificationError> {
331 crate::open(sm, pk)
332 }
333
334 #[inline(always)]
336 pub fn detached_sign(msg: &[u8], sk: &SecretKey) -> DetachedSignature {
337 crate::detached_sign(msg, sk)
338 }
339
340 #[inline(always)]
342 pub fn verify_detached_signature(
343 sig: &DetachedSignature,
344 msg: &[u8],
345 pk: &PublicKey,
346 ) -> Result<(), VerificationError> {
347 crate::verify_detached_signature(sig, msg, pk)
348 }
349
350 #[inline(always)]
352 pub fn public_key_bytes() -> usize {
353 crate::public_key_bytes::<$parameters>()
354 }
355
356 #[inline(always)]
358 pub fn secret_key_bytes() -> usize {
359 crate::secret_key_bytes::<$parameters>()
360 }
361
362 #[inline(always)]
364 pub fn signature_bytes() -> usize {
365 crate::signature_bytes::<$parameters>()
366 }
367
368 #[cfg(test)]
369 mod test {
370 #[cfg(not(feature = "std"))]
371 extern crate alloc;
372
373 #[cfg(not(feature = "std"))]
374 use alloc::vec::Vec;
375
376 use pqcrypto_traits::sign::{DetachedSignature as _, PublicKey as _, SecretKey as _, SignedMessage as _};
377
378 pub(crate) const MSG: &[u8] = b"test message";
379
380 #[test]
381 fn keypair() {
382 let (sk, pk) = super::keypair();
383 assert_eq!(sk.as_bytes().len(), super::secret_key_bytes());
384 assert_eq!(pk.as_bytes().len(), super::public_key_bytes());
385 }
386
387 #[test]
388 fn sign() {
389 let (sk, pk) = super::keypair();
390 let sig = super::sign(MSG, &sk);
391 assert_eq!(super::open(&sig, &pk).unwrap(), MSG);
392 assert!(sig.as_bytes().len() <= super::signature_bytes() + MSG.len() + crate::LENGTH_SIZE)
393 }
394
395 #[test]
396 fn detached_sign() {
397 let (sk, pk) = super::keypair();
398 let sig = super::detached_sign(MSG, &sk);
399 assert!(super::verify_detached_signature(&sig, MSG, &pk).is_ok());
400 assert!(sig.as_bytes().len() <= super::signature_bytes());
401 assert!(super::verify_detached_signature(&sig, b"other msg", &pk).is_err());
402 }
403
404 #[test]
405 fn sizes() {
406 assert!(super::public_key_bytes() > 0);
407 assert!(super::secret_key_bytes() > 0);
408 assert!(super::signature_bytes() > 0);
409 }
410
411 #[test]
412 fn signature_from_bytes() {
413 assert!(super::SignedMessage::from_bytes(b"").is_err());
414 assert!(super::SignedMessage::from_bytes(b"\xff\xff\xff").is_err());
415
416 let bytes = 1234u32.to_le_bytes();
417 assert!(super::SignedMessage::from_bytes(&bytes).is_err());
418
419 let mut bytes = Vec::default();
420 bytes.extend_from_slice(&(14u32.to_le_bytes()));
421 bytes.extend_from_slice(b"some message");
422 bytes.extend_from_slice(b"some signature");
423 assert!(super::SignedMessage::from_bytes(&bytes).is_ok());
424 }
425 }
426
427 #[cfg(all(test, feature = "serialization"))]
428 mod serialization_tests {
429 use super::test::MSG;
430 use serde::{Deserialize, Serialize};
431 use serde_bytes_repr::{ByteFmtSerializer, ByteFmtDeserializer};
432
433 #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
434 struct KeyPair {
435 sk: super::SecretKey,
436 pk: super::PublicKey,
437 }
438
439 #[test]
440 fn serialize() {
441 let (sk, pk) = super::keypair();
442 let kp1 = KeyPair { sk, pk };
443
444 let mut out = vec![];
445 let mut ser = serde_json::Serializer::new(&mut out);
446 let ser = ByteFmtSerializer::hex(&mut ser);
447
448 kp1.serialize(ser).unwrap();
449 let serialized = String::from_utf8(out).unwrap();
450
451 let mut json_de = serde_json::Deserializer::from_str(&serialized);
452 let bytefmt_json_de = ByteFmtDeserializer::new_hex(&mut json_de);
453
454 let kp2 = KeyPair::deserialize(bytefmt_json_de).unwrap();
455 assert_eq!(kp1, kp2);
456 }
457
458 #[test]
459 fn serialize_signed_msg() {
460 let (sk, pk) = super::keypair();
461 let sm1 = super::sign(MSG, &sk);
462
463 let mut out = vec![];
464 let mut ser = serde_json::Serializer::new(&mut out);
465 let ser = ByteFmtSerializer::hex(&mut ser);
466
467 sm1.serialize(ser).unwrap();
468 let serialized = String::from_utf8(out).unwrap();
469
470 let mut json_de = serde_json::Deserializer::from_str(&serialized);
471 let bytefmt_json_de = ByteFmtDeserializer::new_hex(&mut json_de);
472
473 let sm2 = crate::SignedMessage::deserialize(bytefmt_json_de).unwrap();
474 assert_eq!(sm1, sm2);
475 assert_eq!(MSG, super::open(&sm2, &pk).unwrap());
476 }
477
478 #[test]
479 fn serialize_detached_signature() {
480 let (sk, pk) = super::keypair();
481 let sig1 = super::detached_sign(MSG, &sk);
482
483 let mut out = vec![];
484 let mut ser = serde_json::Serializer::new(&mut out);
485 let ser = ByteFmtSerializer::hex(&mut ser);
486
487 sig1.serialize(ser).unwrap();
488 let serialized = String::from_utf8(out).unwrap();
489
490 let mut json_de = serde_json::Deserializer::from_str(&serialized);
491 let bytefmt_json_de = ByteFmtDeserializer::new_hex(&mut json_de);
492
493 let sig2 = crate::DetachedSignature::deserialize(bytefmt_json_de).unwrap();
494 assert_eq!(sig1, sig2);
495 assert!(super::verify_detached_signature(&sig2, MSG, &pk).is_ok());
496 }
497 }
498 }
499
500 pub use $name::{
501 detached_sign as [<$name _detached_sign>],
502 keypair as [<$name _keypair>],
503 open as [<$name _open>],
504 public_key_bytes as [<$name _public_key_bytes>],
505 secret_key_bytes as [<$name _secret_key_bytes>],
506 sign as [<$name _sign>],
507 signature_bytes as [<$name _signature_bytes>],
508 verify_detached_signature as [<$name _verify_detached_signature>],
509 };
510 }
511 };
512}
513
514#[cfg(feature = "picnic")]
515
516define_implementation!(picnic_l1_fs, PicnicL1FS);
517#[cfg(feature = "unruh-transform")]
518define_implementation!(picnic_l1_ur, PicnicL1UR);
519#[cfg(feature = "picnic")]
520define_implementation!(picnic_l1_full, PicnicL1Full);
521#[cfg(feature = "picnic3")]
522define_implementation!(picnic3_l1, Picnic3L1);
523
524#[cfg(feature = "picnic")]
525define_implementation!(picnic_l3_fs, PicnicL3FS);
526#[cfg(feature = "unruh-transform")]
527define_implementation!(picnic_l3_ur, PicnicL3UR);
528#[cfg(feature = "picnic")]
529define_implementation!(picnic_l3_full, PicnicL3Full);
530#[cfg(feature = "picnic3")]
531define_implementation!(picnic3_l3, Picnic3L3);
532
533#[cfg(feature = "picnic")]
534define_implementation!(picnic_l5_fs, PicnicL5FS);
535#[cfg(feature = "unruh-transform")]
536define_implementation!(picnic_l5_ur, PicnicL5UR);
537#[cfg(feature = "picnic")]
538define_implementation!(picnic_l5_full, PicnicL5Full);
539#[cfg(feature = "picnic3")]
540define_implementation!(picnic3_l5, Picnic3L5);