mithril_stm/signature_scheme/bls_multi_signature/
signing_key.rs

1use blst::min_sig::SecretKey as BlstSk;
2use rand_core::{CryptoRng, RngCore};
3
4use crate::StmResult;
5
6use super::{BlsSignature, BlsSignatureError, blst_error_to_stm_error};
7
8/// MultiSig secret key, which is a wrapper over the BlstSk type from the blst
9/// library.
10#[derive(Debug, Clone)]
11pub struct BlsSigningKey(pub BlstSk);
12
13impl BlsSigningKey {
14    /// Generate a secret key
15    pub fn generate(rng: &mut (impl RngCore + CryptoRng)) -> Self {
16        let mut ikm = [0u8; 32];
17        rng.fill_bytes(&mut ikm);
18        BlsSigningKey(
19            BlstSk::key_gen(&ikm, &[])
20                .expect("Error occurs when the length of ikm < 32. This will not happen here."),
21        )
22    }
23
24    /// Sign a message with the given secret key
25    pub fn sign(&self, msg: &[u8]) -> BlsSignature {
26        BlsSignature(self.0.sign(msg, &[], &[]))
27    }
28
29    /// Convert the secret key into byte string.
30    pub fn to_bytes(&self) -> [u8; 32] {
31        self.0.to_bytes()
32    }
33
34    /// Convert a string of bytes into a `SigningKey`.
35    ///
36    /// # Error
37    /// Fails if the byte string represents a scalar larger than the group order.
38    pub fn from_bytes(bytes: &[u8]) -> StmResult<Self> {
39        let bytes = bytes.get(..32).ok_or(BlsSignatureError::SerializationError)?;
40        match BlstSk::from_bytes(bytes) {
41            Ok(sk) => Ok(Self(sk)),
42            Err(e) => Err(blst_error_to_stm_error(e, None, None)
43                .expect_err("If deserialization is not successful, blst returns and error different to SUCCESS."))
44        }
45    }
46
47    pub(crate) fn to_blst_secret_key(&self) -> BlstSk {
48        self.0.clone()
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    mod golden {
57
58        use rand_chacha::ChaCha20Rng;
59        use rand_core::SeedableRng;
60
61        use super::*;
62
63        const GOLDEN_JSON: &str = r#"[64, 129, 87, 121, 27, 239, 221, 215, 2, 103, 45, 207, 207, 201, 157, 163, 81, 47, 156, 14, 168, 24, 137, 15, 203, 106, 183, 73, 88, 14, 242, 207]"#;
64
65        fn golden_value() -> BlsSigningKey {
66            let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
67            BlsSigningKey::generate(&mut rng)
68        }
69
70        #[test]
71        fn golden_conversions() {
72            let value = serde_json::from_str(GOLDEN_JSON)
73                .expect("This JSON deserialization should not fail");
74            assert_eq!(golden_value(), value);
75
76            let serialized =
77                serde_json::to_string(&value).expect("This JSON serialization should not fail");
78            let golden_serialized = serde_json::to_string(&golden_value())
79                .expect("This JSON serialization should not fail");
80            assert_eq!(golden_serialized, serialized);
81        }
82    }
83}