1use crate::error::{QVError, QVResult};
22use pqcrypto_traits::sign::{
23 DetachedSignature as _, PublicKey as _, SecretKey as _, VerificationError,
24};
25
26pub mod falcon512 {
30 use super::*;
31 use pqcrypto_falcon::falcon512 as ffi;
32
33 pub const MAX_SIG_BYTES: usize = 666;
35 pub const VK_BYTES: usize = 897;
36 pub const SK_BYTES: usize = 1281;
37
38 #[derive(Clone)]
39 pub struct QVFalcon512SigningKey(ffi::SecretKey);
40
41 #[derive(Clone)]
42 pub struct QVFalcon512VerifyingKey(ffi::PublicKey);
43
44 impl QVFalcon512SigningKey {
45 pub fn to_bytes(&self) -> Vec<u8> {
46 self.0.as_bytes().to_vec()
47 }
48 pub fn from_bytes(bytes: &[u8]) -> QVResult<Self> {
49 ffi::SecretKey::from_bytes(bytes)
50 .map(Self)
51 .map_err(|_| QVError::SerializationError("Falcon-512 sk".into()))
52 }
53 }
54
55 impl QVFalcon512VerifyingKey {
56 pub fn to_bytes(&self) -> Vec<u8> {
57 self.0.as_bytes().to_vec()
58 }
59 pub fn from_bytes(bytes: &[u8]) -> QVResult<Self> {
60 ffi::PublicKey::from_bytes(bytes)
61 .map(Self)
62 .map_err(|_| QVError::SerializationError("Falcon-512 vk".into()))
63 }
64 }
65
66 pub fn generate_keypair() -> QVResult<(QVFalcon512SigningKey, QVFalcon512VerifyingKey)> {
68 let (pk, sk) = ffi::keypair();
69 Ok((QVFalcon512SigningKey(sk), QVFalcon512VerifyingKey(pk)))
70 }
71
72 pub fn sign(sk: &QVFalcon512SigningKey, msg: &[u8]) -> QVResult<Vec<u8>> {
74 let sig = ffi::detached_sign(msg, &sk.0);
75 Ok(sig.as_bytes().to_vec())
76 }
77
78 pub fn verify(vk: &QVFalcon512VerifyingKey, msg: &[u8], sig: &[u8]) -> QVResult<()> {
80 let parsed = ffi::DetachedSignature::from_bytes(sig)
81 .map_err(|_| QVError::SignatureInvalid)?;
82 match ffi::verify_detached_signature(&parsed, msg, &vk.0) {
83 Ok(()) => Ok(()),
84 Err(VerificationError::InvalidSignature) => Err(QVError::SignatureInvalid),
85 Err(_) => Err(QVError::SignatureInvalid),
86 }
87 }
88}
89
90pub mod falcon1024 {
94 use super::*;
95 use pqcrypto_falcon::falcon1024 as ffi;
96
97 pub const MAX_SIG_BYTES: usize = 1280;
98 pub const VK_BYTES: usize = 1793;
99 pub const SK_BYTES: usize = 2305;
100
101 #[derive(Clone)]
102 pub struct QVFalcon1024SigningKey(ffi::SecretKey);
103
104 #[derive(Clone)]
105 pub struct QVFalcon1024VerifyingKey(ffi::PublicKey);
106
107 impl QVFalcon1024SigningKey {
108 pub fn to_bytes(&self) -> Vec<u8> {
109 self.0.as_bytes().to_vec()
110 }
111 pub fn from_bytes(bytes: &[u8]) -> QVResult<Self> {
112 ffi::SecretKey::from_bytes(bytes)
113 .map(Self)
114 .map_err(|_| QVError::SerializationError("Falcon-1024 sk".into()))
115 }
116 }
117
118 impl QVFalcon1024VerifyingKey {
119 pub fn to_bytes(&self) -> Vec<u8> {
120 self.0.as_bytes().to_vec()
121 }
122 pub fn from_bytes(bytes: &[u8]) -> QVResult<Self> {
123 ffi::PublicKey::from_bytes(bytes)
124 .map(Self)
125 .map_err(|_| QVError::SerializationError("Falcon-1024 vk".into()))
126 }
127 }
128
129 pub fn generate_keypair() -> QVResult<(QVFalcon1024SigningKey, QVFalcon1024VerifyingKey)> {
130 let (pk, sk) = ffi::keypair();
131 Ok((QVFalcon1024SigningKey(sk), QVFalcon1024VerifyingKey(pk)))
132 }
133
134 pub fn sign(sk: &QVFalcon1024SigningKey, msg: &[u8]) -> QVResult<Vec<u8>> {
135 let sig = ffi::detached_sign(msg, &sk.0);
136 Ok(sig.as_bytes().to_vec())
137 }
138
139 pub fn verify(vk: &QVFalcon1024VerifyingKey, msg: &[u8], sig: &[u8]) -> QVResult<()> {
140 let parsed = ffi::DetachedSignature::from_bytes(sig)
141 .map_err(|_| QVError::SignatureInvalid)?;
142 match ffi::verify_detached_signature(&parsed, msg, &vk.0) {
143 Ok(()) => Ok(()),
144 Err(VerificationError::InvalidSignature) => Err(QVError::SignatureInvalid),
145 Err(_) => Err(QVError::SignatureInvalid),
146 }
147 }
148}
149
150#[cfg(test)]
154mod tests {
155 use super::*;
156
157 #[test]
158 fn falcon512_roundtrip() {
159 let (sk, vk) = falcon512::generate_keypair().expect("keygen");
160 let msg = b"Sigvault v4.1 Falcon-512 roundtrip";
161 let sig = falcon512::sign(&sk, msg).expect("sign");
162 assert!(sig.len() <= falcon512::MAX_SIG_BYTES, "sig {} > max", sig.len());
163 assert!(sig.len() > 500, "sig suspiciously small: {}", sig.len());
164 falcon512::verify(&vk, msg, &sig).expect("verify");
165
166 let mut bad = sig.clone();
168 bad[10] ^= 0xFF;
169 assert!(falcon512::verify(&vk, msg, &bad).is_err());
170
171 let vk_bytes = vk.to_bytes();
173 assert_eq!(vk_bytes.len(), falcon512::VK_BYTES);
174 let vk2 = falcon512::QVFalcon512VerifyingKey::from_bytes(&vk_bytes).expect("vk parse");
175 falcon512::verify(&vk2, msg, &sig).expect("verify after reparse");
176 }
177
178 #[test]
179 fn falcon1024_roundtrip() {
180 let (sk, vk) = falcon1024::generate_keypair().expect("keygen");
181 let msg = b"Sigvault v4.1 Falcon-1024 roundtrip";
182 let sig = falcon1024::sign(&sk, msg).expect("sign");
183 assert!(sig.len() <= falcon1024::MAX_SIG_BYTES, "sig {} > max", sig.len());
184 assert!(sig.len() > 1000, "sig suspiciously small: {}", sig.len());
185 falcon1024::verify(&vk, msg, &sig).expect("verify");
186
187 let sk_bytes = sk.to_bytes();
188 assert_eq!(sk_bytes.len(), falcon1024::SK_BYTES);
189 }
190
191 #[test]
192 fn size_advantage_vs_mldsa87() {
193 let (sk, _vk) = falcon512::generate_keypair().expect("keygen");
195 let sig = falcon512::sign(&sk, b"size demo").expect("sign");
196 assert!(sig.len() < 4627 / 5, "expected at least 5x smaller than ML-DSA-87");
198 }
199}