1use chacha20poly1305::{
2 aead::{Aead, OsRng},
3 AeadCore, KeyInit, XChaCha20Poly1305, XNonce,
4};
5
6const APP_SALT: &[u8] = b"VOLTLANE.NET";
7
8pub fn generate_keypair() -> (
9 k256::ecdh::EphemeralSecret, k256::EncodedPoint, ) {
12 let private_key = k256::ecdh::EphemeralSecret::random(&mut OsRng);
13 let public_key = k256::EncodedPoint::from(private_key.public_key());
14 (private_key, public_key)
15}
16
17pub fn generate_shared_secret(
18 their_pubkey: &k256::PublicKey,
19 my_privkey: &k256::ecdh::EphemeralSecret,
20) -> k256::ecdh::SharedSecret {
21 my_privkey.diffie_hellman(their_pubkey)
22}
23
24pub fn encrypt(key: &k256::ecdh::SharedSecret, data: Vec<u8>) -> Vec<u8> {
25 let hkdf = key.extract::<k256::sha2::Sha256>(Some(APP_SALT));
26 let mut okm = [0u8; 32];
27 hkdf.expand(APP_SALT, &mut okm).unwrap();
28 let cipher = XChaCha20Poly1305::new(&okm.into());
29 let nonce = XChaCha20Poly1305::generate_nonce(&mut OsRng);
30 let mut result = cipher.encrypt(&nonce, data.as_ref()).unwrap();
31 result.extend_from_slice(&nonce);
32 result
33}
34
35pub fn decrypt(
36 key: &k256::ecdh::SharedSecret,
37 data: Vec<u8>,
38) -> Result<Vec<u8>, chacha20poly1305::Error> {
39 let hkdf = key.extract::<k256::sha2::Sha256>(Some(APP_SALT));
40 let mut okm = [0u8; 32];
41 hkdf.expand(APP_SALT, &mut okm).unwrap();
42 let cipher = XChaCha20Poly1305::new(&okm.into());
43 let (msg, nonce) = data.split_at(data.len() - 24);
45 let nonce = XNonce::from_slice(&nonce);
46 cipher.decrypt(nonce, msg)
47}
48
49pub fn pubkey_from_bytes(bytes: &[u8]) -> k256::PublicKey {
50 k256::PublicKey::from_sec1_bytes(bytes).unwrap()
51}
52
53pub mod easy {
59 pub fn random_bytes(size: usize) -> Vec<u8> {
60 use chacha20poly1305::aead::OsRng;
61 use k256::elliptic_curve::rand_core::RngCore;
62 let mut bytes = vec![0u8; size];
63 let mut rng = OsRng {};
64 rng.fill_bytes(&mut bytes);
65 bytes
66 }
67
68 pub type PubKey = k256::PublicKey;
69
70 pub fn pubkey_from_bytes(bytes: &[u8]) -> Result<PubKey, k256::elliptic_curve::Error> {
71 k256::PublicKey::from_sec1_bytes(bytes)
72 }
73
74 pub struct Keys {
75 pub pubkey: k256::PublicKey,
76 privkey: k256::ecdh::EphemeralSecret,
77 }
78
79 impl Keys {
80 pub fn new() -> Self {
81 let (privkey, pubkey) = super::generate_keypair();
82 Self {
83 pubkey: k256::PublicKey::from_sec1_bytes(pubkey.as_bytes()).unwrap(),
84 privkey,
85 }
86 }
87
88 pub fn create_encryption(&self, their_pubkey: &PubKey) -> Encryption {
90 let shared_secret = super::generate_shared_secret(&their_pubkey, &self.privkey);
91 Encryption { shared_secret }
92 }
93
94 pub fn pubkey_to_bytes(&self) -> Vec<u8> {
95 self.pubkey.to_sec1_bytes().to_vec()
96 }
97 }
98
99 pub struct Encryption {
100 shared_secret: k256::ecdh::SharedSecret,
101 }
102
103 impl Encryption {
104 pub fn encrypt(&self, data: Vec<u8>) -> Vec<u8> {
107 super::encrypt(&self.shared_secret, data)
108 }
109
110 pub fn decrypt(&self, data: Vec<u8>) -> Result<Vec<u8>, chacha20poly1305::Error> {
111 super::decrypt(&self.shared_secret, data)
112 }
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119
120 #[test]
121 fn test_encrypt_decrypt() {
122 let (my_privkey, my_pubkey) = generate_keypair();
123 let (their_privkey, their_pubkey) = generate_keypair();
124
125 let their_pubkey = k256::PublicKey::from_sec1_bytes(&their_pubkey.as_bytes()).unwrap();
126
127 let my_shared_secret = generate_shared_secret(&their_pubkey, &my_privkey);
128 let data = b"Hello, world!".to_vec();
129
130 let my_pubkey = k256::PublicKey::from_sec1_bytes(&my_pubkey.as_bytes()).unwrap();
131 let their_shared_secret = generate_shared_secret(&my_pubkey, &their_privkey);
132
133 let encrypted_data = encrypt(&my_shared_secret, data.clone());
134 let decrypted_data = decrypt(&their_shared_secret, encrypted_data.clone()).unwrap();
135
136 assert_eq!(data, decrypted_data);
137 }
138
139 #[test]
140 fn test_easy_encrypt_decrypt() {
141 let keys = easy::Keys::new();
142 let their_keys = easy::Keys::new();
143 let data = b"Hello, world!".to_vec();
144
145 let encryption = keys.create_encryption(&their_keys.pubkey);
146 let encrypted_data = encryption.encrypt(data.clone());
147
148 let their_encryption = their_keys.create_encryption(&keys.pubkey);
149 let decrypted_data = their_encryption.decrypt(encrypted_data).unwrap();
150
151 assert_eq!(data, decrypted_data);
152 }
153}