1#[cfg(feature = "serde")]
77use serde::{Deserialize, Serialize};
78use subtle::ConstantTimeEq;
79use zeroize::{Zeroize, ZeroizeOnDrop};
80
81use crate::classic::crypto_sign::{
82 SignerState, crypto_sign_detached, crypto_sign_final_create, crypto_sign_final_verify,
83 crypto_sign_init, crypto_sign_keypair_inplace, crypto_sign_seed_keypair_inplace,
84 crypto_sign_update, crypto_sign_verify_detached,
85};
86use crate::constants::{
87 CRYPTO_SIGN_BYTES, CRYPTO_SIGN_PUBLICKEYBYTES, CRYPTO_SIGN_SECRETKEYBYTES,
88 CRYPTO_SIGN_SEEDBYTES,
89};
90use crate::error::Error;
91use crate::types::*;
92
93pub type PublicKey = StackByteArray<CRYPTO_SIGN_PUBLICKEYBYTES>;
95pub type SecretKey = StackByteArray<CRYPTO_SIGN_SECRETKEYBYTES>;
97pub type Signature = StackByteArray<CRYPTO_SIGN_BYTES>;
99pub type Message = Vec<u8>;
101
102#[cfg_attr(
103 feature = "serde",
104 derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize, Debug, Clone)
105)]
106#[cfg_attr(not(feature = "serde"), derive(Zeroize, ZeroizeOnDrop, Debug, Clone))]
107pub struct SigningKeyPair<
109 PublicKey: ByteArray<CRYPTO_SIGN_PUBLICKEYBYTES> + Zeroize,
110 SecretKey: ByteArray<CRYPTO_SIGN_SECRETKEYBYTES> + Zeroize,
111> {
112 pub public_key: PublicKey,
114 pub secret_key: SecretKey,
116}
117
118impl<
119 PublicKey: NewByteArray<CRYPTO_SIGN_PUBLICKEYBYTES> + Zeroize,
120 SecretKey: NewByteArray<CRYPTO_SIGN_SECRETKEYBYTES> + Zeroize,
121> SigningKeyPair<PublicKey, SecretKey>
122{
123 pub fn new() -> Self {
125 Self {
126 public_key: PublicKey::new_byte_array(),
127 secret_key: SecretKey::new_byte_array(),
128 }
129 }
130
131 pub fn gen() -> Self {
133 let mut public_key = PublicKey::new_byte_array();
134 let mut secret_key = SecretKey::new_byte_array();
135 crypto_sign_keypair_inplace(public_key.as_mut_array(), secret_key.as_mut_array());
136 Self {
137 public_key,
138 secret_key,
139 }
140 }
141
142 pub fn from_secret_key(secret_key: SecretKey) -> Self {
145 let mut seed = [0u8; 32];
146 seed.copy_from_slice(&secret_key.as_slice()[..32]);
147
148 Self::from_seed(&seed)
149 }
150
151 pub fn from_seed<Seed: ByteArray<CRYPTO_SIGN_SEEDBYTES>>(seed: &Seed) -> Self {
154 let mut public_key = PublicKey::new_byte_array();
155 let mut secret_key = SecretKey::new_byte_array();
156
157 crypto_sign_seed_keypair_inplace(
158 public_key.as_mut_array(),
159 secret_key.as_mut_array(),
160 seed.as_array(),
161 );
162
163 Self {
164 public_key,
165 secret_key,
166 }
167 }
168}
169
170impl
171 SigningKeyPair<
172 StackByteArray<CRYPTO_SIGN_PUBLICKEYBYTES>,
173 StackByteArray<CRYPTO_SIGN_SECRETKEYBYTES>,
174 >
175{
176 pub fn gen_with_defaults() -> Self {
179 Self::gen()
180 }
181}
182
183impl<
184 'a,
185 PublicKey: ByteArray<CRYPTO_SIGN_PUBLICKEYBYTES> + std::convert::TryFrom<&'a [u8]> + Zeroize,
186 SecretKey: ByteArray<CRYPTO_SIGN_SECRETKEYBYTES> + std::convert::TryFrom<&'a [u8]> + Zeroize,
187> SigningKeyPair<PublicKey, SecretKey>
188{
189 pub fn from_slices(public_key: &'a [u8], secret_key: &'a [u8]) -> Result<Self, Error> {
192 Ok(Self {
193 public_key: PublicKey::try_from(public_key)
194 .map_err(|_e| dryoc_error!("invalid public key"))?,
195 secret_key: SecretKey::try_from(secret_key)
196 .map_err(|_e| dryoc_error!("invalid secret key"))?,
197 })
198 }
199}
200
201#[cfg(any(feature = "nightly", all(doc, not(doctest))))]
202#[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "nightly")))]
203pub mod protected {
204 use super::*;
227 pub use crate::protected::*;
228
229 pub type PublicKey = HeapByteArray<CRYPTO_SIGN_PUBLICKEYBYTES>;
232 pub type SecretKey = HeapByteArray<CRYPTO_SIGN_SECRETKEYBYTES>;
235 pub type Signature = HeapByteArray<CRYPTO_SIGN_BYTES>;
238 pub type Message = HeapBytes;
241
242 pub type LockedSigningKeyPair = SigningKeyPair<Locked<PublicKey>, Locked<SecretKey>>;
245 pub type LockedSignedMessage = SignedMessage<Locked<Signature>, Locked<Message>>;
248
249 impl
250 SigningKeyPair<
251 Locked<HeapByteArray<CRYPTO_SIGN_PUBLICKEYBYTES>>,
252 Locked<HeapByteArray<CRYPTO_SIGN_SECRETKEYBYTES>>,
253 >
254 {
255 pub fn new_locked_keypair() -> Result<Self, std::io::Error> {
257 Ok(Self {
258 public_key: HeapByteArray::<CRYPTO_SIGN_PUBLICKEYBYTES>::new_locked()?,
259 secret_key: HeapByteArray::<CRYPTO_SIGN_SECRETKEYBYTES>::new_locked()?,
260 })
261 }
262
263 pub fn gen_locked_keypair() -> Result<Self, std::io::Error> {
265 let mut res = Self::new_locked_keypair()?;
266
267 crypto_sign_keypair_inplace(
268 res.public_key.as_mut_array(),
269 res.secret_key.as_mut_array(),
270 );
271
272 Ok(res)
273 }
274 }
275
276 impl
277 SigningKeyPair<
278 LockedRO<HeapByteArray<CRYPTO_SIGN_PUBLICKEYBYTES>>,
279 LockedRO<HeapByteArray<CRYPTO_SIGN_SECRETKEYBYTES>>,
280 >
281 {
282 pub fn gen_readonly_locked_keypair() -> Result<Self, std::io::Error> {
284 let mut public_key = HeapByteArray::<CRYPTO_SIGN_PUBLICKEYBYTES>::new_locked()?;
285 let mut secret_key = HeapByteArray::<CRYPTO_SIGN_SECRETKEYBYTES>::new_locked()?;
286
287 crypto_sign_keypair_inplace(public_key.as_mut_array(), secret_key.as_mut_array());
288
289 let public_key = public_key.mprotect_readonly()?;
290 let secret_key = secret_key.mprotect_readonly()?;
291
292 Ok(Self {
293 public_key,
294 secret_key,
295 })
296 }
297 }
298}
299
300#[cfg_attr(
301 feature = "serde",
302 derive(Zeroize, Clone, Debug, Serialize, Deserialize)
303)]
304#[cfg_attr(not(feature = "serde"), derive(Zeroize, Clone, Debug))]
305pub struct SignedMessage<
307 Signature: ByteArray<CRYPTO_SIGN_BYTES> + Zeroize,
308 Message: Bytes + Zeroize,
309> {
310 signature: Signature,
311 message: Message,
312}
313
314pub type VecSignedMessage = SignedMessage<Signature, Vec<u8>>;
316
317impl<
318 PublicKey: ByteArray<CRYPTO_SIGN_PUBLICKEYBYTES> + Zeroize,
319 SecretKey: ByteArray<CRYPTO_SIGN_SECRETKEYBYTES> + Zeroize,
320> SigningKeyPair<PublicKey, SecretKey>
321{
322 pub fn sign<Signature: NewByteArray<CRYPTO_SIGN_BYTES> + Zeroize, Message: Bytes + Zeroize>(
326 &self,
327 message: Message,
328 ) -> Result<SignedMessage<Signature, Message>, Error> {
329 let mut signature = Signature::new_byte_array();
330 crypto_sign_detached(
331 signature.as_mut_array(),
332 message.as_slice(),
333 self.secret_key.as_array(),
334 )?;
335
336 Ok(SignedMessage::<Signature, Message> { signature, message })
337 }
338
339 pub fn sign_with_defaults<Message: Bytes>(
342 &self,
343 message: Message,
344 ) -> Result<SignedMessage<StackByteArray<CRYPTO_SIGN_BYTES>, Vec<u8>>, Error> {
345 self.sign(Vec::from(message.as_slice()))
346 }
347}
348
349impl Default for SigningKeyPair<PublicKey, SecretKey> {
350 fn default() -> Self {
351 Self::new()
352 }
353}
354
355pub struct IncrementalSigner {
357 state: SignerState,
358}
359
360impl IncrementalSigner {
361 pub fn new() -> Self {
363 Self {
364 state: crypto_sign_init(),
365 }
366 }
367
368 pub fn update<Message: Bytes>(&mut self, message: &Message) {
370 crypto_sign_update(&mut self.state, message.as_slice())
371 }
372
373 pub fn finalize<
376 Signature: NewByteArray<CRYPTO_SIGN_BYTES>,
377 SecretKey: ByteArray<CRYPTO_SIGN_SECRETKEYBYTES>,
378 >(
379 self,
380 secret_key: &SecretKey,
381 ) -> Result<Signature, Error> {
382 let mut signature = Signature::new_byte_array();
383
384 crypto_sign_final_create(self.state, signature.as_mut_array(), secret_key.as_array())?;
385
386 Ok(signature)
387 }
388
389 pub fn verify<
391 Signature: ByteArray<CRYPTO_SIGN_BYTES>,
392 PublicKey: ByteArray<CRYPTO_SIGN_PUBLICKEYBYTES>,
393 >(
394 self,
395 signature: &Signature,
396 public_key: &PublicKey,
397 ) -> Result<(), Error> {
398 crypto_sign_final_verify(self.state, signature.as_array(), public_key.as_array())?;
399
400 Ok(())
401 }
402}
403
404impl Default for IncrementalSigner {
405 fn default() -> Self {
406 Self::new()
407 }
408}
409
410impl<Signature: ByteArray<CRYPTO_SIGN_BYTES> + Zeroize, Message: Bytes + Zeroize>
411 SignedMessage<Signature, Message>
412{
413 pub fn verify<PublicKey: ByteArray<CRYPTO_SIGN_PUBLICKEYBYTES>>(
415 &self,
416 public_key: &PublicKey,
417 ) -> Result<(), Error> {
418 crypto_sign_verify_detached(
419 self.signature.as_array(),
420 self.message.as_slice(),
421 public_key.as_array(),
422 )
423 }
424}
425
426impl<
427 'a,
428 Signature: ByteArray<CRYPTO_SIGN_BYTES> + std::convert::TryFrom<&'a [u8]> + Zeroize,
429 Message: Bytes + From<&'a [u8]> + Zeroize,
430> SignedMessage<Signature, Message>
431{
432 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, Error> {
436 if bytes.len() < CRYPTO_SIGN_BYTES {
437 Err(dryoc_error!(format!(
438 "bytes of len {} less than expected minimum of {}",
439 bytes.len(),
440 CRYPTO_SIGN_BYTES
441 )))
442 } else {
443 let (signature, message) = bytes.split_at(CRYPTO_SIGN_BYTES);
444 Ok(Self {
445 signature: Signature::try_from(signature)
446 .map_err(|_e| dryoc_error!("invalid signature"))?,
447 message: Message::from(message),
448 })
449 }
450 }
451}
452
453impl<Signature: ByteArray<CRYPTO_SIGN_BYTES> + Zeroize, Message: Bytes + Zeroize>
454 SignedMessage<Signature, Message>
455{
456 pub fn from_parts(signature: Signature, message: Message) -> Self {
459 Self { signature, message }
460 }
461
462 pub fn to_vec(&self) -> Vec<u8> {
464 self.to_bytes()
465 }
466
467 pub fn into_parts(self) -> (Signature, Message) {
470 (self.signature, self.message)
471 }
472
473 pub fn to_bytes<Bytes: NewBytes + ResizableBytes>(&self) -> Bytes {
475 let mut data = Bytes::new_bytes();
476
477 data.resize(self.signature.len() + self.message.len(), 0);
478 let s = data.as_mut_slice();
479 s[..CRYPTO_SIGN_BYTES].copy_from_slice(self.signature.as_slice());
480 s[CRYPTO_SIGN_BYTES..].copy_from_slice(self.message.as_slice());
481
482 data
483 }
484}
485
486impl<
487 PublicKey: ByteArray<CRYPTO_SIGN_PUBLICKEYBYTES> + Zeroize,
488 SecretKey: ByteArray<CRYPTO_SIGN_SECRETKEYBYTES> + Zeroize,
489> PartialEq<SigningKeyPair<PublicKey, SecretKey>> for SigningKeyPair<PublicKey, SecretKey>
490{
491 fn eq(&self, other: &Self) -> bool {
492 self.public_key
493 .as_slice()
494 .ct_eq(other.public_key.as_slice())
495 .unwrap_u8()
496 == 1
497 && self
498 .secret_key
499 .as_slice()
500 .ct_eq(other.secret_key.as_slice())
501 .unwrap_u8()
502 == 1
503 }
504}
505
506impl<Signature: ByteArray<CRYPTO_SIGN_BYTES> + Zeroize, Message: Bytes + Zeroize>
507 PartialEq<SignedMessage<Signature, Message>> for SignedMessage<Signature, Message>
508{
509 fn eq(&self, other: &Self) -> bool {
510 self.signature
511 .as_slice()
512 .ct_eq(other.signature.as_slice())
513 .unwrap_u8()
514 == 1
515 && self
516 .message
517 .as_slice()
518 .ct_eq(other.message.as_slice())
519 .unwrap_u8()
520 == 1
521 }
522}
523
524#[cfg(test)]
525mod tests {
526 use super::*;
527
528 #[test]
529 fn test_message_signing() {
530 let keypair = SigningKeyPair::gen_with_defaults();
531 let message = b"hello my frens";
532
533 let signed_message = keypair.sign_with_defaults(message).expect("signing failed");
534
535 signed_message
536 .verify(&keypair.public_key)
537 .expect("verification failed");
538 }
539}