ate_crypto/crypto/
private_encrypt_key.rs

1use crate::utils::vec_deserialize;
2use crate::utils::vec_serialize;
3use pqcrypto_ntru_wasi::ntruhps2048509 as ntru128;
4use pqcrypto_ntru_wasi::ntruhps2048677 as ntru192;
5use pqcrypto_ntru_wasi::ntruhps4096821 as ntru256;
6use pqcrypto_traits_wasi::kem::*;
7use serde::{Deserialize, Serialize};
8use std::result::Result;
9#[allow(unused_imports)]
10use tracing::{debug, error, info, instrument, span, trace, warn, Level};
11
12use super::*;
13
14/// Private encryption keys provide the ability to decrypt a secret
15/// that was encrypted using a Public Key - this capability is
16/// useful for key-exchange and trust validation in the crypto chain.
17/// Asymetric crypto in ATE uses the leading candidates from NIST
18/// that provide protection against quantom computer attacks
19#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq)]
20pub enum PrivateEncryptKey {
21    Ntru128 {
22        pk: PublicEncryptKey,
23        #[serde(serialize_with = "vec_serialize", deserialize_with = "vec_deserialize")]
24        sk: Vec<u8>,
25    },
26    Ntru192 {
27        pk: PublicEncryptKey,
28        #[serde(serialize_with = "vec_serialize", deserialize_with = "vec_deserialize")]
29        sk: Vec<u8>,
30    },
31    Ntru256 {
32        pk: PublicEncryptKey,
33        #[serde(serialize_with = "vec_serialize", deserialize_with = "vec_deserialize")]
34        sk: Vec<u8>,
35    },
36}
37
38impl PrivateEncryptKey {
39    #[allow(dead_code)]
40    pub fn generate(size: KeySize) -> PrivateEncryptKey {
41        match size {
42            KeySize::Bit128 => {
43                let (pk, sk) = ntru128::keypair();
44                PrivateEncryptKey::Ntru128 {
45                    pk: PublicEncryptKey::Ntru128 {
46                        pk: Vec::from(pk.as_bytes()),
47                    },
48                    sk: Vec::from(sk.as_bytes()),
49                }
50            }
51            KeySize::Bit192 => {
52                let (pk, sk) = ntru192::keypair();
53                PrivateEncryptKey::Ntru192 {
54                    pk: PublicEncryptKey::Ntru192 {
55                        pk: Vec::from(pk.as_bytes()),
56                    },
57                    sk: Vec::from(sk.as_bytes()),
58                }
59            }
60            KeySize::Bit256 => {
61                let (pk, sk) = ntru256::keypair();
62                PrivateEncryptKey::Ntru256 {
63                    pk: PublicEncryptKey::Ntru256 {
64                        pk: Vec::from(pk.as_bytes()),
65                    },
66                    sk: Vec::from(sk.as_bytes()),
67                }
68            }
69        }
70    }
71
72    #[allow(dead_code)]
73    pub fn as_public_key<'a>(&'a self) -> &'a PublicEncryptKey {
74        match &self {
75            PrivateEncryptKey::Ntru128 { sk: _, pk } => pk,
76            PrivateEncryptKey::Ntru192 { sk: _, pk } => pk,
77            PrivateEncryptKey::Ntru256 { sk: _, pk } => pk,
78        }
79    }
80
81    #[allow(dead_code)]
82    pub fn hash(&self) -> AteHash {
83        match &self {
84            PrivateEncryptKey::Ntru128 { pk, sk: _ } => pk.hash(),
85            PrivateEncryptKey::Ntru192 { pk, sk: _ } => pk.hash(),
86            PrivateEncryptKey::Ntru256 { pk, sk: _ } => pk.hash(),
87        }
88    }
89
90    #[allow(dead_code)]
91    pub fn pk<'a>(&'a self) -> &'a [u8] {
92        match &self {
93            PrivateEncryptKey::Ntru128 { pk, sk: _ } => pk.pk(),
94            PrivateEncryptKey::Ntru192 { pk, sk: _ } => pk.pk(),
95            PrivateEncryptKey::Ntru256 { pk, sk: _ } => pk.pk(),
96        }
97    }
98
99    #[allow(dead_code)]
100    pub fn sk<'a>(&'a self) -> &'a [u8] {
101        match &self {
102            PrivateEncryptKey::Ntru128 { pk: _, sk } => &sk[..],
103            PrivateEncryptKey::Ntru192 { pk: _, sk } => &sk[..],
104            PrivateEncryptKey::Ntru256 { pk: _, sk } => &sk[..],
105        }
106    }
107
108    #[allow(dead_code)]
109    pub fn decapsulate(&self, iv: &InitializationVector) -> Option<EncryptKey> {
110        match &self {
111            PrivateEncryptKey::Ntru128 { pk: _, sk } => {
112                if iv.bytes.len() != ntru128::ciphertext_bytes() {
113                    return None;
114                }
115                let ct = ntru128::Ciphertext::from_bytes(&iv.bytes[..]).unwrap();
116                let sk = ntru128::SecretKey::from_bytes(&sk[..]).unwrap();
117                let ss = ntru128::decapsulate(&ct, &sk);
118                Some(EncryptKey::from_seed_bytes(ss.as_bytes(), KeySize::Bit128))
119            }
120            PrivateEncryptKey::Ntru192 { pk: _, sk } => {
121                if iv.bytes.len() != ntru192::ciphertext_bytes() {
122                    return None;
123                }
124                let ct = ntru192::Ciphertext::from_bytes(&iv.bytes[..]).unwrap();
125                let sk = ntru192::SecretKey::from_bytes(&sk[..]).unwrap();
126                let ss = ntru192::decapsulate(&ct, &sk);
127                Some(EncryptKey::from_seed_bytes(ss.as_bytes(), KeySize::Bit192))
128            }
129            PrivateEncryptKey::Ntru256 { pk: _, sk } => {
130                if iv.bytes.len() != ntru256::ciphertext_bytes() {
131                    return None;
132                }
133                let ct = ntru256::Ciphertext::from_bytes(&iv.bytes[..]).unwrap();
134                let sk = ntru256::SecretKey::from_bytes(&sk[..]).unwrap();
135                let ss = ntru256::decapsulate(&ct, &sk);
136                Some(EncryptKey::from_seed_bytes(ss.as_bytes(), KeySize::Bit256))
137            }
138        }
139    }
140
141    pub fn decrypt(
142        &self,
143        iv: &InitializationVector,
144        data: &[u8],
145    ) -> Result<Vec<u8>, std::io::Error> {
146        let ek = match self.decapsulate(iv) {
147            Some(a) => a,
148            None => {
149                return Err(std::io::Error::new(
150                    std::io::ErrorKind::Other,
151                    "The encryption key could not be decapsulated from the initialization vector.",
152                ));
153            }
154        };
155        Ok(ek.decrypt(iv, data))
156    }
157
158    pub fn decrypt_ext(
159        &self,
160        iv: &InitializationVector,
161        data: &[u8],
162        ek_hash: &AteHash,
163    ) -> Result<Vec<u8>, std::io::Error> {
164        let ek = match self.decapsulate(iv) {
165            Some(a) => a,
166            None => {
167                return Err(std::io::Error::new(
168                    std::io::ErrorKind::Other,
169                    "The encryption key could not be decapsulated from the initialization vector.",
170                ));
171            }
172        };
173        if ek.hash() != *ek_hash {
174            return Err(std::io::Error::new(
175                std::io::ErrorKind::Other,
176                format!("The decryption key is not valid for this cipher data ({} vs {}).", ek.hash(), ek_hash).as_str(),
177            ));
178        }
179        Ok(ek.decrypt(iv, data))
180    }
181
182    pub fn size(&self) -> KeySize {
183        match &self {
184            PrivateEncryptKey::Ntru128 { pk: _, sk: _ } => KeySize::Bit128,
185            PrivateEncryptKey::Ntru192 { pk: _, sk: _ } => KeySize::Bit192,
186            PrivateEncryptKey::Ntru256 { pk: _, sk: _ } => KeySize::Bit256,
187        }
188    }
189}
190
191impl std::fmt::Display for PrivateEncryptKey {
192    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193        match self {
194            PrivateEncryptKey::Ntru128 { pk: _, sk: _ } => {
195                write!(f, "ntru128:pk:{}+sk", self.hash())
196            }
197            PrivateEncryptKey::Ntru192 { pk: _, sk: _ } => {
198                write!(f, "ntru192:pk:{}+sk", self.hash())
199            }
200            PrivateEncryptKey::Ntru256 { pk: _, sk: _ } => {
201                write!(f, "ntru256:pk:{}+sk", self.hash())
202            }
203        }
204    }
205}
206
207/// Public encryption keys provide the ability to encrypt a secret
208/// without the ability to decrypt it yourself - this capability is
209/// useful for key-exchange and trust validation in the crypto chain.
210/// Asymetric crypto in ATE uses the leading candidates from NIST
211/// that provide protection against quantom computer attacks
212#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq)]
213pub enum PublicEncryptKey {
214    Ntru128 {
215        #[serde(serialize_with = "vec_serialize", deserialize_with = "vec_deserialize")]
216        pk: Vec<u8>,
217    },
218    Ntru192 {
219        #[serde(serialize_with = "vec_serialize", deserialize_with = "vec_deserialize")]
220        pk: Vec<u8>,
221    },
222    Ntru256 {
223        #[serde(serialize_with = "vec_serialize", deserialize_with = "vec_deserialize")]
224        pk: Vec<u8>,
225    },
226}
227
228impl PublicEncryptKey {
229    pub fn from_bytes(bytes: Vec<u8>) -> Option<PublicEncryptKey> {
230        match bytes.len() {
231            a if a == ntru128::public_key_bytes() => Some(PublicEncryptKey::Ntru128 { pk: bytes }),
232            a if a == ntru192::public_key_bytes() => Some(PublicEncryptKey::Ntru192 { pk: bytes }),
233            a if a == ntru256::public_key_bytes() => Some(PublicEncryptKey::Ntru256 { pk: bytes }),
234            _ => None,
235        }
236    }
237
238    pub fn pk<'a>(&'a self) -> &'a [u8] {
239        match &self {
240            PublicEncryptKey::Ntru128 { pk } => &pk[..],
241            PublicEncryptKey::Ntru192 { pk } => &pk[..],
242            PublicEncryptKey::Ntru256 { pk } => &pk[..],
243        }
244    }
245
246    #[allow(dead_code)]
247    pub fn hash(&self) -> AteHash {
248        match &self {
249            PublicEncryptKey::Ntru128 { pk } => AteHash::from_bytes(&pk[..]),
250            PublicEncryptKey::Ntru192 { pk } => AteHash::from_bytes(&pk[..]),
251            PublicEncryptKey::Ntru256 { pk } => AteHash::from_bytes(&pk[..]),
252        }
253    }
254
255    #[allow(dead_code)]
256    pub fn encapsulate(&self) -> (InitializationVector, EncryptKey) {
257        match &self {
258            PublicEncryptKey::Ntru128 { pk } => {
259                let pk = ntru128::PublicKey::from_bytes(&pk[..]).unwrap();
260                let (ss, ct) = ntru128::encapsulate(&pk);
261                let iv = InitializationVector::from(ct.as_bytes());
262                (
263                    iv,
264                    EncryptKey::from_seed_bytes(ss.as_bytes(), KeySize::Bit128),
265                )
266            }
267            PublicEncryptKey::Ntru192 { pk } => {
268                let pk = ntru192::PublicKey::from_bytes(&pk[..]).unwrap();
269                let (ss, ct) = ntru192::encapsulate(&pk);
270                let iv = InitializationVector::from(ct.as_bytes());
271                (
272                    iv,
273                    EncryptKey::from_seed_bytes(ss.as_bytes(), KeySize::Bit192),
274                )
275            }
276            PublicEncryptKey::Ntru256 { pk } => {
277                let pk = ntru256::PublicKey::from_bytes(&pk[..]).unwrap();
278                let (ss, ct) = ntru256::encapsulate(&pk);
279                let iv = InitializationVector::from(ct.as_bytes());
280                (
281                    iv,
282                    EncryptKey::from_seed_bytes(ss.as_bytes(), KeySize::Bit256),
283                )
284            }
285        }
286    }
287
288    pub fn encrypt(&self, data: &[u8]) -> EncryptResult {
289        let (iv, ek) = self.encapsulate();
290        let data = ek.encrypt_with_iv(&iv, data);
291        EncryptResult { iv, data }
292    }
293
294    pub fn size(&self) -> KeySize {
295        match &self {
296            PublicEncryptKey::Ntru128 { pk: _ } => KeySize::Bit128,
297            PublicEncryptKey::Ntru192 { pk: _ } => KeySize::Bit192,
298            PublicEncryptKey::Ntru256 { pk: _ } => KeySize::Bit256,
299        }
300    }
301}
302
303impl std::fmt::Display for PublicEncryptKey {
304    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
305        match self {
306            PublicEncryptKey::Ntru128 { pk: _ } => write!(f, "ntru128:pk:{}", self.hash()),
307            PublicEncryptKey::Ntru192 { pk: _ } => write!(f, "ntru192:pk:{}", self.hash()),
308            PublicEncryptKey::Ntru256 { pk: _ } => write!(f, "ntru256:pk:{}", self.hash()),
309        }
310    }
311}