1use serde::{Deserialize, Serialize, Serializer, ser::SerializeTuple};
2
3use crate::{ClosedRegistrationEntry, MembershipDigest, StmResult};
4
5use super::{SignatureError, SingleSignature};
6
7#[derive(Debug, Clone, Hash, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
9pub struct SingleSignatureWithRegisteredParty {
10 pub sig: SingleSignature,
12 pub reg_party: ClosedRegistrationEntry,
14}
15
16impl SingleSignatureWithRegisteredParty {
17 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(®_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 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}