1use crate::{FINALIZE_NAMESPACE, NOTARIZE_NAMESPACE, NULLIFY_NAMESPACE, SEED_NAMESPACE};
2use bytes::{Buf, BufMut};
3use commonware_cryptography::sha256::Digest;
4use commonware_cryptography::{bls12381, Bls12381, Scheme};
5use commonware_utils::{hex, Array, SizedSerialize};
6
7#[repr(u8)]
9pub enum Kind {
10 Seed = 0,
11 Notarization = 1,
12 Nullification = 2,
13 Finalization = 3,
14}
15
16impl Kind {
17 pub fn from_u8(value: u8) -> Option<Self> {
18 match value {
19 0 => Some(Self::Seed),
20 1 => Some(Self::Notarization),
21 2 => Some(Self::Nullification),
22 3 => Some(Self::Finalization),
23 _ => None,
24 }
25 }
26
27 pub fn to_hex(&self) -> String {
28 match self {
29 Self::Seed => hex(&[0]),
30 Self::Notarization => hex(&[1]),
31 Self::Nullification => hex(&[2]),
32 Self::Finalization => hex(&[3]),
33 }
34 }
35}
36
37#[derive(Clone, Debug, PartialEq, Eq)]
38pub struct Seed {
39 pub view: u64,
40 pub signature: bls12381::Signature,
41}
42
43impl Seed {
44 pub fn payload(view: u64) -> Vec<u8> {
45 let mut bytes = Vec::with_capacity(u64::SERIALIZED_LEN);
46 bytes.put_u64(view);
47 bytes
48 }
49
50 fn pack(view: u64, signature: &bls12381::Signature) -> Vec<u8> {
51 let mut bytes = Vec::with_capacity(Self::SERIALIZED_LEN);
52 bytes.put_u64(view);
53 bytes.extend_from_slice(signature);
54 bytes
55 }
56
57 pub fn new(view: u64, signature: bls12381::Signature) -> Self {
58 Self { view, signature }
59 }
60
61 pub fn serialize(&self) -> Vec<u8> {
62 Self::pack(self.view, &self.signature)
63 }
64
65 pub fn deserialize(public: Option<&bls12381::PublicKey>, mut bytes: &[u8]) -> Option<Self> {
66 if bytes.len() != Self::SERIALIZED_LEN {
68 return None;
69 }
70
71 let view = bytes.get_u64();
73 let signature = bls12381::Signature::read_from(&mut bytes).ok()?;
74
75 if let Some(public) = public {
77 let message = Self::payload(view);
78 if !Bls12381::verify(Some(SEED_NAMESPACE), &message, public, &signature) {
79 return None;
80 }
81 }
82 Some(Self { view, signature })
83 }
84}
85
86impl SizedSerialize for Seed {
87 const SERIALIZED_LEN: usize = u64::SERIALIZED_LEN + bls12381::Signature::SERIALIZED_LEN;
88}
89
90#[derive(Clone, Debug, PartialEq, Eq)]
91pub struct Notarization {
92 pub view: u64,
93 pub parent: u64,
94 pub payload: Digest,
95 pub signature: bls12381::Signature,
96}
97
98impl Notarization {
99 pub fn payload(view: u64, parent: u64, payload: &Digest) -> Vec<u8> {
100 let mut bytes =
101 Vec::with_capacity(u64::SERIALIZED_LEN + u64::SERIALIZED_LEN + Digest::SERIALIZED_LEN);
102 bytes.put_u64(view);
103 bytes.put_u64(parent);
104 bytes.extend_from_slice(payload);
105 bytes
106 }
107
108 fn pack(view: u64, parent: u64, payload: &Digest, signature: &bls12381::Signature) -> Vec<u8> {
109 let mut bytes = Vec::with_capacity(Self::SERIALIZED_LEN);
110 bytes.put_u64(view);
111 bytes.put_u64(parent);
112 bytes.extend_from_slice(payload);
113 bytes.extend_from_slice(signature);
114 bytes
115 }
116
117 pub fn new(view: u64, parent: u64, payload: Digest, signature: bls12381::Signature) -> Self {
118 Self {
119 view,
120 parent,
121 payload,
122 signature,
123 }
124 }
125
126 pub fn serialize(&self) -> Vec<u8> {
127 Self::pack(self.view, self.parent, &self.payload, &self.signature)
128 }
129
130 pub fn deserialize(public: Option<&bls12381::PublicKey>, mut bytes: &[u8]) -> Option<Self> {
131 if bytes.len() != Self::SERIALIZED_LEN {
133 return None;
134 }
135
136 let view = bytes.get_u64();
138 let parent = bytes.get_u64();
139 let payload = Digest::read_from(&mut bytes).ok()?;
140 let signature = bls12381::Signature::read_from(&mut bytes).ok()?;
141
142 if let Some(public) = public {
144 let message = Self::payload(view, parent, &payload);
145 if !Bls12381::verify(Some(NOTARIZE_NAMESPACE), &message, public, &signature) {
146 return None;
147 }
148 }
149 Some(Self {
150 view,
151 parent,
152 payload,
153 signature,
154 })
155 }
156}
157
158impl SizedSerialize for Notarization {
159 const SERIALIZED_LEN: usize = u64::SERIALIZED_LEN
160 + u64::SERIALIZED_LEN
161 + Digest::SERIALIZED_LEN
162 + bls12381::Signature::SERIALIZED_LEN;
163}
164
165#[derive(Clone, Debug, PartialEq, Eq)]
166pub struct Nullification {
167 pub view: u64,
168 pub signature: bls12381::Signature,
169}
170
171impl Nullification {
172 pub fn payload(view: u64) -> Vec<u8> {
173 let mut bytes = Vec::with_capacity(u64::SERIALIZED_LEN);
174 bytes.put_u64(view);
175 bytes
176 }
177
178 fn pack(view: u64, signature: &bls12381::Signature) -> Vec<u8> {
179 let mut bytes = Vec::with_capacity(Self::SERIALIZED_LEN);
180 bytes.put_u64(view);
181 bytes.extend_from_slice(signature);
182 bytes
183 }
184
185 pub fn new(view: u64, signature: bls12381::Signature) -> Self {
186 Self { view, signature }
187 }
188
189 pub fn serialize(&self) -> Vec<u8> {
190 Self::pack(self.view, &self.signature)
191 }
192
193 pub fn deserialize(public: Option<&bls12381::PublicKey>, mut bytes: &[u8]) -> Option<Self> {
194 if bytes.len() != Self::SERIALIZED_LEN {
196 return None;
197 }
198
199 let view = bytes.get_u64();
201 let signature = bls12381::Signature::read_from(&mut bytes).ok()?;
202
203 if let Some(public) = public {
205 let message = Self::payload(view);
206 if !Bls12381::verify(Some(NULLIFY_NAMESPACE), &message, public, &signature) {
207 return None;
208 }
209 }
210 Some(Self { view, signature })
211 }
212}
213
214impl SizedSerialize for Nullification {
215 const SERIALIZED_LEN: usize = u64::SERIALIZED_LEN + bls12381::Signature::SERIALIZED_LEN;
216}
217
218#[derive(Clone, Debug, PartialEq, Eq)]
219pub struct Finalization {
220 pub view: u64,
221 pub parent: u64,
222 pub payload: Digest,
223 pub signature: bls12381::Signature,
224}
225
226impl Finalization {
227 pub fn payload(view: u64, parent: u64, payload: &Digest) -> Vec<u8> {
228 let mut bytes =
229 Vec::with_capacity(u64::SERIALIZED_LEN + u64::SERIALIZED_LEN + Digest::SERIALIZED_LEN);
230 bytes.put_u64(view);
231 bytes.put_u64(parent);
232 bytes.extend_from_slice(payload);
233 bytes
234 }
235
236 fn pack(view: u64, parent: u64, payload: &Digest, signature: &bls12381::Signature) -> Vec<u8> {
237 let mut bytes = Vec::with_capacity(Self::SERIALIZED_LEN);
238 bytes.put_u64(view);
239 bytes.put_u64(parent);
240 bytes.extend_from_slice(payload);
241 bytes.extend_from_slice(signature);
242 bytes
243 }
244
245 pub fn new(view: u64, parent: u64, payload: Digest, signature: bls12381::Signature) -> Self {
246 Self {
247 view,
248 parent,
249 payload,
250 signature,
251 }
252 }
253
254 pub fn serialize(&self) -> Vec<u8> {
255 Self::pack(self.view, self.parent, &self.payload, &self.signature)
256 }
257
258 pub fn deserialize(public: Option<&bls12381::PublicKey>, mut bytes: &[u8]) -> Option<Self> {
259 if bytes.len() != Self::SERIALIZED_LEN {
261 return None;
262 }
263
264 let view = bytes.get_u64();
266 let parent = bytes.get_u64();
267 let payload = Digest::read_from(&mut bytes).ok()?;
268 let signature = bls12381::Signature::read_from(&mut bytes).ok()?;
269
270 if let Some(public) = public {
272 let message = Self::payload(view, parent, &payload);
273 if !Bls12381::verify(Some(FINALIZE_NAMESPACE), &message, public, &signature) {
274 return None;
275 }
276 }
277 Some(Self {
278 view,
279 parent,
280 payload,
281 signature,
282 })
283 }
284}
285
286impl SizedSerialize for Finalization {
287 const SERIALIZED_LEN: usize = u64::SERIALIZED_LEN
288 + u64::SERIALIZED_LEN
289 + Digest::SERIALIZED_LEN
290 + bls12381::Signature::SERIALIZED_LEN;
291}