1use alloc::vec::Vec;
6
7use core::ptr::{null, NonNull};
8use core::str::FromStr;
9
10#[cfg(not(feature = "std"))]
11use cstr_core::CStr;
12#[cfg(feature = "std")]
13use std::ffi::CStr;
14
15use crate::ffi::sig as ffi;
16use crate::newtype_buffer;
17use crate::*;
18#[cfg(feature = "rustcrypto")]
19use ::signature::Signer as RustCryptoSigner;
20#[cfg(feature = "rustcrypto")]
21use ::signature::Verifier as RustCryptoVerifier;
22
23#[cfg(feature = "serde")]
24use serde::{Deserialize, Serialize};
25
26newtype_buffer!(PublicKey, PublicKeyRef);
27newtype_buffer!(SecretKey, SecretKeyRef);
28newtype_buffer!(Signature, SignatureRef);
29
30pub type Message = [u8];
32pub type CtxStr = [u8];
34
35macro_rules! implement_sigs {
36 { $($(#[$test_attr:meta])* ($feat: literal) $sig: ident: $oqs_id: ident),* $(,)? } => (
37 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
43 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44 #[allow(missing_docs)]
45 pub enum Algorithm {
46 $(
47 $sig,
48 )*
49 }
50
51 fn algorithm_to_id(algorithm: Algorithm) -> *const libc::c_char {
52 let id: &[u8] = match algorithm {
53 $(
54 Algorithm::$sig => &ffi::$oqs_id[..],
55 )*
56 };
57 id as *const _ as *const libc::c_char
58 }
59
60 impl FromStr for Algorithm {
61 type Err = crate::Error;
62
63 fn from_str(s: &str) -> Result<Self> {
64 $(
65 if s == Algorithm::$sig.name() {
66 return Ok(Algorithm::$sig);
67 }
68 )*
69 Err(crate::Error::AlgorithmParsingError)
70 }
71 }
72
73 $(
74 #[cfg(test)]
75 #[allow(non_snake_case)]
76 mod $sig {
77 use super::*;
78
79 #[test]
80 #[cfg(feature = $feat)]
81 $(#[$test_attr])*
82 fn test_signing() -> Result<()> {
83 crate::init();
84 let message = [0u8; 100];
85 let sig = Sig::new(Algorithm::$sig)?;
86 let (pk, sk) = sig.keypair()?;
87 let signature = sig.sign(&message, &sk)?;
88 sig.verify(&message, &signature, &pk)
89 }
90
91 #[test]
92 #[cfg(feature = $feat)]
93 $(#[$test_attr])*
94 fn test_signing_with_empty_context_string() -> Result<()> {
95 crate::init();
96 let message = [0u8; 100];
97 let ctx_str: [u8; 0] = [];
98 let sig = Sig::new(Algorithm::$sig)?;
99 let (pk, sk) = sig.keypair()?;
100 let signature = sig.sign_with_ctx_str(&message, &ctx_str, &sk)?;
101 sig.verify_with_ctx_str(&message, &signature, &ctx_str, &pk)
102 }
103
104 #[test]
105 #[cfg(feature = $feat)]
106 $(#[$test_attr])*
107 fn test_signing_with_nonempty_context_string() -> Result<()> {
108 crate::init();
109 let message = [0u8; 100];
110 let ctx_str = [0u8; 100];
111 let sig = Sig::new(Algorithm::$sig)?;
112 let (pk, sk) = sig.keypair()?;
113 if sig.has_ctx_str_support() {
114 let signature = sig.sign_with_ctx_str(&message, &ctx_str, &sk)?;
115 sig.verify_with_ctx_str(&message, &signature, &ctx_str, &pk)
116 } else {
117 let sig_result = sig.sign_with_ctx_str(&message, &ctx_str, &sk);
118 let sig_result: Result<()> = match sig_result {
120 Err(Error::Error) => Ok(()),
121 Ok(_) => Err(Error::Error),
122 Err(e) => Err(e)
123 };
124 if sig_result.is_ok() {
125 let signature = sig.sign(&message, &sk)?;
127 match sig.verify_with_ctx_str(&message, &signature, &ctx_str, &pk) {
129 Err(Error::Error) => Ok(()),
130 Ok(_) => Err(Error::Error),
131 Err(e) => Err(e)
132
133 }
134 } else {
135 sig_result
136 }
137 }
138 }
139
140 #[test]
141 fn test_enabled() {
142 crate::init();
143 if cfg!(feature = $feat) {
144 assert!(Algorithm::$sig.is_enabled());
145 } else {
146 assert!(!Algorithm::$sig.is_enabled())
147 }
148 }
149
150 #[test]
151 fn test_name() {
152 let algo = Algorithm::$sig;
153 let name = algo.name();
155
156 #[cfg(feature = "std")]
157 assert_eq!(name, algo.to_string());
158
159 assert!(!name.is_empty());
161 }
162
163 #[test]
164 fn test_get_algorithm_back() {
165 let algorithm = Algorithm::$sig;
166 if algorithm.is_enabled() {
167 let sig = Sig::new(algorithm).unwrap();
168 assert_eq!(algorithm, sig.algorithm());
169 }
170 }
171
172 #[test]
173 fn test_version() {
174 if let Ok(sig) = Sig::new(Algorithm::$sig) {
175 let version = sig.version();
177 assert!(!version.is_empty());
179 }
180 }
181
182 #[test]
183 fn test_from_str() {
184 let algorithm = Algorithm::$sig;
185 let name = algorithm.name();
186 let parsed = Algorithm::from_str(name).unwrap();
187 assert_eq!(algorithm, parsed);}
188 }
189 )*
190 )
191}
192
193include!("generated_sig_algorithms.rs");
194
195impl Algorithm {
196 pub fn is_enabled(self) -> bool {
199 unsafe { ffi::OQS_SIG_alg_is_enabled(algorithm_to_id(self)) == 1 }
200 }
201
202 pub fn to_id(self) -> *const libc::c_char {
206 algorithm_to_id(self)
207 }
208
209 pub fn name(&self) -> &'static str {
213 let id = unsafe { CStr::from_ptr(self.to_id()) };
215 id.to_str().expect("OQS algorithm names must be UTF-8")
216 }
217}
218
219pub struct Sig {
233 algorithm: Algorithm,
234 sig: NonNull<ffi::OQS_SIG>,
235}
236
237unsafe impl Sync for Sig {}
238unsafe impl Send for Sig {}
239
240impl Drop for Sig {
241 fn drop(&mut self) {
242 unsafe { ffi::OQS_SIG_free(self.sig.as_ptr()) };
243 }
244}
245
246#[cfg(feature = "std")]
247impl std::fmt::Display for Algorithm {
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 self.name().fmt(f)
250 }
251}
252
253impl core::convert::TryFrom<Algorithm> for Sig {
254 type Error = crate::Error;
255 fn try_from(alg: Algorithm) -> Result<Sig> {
256 Sig::new(alg)
257 }
258}
259
260impl Sig {
261 pub fn new(algorithm: Algorithm) -> Result<Self> {
265 let sig = unsafe { ffi::OQS_SIG_new(algorithm_to_id(algorithm)) };
266 NonNull::new(sig).map_or_else(
267 || Err(Error::AlgorithmDisabled),
268 |sig| Ok(Self { algorithm, sig }),
269 )
270 }
271
272 pub fn algorithm(&self) -> Algorithm {
274 self.algorithm
275 }
276
277 pub fn version(&self) -> &'static str {
279 let sig = unsafe { self.sig.as_ref() };
280 let cstr = unsafe { CStr::from_ptr(sig.alg_version) };
282 cstr.to_str()
283 .expect("Algorithm version strings must be UTF-8")
284 }
285
286 pub fn claimed_nist_level(&self) -> u8 {
288 let sig = unsafe { self.sig.as_ref() };
289 sig.claimed_nist_level
290 }
291
292 pub fn is_euf_cma(&self) -> bool {
294 let sig = unsafe { self.sig.as_ref() };
295 sig.euf_cma
296 }
297
298 pub fn has_ctx_str_support(&self) -> bool {
300 let sig = unsafe { self.sig.as_ref() };
301 sig.sig_with_ctx_support
302 }
303
304 pub fn length_public_key(&self) -> usize {
306 let sig = unsafe { self.sig.as_ref() };
307 sig.length_public_key
308 }
309
310 pub fn length_secret_key(&self) -> usize {
312 let sig = unsafe { self.sig.as_ref() };
313 sig.length_secret_key
314 }
315
316 pub fn length_signature(&self) -> usize {
318 let sig = unsafe { self.sig.as_ref() };
319 sig.length_signature
320 }
321
322 pub fn secret_key_from_bytes<'a>(&self, buf: &'a [u8]) -> Option<SecretKeyRef<'a>> {
324 if buf.len() != self.length_secret_key() {
325 None
326 } else {
327 Some(SecretKeyRef::new(buf))
328 }
329 }
330
331 pub fn public_key_from_bytes<'a>(&self, buf: &'a [u8]) -> Option<PublicKeyRef<'a>> {
333 if buf.len() != self.length_public_key() {
334 None
335 } else {
336 Some(PublicKeyRef::new(buf))
337 }
338 }
339
340 pub fn signature_from_bytes<'a>(&self, buf: &'a [u8]) -> Option<SignatureRef<'a>> {
342 if buf.len() > self.length_signature() {
343 None
344 } else {
345 Some(SignatureRef::new(buf))
346 }
347 }
348
349 pub fn keypair(&self) -> Result<(PublicKey, SecretKey)> {
351 let sig = unsafe { self.sig.as_ref() };
352 let func = sig.keypair.unwrap();
353 let mut pk = PublicKey {
354 bytes: Vec::with_capacity(sig.length_public_key),
355 };
356 let mut sk = SecretKey {
357 bytes: Vec::with_capacity(sig.length_secret_key),
358 };
359 let status = unsafe { func(pk.bytes.as_mut_ptr(), sk.bytes.as_mut_ptr()) };
360 unsafe {
362 pk.bytes.set_len(sig.length_public_key);
363 sk.bytes.set_len(sig.length_secret_key);
364 }
365 status_to_result(status)?;
366 Ok((pk, sk))
367 }
368
369 pub fn sign<'a, S: Into<SecretKeyRef<'a>>>(
371 &self,
372 message: &Message,
373 sk: S,
374 ) -> Result<Signature> {
375 let sk = sk.into();
376 let sig = unsafe { self.sig.as_ref() };
377 let func = sig.sign.unwrap();
378 let mut sig = Signature {
379 bytes: Vec::with_capacity(sig.length_signature),
380 };
381 let mut sig_len = 0;
382 let status = unsafe {
383 func(
384 sig.bytes.as_mut_ptr(),
385 &mut sig_len,
386 message.as_ptr(),
387 message.len(),
388 sk.bytes.as_ptr(),
389 )
390 };
391 status_to_result(status)?;
392 unsafe {
394 sig.bytes.set_len(sig_len);
395 }
396 Ok(sig)
397 }
398
399 pub fn sign_with_ctx_str<'a, S: Into<SecretKeyRef<'a>>>(
401 &self,
402 message: &Message,
403 ctx_str: &CtxStr,
404 sk: S,
405 ) -> Result<Signature> {
406 let sk = sk.into();
407 let sig = unsafe { self.sig.as_ref() };
408 let func = sig.sign_with_ctx_str.unwrap();
409 let mut sig = Signature {
410 bytes: Vec::with_capacity(sig.length_signature),
411 };
412 let mut sig_len = 0;
413 let ctx_str_ptr = if !ctx_str.is_empty() {
417 ctx_str.as_ptr()
418 } else {
419 null()
420 };
421 let status = unsafe {
422 func(
423 sig.bytes.as_mut_ptr(),
424 &mut sig_len,
425 message.as_ptr(),
426 message.len(),
427 ctx_str_ptr,
428 ctx_str.len(),
429 sk.bytes.as_ptr(),
430 )
431 };
432 status_to_result(status)?;
433 unsafe {
435 sig.bytes.set_len(sig_len);
436 }
437 Ok(sig)
438 }
439
440 pub fn verify<'a, 'b>(
442 &self,
443 message: &Message,
444 signature: impl Into<SignatureRef<'a>>,
445 pk: impl Into<PublicKeyRef<'b>>,
446 ) -> Result<()> {
447 let signature = signature.into();
448 let pk = pk.into();
449 if signature.bytes.len() > self.length_signature()
450 || pk.bytes.len() != self.length_public_key()
451 {
452 return Err(Error::InvalidLength);
453 }
454 let sig = unsafe { self.sig.as_ref() };
455 let func = sig.verify.unwrap();
456 let status = unsafe {
457 func(
458 message.as_ptr(),
459 message.len(),
460 signature.bytes.as_ptr(),
461 signature.len(),
462 pk.bytes.as_ptr(),
463 )
464 };
465 status_to_result(status)
466 }
467
468 pub fn verify_with_ctx_str<'a, 'b>(
470 &self,
471 message: &Message,
472 signature: impl Into<SignatureRef<'a>>,
473 ctx_str: &CtxStr,
474 pk: impl Into<PublicKeyRef<'b>>,
475 ) -> Result<()> {
476 let signature = signature.into();
477 let pk = pk.into();
478 if signature.bytes.len() > self.length_signature()
479 || pk.bytes.len() != self.length_public_key()
480 {
481 return Err(Error::InvalidLength);
482 }
483 let sig = unsafe { self.sig.as_ref() };
484 let func = sig.verify_with_ctx_str.unwrap();
485 let ctx_str_ptr = if !ctx_str.is_empty() {
489 ctx_str.as_ptr()
490 } else {
491 null()
492 };
493 let status = unsafe {
494 func(
495 message.as_ptr(),
496 message.len(),
497 signature.bytes.as_ptr(),
498 signature.len(),
499 ctx_str_ptr,
500 ctx_str.len(),
501 pk.bytes.as_ptr(),
502 )
503 };
504 status_to_result(status)
505 }
506}
507
508#[cfg(feature = "rustcrypto")]
509#[cfg(feature = "rustcrypto")]
526pub struct Signer<'a> {
527 scheme: &'a Sig,
528 sk: SecretKey,
529}
530
531#[cfg(feature = "rustcrypto")]
532impl<'a> Signer<'a> {
533 pub fn new(scheme: &'a Sig, sk: SecretKey) -> Self {
535 Signer { scheme, sk }
536 }
537}
538
539#[cfg(feature = "rustcrypto")]
540impl<'a> RustCryptoSigner<sig::Signature> for Signer<'a> {
541 fn try_sign(&self, msg: &[u8]) -> core::result::Result<sig::Signature, signature::Error> {
542 match self.scheme.sign(msg, &self.sk) {
543 Ok(s) => Ok(s),
544 Err(_) => Err(signature::Error::new()),
545 }
546 }
547}
548
549#[cfg(feature = "rustcrypto")]
550#[cfg(feature = "rustcrypto")]
569pub struct Verifier<'a> {
570 scheme: &'a Sig,
571 pk: PublicKey,
572}
573
574#[cfg(feature = "rustcrypto")]
575impl<'a> Verifier<'a> {
576 pub fn new(scheme: &'a Sig, pk: PublicKey) -> Self {
578 Verifier { scheme, pk }
579 }
580}
581
582#[cfg(feature = "rustcrypto")]
583impl<'a> RustCryptoVerifier<sig::Signature> for Verifier<'a> {
584 fn verify(
585 &self,
586 msg: &[u8],
587 signature: &sig::Signature,
588 ) -> core::result::Result<(), signature::Error> {
589 match self.scheme.verify(msg, signature, &self.pk) {
590 Ok(_) => Ok(()),
591 Err(_) => Err(signature::Error::new()),
592 }
593 }
594}