wots_rs/
keypair.rs

1//! WOTS keypairs.
2use crate::{public::PublicKey, secret::SecretKey, signature::Signature};
3use rand::{CryptoRng, RngCore};
4
5/// An WOTS keypair.
6pub struct Keypair {
7    /// The secret half of this keypair.
8    pub secret: SecretKey,
9    /// The public half of this keypair.
10    pub public: PublicKey,
11}
12
13impl Keypair {
14    /// Generate an WOTS keypair.
15    ///
16    /// # Example
17    ///
18    /// ```
19    /// use rand::rngs::OsRng;
20    /// use wots_rs::Keypair;
21    ///
22    /// let mut csprng = OsRng{};
23    /// let keypair: Keypair = Keypair::generate(&mut csprng);
24    ///
25    /// ```
26    ///
27    /// # Input
28    ///
29    /// A CSPRNG with a `fill_bytes()` method, e.g. `rand_os::OsRng`.
30    pub fn generate<R>(csprng: &mut R) -> Self
31    where
32        R: CryptoRng + RngCore,
33    {
34        let sk = SecretKey::generate(csprng);
35        let pk = PublicKey::from(&sk);
36
37        Keypair {
38            secret: sk,
39            public: pk,
40        }
41    }
42
43    /// Sign a `message` with this `Keypair` using the
44    /// WOTS algorithm.
45    ///
46    /// # Inputs
47    ///
48    /// * `message` in bytes representation.
49    ///
50    /// # Returns
51    ///
52    /// An WOTS [`Signature`] on the `message`.
53    ///
54    /// # Example
55    ///
56    /// ```
57    /// use rand::rngs::OsRng;
58    /// use wots_rs::Keypair;
59    ///
60    /// let mut csprng = OsRng{};
61    /// let keypair: Keypair = Keypair::generate(&mut csprng);
62    ///
63    /// let message = b"hello";
64    /// let signature = keypair.sign(message);
65    ///
66    /// ```
67    pub fn sign(&self, message: &[u8]) -> Signature {
68        self.secret.sign(message)
69    }
70
71    /// Verify a `signature` on a `message` using the WOTS algorithm.
72    ///
73    /// # Inputs
74    ///
75    /// * `message` in bytes representation.
76    /// * `signature` is a purported WOTS [`Signature`] on the `message`.
77    ///
78    /// # Returns
79    ///
80    /// Returns `true` if the `signature` was a valid signature created by this
81    /// `Keypair` on the `message`.
82    ///
83    /// # Example
84    ///
85    /// ```
86    /// use rand::rngs::OsRng;
87    /// use wots_rs::Keypair;
88    ///
89    /// let mut csprng = OsRng{};
90    /// let keypair: Keypair = Keypair::generate(&mut csprng);
91    ///
92    /// let message = b"hello";
93    /// let signature = keypair.sign(message);
94    ///
95    /// assert!(keypair.verify(message, signature));
96    ///
97    /// ```
98    pub fn verify(&self, message: &[u8], signature: Signature) -> bool {
99        self.public.verify(message, signature)
100    }
101}