keri_core/event_message/
signature.rs

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    /// Created by transferable identifier
18    Transferable(SignerData, Vec<IndexedSignature>),
19    /// Created by nontransferable identifier
20    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                // TODO
77                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    // Group same type of signature in one attachment
108    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}