1#![deny(missing_docs)]
51#![deny(unsafe_code)]
52
53use alloc::{vec, vec::Vec};
54use core::fmt;
55
56use zeroize::Zeroizing;
57
58use crate::{
59 falcon as falcon_api,
60 rng::get_seed,
61 shake::{i_shake256_flip, i_shake256_init, i_shake256_inject, InnerShake256Context},
62};
63
64#[doc(hidden)]
73pub fn sha256_public(data: &[u8]) -> [u8; 32] {
74 sha256(data)
75}
76
77#[doc(hidden)]
81pub fn sha512_public(data: &[u8]) -> [u8; 64] {
82 sha512(data)
83}
84
85fn sha256(data: &[u8]) -> [u8; 32] {
87 let mut h: [u32; 8] = [
89 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
90 0x5be0cd19,
91 ];
92 const K: [u32; 64] = [
94 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
95 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
96 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
97 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
98 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
99 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
100 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
101 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
102 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
103 0xc67178f2,
104 ];
105
106 let bit_len = (data.len() as u64).wrapping_mul(8);
108 let mut msg: Vec<u8> = Vec::with_capacity(data.len() + 64);
109 msg.extend_from_slice(data);
110 msg.push(0x80);
111 while (msg.len() % 64) != 56 {
112 msg.push(0x00);
113 }
114 msg.extend_from_slice(&bit_len.to_be_bytes());
115
116 for chunk in msg.chunks(64) {
118 let mut w = [0u32; 64];
119 for i in 0..16 {
120 w[i] = u32::from_be_bytes([
121 chunk[4 * i],
122 chunk[4 * i + 1],
123 chunk[4 * i + 2],
124 chunk[4 * i + 3],
125 ]);
126 }
127 for i in 16..64 {
128 let s0 = w[i - 15].rotate_right(7) ^ w[i - 15].rotate_right(18) ^ (w[i - 15] >> 3);
129 let s1 = w[i - 2].rotate_right(17) ^ w[i - 2].rotate_right(19) ^ (w[i - 2] >> 10);
130 w[i] = w[i - 16]
131 .wrapping_add(s0)
132 .wrapping_add(w[i - 7])
133 .wrapping_add(s1);
134 }
135 let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut hh] =
136 [h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]];
137 for i in 0..64 {
138 let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25);
139 let ch = (e & f) ^ ((!e) & g);
140 let temp1 = hh
141 .wrapping_add(s1)
142 .wrapping_add(ch)
143 .wrapping_add(K[i])
144 .wrapping_add(w[i]);
145 let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22);
146 let maj = (a & b) ^ (a & c) ^ (b & c);
147 let temp2 = s0.wrapping_add(maj);
148 hh = g;
149 g = f;
150 f = e;
151 e = d.wrapping_add(temp1);
152 d = c;
153 c = b;
154 b = a;
155 a = temp1.wrapping_add(temp2);
156 }
157 h[0] = h[0].wrapping_add(a);
158 h[1] = h[1].wrapping_add(b);
159 h[2] = h[2].wrapping_add(c);
160 h[3] = h[3].wrapping_add(d);
161 h[4] = h[4].wrapping_add(e);
162 h[5] = h[5].wrapping_add(f);
163 h[6] = h[6].wrapping_add(g);
164 h[7] = h[7].wrapping_add(hh);
165 }
166
167 let mut out = [0u8; 32];
168 for (i, &v) in h.iter().enumerate() {
169 out[4 * i..4 * i + 4].copy_from_slice(&v.to_be_bytes());
170 }
171 out
172}
173
174fn sha512(data: &[u8]) -> [u8; 64] {
176 let mut h: [u64; 8] = [
177 0x6a09e667f3bcc908,
178 0xbb67ae8584caa73b,
179 0x3c6ef372fe94f82b,
180 0xa54ff53a5f1d36f1,
181 0x510e527fade682d1,
182 0x9b05688c2b3e6c1f,
183 0x1f83d9abfb41bd6b,
184 0x5be0cd19137e2179,
185 ];
186 const K: [u64; 80] = [
187 0x428a2f98d728ae22,
188 0x7137449123ef65cd,
189 0xb5c0fbcfec4d3b2f,
190 0xe9b5dba58189dbbc,
191 0x3956c25bf348b538,
192 0x59f111f1b605d019,
193 0x923f82a4af194f9b,
194 0xab1c5ed5da6d8118,
195 0xd807aa98a3030242,
196 0x12835b0145706fbe,
197 0x243185be4ee4b28c,
198 0x550c7dc3d5ffb4e2,
199 0x72be5d74f27b896f,
200 0x80deb1fe3b1696b1,
201 0x9bdc06a725c71235,
202 0xc19bf174cf692694,
203 0xe49b69c19ef14ad2,
204 0xefbe4786384f25e3,
205 0x0fc19dc68b8cd5b5,
206 0x240ca1cc77ac9c65,
207 0x2de92c6f592b0275,
208 0x4a7484aa6ea6e483,
209 0x5cb0a9dcbd41fbd4,
210 0x76f988da831153b5,
211 0x983e5152ee66dfab,
212 0xa831c66d2db43210,
213 0xb00327c898fb213f,
214 0xbf597fc7beef0ee4,
215 0xc6e00bf33da88fc2,
216 0xd5a79147930aa725,
217 0x06ca6351e003826f,
218 0x142929670a0e6e70,
219 0x27b70a8546d22ffc,
220 0x2e1b21385c26c926,
221 0x4d2c6dfc5ac42aed,
222 0x53380d139d95b3df,
223 0x650a73548baf63de,
224 0x766a0abb3c77b2a8,
225 0x81c2c92e47edaee6,
226 0x92722c851482353b,
227 0xa2bfe8a14cf10364,
228 0xa81a664bbc423001,
229 0xc24b8b70d0f89791,
230 0xc76c51a30654be30,
231 0xd192e819d6ef5218,
232 0xd69906245565a910,
233 0xf40e35855771202a,
234 0x106aa07032bbd1b8,
235 0x19a4c116b8d2d0c8,
236 0x1e376c085141ab53,
237 0x2748774cdf8eeb99,
238 0x34b0bcb5e19b48a8,
239 0x391c0cb3c5c95a63,
240 0x4ed8aa4ae3418acb,
241 0x5b9cca4f7763e373,
242 0x682e6ff3d6b2b8a3,
243 0x748f82ee5defb2fc,
244 0x78a5636f43172f60,
245 0x84c87814a1f0ab72,
246 0x8cc702081a6439ec,
247 0x90befffa23631e28,
248 0xa4506cebde82bde9,
249 0xbef9a3f7b2c67915,
250 0xc67178f2e372532b,
251 0xca273eceea26619c,
252 0xd186b8c721c0c207,
253 0xeada7dd6cde0eb1e,
254 0xf57d4f7fee6ed178,
255 0x06f067aa72176fba,
256 0x0a637dc5a2c898a6,
257 0x113f9804bef90dae,
258 0x1b710b35131c471b,
259 0x28db77f523047d84,
260 0x32caab7b40c72493,
261 0x3c9ebe0a15c9bebc,
262 0x431d67c49c100d4c,
263 0x4cc5d4becb3e42b6,
264 0x597f299cfc657e2a,
265 0x5fcb6fab3ad6faec,
266 0x6c44198c4a475817,
267 ];
268
269 let bit_len = (data.len() as u128).wrapping_mul(8);
270 let mut msg: Vec<u8> = Vec::with_capacity(data.len() + 128);
271 msg.extend_from_slice(data);
272 msg.push(0x80);
273 while (msg.len() % 128) != 112 {
274 msg.push(0x00);
275 }
276 msg.extend_from_slice(&[0u8; 8]); msg.extend_from_slice(&(bit_len as u64).to_be_bytes());
278
279 for chunk in msg.chunks(128) {
280 let mut w = [0u64; 80];
281 for i in 0..16 {
282 let b = &chunk[8 * i..8 * i + 8];
283 w[i] = u64::from_be_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]]);
284 }
285 for i in 16..80 {
286 let s0 = w[i - 15].rotate_right(1) ^ w[i - 15].rotate_right(8) ^ (w[i - 15] >> 7);
287 let s1 = w[i - 2].rotate_right(19) ^ w[i - 2].rotate_right(61) ^ (w[i - 2] >> 6);
288 w[i] = w[i - 16]
289 .wrapping_add(s0)
290 .wrapping_add(w[i - 7])
291 .wrapping_add(s1);
292 }
293 let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut hh] =
294 [h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]];
295 for i in 0..80 {
296 let s1 = e.rotate_right(14) ^ e.rotate_right(18) ^ e.rotate_right(41);
297 let ch = (e & f) ^ ((!e) & g);
298 let t1 = hh
299 .wrapping_add(s1)
300 .wrapping_add(ch)
301 .wrapping_add(K[i])
302 .wrapping_add(w[i]);
303 let s0 = a.rotate_right(28) ^ a.rotate_right(34) ^ a.rotate_right(39);
304 let maj = (a & b) ^ (a & c) ^ (b & c);
305 let t2 = s0.wrapping_add(maj);
306 hh = g;
307 g = f;
308 f = e;
309 e = d.wrapping_add(t1);
310 d = c;
311 c = b;
312 b = a;
313 a = t1.wrapping_add(t2);
314 }
315 h[0] = h[0].wrapping_add(a);
316 h[1] = h[1].wrapping_add(b);
317 h[2] = h[2].wrapping_add(c);
318 h[3] = h[3].wrapping_add(d);
319 h[4] = h[4].wrapping_add(e);
320 h[5] = h[5].wrapping_add(f);
321 h[6] = h[6].wrapping_add(g);
322 h[7] = h[7].wrapping_add(hh);
323 }
324
325 let mut out = [0u8; 64];
326 for (i, &v) in h.iter().enumerate() {
327 out[8 * i..8 * i + 8].copy_from_slice(&v.to_be_bytes());
328 }
329 out
330}
331
332const OID_SHA256: &[u8] = &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01];
338const OID_SHA512: &[u8] = &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03];
340
341#[derive(Debug, Clone, Copy, PartialEq, Eq)]
351#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
352pub enum PreHashAlgorithm {
353 Sha256,
355 Sha512,
357}
358
359impl PreHashAlgorithm {
360 fn oid(self) -> &'static [u8] {
361 match self {
362 PreHashAlgorithm::Sha256 => OID_SHA256,
363 PreHashAlgorithm::Sha512 => OID_SHA512,
364 }
365 }
366
367 fn hash(self, msg: &[u8]) -> Vec<u8> {
368 match self {
369 PreHashAlgorithm::Sha256 => sha256(msg).to_vec(),
370 PreHashAlgorithm::Sha512 => sha512(msg).to_vec(),
371 }
372 }
373}
374
375#[derive(Debug, Clone, Copy, PartialEq, Eq)]
400#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
401pub enum DomainSeparation<'a> {
402 None,
404 Context(&'a [u8]),
406 Prehashed {
409 alg: PreHashAlgorithm,
411 context: &'a [u8],
413 },
414}
415
416impl<'a> DomainSeparation<'a> {
417 fn validate_context(ctx: &[u8]) -> Result<(), FalconError> {
419 if ctx.len() > 255 {
420 return Err(FalconError::BadArgument);
421 }
422 Ok(())
423 }
424
425 pub(crate) fn validate(&self) -> Result<(), FalconError> {
427 match self {
428 DomainSeparation::None => Ok(()),
429 DomainSeparation::Context(ctx) => Self::validate_context(ctx),
430 DomainSeparation::Prehashed { context, .. } => Self::validate_context(context),
431 }
432 }
433
434 fn ph_flag(&self) -> u8 {
436 match self {
437 DomainSeparation::Prehashed { .. } => 0x01,
438 _ => 0x00,
439 }
440 }
441
442 pub(crate) fn inject_header(&self, sc: &mut InnerShake256Context) {
447 let (ctx, oid) = match self {
448 DomainSeparation::None => (&b""[..], None),
449 DomainSeparation::Context(c) => (*c, None),
450 DomainSeparation::Prehashed { alg, context } => (*context, Some(alg.oid())),
451 };
452 let len = ctx.len().min(255) as u8;
454 i_shake256_inject(sc, &[self.ph_flag(), len]);
455 if len > 0 {
456 i_shake256_inject(sc, &ctx[..len as usize]);
457 }
458 if let Some(o) = oid {
460 i_shake256_inject(sc, o);
461 }
462 }
463
464 pub(crate) fn inject_message(&self, sc: &mut InnerShake256Context, message: &[u8]) {
467 match self {
468 DomainSeparation::Prehashed { alg, .. } => {
469 let digest = alg.hash(message);
470 falcon_api::shake256_inject(sc, &digest);
471 }
472 _ => {
473 falcon_api::shake256_inject(sc, message);
474 }
475 }
476 }
477
478 pub(crate) fn inject(&self, sc: &mut InnerShake256Context, message: &[u8]) {
480 self.inject_header(sc);
481 self.inject_message(sc, message);
482 }
483}
484
485#[derive(Debug, Clone, Copy, PartialEq, Eq)]
491#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
492pub enum FalconError {
493 RandomError,
495 SizeError,
497 FormatError,
499 BadSignature,
501 BadArgument,
503 InternalError,
505}
506
507impl fmt::Display for FalconError {
508 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
509 match self {
510 FalconError::RandomError => write!(f, "random number generation failed"),
511 FalconError::SizeError => write!(f, "buffer size error"),
512 FalconError::FormatError => write!(f, "invalid format"),
513 FalconError::BadSignature => write!(f, "invalid signature"),
514 FalconError::BadArgument => write!(f, "invalid argument"),
515 FalconError::InternalError => write!(f, "internal error"),
516 }
517 }
518}
519
520#[cfg(feature = "std")]
521impl std::error::Error for FalconError {}
522
523fn translate_error(rc: i32) -> FalconError {
524 match rc {
525 falcon_api::FALCON_ERR_RANDOM => FalconError::RandomError,
526 falcon_api::FALCON_ERR_SIZE => FalconError::SizeError,
527 falcon_api::FALCON_ERR_FORMAT => FalconError::FormatError,
528 falcon_api::FALCON_ERR_BADSIG => FalconError::BadSignature,
529 falcon_api::FALCON_ERR_BADARG => FalconError::BadArgument,
530 falcon_api::FALCON_ERR_INTERNAL => FalconError::InternalError,
531 _ => FalconError::InternalError,
532 }
533}
534
535#[derive(Clone)]
549#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
550pub struct FnDsaKeyPair {
551 privkey: Zeroizing<Vec<u8>>,
553 pubkey: Vec<u8>,
555 logn: u32,
557}
558
559impl fmt::Debug for FnDsaKeyPair {
560 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
561 f.debug_struct("FnDsaKeyPair")
562 .field("privkey", &"[REDACTED]")
563 .field("pubkey_len", &self.pubkey.len())
564 .field("logn", &self.logn)
565 .finish()
566 }
567}
568
569pub type FalconKeyPair = FnDsaKeyPair;
571
572impl FnDsaKeyPair {
573 pub fn generate(logn: u32) -> Result<Self, FalconError> {
577 if logn < 1 || logn > 10 {
578 return Err(FalconError::BadArgument);
579 }
580 let mut seed = Zeroizing::new([0u8; 48]);
581 if !get_seed(&mut *seed) {
582 return Err(FalconError::RandomError);
583 }
584 Self::generate_deterministic(&seed[..], logn)
585 }
586
587 pub fn generate_deterministic(seed: &[u8], logn: u32) -> Result<Self, FalconError> {
589 if logn < 1 || logn > 10 {
590 return Err(FalconError::BadArgument);
591 }
592 let sk_len = falcon_api::falcon_privkey_size(logn);
593 let pk_len = falcon_api::falcon_pubkey_size(logn);
594 let tmp_len = falcon_api::falcon_tmpsize_keygen(logn);
595
596 let mut rng = InnerShake256Context::new();
597 i_shake256_init(&mut rng);
598 i_shake256_inject(&mut rng, seed);
599 i_shake256_flip(&mut rng);
600
601 let mut privkey = vec![0u8; sk_len];
602 let mut pubkey = vec![0u8; pk_len];
603 let mut tmp = Zeroizing::new(vec![0u8; tmp_len]);
604
605 let rc = falcon_api::falcon_keygen_make(
606 &mut rng,
607 logn,
608 &mut privkey,
609 Some(&mut pubkey),
610 &mut tmp,
611 );
612 if rc != 0 {
613 return Err(translate_error(rc));
614 }
615 Ok(FnDsaKeyPair {
616 privkey: Zeroizing::new(privkey),
617 pubkey,
618 logn,
619 })
620 }
621
622 pub fn from_keys(privkey: &[u8], pubkey: &[u8]) -> Result<Self, FalconError> {
624 if privkey.is_empty() || pubkey.is_empty() {
625 return Err(FalconError::FormatError);
626 }
627 let sk_logn = falcon_api::falcon_get_logn(privkey);
628 let pk_logn = falcon_api::falcon_get_logn(pubkey);
629 if sk_logn < 0 || pk_logn < 0 {
630 return Err(FalconError::FormatError);
631 }
632 if (privkey[0] & 0xF0) != 0x50 {
633 return Err(FalconError::FormatError);
634 }
635 if (pubkey[0] & 0xF0) != 0x00 {
636 return Err(FalconError::FormatError);
637 }
638 let logn = (sk_logn & 0x0F) as u32;
639 if logn != (pk_logn & 0x0F) as u32 {
640 return Err(FalconError::FormatError);
641 }
642 if privkey.len() != falcon_api::falcon_privkey_size(logn) {
643 return Err(FalconError::FormatError);
644 }
645 if pubkey.len() != falcon_api::falcon_pubkey_size(logn) {
646 return Err(FalconError::FormatError);
647 }
648 Ok(FnDsaKeyPair {
649 privkey: Zeroizing::new(privkey.to_vec()),
650 pubkey: pubkey.to_vec(),
651 logn,
652 })
653 }
654
655 pub fn from_private_key(privkey: &[u8]) -> Result<Self, FalconError> {
657 if privkey.is_empty() {
658 return Err(FalconError::FormatError);
659 }
660 if (privkey[0] & 0xF0) != 0x50 {
661 return Err(FalconError::FormatError);
662 }
663 let logn_val = falcon_api::falcon_get_logn(privkey);
664 if logn_val < 0 {
665 return Err(FalconError::FormatError);
666 }
667 let logn = logn_val as u32;
668 if privkey.len() != falcon_api::falcon_privkey_size(logn) {
669 return Err(FalconError::FormatError);
670 }
671 let pk_len = falcon_api::falcon_pubkey_size(logn);
672 let tmp_len = falcon_api::falcon_tmpsize_makepub(logn);
673 let mut pubkey = vec![0u8; pk_len];
674 let mut tmp = Zeroizing::new(vec![0u8; tmp_len]);
675 let rc = falcon_api::falcon_make_public(&mut pubkey, privkey, &mut tmp);
676 if rc != 0 {
677 return Err(translate_error(rc));
678 }
679 Ok(FnDsaKeyPair {
680 privkey: Zeroizing::new(privkey.to_vec()),
681 pubkey,
682 logn,
683 })
684 }
685
686 pub fn public_key_from_private(privkey: &[u8]) -> Result<Vec<u8>, FalconError> {
688 Ok(Self::from_private_key(privkey)?.pubkey)
689 }
690
691 pub fn sign(
702 &self,
703 message: &[u8],
704 domain: &DomainSeparation,
705 ) -> Result<FnDsaSignature, FalconError> {
706 domain.validate()?;
707
708 let sig_max = falcon_api::falcon_sig_ct_size(self.logn);
709 let tmp_len = falcon_api::falcon_tmpsize_signdyn(self.logn);
710
711 let mut seed = Zeroizing::new([0u8; 48]);
712 if !get_seed(&mut *seed) {
713 return Err(FalconError::RandomError);
714 }
715 let mut rng = InnerShake256Context::new();
716 i_shake256_init(&mut rng);
717 i_shake256_inject(&mut rng, &*seed);
718 i_shake256_flip(&mut rng);
719
720 let mut sig = vec![0u8; sig_max];
721 let mut sig_len = sig_max;
722 let mut tmp = Zeroizing::new(vec![0u8; tmp_len]);
723
724 let mut nonce = [0u8; 40];
725 falcon_api::shake256_extract(&mut rng, &mut nonce);
726 let mut hd = InnerShake256Context::new();
727 falcon_api::shake256_init(&mut hd);
728 falcon_api::shake256_inject(&mut hd, &nonce);
729 domain.inject(&mut hd, message);
730
731 let rc = falcon_api::falcon_sign_dyn_finish(
732 &mut rng,
733 &mut sig,
734 &mut sig_len,
735 falcon_api::FALCON_SIG_CT,
736 &self.privkey,
737 &mut hd,
738 &nonce,
739 &mut tmp,
740 );
741 if rc != 0 {
742 return Err(translate_error(rc));
743 }
744 sig.truncate(sig_len);
745 Ok(FnDsaSignature { data: sig })
746 }
747
748 pub fn sign_deterministic(
757 &self,
758 message: &[u8],
759 seed: &[u8],
760 domain: &DomainSeparation,
761 ) -> Result<FnDsaSignature, FalconError> {
762 domain.validate()?;
763
764 let sig_max = falcon_api::falcon_sig_ct_size(self.logn);
765 let tmp_len = falcon_api::falcon_tmpsize_signdyn(self.logn);
766
767 let mut rng = InnerShake256Context::new();
768 i_shake256_init(&mut rng);
769 i_shake256_inject(&mut rng, seed);
770 i_shake256_flip(&mut rng);
771
772 let mut sig = vec![0u8; sig_max];
773 let mut sig_len = sig_max;
774 let mut tmp = Zeroizing::new(vec![0u8; tmp_len]);
775
776 let mut nonce = [0u8; 40];
777 falcon_api::shake256_extract(&mut rng, &mut nonce);
778 let mut hd = InnerShake256Context::new();
779 falcon_api::shake256_init(&mut hd);
780 falcon_api::shake256_inject(&mut hd, &nonce);
781 domain.inject(&mut hd, message);
782
783 let rc = falcon_api::falcon_sign_dyn_finish(
784 &mut rng,
785 &mut sig,
786 &mut sig_len,
787 falcon_api::FALCON_SIG_CT,
788 &self.privkey,
789 &mut hd,
790 &nonce,
791 &mut tmp,
792 );
793 if rc != 0 {
794 return Err(translate_error(rc));
795 }
796 sig.truncate(sig_len);
797 Ok(FnDsaSignature { data: sig })
798 }
799
800 pub fn public_key(&self) -> &[u8] {
802 &self.pubkey
803 }
804
805 pub fn private_key(&self) -> &[u8] {
809 &self.privkey
810 }
811
812 pub fn logn(&self) -> u32 {
816 self.logn
817 }
818
819 pub fn variant_name(&self) -> &'static str {
821 match self.logn {
822 9 => "FN-DSA-512",
823 10 => "FN-DSA-1024",
824 n => match n {
825 1 => "FN-DSA-2",
826 2 => "FN-DSA-4",
827 3 => "FN-DSA-8",
828 4 => "FN-DSA-16",
829 5 => "FN-DSA-32",
830 6 => "FN-DSA-64",
831 7 => "FN-DSA-128",
832 8 => "FN-DSA-256",
833 _ => "FN-DSA-unknown",
834 },
835 }
836 }
837}
838
839#[derive(Debug, Clone)]
848#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
849pub struct FnDsaSignature {
850 data: Vec<u8>,
851}
852
853pub type FalconSignature = FnDsaSignature;
855
856impl FnDsaSignature {
857 pub fn from_bytes(data: Vec<u8>) -> Result<Self, FalconError> {
862 if data.len() < 41 {
863 return Err(FalconError::FormatError);
864 }
865 let hdr = data[0] & 0xF0;
867 if hdr != 0x30 && hdr != 0x50 {
868 return Err(FalconError::FormatError);
869 }
870 let logn = data[0] & 0x0F;
871 if logn < 1 || logn > 10 {
872 return Err(FalconError::FormatError);
873 }
874 Ok(FnDsaSignature { data })
875 }
876
877 pub fn verify(
890 sig: &[u8],
891 pubkey: &[u8],
892 message: &[u8],
893 domain: &DomainSeparation,
894 ) -> Result<(), FalconError> {
895 domain.validate()?;
896
897 if pubkey.is_empty() || sig.is_empty() {
898 return Err(FalconError::FormatError);
899 }
900 let logn_val = falcon_api::falcon_get_logn(pubkey);
901 if logn_val < 0 {
902 return Err(FalconError::FormatError);
903 }
904 let logn = logn_val as u32;
905
906 let sig_ct = falcon_api::falcon_sig_ct_size(logn);
908 let sig_padded = falcon_api::falcon_sig_padded_size(logn);
909 let sig_comp_max = falcon_api::falcon_sig_compressed_maxsize(logn);
910 if sig.len() < 41 || sig.len() > sig_ct.max(sig_padded).max(sig_comp_max) {
911 return Err(FalconError::FormatError);
912 }
913
914 let tmp_len = falcon_api::falcon_tmpsize_verify(logn);
915 let mut tmp = Zeroizing::new(vec![0u8; tmp_len]);
916
917 let mut hd = InnerShake256Context::new();
918 let r = falcon_api::falcon_verify_start(&mut hd, sig);
919 if r < 0 {
920 return Err(translate_error(r));
921 }
922 domain.inject(&mut hd, message);
923 let rc = falcon_api::falcon_verify_finish(sig, 0, pubkey, &mut hd, &mut tmp);
924 if rc != 0 {
925 return Err(translate_error(rc));
926 }
927 Ok(())
928 }
929
930 pub fn to_bytes(&self) -> &[u8] {
932 &self.data
933 }
934
935 pub fn into_bytes(self) -> Vec<u8> {
937 self.data
938 }
939
940 pub fn len(&self) -> usize {
942 self.data.len()
943 }
944
945 pub fn is_empty(&self) -> bool {
947 self.data.is_empty()
948 }
949}
950
951#[derive(Clone)]
975pub struct FnDsaExpandedKey {
976 expanded: Zeroizing<Vec<u8>>,
978 pubkey: Vec<u8>,
980 logn: u32,
982}
983
984impl fmt::Debug for FnDsaExpandedKey {
985 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
986 f.debug_struct("FnDsaExpandedKey")
987 .field("expanded", &"[REDACTED]")
988 .field("pubkey_len", &self.pubkey.len())
989 .field("logn", &self.logn)
990 .finish()
991 }
992}
993
994impl FnDsaKeyPair {
995 pub fn expand(&self) -> Result<FnDsaExpandedKey, FalconError> {
1000 let logn = self.logn;
1001 let ek_len = falcon_api::falcon_expandedkey_size(logn);
1002 let tmp_len = falcon_api::falcon_tmpsize_expandpriv(logn);
1003 let mut expanded = vec![0u8; ek_len];
1004 let mut tmp = Zeroizing::new(vec![0u8; tmp_len]);
1005 let rc = falcon_api::falcon_expand_privkey(&mut expanded, &self.privkey, &mut tmp);
1006 if rc != 0 {
1007 return Err(translate_error(rc));
1008 }
1009 Ok(FnDsaExpandedKey {
1010 expanded: Zeroizing::new(expanded),
1011 pubkey: self.pubkey.clone(),
1012 logn,
1013 })
1014 }
1015}
1016
1017impl FnDsaExpandedKey {
1018 pub fn sign(
1020 &self,
1021 message: &[u8],
1022 domain: &DomainSeparation<'_>,
1023 ) -> Result<FnDsaSignature, FalconError> {
1024 domain.validate()?;
1025 let logn = self.logn;
1026 let sig_max = falcon_api::falcon_sig_ct_size(logn);
1027 let tmp_len = falcon_api::falcon_tmpsize_signtree(logn);
1028 let mut sig = vec![0u8; sig_max];
1029 let mut sig_len = sig_max;
1030 let mut tmp = Zeroizing::new(vec![0u8; tmp_len]);
1031
1032 let mut seed = Zeroizing::new([0u8; 48]);
1033 if !get_seed(&mut *seed) {
1034 return Err(FalconError::RandomError);
1035 }
1036 let mut rng = InnerShake256Context::new();
1037 i_shake256_init(&mut rng);
1038 i_shake256_inject(&mut rng, &*seed);
1039 i_shake256_flip(&mut rng);
1040
1041 let mut hd = InnerShake256Context::new();
1042 let mut nonce = [0u8; 40];
1043 falcon_api::falcon_sign_start(&mut rng, &mut nonce, &mut hd);
1044 domain.inject(&mut hd, message);
1045
1046 let rc = falcon_api::falcon_sign_tree_finish(
1047 &mut rng,
1048 &mut sig,
1049 &mut sig_len,
1050 falcon_api::FALCON_SIG_CT,
1051 &self.expanded,
1052 &mut hd,
1053 &nonce,
1054 &mut tmp,
1055 );
1056 if rc != 0 {
1057 return Err(translate_error(rc));
1058 }
1059 sig.truncate(sig_len);
1060 Ok(FnDsaSignature { data: sig })
1061 }
1062
1063 pub fn sign_deterministic(
1065 &self,
1066 message: &[u8],
1067 sign_seed: &[u8],
1068 domain: &DomainSeparation<'_>,
1069 ) -> Result<FnDsaSignature, FalconError> {
1070 let logn = self.logn;
1071 let sig_max = falcon_api::falcon_sig_ct_size(logn);
1072 let tmp_len = falcon_api::falcon_tmpsize_signtree(logn);
1073 let mut sig = vec![0u8; sig_max];
1074 let mut sig_len = sig_max;
1075 let mut tmp = Zeroizing::new(vec![0u8; tmp_len]);
1076
1077 let mut rng = InnerShake256Context::new();
1078 i_shake256_init(&mut rng);
1079 i_shake256_inject(&mut rng, sign_seed);
1080 i_shake256_flip(&mut rng);
1081
1082 let mut hd = InnerShake256Context::new();
1083 let mut nonce = [0u8; 40];
1084 falcon_api::falcon_sign_start(&mut rng, &mut nonce, &mut hd);
1085 domain.inject(&mut hd, message);
1086
1087 let rc = falcon_api::falcon_sign_tree_finish(
1088 &mut rng,
1089 &mut sig,
1090 &mut sig_len,
1091 falcon_api::FALCON_SIG_CT,
1092 &self.expanded,
1093 &mut hd,
1094 &nonce,
1095 &mut tmp,
1096 );
1097 if rc != 0 {
1098 return Err(translate_error(rc));
1099 }
1100 sig.truncate(sig_len);
1101 Ok(FnDsaSignature { data: sig })
1102 }
1103
1104 pub fn public_key(&self) -> &[u8] {
1106 &self.pubkey
1107 }
1108
1109 pub fn logn(&self) -> u32 {
1111 self.logn
1112 }
1113}