1use cesrox::{group::Group, primitives::IndexedSignature as CesrIndexedSignature};
2use said::SelfAddressingIdentifier;
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 database::EventDatabase,
7 error::Error,
8 event::sections::seal::EventSeal,
9 prefix::{BasicPrefix, IdentifierPrefix, IndexedSignature, SelfSigningPrefix},
10 processor::event_storage::EventStorage,
11};
12
13use super::cesr_adapter::ParseError;
14
15#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
16pub enum Signature {
17 Transferable(SignerData, Vec<IndexedSignature>),
19 NonTransferable(Nontransferable),
21}
22
23#[derive(
24 Serialize,
25 Deserialize,
26 Debug,
27 Clone,
28 PartialEq,
29 rkyv::Archive,
30 rkyv::Serialize,
31 rkyv::Deserialize,
32)]
33#[rkyv(compare(PartialEq), derive(Debug))]
34pub enum Nontransferable {
35 Indexed(Vec<IndexedSignature>),
36 Couplet(Vec<(BasicPrefix, SelfSigningPrefix)>),
37}
38
39#[derive(
40 Serialize,
41 Deserialize,
42 Debug,
43 Clone,
44 PartialEq,
45 rkyv::Serialize,
46 rkyv::Deserialize,
47 rkyv::Archive,
48)]
49#[rkyv(derive(Debug))]
50pub enum Transferable {
51 Seal(EventSeal, Vec<IndexedSignature>),
52}
53
54#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
55pub enum SignerData {
56 EventSeal(EventSeal),
57 LastEstablishment(IdentifierPrefix),
58 JustSignatures,
59}
60
61impl SignerData {
62 pub fn get_signer(&self) -> Option<IdentifierPrefix> {
63 match self {
64 SignerData::EventSeal(seal) => Some(seal.prefix.clone()),
65 SignerData::LastEstablishment(id) => Some(id.clone()),
66 SignerData::JustSignatures => None,
67 }
68 }
69}
70
71impl Signature {
72 pub fn get_signer(&self) -> Option<IdentifierPrefix> {
73 match self {
74 Signature::Transferable(signer_data, _) => signer_data.get_signer(),
75 Signature::NonTransferable(Nontransferable::Couplet(couplets)) => {
76 Some(IdentifierPrefix::Basic(couplets[0].0.clone()))
78 }
79 Signature::NonTransferable(Nontransferable::Indexed(_)) => None,
80 }
81 }
82
83 pub fn verify<D: EventDatabase>(
84 &self,
85 data: &[u8],
86 storage: &EventStorage<D>,
87 ) -> Result<bool, Error> {
88 match self {
89 Signature::Transferable(_sigd, sigs) => {
90 let kc = storage
91 .get_state(&self.get_signer().ok_or(Error::MissingSigner)?)
92 .ok_or_else(|| Error::UnknownSigner(self.get_signer().unwrap()))?
93 .current;
94 Ok(kc.verify(data, sigs)?)
95 }
96 Signature::NonTransferable(Nontransferable::Couplet(couplets)) => Ok(couplets
97 .iter()
98 .all(|(id, sig)| id.verify(data, sig).unwrap())),
99 Signature::NonTransferable(Nontransferable::Indexed(_sigs)) => {
100 Err(Error::MissingSigner)
101 }
102 }
103 }
104}
105
106pub fn signatures_into_groups(sigs: &[Signature]) -> Vec<Group> {
107 let (trans_seal, trans_last, nontrans, indexed, witness_indexed) = sigs.iter().cloned().fold(
109 (vec![], vec![], vec![], vec![], vec![]),
110 |(mut trans_seal, mut trans_last, mut nontrans, mut indexed, mut witness_indexed), sig| {
111 match sig {
112 Signature::Transferable(SignerData::EventSeal(seal), sig) => {
113 let event_digest = seal.event_digest();
114 trans_seal.push((
115 seal.prefix.into(),
116 seal.sn,
117 event_digest.into(),
118 sig.into_iter().map(|sig| sig.into()).collect(),
119 ))
120 }
121 Signature::Transferable(SignerData::LastEstablishment(id), sig) => {
122 trans_last.push((id.into(), sig.into_iter().map(|sig| sig.into()).collect()))
123 }
124 Signature::Transferable(SignerData::JustSignatures, sig) => {
125 indexed.append(&mut sig.into_iter().map(|sig| sig.into()).collect())
126 }
127 Signature::NonTransferable(Nontransferable::Couplet(couplets)) => nontrans.append(
128 &mut couplets
129 .into_iter()
130 .map(|(bp, sp)| (bp.into(), sp.into()))
131 .collect(),
132 ),
133 Signature::NonTransferable(Nontransferable::Indexed(sigs)) => {
134 witness_indexed.append(&mut sigs.into_iter().map(|sig| sig.into()).collect())
135 }
136 };
137 (trans_seal, trans_last, nontrans, indexed, witness_indexed)
138 },
139 );
140
141 let mut attachments = vec![];
142 if !trans_seal.is_empty() {
143 attachments.push(Group::TransIndexedSigGroups(trans_seal));
144 }
145 if !trans_last.is_empty() {
146 attachments.push(Group::LastEstSignaturesGroups(trans_last));
147 }
148 if !nontrans.is_empty() {
149 attachments.push(Group::NontransReceiptCouples(nontrans));
150 };
151 if !indexed.is_empty() {
152 attachments.push(Group::IndexedControllerSignatures(indexed));
153 };
154 if !witness_indexed.is_empty() {
155 attachments.push(Group::IndexedWitnessSignatures(witness_indexed));
156 };
157 attachments
158}
159
160pub fn get_signatures(group: Group) -> Result<Vec<Signature>, ParseError> {
161 match group {
162 Group::IndexedControllerSignatures(sigs) => {
163 let signatures = sigs.into_iter().map(|sig| sig.into()).collect();
164 Ok(vec![Signature::Transferable(
165 SignerData::JustSignatures,
166 signatures,
167 )])
168 }
169 Group::NontransReceiptCouples(sigs) => {
170 let signatures = sigs
171 .into_iter()
172 .map(|(bp, sp)| (bp.into(), sp.into()))
173 .collect();
174 Ok(vec![Signature::NonTransferable(Nontransferable::Couplet(
175 signatures,
176 ))])
177 }
178 Group::LastEstSignaturesGroups(sigs) => Ok(sigs
179 .into_iter()
180 .map(|(id, sigs)| {
181 let signatures = sigs.into_iter().map(|sig| sig.into()).collect();
182 Signature::Transferable(SignerData::LastEstablishment(id.into()), signatures)
183 })
184 .collect()),
185 Group::TransIndexedSigGroups(sigs) => Ok(sigs
186 .into_iter()
187 .map(|(id, sn, digest, sigs)| {
188 let signatures = sigs.into_iter().map(|sig| sig.into()).collect();
189 Signature::Transferable(
190 SignerData::EventSeal(EventSeal::new(
191 id.into(),
192 sn,
193 SelfAddressingIdentifier::from(digest),
194 )),
195 signatures,
196 )
197 })
198 .collect()),
199 Group::IndexedWitnessSignatures(sigs) => {
200 let signatures = sigs.into_iter().map(|sig| sig.into()).collect();
201 Ok(vec![Signature::NonTransferable(Nontransferable::Indexed(
202 signatures,
203 ))])
204 }
205 _ => Err(ParseError::AttachmentError(
206 "Improper attachment type".into(),
207 )),
208 }
209}
210
211impl Into<Group> for Nontransferable {
212 fn into(self) -> Group {
213 match self {
214 Nontransferable::Indexed(indexed) => {
215 let signatures = indexed.into_iter().map(|sig| sig.into()).collect();
216 Group::IndexedWitnessSignatures(signatures)
217 }
218 Nontransferable::Couplet(couples) => {
219 let couples = couples
220 .into_iter()
221 .map(|(bp, sp)| (bp.into(), sp.into()))
222 .collect();
223 Group::NontransReceiptCouples(couples)
224 }
225 }
226 }
227}
228
229impl Into<Group> for crate::event_message::signature::Signature {
230 fn into(self) -> Group {
231 match self {
232 crate::event_message::signature::Signature::Transferable(seal, signature) => {
233 let signatures: Vec<CesrIndexedSignature> =
234 signature.into_iter().map(|sig| sig.into()).collect();
235 match seal {
236 crate::event_message::signature::SignerData::EventSeal(event_seal) => {
237 let event_digest = event_seal.event_digest();
238 Group::TransIndexedSigGroups(vec![(
239 event_seal.prefix.into(),
240 event_seal.sn,
241 event_digest.into(),
242 signatures,
243 )])
244 }
245 crate::event_message::signature::SignerData::LastEstablishment(id) => {
246 Group::LastEstSignaturesGroups(vec![(id.into(), signatures)])
247 }
248 crate::event_message::signature::SignerData::JustSignatures => {
249 Group::IndexedControllerSignatures(signatures)
250 }
251 }
252 }
253 crate::event_message::signature::Signature::NonTransferable(nt) => nt.into(),
254 }
255 }
256}