1use std::fmt::Display;
2
3use crate::{address::Address, error::ModelsError};
4use massa_hash::Hash;
5use massa_serialization::{Deserializer, SerializeError, Serializer};
6use massa_signature::{
7 KeyPair, PublicKey, PublicKeyDeserializer, Signature, SignatureDeserializer,
8};
9use nom::{
10 error::{context, ContextError, ParseError},
11 sequence::tuple,
12 IResult,
13};
14use serde::{Deserialize, Serialize};
15
16#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
21pub struct SecureShare<T, ID>
22where
23 T: Display + SecureShareContent,
24 ID: Id,
25{
26 pub content: T,
31 #[serde(skip)]
32 pub serialized_data: Vec<u8>,
34
35 pub signature: Signature,
37 pub content_creator_pub_key: PublicKey,
39 pub content_creator_address: Address,
41 pub id: ID,
43}
44
45pub trait Id {
48 fn new(hash: Hash) -> Self;
50 fn get_hash(&self) -> &Hash;
52}
53
54pub trait SecureShareContent
56where
57 Self: Sized + Display,
58{
59 fn sign(&self, keypair: &KeyPair, content_hash: &Hash) -> Result<Signature, ModelsError> {
61 Ok(keypair.sign(&self.compute_signed_hash(&keypair.get_public_key(), content_hash))?)
62 }
63
64 fn verify_signature(
66 &self,
67 public_key: &PublicKey,
68 content_hash: &Hash,
69 signature: &Signature,
70 ) -> Result<(), ModelsError> {
71 Ok(public_key.verify_signature(
72 &self.compute_signed_hash(public_key, content_hash),
73 signature,
74 )?)
75 }
76
77 fn new_verifiable<Ser: Serializer<Self>, ID: Id>(
80 self,
81 content_serializer: Ser,
82 keypair: &KeyPair,
83 chain_id: u64,
84 ) -> Result<SecureShare<Self, ID>, ModelsError> {
85 let mut content_serialized = Vec::new();
86 content_serializer.serialize(&self, &mut content_serialized)?;
87 let public_key = keypair.get_public_key();
88 let hash = Self::compute_hash(&self, &content_serialized, &public_key, chain_id);
89 let creator_address = Address::from_public_key(&public_key);
90 Ok(SecureShare {
91 signature: self.sign(keypair, &hash)?,
92 content_creator_pub_key: public_key,
93 content_creator_address: creator_address,
94 content: self,
95 serialized_data: content_serialized,
96 id: ID::new(hash),
97 })
98 }
99
100 fn compute_hash(
102 &self,
103 content_serialized: &[u8],
104 content_creator_pub_key: &PublicKey,
105 _chain_id: u64,
106 ) -> Hash {
107 let mut hash_data = Vec::new();
108 hash_data.extend(content_creator_pub_key.to_bytes());
109 hash_data.extend(content_serialized);
110 Hash::compute_from(&hash_data)
111 }
112
113 fn compute_signed_hash(&self, _public_key: &PublicKey, content_hash: &Hash) -> Hash {
115 *content_hash
116 }
117
118 fn serialize(
120 signature: &Signature,
121 creator_public_key: &PublicKey,
122 serialized_content: &[u8],
123 buffer: &mut Vec<u8>,
124 ) -> Result<(), SerializeError> {
125 buffer.extend(signature.to_bytes());
126 buffer.extend(creator_public_key.to_bytes());
127 buffer.extend(serialized_content);
128 Ok(())
129 }
130
131 fn deserialize<
133 'a,
134 E: ParseError<&'a [u8]> + ContextError<&'a [u8]>,
135 Deser: Deserializer<Self>,
136 ID: Id,
137 >(
138 content_serializer: Option<&dyn Serializer<Self>>,
139 signature_deserializer: &SignatureDeserializer,
140 creator_public_key_deserializer: &PublicKeyDeserializer,
141 content_deserializer: &Deser,
142 buffer: &'a [u8],
143 chain_id: u64,
144 ) -> IResult<&'a [u8], SecureShare<Self, ID>, E> {
145 let (serialized_data, (signature, creator_public_key)) = context(
146 "Failed SecureShare deserialization",
147 tuple((
148 context("Failed signature deserialization", |input| {
149 signature_deserializer.deserialize(input)
150 }),
151 context("Failed public_key deserialization", |input| {
152 creator_public_key_deserializer.deserialize(input)
153 }),
154 )),
155 )(buffer)?;
156 let (rest, content) = content_deserializer.deserialize(serialized_data)?;
157 let content_serialized = if let Some(content_serializer) = content_serializer {
158 let mut content_buffer = Vec::new();
159 content_serializer
160 .serialize(&content, &mut content_buffer)
161 .map_err(|_| {
162 nom::Err::Error(ParseError::from_error_kind(
163 rest,
164 nom::error::ErrorKind::Fail,
165 ))
166 })?;
167 content_buffer
168 } else {
169 serialized_data[..serialized_data.len() - rest.len()].to_vec()
171 };
172 let creator_address = Address::from_public_key(&creator_public_key);
173 let hash = Self::compute_hash(&content, &content_serialized, &creator_public_key, chain_id);
174
175 Ok((
176 rest,
177 SecureShare {
178 content,
179 signature,
180 content_creator_pub_key: creator_public_key,
181 content_creator_address: creator_address,
182 serialized_data: content_serialized.to_vec(),
183 id: ID::new(hash),
184 },
185 ))
186 }
187}
188
189impl<T, ID> Display for SecureShare<T, ID>
190where
191 T: Display + SecureShareContent,
192 ID: Id,
193{
194 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195 writeln!(f, "Signature: {}", self.signature)?;
196 writeln!(f, "Creator pubkey: {}", self.content_creator_pub_key)?;
197 writeln!(f, "Creator address: {}", self.content_creator_address)?;
198 writeln!(f, "Id: {}", self.id.get_hash())?;
199 writeln!(f, "{}", self.content)?;
200 Ok(())
201 }
202}
203
204impl<T, ID> SecureShare<T, ID>
205where
206 T: Display + SecureShareContent,
207 ID: Id,
208{
209 pub fn sign(
211 keypair: &KeyPair,
212 content_hash: &Hash,
213 _content: &T,
214 ) -> Result<Signature, ModelsError> {
215 Ok(keypair.sign(content_hash)?)
216 }
217
218 pub fn verify_signature(&self) -> Result<(), ModelsError> {
220 self.content.verify_signature(
221 &self.content_creator_pub_key,
222 self.id.get_hash(),
223 &self.signature,
224 )
225 }
226
227 pub fn compute_signed_hash(&self) -> Hash {
229 self.content
230 .compute_signed_hash(&self.content_creator_pub_key, self.id.get_hash())
231 }
232
233 pub fn serialized_size(&self) -> usize {
235 self.serialized_data
236 .len()
237 .saturating_add(self.signature.get_ser_len())
238 .saturating_add(self.content_creator_pub_key.get_ser_len())
239 }
240}
241
242#[derive(Default, Clone)]
245pub struct SecureShareSerializer;
246
247impl SecureShareSerializer {
248 pub const fn new() -> Self {
250 Self
251 }
252
253 pub fn serialize_with<Ser, T, ID>(
262 &self,
263 content_serializer: &Ser,
264 value: &SecureShare<T, ID>,
265 buffer: &mut Vec<u8>,
266 ) -> Result<(), SerializeError>
267 where
268 Ser: Serializer<T>,
269 T: Display + SecureShareContent,
270 ID: Id,
271 {
272 let mut content_buffer = Vec::new();
273 content_serializer.serialize(&value.content, &mut content_buffer)?;
274 T::serialize(
275 &value.signature,
276 &value.content_creator_pub_key,
277 &content_buffer,
278 buffer,
279 )
280 }
281}
282
283impl<T, ID> Serializer<SecureShare<T, ID>> for SecureShareSerializer
284where
285 T: Display + SecureShareContent,
286 ID: Id,
287{
288 fn serialize(
289 &self,
290 value: &SecureShare<T, ID>,
291 buffer: &mut Vec<u8>,
292 ) -> Result<(), SerializeError> {
293 T::serialize(
294 &value.signature,
295 &value.content_creator_pub_key,
296 &value.serialized_data,
297 buffer,
298 )
299 }
300}
301
302pub struct SecureShareDeserializer<T, Deser>
304where
305 T: Display + SecureShareContent,
306 Deser: Deserializer<T>,
307{
308 signature_deserializer: SignatureDeserializer,
309 public_key_deserializer: PublicKeyDeserializer,
310 content_deserializer: Deser,
311 chain_id: u64,
312 marker_t: std::marker::PhantomData<T>,
313}
314
315impl<T, Deser> SecureShareDeserializer<T, Deser>
316where
317 T: Display + SecureShareContent,
318 Deser: Deserializer<T>,
319{
320 pub const fn new(content_deserializer: Deser, chain_id: u64) -> Self {
325 Self {
326 signature_deserializer: SignatureDeserializer::new(),
327 public_key_deserializer: PublicKeyDeserializer::new(),
328 content_deserializer,
329 chain_id,
330 marker_t: std::marker::PhantomData,
331 }
332 }
333
334 pub fn deserialize_with<
347 'a,
348 E: ParseError<&'a [u8]> + ContextError<&'a [u8]>,
349 ID: Id,
350 Ser: Serializer<T>,
351 >(
352 &self,
353 content_serializer: &Ser,
354 buffer: &'a [u8],
355 ) -> IResult<&'a [u8], SecureShare<T, ID>, E> {
356 T::deserialize(
357 Some(content_serializer),
358 &self.signature_deserializer,
359 &self.public_key_deserializer,
360 &self.content_deserializer,
361 buffer,
362 self.chain_id,
363 )
364 }
365}
366
367impl<T, ID, Deser> Deserializer<SecureShare<T, ID>> for SecureShareDeserializer<T, Deser>
368where
369 T: Display + SecureShareContent,
370 ID: Id,
371 Deser: Deserializer<T>,
372{
373 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
402 &self,
403 buffer: &'a [u8],
404 ) -> IResult<&'a [u8], SecureShare<T, ID>, E> {
405 T::deserialize(
406 None,
407 &self.signature_deserializer,
408 &self.public_key_deserializer,
409 &self.content_deserializer,
410 buffer,
411 self.chain_id,
412 )
413 }
414}