confium_tc/kem/
encapsulate.rs1use crate::kem::share::ThresholdShare;
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct ThresholdPublicKey {
14 pub algorithm: String,
16 pub bytes: Vec<u8>,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct EncapsulatedKey {
23 pub algorithm: String,
25 pub bytes: Vec<u8>,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, zeroize::ZeroizeOnDrop)]
32pub struct SharedSecret {
33 pub bytes: Vec<u8>,
35}
36
37#[derive(Debug, thiserror::Error)]
39pub enum EncapsulateError {
40 #[error("unknown algorithm: {0}")]
42 UnknownAlgorithm(String),
43 #[error("invalid public key: {0}")]
45 InvalidPublicKey(String),
46 #[error("backend failure: {0}")]
48 Backend(String),
49}
50
51pub trait Encapsulator {
53 fn encapsulate(
58 &self,
59 recipient_public_key: &ThresholdPublicKey,
60 ) -> Result<(EncapsulatedKey, SharedSecret), EncapsulateError>;
61}
62
63pub struct MockEncapsulator;
69
70impl Encapsulator for MockEncapsulator {
71 fn encapsulate(
72 &self,
73 _recipient_public_key: &ThresholdPublicKey,
74 ) -> Result<(EncapsulatedKey, SharedSecret), EncapsulateError> {
75 Ok((
78 EncapsulatedKey {
79 algorithm: "mock-threshold-kem".into(),
80 bytes: vec![0u8; 32],
81 },
82 SharedSecret {
83 bytes: vec![0u8; 32],
84 },
85 ))
86 }
87}
88
89pub fn encapsulate_mock(
91 recipient: &ThresholdPublicKey,
92) -> Result<(EncapsulatedKey, SharedSecret), EncapsulateError> {
93 MockEncapsulator.encapsulate(recipient)
94}
95
96pub fn validate_share_for_algorithm(
98 share: &ThresholdShare,
99 algorithm: &str,
100) -> Result<(), EncapsulateError> {
101 if share.algorithm != algorithm {
102 return Err(EncapsulateError::InvalidPublicKey(format!(
103 "share algorithm {} does not match expected {}",
104 share.algorithm, algorithm
105 )));
106 }
107 Ok(())
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn mock_encapsulator_round_trip_data() {
116 let pk = ThresholdPublicKey {
117 algorithm: "mock-threshold-kem".into(),
118 bytes: vec![1u8; 32],
119 };
120 let (ek, ss) = encapsulate_mock(&pk).unwrap();
121 assert_eq!(ek.bytes.len(), 32);
122 assert_eq!(ss.bytes.len(), 32);
123 }
124
125 #[test]
126 fn validate_share_checks_algorithm() {
127 let share = ThresholdShare {
128 algorithm: "different-alg".into(),
129 party_index: 0,
130 bytes: vec![],
131 };
132 let result = validate_share_for_algorithm(&share, "expected-alg");
133 assert!(result.is_err());
134 }
135}