mithril_stm/protocol/single_signature/
signature_registered_party.rs

1use serde::{Deserialize, Serialize, Serializer, ser::SerializeTuple};
2
3use crate::{MembershipDigest, RegistrationEntry, StmResult};
4
5use super::{SignatureError, SingleSignature};
6
7/// Signature with its registered party.
8#[derive(Debug, Clone, Hash, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
9pub struct SingleSignatureWithRegisteredParty {
10    /// Stm signature
11    pub sig: SingleSignature,
12    /// Registered party
13    pub reg_party: RegistrationEntry,
14}
15
16impl SingleSignatureWithRegisteredParty {
17    /// Convert `SingleSignatureWithRegisteredParty` to bytes
18    /// # Layout
19    /// * RegParty
20    /// * Signature
21    pub fn to_bytes(&self) -> Vec<u8> {
22        let mut out = Vec::new();
23        out.extend_from_slice(&(self.reg_party.to_bytes()));
24        out.extend_from_slice(&self.sig.to_bytes());
25
26        out
27    }
28    ///Extract a `SingleSignatureWithRegisteredParty` from a byte slice.
29    pub fn from_bytes<D: MembershipDigest>(
30        bytes: &[u8],
31    ) -> StmResult<SingleSignatureWithRegisteredParty> {
32        let reg_party = RegistrationEntry::from_bytes(
33            bytes.get(0..104).ok_or(SignatureError::SerializationError)?,
34        )?;
35        let sig = SingleSignature::from_bytes::<D>(
36            bytes.get(104..).ok_or(SignatureError::SerializationError)?,
37        )?;
38
39        Ok(SingleSignatureWithRegisteredParty { sig, reg_party })
40    }
41}
42
43impl Serialize for SingleSignatureWithRegisteredParty {
44    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
45    where
46        S: Serializer,
47    {
48        let mut tuple = serializer.serialize_tuple(2)?;
49        tuple.serialize_element(&self.sig)?;
50        tuple.serialize_element(&self.reg_party)?;
51        tuple.end()
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    mod golden {
58        use rand_chacha::ChaCha20Rng;
59        use rand_core::SeedableRng;
60
61        use crate::{
62            ClosedKeyRegistration, KeyRegistration, MithrilMembershipDigest, Parameters,
63            RegistrationEntry, Signer, SingleSignatureWithRegisteredParty,
64            VerificationKeyProofOfPossessionForConcatenation,
65            proof_system::ConcatenationProofSigner, signature_scheme::BlsSigningKey,
66        };
67
68        const GOLDEN_JSON: &str = r#"
69        [
70            {
71                "sigma": [
72                149, 157, 201, 187, 140, 54, 0, 128, 209, 88, 16, 203, 61, 78, 77, 98,
73                161, 133, 58, 152, 29, 74, 217, 113, 64, 100, 10, 161, 186, 167, 133, 114,
74                211, 153, 218, 56, 223, 84, 105, 242, 41, 54, 224, 170, 208, 185, 126, 83
75                ],
76                "indexes": [1, 4, 5, 8],
77                "signer_index": 1
78            },
79            [
80                [
81                143, 161, 255, 48, 78, 57, 204, 220, 25, 221, 164, 252, 248, 14, 56, 126,
82                186, 135, 228, 188, 145, 181, 52, 200, 97, 99, 213, 46, 0, 199, 193, 89,
83                187, 88, 29, 135, 173, 244, 86, 36, 83, 54, 67, 164, 6, 137, 94, 72, 6,
84                105, 128, 128, 93, 48, 176, 11, 4, 246, 138, 48, 180, 133, 90, 142, 192,
85                24, 193, 111, 142, 31, 76, 111, 110, 234, 153, 90, 208, 192, 31, 124, 95,
86                102, 49, 158, 99, 52, 220, 165, 94, 251, 68, 69, 121, 16, 224, 194
87                ],
88                1
89            ]
90        ]
91        "#;
92
93        fn golden_value() -> SingleSignatureWithRegisteredParty {
94            let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
95            let msg = [0u8; 16];
96            let params = Parameters {
97                m: 10,
98                k: 5,
99                phi_f: 0.8,
100            };
101            let sk_1 = BlsSigningKey::generate(&mut rng);
102            let sk_2 = BlsSigningKey::generate(&mut rng);
103            let pk_1 = VerificationKeyProofOfPossessionForConcatenation::from(&sk_1);
104            let pk_2 = VerificationKeyProofOfPossessionForConcatenation::from(&sk_2);
105            let mut key_reg = KeyRegistration::initialize();
106
107            let entry1 = RegistrationEntry::new(pk_1, 1).unwrap();
108
109            let entry2 = RegistrationEntry::new(pk_2, 1).unwrap();
110            key_reg.register_by_entry(&entry1).unwrap();
111            key_reg.register_by_entry(&entry2).unwrap();
112            let closed_key_reg: ClosedKeyRegistration = key_reg.close_registration();
113
114            let signer: Signer<MithrilMembershipDigest> = Signer::new(
115                1,
116                ConcatenationProofSigner::new(
117                    1,
118                    2,
119                    params,
120                    sk_1,
121                    pk_1.vk,
122                    closed_key_reg.clone().key_registration.into_merkle_tree(),
123                ),
124                closed_key_reg.clone(),
125                params,
126                1,
127            );
128            let signature = signer.create_single_signature(&msg).unwrap();
129            SingleSignatureWithRegisteredParty {
130                sig: signature,
131                reg_party: entry1,
132            }
133        }
134
135        #[test]
136        fn golden_conversions() {
137            let value = serde_json::from_str(GOLDEN_JSON)
138                .expect("This JSON deserialization should not fail");
139            assert_eq!(golden_value(), value);
140
141            let serialized =
142                serde_json::to_string(&value).expect("This JSON serialization should not fail");
143            let golden_serialized = serde_json::to_string(&golden_value())
144                .expect("This JSON serialization should not fail");
145            assert_eq!(golden_serialized, serialized);
146        }
147    }
148}