keri_core/event_message/
key_event_message.rs1use 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 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 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}