phoenix_core/encryption/
aes.rs1use dusk_jubjub::JubJubAffine;
8use rand::{CryptoRng, RngCore};
9
10use aes_gcm::{
11 Aes256Gcm, Key,
12 aead::{Aead, AeadCore, KeyInit},
13};
14
15use hkdf::Hkdf;
16use sha2::Sha256;
17
18use crate::Error;
19
20const NONCE_SIZE: usize = 12;
21
22pub const ENCRYPTION_EXTRA_SIZE: usize = NONCE_SIZE + 16;
25
26pub fn encrypt<R: RngCore + CryptoRng, const ENCRYPTION_SIZE: usize>(
29 shared_secret_key: &JubJubAffine,
30 salt: &[u8],
31 plaintext: &[u8],
32 rng: &mut R,
33) -> Result<[u8; ENCRYPTION_SIZE], Error> {
34 let ikm = shared_secret_key.to_bytes();
38 let info = b"Phoenix-Dusk".to_vec();
39
40 let hk = Hkdf::<Sha256>::new(Some(salt), &ikm);
41 let mut okm = [0u8; 32];
42 hk.expand(&info, &mut okm)
43 .expect("32 is a valid length for Sha256 to output");
44
45 let key = Key::<Aes256Gcm>::from_slice(&okm);
46
47 let cipher = Aes256Gcm::new(key);
48 let nonce = Aes256Gcm::generate_nonce(rng);
49 let ciphertext = cipher.encrypt(&nonce, plaintext.as_ref())?;
50
51 let mut encryption = [0u8; ENCRYPTION_SIZE];
52
53 encryption[..NONCE_SIZE].copy_from_slice(&nonce);
54 encryption[NONCE_SIZE..].copy_from_slice(&ciphertext);
55
56 Ok(encryption)
57}
58
59pub fn decrypt<const PLAINTEXT_SIZE: usize>(
62 shared_secret_key: &JubJubAffine,
63 salt: &[u8],
64 encryption: &[u8],
65) -> Result<[u8; PLAINTEXT_SIZE], Error> {
66 let ikm = shared_secret_key.to_bytes();
70 let info = b"Phoenix-Dusk".to_vec();
71
72 let hk = Hkdf::<Sha256>::new(Some(salt), &ikm);
73 let mut okm = [0u8; 32];
74 hk.expand(&info, &mut okm)
75 .expect("32 is a valid length for Sha256 to output");
76
77 let key = Key::<Aes256Gcm>::from_slice(&okm);
78
79 let nonce = &encryption[..NONCE_SIZE];
80 let ciphertext = &encryption[NONCE_SIZE..];
81
82 let cipher = Aes256Gcm::new(key);
83
84 let mut plaintext = [0u8; PLAINTEXT_SIZE];
85 plaintext.copy_from_slice(&cipher.decrypt(nonce.into(), ciphertext)?);
86
87 Ok(plaintext)
88}