Skip to main content

keri_controller/identifier/mechanics/
group.rs

1use keri_core::{
2    actor::{event_generator, MaterialPath},
3    event::{sections::threshold::SignatureThreshold, KeyEvent},
4    event_message::{
5        cesr_adapter::{parse_event_type, EventType},
6        msg::KeriEvent,
7        signature::{Signature, SignerData},
8        signed_event_message::{Message, Op},
9        EventTypeTag,
10    },
11    mailbox::exchange::{Exchange, ForwardTopic, SignedExchange},
12    prefix::{BasicPrefix, IdentifierPrefix, IndexedSignature, SelfSigningPrefix},
13};
14
15use crate::identifier::Identifier;
16
17use super::MechanicsError;
18
19impl Identifier {
20    /// Init group identifier
21    ///
22    /// Returns serialized group icp and list of exchange messages to sign.
23    /// Exchanges are meant to be send to witness and forwarded to group
24    /// participants.
25    /// If `delegator` parameter is provided, it will generate delegated
26    /// inception and append delegation request to exchange messages.
27    pub fn incept_group(
28        &self,
29        participants: Vec<IdentifierPrefix>,
30        signature_threshold: u64,
31        next_keys_threshold: Option<u64>,
32        initial_witness: Option<Vec<BasicPrefix>>,
33        witness_threshold: Option<u64>,
34        delegator: Option<IdentifierPrefix>,
35    ) -> Result<(String, Vec<String>), MechanicsError> {
36        let key_config = self
37            .known_events
38            .storage
39            .get_state(&self.id)
40            .ok_or(MechanicsError::UnknownIdentifierError(self.id.clone()))?
41            .current;
42
43        let mut pks = key_config.public_keys;
44        let mut npks = key_config.next_keys_data.next_keys_hashes();
45        for participant in &participants {
46            let state = self
47                .known_events
48                .storage
49                .get_state(participant)
50                .ok_or(MechanicsError::UnknownIdentifierError(participant.clone()))?;
51            pks.append(&mut state.clone().current.public_keys);
52            npks.append(&mut state.clone().current.next_keys_data.next_keys_hashes());
53        }
54
55        let current_sig_threshold = SignatureThreshold::Simple(signature_threshold);
56        let next_sig_threshold = next_keys_threshold
57            .map(|sig| SignatureThreshold::Simple(sig))
58            .unwrap_or(current_sig_threshold.clone());
59        let icp = event_generator::incept_with_next_hashes(
60            pks,
61            &current_sig_threshold,
62            npks,
63            &next_sig_threshold,
64            initial_witness.unwrap_or_default(),
65            witness_threshold.unwrap_or(0),
66            delegator.as_ref(),
67        )?;
68
69        let serialized_icp = String::from_utf8(icp.encode()?)
70            .map_err(|e| MechanicsError::EventGenerationError(e.to_string()))?;
71
72        let mut exchanges = participants
73            .iter()
74            .map(|id| -> Result<_, _> {
75                let exn = event_generator::exchange(id, &icp, ForwardTopic::Multisig).encode()?;
76                String::from_utf8(exn).map_err(|_e| MechanicsError::EventFormatError)
77            })
78            .collect::<Result<Vec<String>, MechanicsError>>()?;
79
80        if let Some(delegator) = delegator {
81            let delegation_request = String::from_utf8(
82                event_generator::exchange(&delegator, &icp, ForwardTopic::Delegate).encode()?,
83            )
84            .map_err(|_e| MechanicsError::EventFormatError)?;
85            exchanges.push(delegation_request);
86        }
87
88        Ok((serialized_icp, exchanges))
89    }
90
91    /// Finalizes group identifier.
92    pub async fn finalize_group_incept(
93        &mut self,
94        group_event: &[u8],
95        sig: SelfSigningPrefix,
96        exchanges: Vec<(Vec<u8>, Signature)>,
97    ) -> Result<IdentifierPrefix, MechanicsError> {
98        // Join icp event with signature
99        let key_event =
100            parse_event_type(group_event).map_err(|_e| MechanicsError::EventFormatError)?;
101        let ke = if let EventType::KeyEvent(icp) = key_event {
102            match icp.event_type {
103                EventTypeTag::Icp | EventTypeTag::Dip => icp,
104                _ => Err(MechanicsError::InceptionError(
105                    "Event is not inception".to_string(),
106                ))?,
107            }
108        } else {
109            return Err(MechanicsError::WrongEventTypeError);
110        };
111        let group_prefix = ke.data.get_prefix();
112        self.finalize_event(&ke, sig, exchanges).await?;
113        Ok(group_prefix)
114    }
115
116    /// Finalizes group event.
117    pub async fn finalize_group_event(
118        &mut self,
119        group_event: &[u8],
120        sig: SelfSigningPrefix,
121        exchanges: Vec<(Vec<u8>, Signature)>,
122    ) -> Result<(), MechanicsError> {
123        // Join icp event with signature
124        let key_event =
125            parse_event_type(group_event).map_err(|_e| MechanicsError::EventFormatError)?;
126        let ke = if let EventType::KeyEvent(icp) = key_event {
127            icp
128        } else {
129            return Err(MechanicsError::WrongEventTypeError);
130        };
131        self.finalize_event(&ke, sig, exchanges).await?;
132        Ok(())
133    }
134
135    /// Finalizes group event.
136    /// Joins event with signature and verifies them.
137    async fn finalize_event(
138        &mut self,
139        key_event: &KeriEvent<KeyEvent>,
140        sig: SelfSigningPrefix,
141        exchanges: Vec<(Vec<u8>, Signature)>,
142    ) -> Result<(), MechanicsError> {
143        let own_index = self.get_index(&key_event.data)?;
144
145        self.known_events
146            .finalize_key_event(&key_event, &sig, own_index)?;
147
148        let signature = IndexedSignature::new_both_same(sig.clone(), own_index as u16);
149
150        let signed_message = key_event.sign(vec![signature], None, None);
151        self.to_notify.push(signed_message);
152
153        let att_signature = IndexedSignature::new_both_same(sig, own_index as u16);
154
155        for (exn, signature) in exchanges {
156            self.finalize_exchange(&exn, signature, att_signature.clone())
157                .await?;
158        }
159        Ok(())
160    }
161
162    pub async fn finalize_exchange(
163        &self,
164        exchange: &[u8],
165        exn_signature: Signature,
166        data_signature: IndexedSignature,
167    ) -> Result<(), MechanicsError> {
168        // Join exn messages with their signatures and send it to witness.
169        let material_path = MaterialPath::to_path("-a".into());
170        // let attached_sig = sigs;
171        let parsed_exn =
172            parse_event_type(exchange).map_err(|_e| MechanicsError::EventFormatError)?;
173        if let EventType::Exn(exn) = parsed_exn {
174            let Exchange::Fwd {
175                args: _,
176                to_forward,
177            } = exn.data.data.clone();
178
179            let sigs: Vec<_> = if let Some(receipts) = self.known_events.find_receipt(
180                &to_forward.data.get_prefix(),
181                to_forward.data.get_sn(),
182                &to_forward.digest()?,
183            )? {
184                receipts
185                    .signatures
186                    .iter()
187                    .map(|c| Signature::NonTransferable(c.clone()))
188                    .chain([Signature::Transferable(
189                        SignerData::JustSignatures,
190                        vec![data_signature],
191                    )])
192                    .collect::<Vec<_>>()
193            } else {
194                vec![Signature::Transferable(
195                    SignerData::JustSignatures,
196                    vec![data_signature],
197                )]
198            };
199
200            let signer_exn = Message::Op(Op::Exchange(SignedExchange {
201                exchange_message: exn,
202                signature: vec![exn_signature],
203                data_signature: (material_path.clone(), sigs.clone()),
204            }));
205            let wits = self
206                .known_events
207                .get_state_at_event(&to_forward)?
208                .witness_config
209                .witnesses;
210            // TODO for now get first witness
211            if let Some(wit) = wits.first() {
212                self.communication
213                    .send_message_to(
214                        IdentifierPrefix::Basic(wit.clone()),
215                        keri_core::oobi::Scheme::Http,
216                        signer_exn,
217                    )
218                    .await?;
219            }
220            Ok(())
221        } else {
222            Ok(())
223        }
224    }
225}