mithril_stm/bls_multi_signature/
proof_of_possession.rs1use blst::{blst_p1, min_sig::Signature as BlstSig};
2
3use crate::bls_multi_signature::{
4 BlsSigningKey, POP,
5 helper::unsafe_helpers::{compress_p1, scalar_to_pk_in_g1, uncompress_p1},
6};
7use crate::error::{MultiSignatureError, blst_err_to_mithril};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub struct BlsProofOfPossession {
16 k1: BlstSig,
17 k2: blst_p1,
18}
19
20impl BlsProofOfPossession {
21 pub fn to_bytes(self) -> [u8; 96] {
28 let mut pop_bytes = [0u8; 96];
29 pop_bytes[..48].copy_from_slice(&self.k1.to_bytes());
30
31 pop_bytes[48..].copy_from_slice(&compress_p1(&self.k2)[..]);
32 pop_bytes
33 }
34
35 pub fn from_bytes(bytes: &[u8]) -> Result<Self, MultiSignatureError> {
37 let k1 = match BlstSig::from_bytes(
38 bytes.get(..48).ok_or(MultiSignatureError::SerializationError)?,
39 ) {
40 Ok(key) => key,
41 Err(e) => {
42 return Err(blst_err_to_mithril(e, None, None)
43 .expect_err("If it passed, blst returns and error different to SUCCESS."));
44 }
45 };
46
47 let k2 = uncompress_p1(bytes.get(48..96).ok_or(MultiSignatureError::SerializationError)?)?;
48
49 Ok(Self { k1, k2 })
50 }
51
52 pub(crate) fn get_k1(self) -> BlstSig {
53 self.k1
54 }
55
56 pub(crate) fn get_k2(self) -> blst_p1 {
57 self.k2
58 }
59}
60
61impl From<&BlsSigningKey> for BlsProofOfPossession {
62 fn from(sk: &BlsSigningKey) -> Self {
66 let k1 = sk.to_blst_secret_key().sign(POP, &[], &[]);
67 let k2 = scalar_to_pk_in_g1(&sk.to_blst_secret_key());
68 Self { k1, k2 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 mod golden {
75
76 use rand_chacha::ChaCha20Rng;
77 use rand_core::SeedableRng;
78
79 use crate::bls_multi_signature::{BlsProofOfPossession, BlsSigningKey};
80
81 const GOLDEN_JSON: &str = r#"[168,50,233,193,15,136,65,72,123,148,129,176,38,198,209,47,28,204,176,144,57,251,42,28,66,76,89,97,158,63,54,198,194,176,135,221,14,185,197,225,202,98,243,74,233,225,143,151,147,177,170,117,66,165,66,62,33,216,232,75,68,114,195,22,100,65,44,198,4,166,102,233,253,240,59,175,60,117,142,114,140,122,17,87,110,187,1,17,10,195,154,13,249,86,54,226]"#;
82
83 fn golden_value() -> BlsProofOfPossession {
84 let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
85 let sk = BlsSigningKey::generate(&mut rng);
86 BlsProofOfPossession::from(&sk)
87 }
88
89 #[test]
90 fn golden_conversions() {
91 let value = serde_json::from_str(GOLDEN_JSON)
92 .expect("This JSON deserialization should not fail");
93 assert_eq!(golden_value(), value);
94
95 let serialized =
96 serde_json::to_string(&value).expect("This JSON serialization should not fail");
97 let golden_serialized = serde_json::to_string(&golden_value())
98 .expect("This JSON serialization should not fail");
99 assert_eq!(golden_serialized, serialized);
100 }
101 }
102}