confium_patterns/escrow/blob.rs
1//! Escrow blob types.
2
3use crate::escrow::metadata::EscrowMetadata;
4use serde::{Deserialize, Serialize};
5
6/// An escrowed key (or any secret) — encrypted to a threshold KEM public key.
7///
8/// Recovery requires T-of-N custodians to participate in an async
9/// threshold decryption ceremony. The structure intentionally mirrors
10/// CMS-style "envelope" patterns.
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct EscrowBlob {
13 /// Identifies the recipient quorum (e.g., "biml-escrow-quorum").
14 pub recipient_quorum_id: String,
15 /// Threshold KEM encapsulated key (algorithm-specific bytes).
16 pub encapsulated_key: Vec<u8>,
17 /// AEAD ciphertext of the plaintext key, using the KEM-derived shared secret.
18 pub ciphertext: Vec<u8>,
19 /// AEAD nonce.
20 pub nonce: Vec<u8>,
21 /// AEAD additional data (typically the metadata hash).
22 pub aad: Vec<u8>,
23 /// Escrow metadata.
24 pub metadata: EscrowMetadata,
25}
26
27impl EscrowBlob {
28 /// Compute the SHA-256 fingerprint of this blob (canonical JSON, then hash).
29 pub fn fingerprint(&self) -> [u8; 32] {
30 use sha2::{Digest, Sha256};
31 let mut h = Sha256::new();
32 h.update(self.recipient_quorum_id.as_bytes());
33 h.update(&self.encapsulated_key);
34 h.update(&self.ciphertext);
35 h.update(&self.nonce);
36 h.update(&self.aad);
37 let r = h.finalize();
38 let mut out = [0u8; 32];
39 out.copy_from_slice(&r);
40 out
41 }
42}