1#[cfg(feature = "serialization")]
23use serde::{Deserialize, Serialize};
24#[cfg(feature = "serialization")]
25use serde_big_array::BigArray;
26
27use crate::ffi;
28use alloc::vec::Vec;
29use pqcrypto_traits::sign as primitive;
30use pqcrypto_traits::{Error, Result};
31
32#[cfg(feature = "std")]
33use std::fmt;
34
35macro_rules! simple_struct {
36 ($type: ident, $size: expr) => {
37 #[derive(Clone, Copy)]
38 #[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
39 pub struct $type(
40 #[cfg_attr(feature = "serialization", serde(with = "BigArray"))] [u8; $size],
41 );
42
43 impl $type {
44 fn new() -> Self {
50 $type([0u8; $size])
51 }
52 }
53
54 impl primitive::$type for $type {
55 #[inline]
57 fn as_bytes(&self) -> &[u8] {
58 &self.0
59 }
60
61 fn from_bytes(bytes: &[u8]) -> Result<Self> {
63 if bytes.len() != $size {
64 Err(Error::BadLength {
65 name: stringify!($type),
66 actual: bytes.len(),
67 expected: $size,
68 })
69 } else {
70 let mut array = [0u8; $size];
71 array.copy_from_slice(bytes);
72 Ok($type(array))
73 }
74 }
75 }
76
77 impl PartialEq for $type {
78 fn eq(&self, other: &Self) -> bool {
80 self.0
81 .iter()
82 .zip(other.0.iter())
83 .try_for_each(|(a, b)| if a == b { Ok(()) } else { Err(()) })
84 .is_ok()
85 }
86 }
87
88 #[cfg(feature = "std")]
89 impl fmt::Debug for $type {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 write!(f, "{} ({} bytes)", stringify!($type), self.0.len())
93 }
94 }
95 };
96}
97
98simple_struct!(
99 PublicKey,
100 ffi::PQCLEAN_FALCON1024_CLEAN_CRYPTO_PUBLICKEYBYTES
101);
102simple_struct!(
103 SecretKey,
104 ffi::PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES
105);
106
107#[derive(Clone, Copy)]
108#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
109pub struct DetachedSignature(
110 #[cfg_attr(feature = "serialization", serde(with = "BigArray"))]
111 [u8; ffi::PQCLEAN_FALCON1024_CLEAN_CRYPTO_BYTES],
112 usize,
113);
114
115impl DetachedSignature {
117 fn new() -> Self {
118 DetachedSignature([0u8; ffi::PQCLEAN_FALCON1024_CLEAN_CRYPTO_BYTES], 0)
119 }
120}
121
122impl primitive::DetachedSignature for DetachedSignature {
123 #[inline]
125 fn as_bytes(&self) -> &[u8] {
126 &self.0[..self.1]
127 }
128
129 #[inline]
130 fn from_bytes(bytes: &[u8]) -> Result<Self> {
131 let actual = bytes.len();
132 let expected = ffi::PQCLEAN_FALCON1024_CLEAN_CRYPTO_BYTES;
133 if actual > expected {
134 return Err(Error::BadLength {
135 name: "DetachedSignature",
136 actual,
137 expected,
138 });
139 }
140 let mut array = [0u8; ffi::PQCLEAN_FALCON1024_CLEAN_CRYPTO_BYTES];
141 array[..bytes.len()].copy_from_slice(bytes);
142 Ok(DetachedSignature(array, actual))
143 }
144}
145
146#[derive(Clone)]
147#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
148pub struct SignedMessage(Vec<u8>);
149impl primitive::SignedMessage for SignedMessage {
150 #[inline]
152 fn as_bytes(&self) -> &[u8] {
153 self.0.as_slice()
154 }
155
156 #[inline]
158 fn from_bytes(bytes: &[u8]) -> Result<Self> {
159 Ok(SignedMessage(bytes.to_vec()))
160 }
161}
162
163impl SignedMessage {
164 pub fn len(&self) -> usize {
165 self.0.len()
166 }
167}
168
169pub const fn public_key_bytes() -> usize {
171 ffi::PQCLEAN_FALCON1024_CLEAN_CRYPTO_PUBLICKEYBYTES
172}
173
174pub const fn secret_key_bytes() -> usize {
176 ffi::PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES
177}
178
179pub const fn signature_bytes() -> usize {
181 ffi::PQCLEAN_FALCON1024_CLEAN_CRYPTO_BYTES
182}
183
184macro_rules! gen_keypair {
185 ($variant:ident) => {{
186 let mut pk = PublicKey::new();
187 let mut sk = SecretKey::new();
188 assert_eq!(
189 unsafe { ffi::$variant(pk.0.as_mut_ptr(), sk.0.as_mut_ptr()) },
190 0
191 );
192 (pk, sk)
193 }};
194}
195
196pub fn keypair() -> (PublicKey, SecretKey) {
198 #[cfg(all(enable_x86_avx2, feature = "avx2"))]
199 {
200 if std::is_x86_feature_detected!("avx2") {
201 return gen_keypair!(PQCLEAN_FALCON1024_AVX2_crypto_sign_keypair);
202 }
203 }
204 #[cfg(all(enable_aarch64_neon, feature = "neon"))]
205 {
206 if true {
210 return gen_keypair!(PQCLEAN_FALCON1024_AARCH64_crypto_sign_keypair);
211 }
212 }
213 gen_keypair!(PQCLEAN_FALCON1024_CLEAN_crypto_sign_keypair)
214}
215
216macro_rules! gen_signature {
217 ($variant:ident, $msg:ident, $sk:ident) => {{
218 let max_len = $msg.len() + signature_bytes();
219 let mut signed_msg = Vec::with_capacity(max_len);
220 let mut smlen: usize = 0;
221 unsafe {
222 ffi::$variant(
223 signed_msg.as_mut_ptr(),
224 &mut smlen as *mut usize,
225 $msg.as_ptr(),
226 $msg.len(),
227 $sk.0.as_ptr(),
228 );
229 debug_assert!(smlen <= max_len, "exceeded vector capacity");
230 signed_msg.set_len(smlen);
231 }
232 SignedMessage(signed_msg)
233 }};
234}
235
236pub fn sign(msg: &[u8], sk: &SecretKey) -> SignedMessage {
238 #[cfg(all(enable_x86_avx2, feature = "avx2"))]
239 {
240 if std::is_x86_feature_detected!("avx2") {
241 return gen_signature!(PQCLEAN_FALCON1024_AVX2_crypto_sign, msg, sk);
242 }
243 }
244 #[cfg(all(enable_aarch64_neon, feature = "neon"))]
245 {
246 if true {
247 return gen_signature!(PQCLEAN_FALCON1024_AARCH64_crypto_sign, msg, sk);
248 }
249 }
250 gen_signature!(PQCLEAN_FALCON1024_CLEAN_crypto_sign, msg, sk)
251}
252
253macro_rules! open_signed {
254 ($variant:ident, $sm:ident, $pk:ident) => {{
255 let mut m: Vec<u8> = Vec::with_capacity($sm.len());
256 let mut mlen: usize = 0;
257 match unsafe {
258 ffi::$variant(
259 m.as_mut_ptr(),
260 &mut mlen as *mut usize,
261 $sm.0.as_ptr(),
262 $sm.len(),
263 $pk.0.as_ptr(),
264 )
265 } {
266 0 => {
267 unsafe { m.set_len(mlen) };
268 Ok(m)
269 }
270 -1 => Err(primitive::VerificationError::InvalidSignature),
271 _ => Err(primitive::VerificationError::UnknownVerificationError),
272 }
273 }};
274}
275
276pub fn open(
278 sm: &SignedMessage,
279 pk: &PublicKey,
280) -> core::result::Result<Vec<u8>, primitive::VerificationError> {
281 #[cfg(all(enable_x86_avx2, feature = "avx2"))]
282 {
283 if std::is_x86_feature_detected!("avx2") {
284 return open_signed!(PQCLEAN_FALCON1024_AVX2_crypto_sign_open, sm, pk);
285 }
286 }
287 #[cfg(all(enable_aarch64_neon, feature = "neon"))]
288 {
289 if true {
290 return open_signed!(PQCLEAN_FALCON1024_AARCH64_crypto_sign_open, sm, pk);
291 }
292 }
293 open_signed!(PQCLEAN_FALCON1024_CLEAN_crypto_sign_open, sm, pk)
294}
295
296macro_rules! detached_signature {
297 ($variant:ident, $msg:ident, $sk:ident) => {{
298 let mut sig = DetachedSignature::new();
299 unsafe {
300 ffi::$variant(
301 sig.0.as_mut_ptr(),
302 &mut sig.1 as *mut usize,
303 $msg.as_ptr(),
304 $msg.len(),
305 $sk.0.as_ptr(),
306 );
307 }
308 sig
309 }};
310}
311
312pub fn detached_sign(msg: &[u8], sk: &SecretKey) -> DetachedSignature {
314 #[cfg(all(enable_x86_avx2, feature = "avx2"))]
315 {
316 if std::is_x86_feature_detected!("avx2") {
317 return detached_signature!(PQCLEAN_FALCON1024_AVX2_crypto_sign_signature, msg, sk);
318 }
319 }
320 #[cfg(all(enable_aarch64_neon, feature = "neon"))]
321 {
322 if true {
323 return detached_signature!(PQCLEAN_FALCON1024_AARCH64_crypto_sign_signature, msg, sk);
324 }
325 }
326 detached_signature!(PQCLEAN_FALCON1024_CLEAN_crypto_sign_signature, msg, sk)
327}
328
329macro_rules! verify_detached_sig {
330 ($variant:ident, $sig:ident, $msg:ident, $pk:ident) => {{
331 let res = unsafe {
332 ffi::$variant(
333 $sig.0.as_ptr(),
334 $sig.1,
335 $msg.as_ptr(),
336 $msg.len(),
337 $pk.0.as_ptr(),
338 )
339 };
340 match res {
341 0 => Ok(()),
342 -1 => Err(primitive::VerificationError::InvalidSignature),
343 _ => Err(primitive::VerificationError::UnknownVerificationError),
344 }
345 }};
346}
347
348pub fn verify_detached_signature(
350 sig: &DetachedSignature,
351 msg: &[u8],
352 pk: &PublicKey,
353) -> core::result::Result<(), primitive::VerificationError> {
354 #[cfg(all(enable_x86_avx2, feature = "avx2"))]
355 {
356 if std::is_x86_feature_detected!("avx2") {
357 return verify_detached_sig!(PQCLEAN_FALCON1024_AVX2_crypto_sign_verify, sig, msg, pk);
358 }
359 }
360 #[cfg(all(enable_aarch64_neon, feature = "neon"))]
361 {
362 if true {
363 return verify_detached_sig!(
364 PQCLEAN_FALCON1024_AARCH64_crypto_sign_verify,
365 sig,
366 msg,
367 pk
368 );
369 }
370 }
371 verify_detached_sig!(PQCLEAN_FALCON1024_CLEAN_crypto_sign_verify, sig, msg, pk)
372}
373
374#[cfg(test)]
375mod test {
376 use super::*;
377 use rand::prelude::*;
378
379 #[test]
380 pub fn test_sign() {
381 let mut rng = rand::rng();
382 let len: u16 = rng.random();
383
384 let message = (0..len).map(|_| rng.gen::<u8>()).collect::<Vec<_>>();
385 let (pk, sk) = keypair();
386 let sm = sign(&message, &sk);
387 let verifiedmsg = open(&sm, &pk).unwrap();
388 assert!(verifiedmsg == message);
389 }
390
391 #[test]
392 pub fn test_sign_detached() {
393 let mut rng = rand::rng();
394 let len: u16 = rng.random();
395 let message = (0..len).map(|_| rng.gen::<u8>()).collect::<Vec<_>>();
396
397 let (pk, sk) = keypair();
398 let sig = detached_sign(&message, &sk);
399 assert!(verify_detached_signature(&sig, &message, &pk).is_ok());
400 assert!(!verify_detached_signature(&sig, &message[..message.len() - 1], &pk).is_ok());
401 }
402}