Skip to main content

sentc_crypto_std_keys/core/asym/
pqc_kyber.rs

1use alloc::vec::Vec;
2
3use pqc_kyber_edit::{decapsulate, encapsulate, keypair, PublicKey, SecretKey, KYBER_CIPHERTEXTBYTES, KYBER_PUBLICKEYBYTES, KYBER_SECRETKEYBYTES};
4use rand_core::{CryptoRng, RngCore};
5use sentc_crypto_core::cryptomat::{Pk, SignK, Sk, StaticKeyPair, SymKey, VerifyK};
6use sentc_crypto_core::{as_ref_bytes_single_value, crypto_alg_str_impl, try_from_bytes_owned_single_value, Error};
7
8use crate::core::sym::aes_gcm::{raw_decrypt as aes_decrypt, raw_encrypt as aes_encrypt};
9use crate::get_rand;
10
11pub const KYBER_OUTPUT: &str = "KYBER_768";
12
13#[derive(Clone)]
14pub struct KyberPk([u8; KYBER_PUBLICKEYBYTES]);
15try_from_bytes_owned_single_value!(KyberPk);
16crypto_alg_str_impl!(KyberPk, KYBER_OUTPUT);
17as_ref_bytes_single_value!(KyberPk);
18
19impl Into<crate::core::asym::PublicKey> for KyberPk
20{
21	fn into(self) -> crate::core::asym::PublicKey
22	{
23		crate::core::asym::PublicKey::Kyber(self)
24	}
25}
26
27impl Pk for KyberPk
28{
29	fn sign_public_key<S: SignK>(&self, sign_key: &S) -> Result<S::Signature, Error>
30	{
31		sign_key.sign_only(self.0)
32	}
33
34	fn verify_public_key<V: VerifyK>(&self, verify_key: &V, sig: &V::Signature) -> Result<bool, Error>
35	{
36		verify_key.verify_only(sig, &self.0)
37	}
38
39	fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, Error>
40	{
41		encrypt_internally(&self.0, data, &mut get_rand())
42	}
43}
44
45pub struct KyberSk([u8; KYBER_SECRETKEYBYTES]);
46try_from_bytes_owned_single_value!(KyberSk);
47crypto_alg_str_impl!(KyberSk, KYBER_OUTPUT);
48as_ref_bytes_single_value!(KyberSk);
49
50impl Into<crate::core::asym::SecretKey> for KyberSk
51{
52	fn into(self) -> crate::core::asym::SecretKey
53	{
54		crate::core::asym::SecretKey::Kyber(self)
55	}
56}
57
58impl Sk for KyberSk
59{
60	fn encrypt_by_master_key<M: SymKey>(&self, master_key: &M) -> Result<Vec<u8>, Error>
61	{
62		master_key.encrypt(&self.0)
63	}
64
65	fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, Error>
66	{
67		decrypt_internally(&self.0, ciphertext)
68	}
69}
70
71pub struct KyberKeyPair;
72
73impl StaticKeyPair for KyberKeyPair
74{
75	type SecretKey = KyberSk;
76	type PublicKey = KyberPk;
77
78	fn generate_static_keypair() -> Result<(Self::SecretKey, Self::PublicKey), Error>
79	{
80		let (sk, pk) = generate_keypair_internally(&mut get_rand())?;
81
82		Ok((KyberSk(sk), KyberPk(pk)))
83	}
84}
85
86//__________________________________________________________________________________________________
87
88pub(super) fn generate_keypair_internally<R: CryptoRng + RngCore>(rng: &mut R) -> Result<(SecretKey, PublicKey), Error>
89{
90	let keys = keypair(rng).map_err(|_| Error::KeyCreationFailed)?;
91
92	Ok((keys.secret, keys.public))
93}
94
95pub(super) fn encrypt_internally<R: CryptoRng + RngCore>(receiver_pub: &PublicKey, data: &[u8], rng: &mut R) -> Result<Vec<u8>, Error>
96{
97	let (ciphertext, shared_secret_alice) = encapsulate(receiver_pub, rng).map_err(|_| Error::EncryptionFailed)?;
98
99	let encrypted = aes_encrypt(&shared_secret_alice, data)?;
100
101	let mut cipher_text = Vec::with_capacity(KYBER_CIPHERTEXTBYTES + encrypted.len());
102	cipher_text.extend_from_slice(&ciphertext);
103	cipher_text.extend_from_slice(&encrypted);
104
105	Ok(cipher_text)
106}
107
108pub(super) fn decrypt_internally(receiver_sec: &SecretKey, ciphertext: &[u8]) -> Result<Vec<u8>, Error>
109{
110	if ciphertext.len() <= KYBER_CIPHERTEXTBYTES {
111		return Err(Error::DecryptionFailedCiphertextShort);
112	}
113
114	let shared_secret_bob = decapsulate(&ciphertext[..KYBER_CIPHERTEXTBYTES], receiver_sec).map_err(|_| Error::DecryptionFailed)?;
115
116	let encrypted = &ciphertext[KYBER_CIPHERTEXTBYTES..];
117	let decrypted = aes_decrypt(&shared_secret_bob, encrypted)?;
118
119	Ok(decrypted)
120}
121
122#[cfg(test)]
123mod test
124{
125	use core::str::from_utf8;
126
127	use sentc_crypto_core::Error::{DecryptionFailed, DecryptionFailedCiphertextShort};
128
129	use super::*;
130
131	#[test]
132	fn test_key_gen()
133	{
134		let _ = KyberKeyPair::generate_static_keypair().unwrap();
135	}
136
137	#[test]
138	fn test_encrypt_and_decrypt()
139	{
140		let (sk, pk) = KyberKeyPair::generate_static_keypair().unwrap();
141
142		let text = "Hello world üöäéèßê°";
143
144		let encrypted = pk.encrypt(text.as_bytes()).unwrap();
145
146		let decrypted = sk.decrypt(&encrypted).unwrap();
147
148		assert_eq!(text.as_bytes(), decrypted);
149
150		let decrypted_text = from_utf8(&decrypted).unwrap();
151
152		assert_eq!(text, decrypted_text);
153	}
154
155	#[test]
156	fn test_not_decrypt_with_wrong_key()
157	{
158		let (_sk, pk) = KyberKeyPair::generate_static_keypair().unwrap();
159
160		let (sk, _pk) = KyberKeyPair::generate_static_keypair().unwrap();
161
162		let text = "Hello world üöäéèßê°";
163
164		let encrypted = pk.encrypt(text.as_bytes()).unwrap();
165
166		let decrypted_result = sk.decrypt(&encrypted);
167
168		assert!(matches!(decrypted_result, Err(DecryptionFailed)));
169	}
170
171	#[test]
172	fn test_not_decrypt_with_wrong_ciphertext()
173	{
174		let (sk, pk) = KyberKeyPair::generate_static_keypair().unwrap();
175
176		let text = "Hello world üöäéèßê°";
177
178		let encrypted = pk.encrypt(text.as_bytes()).unwrap();
179
180		//too short ciphertext: text must be min 32 long, output was 88 long
181		let encrypted = &encrypted[..(encrypted.len() - 56)];
182
183		let decrypted_result = sk.decrypt(encrypted);
184
185		assert!(matches!(decrypted_result, Err(DecryptionFailedCiphertextShort)));
186	}
187}