1use crate::device::Device;
6use crate::error::{check_error, QuacError, Result};
7use crate::ffi;
8use crate::types::SignAlgorithm;
9
10use zeroize::ZeroizeOnDrop;
11
12#[derive(Clone, ZeroizeOnDrop)]
17pub struct SignatureKeyPair {
18 #[zeroize(skip)]
20 public_key: Vec<u8>,
21 secret_key: Vec<u8>,
23 #[zeroize(skip)]
25 algorithm: SignAlgorithm,
26}
27
28impl SignatureKeyPair {
29 fn new(public_key: Vec<u8>, secret_key: Vec<u8>, algorithm: SignAlgorithm) -> Self {
31 Self {
32 public_key,
33 secret_key,
34 algorithm,
35 }
36 }
37
38 pub fn public_key(&self) -> &[u8] {
40 &self.public_key
41 }
42
43 pub fn secret_key(&self) -> &[u8] {
45 &self.secret_key
46 }
47
48 pub fn algorithm(&self) -> SignAlgorithm {
50 self.algorithm
51 }
52
53 pub fn into_bytes(mut self) -> (Vec<u8>, Vec<u8>) {
55 let pk = std::mem::take(&mut self.public_key);
56 let sk = std::mem::take(&mut self.secret_key);
57 std::mem::forget(self);
58 (pk, sk)
59 }
60}
61
62impl std::fmt::Debug for SignatureKeyPair {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 f.debug_struct("SignatureKeyPair")
65 .field("algorithm", &self.algorithm)
66 .field("public_key_len", &self.public_key.len())
67 .field("secret_key_len", &self.secret_key.len())
68 .finish()
69 }
70}
71
72#[derive(Clone)]
98pub struct Sign {
99 device: Device,
100}
101
102impl Sign {
103 pub(crate) fn new(device: Device) -> Self {
105 Self { device }
106 }
107
108 pub fn generate_keypair(&self, algorithm: SignAlgorithm) -> Result<SignatureKeyPair> {
118 let pk_size = algorithm.public_key_size();
119 let sk_size = algorithm.secret_key_size();
120
121 let mut public_key = vec![0u8; pk_size];
122 let mut secret_key = vec![0u8; sk_size];
123 let mut pk_len = pk_size;
124 let mut sk_len = sk_size;
125
126 let result = unsafe {
127 ffi::quac_sign_keygen(
128 self.device.handle(),
129 algorithm.to_raw(),
130 public_key.as_mut_ptr(),
131 &mut pk_len,
132 secret_key.as_mut_ptr(),
133 &mut sk_len,
134 )
135 };
136
137 check_error(result)?;
138
139 public_key.truncate(pk_len);
140 secret_key.truncate(sk_len);
141
142 Ok(SignatureKeyPair::new(public_key, secret_key, algorithm))
143 }
144
145 pub fn generate_keypair_44(&self) -> Result<SignatureKeyPair> {
147 self.generate_keypair(SignAlgorithm::MlDsa44)
148 }
149
150 pub fn generate_keypair_65(&self) -> Result<SignatureKeyPair> {
152 self.generate_keypair(SignAlgorithm::MlDsa65)
153 }
154
155 pub fn generate_keypair_87(&self) -> Result<SignatureKeyPair> {
157 self.generate_keypair(SignAlgorithm::MlDsa87)
158 }
159
160 pub fn sign(
172 &self,
173 secret_key: &[u8],
174 message: &[u8],
175 algorithm: SignAlgorithm,
176 ) -> Result<Vec<u8>> {
177 let sig_size = algorithm.signature_size();
178 let mut signature = vec![0u8; sig_size];
179 let mut sig_len = sig_size;
180
181 let result = unsafe {
182 ffi::quac_sign(
183 self.device.handle(),
184 algorithm.to_raw(),
185 secret_key.as_ptr(),
186 secret_key.len(),
187 message.as_ptr(),
188 message.len(),
189 signature.as_mut_ptr(),
190 &mut sig_len,
191 )
192 };
193
194 check_error(result)?;
195 signature.truncate(sig_len);
196
197 Ok(signature)
198 }
199
200 pub fn sign_44(&self, secret_key: &[u8], message: &[u8]) -> Result<Vec<u8>> {
202 self.sign(secret_key, message, SignAlgorithm::MlDsa44)
203 }
204
205 pub fn sign_65(&self, secret_key: &[u8], message: &[u8]) -> Result<Vec<u8>> {
207 self.sign(secret_key, message, SignAlgorithm::MlDsa65)
208 }
209
210 pub fn sign_87(&self, secret_key: &[u8], message: &[u8]) -> Result<Vec<u8>> {
212 self.sign(secret_key, message, SignAlgorithm::MlDsa87)
213 }
214
215 pub fn sign_str(
217 &self,
218 secret_key: &[u8],
219 message: &str,
220 algorithm: SignAlgorithm,
221 ) -> Result<Vec<u8>> {
222 self.sign(secret_key, message.as_bytes(), algorithm)
223 }
224
225 pub fn verify(
238 &self,
239 public_key: &[u8],
240 message: &[u8],
241 signature: &[u8],
242 algorithm: SignAlgorithm,
243 ) -> Result<bool> {
244 let result = unsafe {
245 ffi::quac_verify(
246 self.device.handle(),
247 algorithm.to_raw(),
248 public_key.as_ptr(),
249 public_key.len(),
250 message.as_ptr(),
251 message.len(),
252 signature.as_ptr(),
253 signature.len(),
254 )
255 };
256
257 match result {
258 0 => Ok(true),
259 -13 => Ok(false), _ => {
261 check_error(result)?;
262 Ok(false)
263 }
264 }
265 }
266
267 pub fn verify_44(&self, public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<bool> {
269 self.verify(public_key, message, signature, SignAlgorithm::MlDsa44)
270 }
271
272 pub fn verify_65(&self, public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<bool> {
274 self.verify(public_key, message, signature, SignAlgorithm::MlDsa65)
275 }
276
277 pub fn verify_87(&self, public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<bool> {
279 self.verify(public_key, message, signature, SignAlgorithm::MlDsa87)
280 }
281
282 pub fn verify_str(
284 &self,
285 public_key: &[u8],
286 message: &str,
287 signature: &[u8],
288 algorithm: SignAlgorithm,
289 ) -> Result<bool> {
290 self.verify(public_key, message.as_bytes(), signature, algorithm)
291 }
292
293 pub fn verify_or_error(
298 &self,
299 public_key: &[u8],
300 message: &[u8],
301 signature: &[u8],
302 algorithm: SignAlgorithm,
303 ) -> Result<()> {
304 if self.verify(public_key, message, signature, algorithm)? {
305 Ok(())
306 } else {
307 Err(QuacError::VerificationFailed)
308 }
309 }
310}
311
312impl std::fmt::Debug for Sign {
313 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
314 f.debug_struct("Sign").finish()
315 }
316}
317
318#[cfg(test)]
319mod tests {
320 use super::*;
321
322 #[test]
323 fn test_keypair_debug_hides_secret() {
324 let kp = SignatureKeyPair::new(
325 vec![1, 2, 3],
326 vec![4, 5, 6],
327 SignAlgorithm::MlDsa65,
328 );
329 let debug = format!("{:?}", kp);
330 assert!(!debug.contains("[4, 5, 6]"));
331 assert!(debug.contains("secret_key_len"));
332 }
333}