Skip to main content

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}