1use crate::OqsError;
4use zeroize::Zeroize;
5
6#[cfg(not(feature = "liboqs"))]
7use rand_core::{OsRng, RngCore};
8
9#[cfg(feature = "serde")]
10use serde::{Deserialize, Serialize};
11
12#[derive(Clone, Debug)]
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14pub struct PublicKey(pub(crate) Vec<u8>);
15
16#[derive(Clone, Debug, Zeroize)]
17#[zeroize(drop)]
18#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19pub struct SecretKey(pub(crate) Vec<u8>);
20
21#[derive(Clone, Debug)]
22#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
23pub struct Signature(pub(crate) Vec<u8>);
24
25impl PublicKey {
27 #[inline]
28 pub fn as_bytes(&self) -> &[u8] {
29 &self.0
30 }
31 #[inline]
32 pub fn len(&self) -> usize {
33 self.0.len()
34 }
35 #[inline]
36 pub fn is_empty(&self) -> bool {
37 self.0.is_empty()
38 }
39}
40impl SecretKey {
41 #[inline]
42 pub fn as_bytes(&self) -> &[u8] {
43 &self.0
44 }
45 #[inline]
46 pub fn len(&self) -> usize {
47 self.0.len()
48 }
49 #[inline]
50 pub fn is_empty(&self) -> bool {
51 self.0.is_empty()
52 }
53}
54impl Signature {
55 #[inline]
56 pub fn as_bytes(&self) -> &[u8] {
57 &self.0
58 }
59 #[inline]
60 pub fn len(&self) -> usize {
61 self.0.len()
62 }
63 #[inline]
64 pub fn is_empty(&self) -> bool {
65 self.0.is_empty()
66 }
67}
68
69pub trait SignatureScheme {
70 fn keypair() -> Result<(PublicKey, SecretKey), OqsError>;
71 fn sign(sk: &SecretKey, msg: &[u8]) -> Result<Signature, OqsError>;
72 fn verify(pk: &PublicKey, msg: &[u8], sig: &Signature) -> Result<(), OqsError>;
73}
74
75pub struct Dilithium2;
76
77impl SignatureScheme for Dilithium2 {
78 fn keypair() -> Result<(PublicKey, SecretKey), OqsError> {
79 #[cfg(feature = "liboqs")]
80 {
81 let (pk, sk) = crate::ffi::dilithium2_keypair()?;
82 Ok((PublicKey(pk), SecretKey(sk)))
83 }
84 #[cfg(not(feature = "liboqs"))]
85 {
86 let mut pk = vec![0u8; 1312];
88 let mut sk = vec![0u8; 2528];
89 OsRng.fill_bytes(&mut pk);
90 OsRng.fill_bytes(&mut sk);
91 Ok((PublicKey(pk), SecretKey(sk)))
92 }
93 }
94
95 fn sign(sk: &SecretKey, msg: &[u8]) -> Result<Signature, OqsError> {
96 #[cfg(feature = "liboqs")]
97 {
98 crate::ffi::dilithium2_sign(sk.as_bytes(), msg).map(Signature)
99 }
100 #[cfg(not(feature = "liboqs"))]
101 {
102 let _ = (sk, msg);
104 let mut sig = vec![0u8; 2420];
105 OsRng.fill_bytes(&mut sig);
106 Ok(Signature(sig))
107 }
108 }
109
110 fn verify(pk: &PublicKey, msg: &[u8], sig: &Signature) -> Result<(), OqsError> {
111 #[cfg(feature = "liboqs")]
112 {
113 crate::ffi::dilithium2_verify(pk.as_bytes(), msg, sig.as_bytes())
114 }
115 #[cfg(not(feature = "liboqs"))]
116 {
117 let _ = (pk, msg);
119 if sig.len() != 2420 {
120 return Err(OqsError::InvalidLength);
121 }
122 Ok(())
123 }
124 }
125}