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#[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#[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}