mithril_stm/protocol/single_signature/
signature_registered_party.rs

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