keri_core/event_message/
key_event_message.rs

1use said::{derivation::HashFunctionCode, sad::SAD, SelfAddressingIdentifier};
2
3use crate::{
4    error::Error,
5    event::{event_data::EventData, sections::seal::SourceSeal, KeyEvent},
6    prefix::{IdentifierPrefix, IndexedSignature},
7    state::{EventSemantics, IdentifierState},
8};
9
10use super::{
11    dummy_event::DummyInceptionEvent, msg::KeriEvent, signature::Nontransferable,
12    signed_event_message::SignedEventMessage, EventTypeTag,
13};
14
15impl KeyEvent {
16    pub fn get_sn(&self) -> u64 {
17        self.sn
18    }
19    pub fn get_prefix(&self) -> IdentifierPrefix {
20        self.prefix.clone()
21    }
22    pub fn get_event_data(&self) -> EventData {
23        self.event_data.clone()
24    }
25}
26
27impl KeriEvent<KeyEvent> {
28    pub fn sign(
29        &self,
30        sigs: Vec<IndexedSignature>,
31        witness_sigs: Option<Vec<Nontransferable>>,
32        delegator_seal: Option<SourceSeal>,
33    ) -> SignedEventMessage {
34        SignedEventMessage::new(self, sigs, witness_sigs, delegator_seal)
35    }
36
37    pub fn compare_digest(&self, sai: &SelfAddressingIdentifier) -> Result<bool, Error> {
38        let self_dig = self.digest()?;
39        if self_dig.derivation.eq(&sai.derivation) {
40            Ok(&self_dig == sai)
41        } else {
42            Ok(sai.verify_binding(&self.to_derivation_data()?))
43        }
44    }
45
46    pub fn to_derivation_data(&self) -> Result<Vec<u8>, Error> {
47        let event_digest = self.digest()?;
48        let hash_function_code: HashFunctionCode = event_digest.derivation.into();
49        Ok(match self.data.get_event_data() {
50            EventData::Icp(icp) => DummyInceptionEvent::dummy_inception_data(
51                icp,
52                &hash_function_code,
53                self.serialization_info.kind,
54            )?
55            .derivation_data(&hash_function_code, &self.serialization_info.kind),
56            EventData::Dip(dip) => DummyInceptionEvent::dummy_delegated_inception_data(
57                dip,
58                &hash_function_code,
59                self.serialization_info.kind,
60            )?
61            .derivation_data(&hash_function_code, &self.serialization_info.kind),
62            _ => self.derivation_data(&hash_function_code, &self.serialization_info.kind),
63        })
64    }
65}
66
67impl EventSemantics for KeriEvent<KeyEvent> {
68    fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, Error> {
69        let event_digest = self.digest()?;
70        let check_event_digest = |ev: &KeriEvent<KeyEvent>| -> Result<(), Error> {
71            ev.compare_digest(&event_digest)?
72                .then_some(())
73                .ok_or(Error::IncorrectDigest)
74        };
75        let last_event_digest = &state.last_event_digest.said;
76        // Update state.last with serialized current event message.
77        match (self.data.get_event_data(), &self.event_type) {
78            (EventData::Icp(_), _) | (EventData::Dip(_), _) => {
79                if verify_identifier_binding(self)? {
80                    self.data.apply_to(IdentifierState {
81                        last_event_digest: event_digest.into(),
82                        ..state
83                    })
84                } else {
85                    Err(Error::SemanticError(
86                        "Invalid Identifier Prefix Binding".into(),
87                    ))
88                }
89            }
90            (EventData::Rot(ref rot), EventTypeTag::Rot)
91            | (EventData::Drt(ref rot), EventTypeTag::Rot) => {
92                check_event_digest(self)?;
93                if state.delegator.is_some() {
94                    Err(Error::SemanticError(
95                        "Applying non-delegated rotation to delegated state.".into(),
96                    ))
97                } else {
98                    // Event may be out of order or duplicated, so before checking
99                    // previous event hash binding and update state last, apply it
100                    // to the state. It will return EventOutOfOrderError or
101                    // EventDuplicateError in that cases.
102                    self.data.apply_to(state.clone()).and_then(|next_state| {
103                        if last_event_digest.eq(rot.previous_event_hash()) {
104                            Ok(IdentifierState {
105                                last_event_digest: event_digest.into(),
106                                ..next_state
107                            })
108                        } else {
109                            Err(Error::SemanticError(
110                                "Last event does not match previous event".into(),
111                            ))
112                        }
113                    })
114                }
115            }
116            (EventData::Rot(ref drt), EventTypeTag::Drt)
117            | (EventData::Drt(ref drt), EventTypeTag::Drt) => {
118                self.data.apply_to(state.clone()).and_then(|next_state| {
119                    check_event_digest(self)?;
120                    if state.delegator.is_none() {
121                        Err(Error::SemanticError(
122                            "Applying delegated rotation to non-delegated state.".into(),
123                        ))
124                    } else if last_event_digest.eq(drt.previous_event_hash()) {
125                        Ok(IdentifierState {
126                            last_event_digest: event_digest.clone().into(),
127                            ..next_state
128                        })
129                    } else {
130                        Err(Error::SemanticError(
131                            "Last event does not match previous event".into(),
132                        ))
133                    }
134                })
135            }
136            (EventData::Ixn(ref inter), _) => {
137                check_event_digest(self)?;
138                self.data.apply_to(state.clone()).and_then(|next_state| {
139                    if last_event_digest.eq(inter.previous_event_hash()) {
140                        Ok(IdentifierState {
141                            last_event_digest: event_digest.into(),
142                            ..next_state
143                        })
144                    } else {
145                        Err(Error::SemanticError(
146                            "Last event does not match previous event".to_string(),
147                        ))
148                    }
149                })
150            }
151            _ => Err(Error::SemanticError("Wrong type tag".to_string())),
152        }
153    }
154}
155
156pub fn verify_identifier_binding(icp_event: &KeriEvent<KeyEvent>) -> Result<bool, Error> {
157    let event_data = &icp_event.data.get_event_data();
158    match event_data {
159        EventData::Icp(icp) => match &icp_event.data.get_prefix() {
160            IdentifierPrefix::Basic(bp) => Ok(icp.key_config.public_keys.len() == 1
161                && bp.eq(icp
162                    .key_config
163                    .public_keys
164                    .first()
165                    .ok_or_else(|| Error::SemanticError("Missing public key".into()))?)),
166            IdentifierPrefix::SelfAddressing(sap) => {
167                Ok(icp_event.compare_digest(&sap.said)? && icp_event.digest()?.eq(&sap.said))
168            }
169            IdentifierPrefix::SelfSigning(_ssp) => todo!(),
170        },
171        EventData::Dip(_dip) => match &icp_event.data.get_prefix() {
172            IdentifierPrefix::SelfAddressing(sap) => icp_event.compare_digest(&sap.said),
173            _ => todo!(),
174        },
175        _ => Err(Error::SemanticError("Not an ICP or DIP event".into())),
176    }
177}