1#[cfg(feature = "serialization")]
22use serde::{Deserialize, Serialize};
23#[cfg(feature = "serialization")]
24use serde_big_array::BigArray;
25
26use crate::ffi;
27use alloc::vec::Vec;
28use pqcrypto_traits::sign as primitive;
29use pqcrypto_traits::{Error, Result};
30
31macro_rules! simple_struct {
32 ($type: ident, $size: expr) => {
33 #[derive(Clone, Copy)]
34 #[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
35 pub struct $type(
36 #[cfg_attr(feature = "serialization", serde(with = "BigArray"))] [u8; $size],
37 );
38
39 impl $type {
40 fn new() -> Self {
46 $type([0u8; $size])
47 }
48 }
49
50 impl primitive::$type for $type {
51 #[inline]
53 fn as_bytes(&self) -> &[u8] {
54 &self.0
55 }
56
57 fn from_bytes(bytes: &[u8]) -> Result<Self> {
59 if bytes.len() != $size {
60 Err(Error::BadLength {
61 name: stringify!($type),
62 actual: bytes.len(),
63 expected: $size,
64 })
65 } else {
66 let mut array = [0u8; $size];
67 array.copy_from_slice(bytes);
68 Ok($type(array))
69 }
70 }
71 }
72
73 impl PartialEq for $type {
74 fn eq(&self, other: &Self) -> bool {
76 self.0
77 .iter()
78 .zip(other.0.iter())
79 .try_for_each(|(a, b)| if a == b { Ok(()) } else { Err(()) })
80 .is_ok()
81 }
82 }
83 };
84}
85
86simple_struct!(
87 PublicKey,
88 ffi::PQCLEAN_RAINBOWIIICLASSIC_CLEAN_CRYPTO_PUBLICKEYBYTES
89);
90simple_struct!(
91 SecretKey,
92 ffi::PQCLEAN_RAINBOWIIICLASSIC_CLEAN_CRYPTO_SECRETKEYBYTES
93);
94
95#[derive(Clone, Copy)]
96#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
97pub struct DetachedSignature(
98 #[cfg_attr(feature = "serialization", serde(with = "BigArray"))]
99 [u8; ffi::PQCLEAN_RAINBOWIIICLASSIC_CLEAN_CRYPTO_BYTES],
100 usize,
101);
102
103impl DetachedSignature {
105 fn new() -> Self {
106 DetachedSignature([0u8; ffi::PQCLEAN_RAINBOWIIICLASSIC_CLEAN_CRYPTO_BYTES], 0)
107 }
108}
109
110impl primitive::DetachedSignature for DetachedSignature {
111 #[inline]
113 fn as_bytes(&self) -> &[u8] {
114 &self.0[..self.1]
115 }
116
117 #[inline]
118 fn from_bytes(bytes: &[u8]) -> Result<Self> {
119 let actual = bytes.len();
120 let expected = ffi::PQCLEAN_RAINBOWIIICLASSIC_CLEAN_CRYPTO_BYTES;
121 if actual > expected {
122 return Err(Error::BadLength {
123 name: "DetachedSignature",
124 actual,
125 expected,
126 });
127 }
128 let mut array = [0u8; ffi::PQCLEAN_RAINBOWIIICLASSIC_CLEAN_CRYPTO_BYTES];
129 array[..bytes.len()].copy_from_slice(bytes);
130 Ok(DetachedSignature(array, actual))
131 }
132}
133
134#[derive(Clone)]
135#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
136pub struct SignedMessage(Vec<u8>);
137impl primitive::SignedMessage for SignedMessage {
138 #[inline]
140 fn as_bytes(&self) -> &[u8] {
141 self.0.as_slice()
142 }
143
144 #[inline]
146 fn from_bytes(bytes: &[u8]) -> Result<Self> {
147 Ok(SignedMessage(bytes.to_vec()))
148 }
149}
150
151impl SignedMessage {
152 pub fn len(&self) -> usize {
153 self.0.len()
154 }
155}
156
157pub const fn public_key_bytes() -> usize {
159 ffi::PQCLEAN_RAINBOWIIICLASSIC_CLEAN_CRYPTO_PUBLICKEYBYTES
160}
161
162pub const fn secret_key_bytes() -> usize {
164 ffi::PQCLEAN_RAINBOWIIICLASSIC_CLEAN_CRYPTO_SECRETKEYBYTES
165}
166
167pub const fn signature_bytes() -> usize {
169 ffi::PQCLEAN_RAINBOWIIICLASSIC_CLEAN_CRYPTO_BYTES
170}
171
172macro_rules! gen_keypair {
173 ($variant:ident) => {{
174 let mut pk = PublicKey::new();
175 let mut sk = SecretKey::new();
176 assert_eq!(
177 unsafe { ffi::$variant(pk.0.as_mut_ptr(), sk.0.as_mut_ptr()) },
178 0
179 );
180 (pk, sk)
181 }};
182}
183
184#[deprecated(note = "Insecure cryptography, do not use in production")]
186pub fn keypair() -> (PublicKey, SecretKey) {
187 gen_keypair!(PQCLEAN_RAINBOWIIICLASSIC_CLEAN_crypto_sign_keypair)
188}
189
190macro_rules! gen_signature {
191 ($variant:ident, $msg:ident, $sk:ident) => {{
192 let max_len = $msg.len() + signature_bytes();
193 let mut signed_msg = Vec::with_capacity(max_len);
194 let mut smlen: usize = 0;
195 unsafe {
196 ffi::$variant(
197 signed_msg.as_mut_ptr(),
198 &mut smlen as *mut usize,
199 $msg.as_ptr(),
200 $msg.len(),
201 $sk.0.as_ptr(),
202 );
203 debug_assert!(smlen <= max_len, "exceeded vector capacity");
204 signed_msg.set_len(smlen);
205 }
206 SignedMessage(signed_msg)
207 }};
208}
209
210#[deprecated(note = "Insecure cryptography, do not use in production")]
212pub fn sign(msg: &[u8], sk: &SecretKey) -> SignedMessage {
213 gen_signature!(PQCLEAN_RAINBOWIIICLASSIC_CLEAN_crypto_sign, msg, sk)
214}
215
216macro_rules! open_signed {
217 ($variant:ident, $sm:ident, $pk:ident) => {{
218 let mut m: Vec<u8> = Vec::with_capacity($sm.len());
219 let mut mlen: usize = 0;
220 match unsafe {
221 ffi::$variant(
222 m.as_mut_ptr(),
223 &mut mlen as *mut usize,
224 $sm.0.as_ptr(),
225 $sm.len(),
226 $pk.0.as_ptr(),
227 )
228 } {
229 0 => {
230 unsafe { m.set_len(mlen) };
231 Ok(m)
232 }
233 -1 => Err(primitive::VerificationError::InvalidSignature),
234 _ => Err(primitive::VerificationError::UnknownVerificationError),
235 }
236 }};
237}
238
239#[deprecated(note = "Insecure cryptography, do not use in production")]
241pub fn open(
242 sm: &SignedMessage,
243 pk: &PublicKey,
244) -> core::result::Result<Vec<u8>, primitive::VerificationError> {
245 open_signed!(PQCLEAN_RAINBOWIIICLASSIC_CLEAN_crypto_sign_open, sm, pk)
246}
247
248macro_rules! detached_signature {
249 ($variant:ident, $msg:ident, $sk:ident) => {{
250 let mut sig = DetachedSignature::new();
251 unsafe {
252 ffi::$variant(
253 sig.0.as_mut_ptr(),
254 &mut sig.1 as *mut usize,
255 $msg.as_ptr(),
256 $msg.len(),
257 $sk.0.as_ptr(),
258 );
259 }
260 sig
261 }};
262}
263
264#[deprecated(note = "Insecure cryptography, do not use in production")]
265pub fn detached_sign(msg: &[u8], sk: &SecretKey) -> DetachedSignature {
267 detached_signature!(
268 PQCLEAN_RAINBOWIIICLASSIC_CLEAN_crypto_sign_signature,
269 msg,
270 sk
271 )
272}
273
274macro_rules! verify_detached_sig {
275 ($variant:ident, $sig:ident, $msg:ident, $pk:ident) => {{
276 let res = unsafe {
277 ffi::$variant(
278 $sig.0.as_ptr(),
279 $sig.1,
280 $msg.as_ptr(),
281 $msg.len(),
282 $pk.0.as_ptr(),
283 )
284 };
285 match res {
286 0 => Ok(()),
287 -1 => Err(primitive::VerificationError::InvalidSignature),
288 _ => Err(primitive::VerificationError::UnknownVerificationError),
289 }
290 }};
291}
292
293#[deprecated(note = "Insecure cryptography, do not use in production")]
295pub fn verify_detached_signature(
296 sig: &DetachedSignature,
297 msg: &[u8],
298 pk: &PublicKey,
299) -> core::result::Result<(), primitive::VerificationError> {
300 verify_detached_sig!(
301 PQCLEAN_RAINBOWIIICLASSIC_CLEAN_crypto_sign_verify,
302 sig,
303 msg,
304 pk
305 )
306}
307
308#[cfg(test)]
309mod test {
310 use super::*;
311 use rand::prelude::*;
312
313 #[test]
314 pub fn test_sign() {
315 let mut rng = rand::thread_rng();
316 let len: u16 = rng.gen();
317
318 let message = (0..len).map(|_| rng.gen::<u8>()).collect::<Vec<_>>();
319 let (pk, sk) = keypair();
320 let sm = sign(&message, &sk);
321 let verifiedmsg = open(&sm, &pk).unwrap();
322 assert!(verifiedmsg == message);
323 }
324
325 #[test]
326 pub fn test_sign_detached() {
327 let mut rng = rand::thread_rng();
328 let len: u16 = rng.gen();
329 let message = (0..len).map(|_| rng.gen::<u8>()).collect::<Vec<_>>();
330
331 let (pk, sk) = keypair();
332 let sig = detached_sign(&message, &sk);
333 assert!(verify_detached_signature(&sig, &message, &pk).is_ok());
334 assert!(!verify_detached_signature(&sig, &message[..message.len() - 1], &pk).is_ok());
335 }
336}