sentc_crypto_std_keys/core/asym/
pqc_kyber.rs1use 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
86pub(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 let encrypted = &encrypted[..(encrypted.len() - 56)];
182
183 let decrypted_result = sk.decrypt(encrypted);
184
185 assert!(matches!(decrypted_result, Err(DecryptionFailedCiphertextShort)));
186 }
187}