1use hex::decode;
2use hkdf::Hkdf;
3use rand::{thread_rng};
5use secp256k1::{util::FULL_PUBLIC_KEY_SIZE, PublicKey, SecretKey};
6use sha2::Sha256;
7
8const AES_IV_LENGTH: usize = 16;
9const AES_TAG_LENGTH: usize = 16;
10const AES_IV_PLUS_TAG_LENGTH: usize = AES_IV_LENGTH + AES_TAG_LENGTH;
11const EMPTY_BYTES: [u8; 0] = [];
12
13pub type AesKey = [u8; 48];
14
15pub fn generate_keypair() -> (SecretKey, PublicKey) {
16 let sk = SecretKey::random(&mut thread_rng());
17 (sk.clone(), PublicKey::from_secret_key(&sk))
18}
19
20pub fn remove0x(hex: &str) -> &str {
21 if hex.starts_with("0x") || hex.starts_with("0X") {
22 return &hex[2..];
23 }
24 hex
25}
26
27pub fn decode_hex(hex: &str) -> Vec<u8> {
28 decode(remove0x(hex)).unwrap()
29}
30
31pub fn encapsulate(sk: &SecretKey, peer_pk: &PublicKey) -> AesKey {
32 let mut shared_point = peer_pk.clone();
33 shared_point.tweak_mul_assign(&sk).unwrap();
34
35 let mut master = Vec::with_capacity(FULL_PUBLIC_KEY_SIZE * 2);
36 master.extend(PublicKey::from_secret_key(&sk).serialize().iter());
37 master.extend(shared_point.serialize().iter());
38
39 hkdf_sha256(master.as_slice())
40}
41
42pub fn decapsulate(pk: &PublicKey, peer_sk: &SecretKey) -> AesKey {
43 let mut shared_point = pk.clone();
44 shared_point.tweak_mul_assign(&peer_sk).unwrap();
45
46 let mut master = Vec::with_capacity(FULL_PUBLIC_KEY_SIZE * 2);
47 master.extend(pk.serialize().iter());
48 master.extend(shared_point.serialize().iter());
49
50 hkdf_sha256(master.as_slice())
51}
52
53pub fn aes_encrypt(_key: &[u8], _msg: &[u8]) -> Option<Vec<u8>> {
54 unimplemented!();
56 }
76
77pub fn aes_decrypt(_key: &[u8], _encrypted_msg: &[u8]) -> Option<Vec<u8>> {
78 unimplemented!();
80
81 }
95
96fn hkdf_sha256(master: &[u8]) -> AesKey {
98 let h = Hkdf::<Sha256>::new(None, master);
99 let mut out = [0u8; 48];
100 h.expand(&EMPTY_BYTES, &mut out).unwrap();
101 out
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107 use secp256k1::Error;
108
109 #[test]
110 fn test_remove_0x_decode_hex() {
111 assert_eq!(remove0x("0x0011"), "0011");
112 assert_eq!(remove0x("0X0011"), "0011");
113 assert_eq!(remove0x("0011"), "0011");
114 assert_eq!(decode_hex("0x0011"), [0u8, 17u8]);
115 }
116
117 #[test]
118 fn test_generate_keypair() {
119 let (sk1, pk1) = generate_keypair();
120 let (sk2, pk2) = generate_keypair();
121 assert_ne!(sk1, sk2);
122 assert_ne!(pk1, pk2);
123 }
124
125 #[test]
126 fn test_attempt_to_decrypt_invalid_message() {
127 assert!(aes_decrypt(&[], &[]).is_none());
128
129 assert!(aes_decrypt(&[], &[0; AES_IV_LENGTH]).is_none());
130 }
131
132 #[test]
133 fn test_aes_random_key() {
134 let text = b"this is a text";
135 let mut key = [0u8; 32];
136 thread_rng().fill(&mut key);
137
138 assert_eq!(
139 text,
140 aes_decrypt(&key, aes_encrypt(&key, text).unwrap().as_slice())
141 .unwrap()
142 .as_slice()
143 );
144
145 let utf8_text = "😀😀😀😀".as_bytes();
146 assert_eq!(
147 utf8_text,
148 aes_decrypt(&key, aes_encrypt(&key, utf8_text).unwrap().as_slice())
149 .unwrap()
150 .as_slice()
151 );
152 }
153
154 #[test]
155 fn test_aes_known_key() {
156 let text = b"helloworld";
157 let key = decode_hex("0000000000000000000000000000000000000000000000000000000000000000");
158 let iv = decode_hex("f3e1ba810d2c8900b11312b7c725565f");
159 let tag = decode_hex("ec3b71e17c11dbe31484da9450edcf6c");
160 let encrypted = decode_hex("02d2ffed93b856f148b9");
161
162 let mut cipher_text = Vec::new();
163 cipher_text.extend(iv);
164 cipher_text.extend(tag);
165 cipher_text.extend(encrypted);
166
167 assert_eq!(text, aes_decrypt(&key, &cipher_text).unwrap().as_slice());
168 }
169
170 #[test]
171 fn test_valid_secret() {
172 let zero = [0u8; 32];
174 assert_eq!(SecretKey::parse_slice(&zero).err().unwrap(), Error::InvalidSecretKey);
175
176 let group_order_minus_1 = decode_hex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140");
177 SecretKey::parse_slice(&group_order_minus_1).unwrap();
178
179 let group_order = decode_hex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");
180 assert_eq!(
181 SecretKey::parse_slice(&group_order).err().unwrap(),
182 Error::InvalidSecretKey
183 );
184 }
185
186 #[test]
187 fn test_hkdf() {
188 let text = b"secret";
189
190 let h = Hkdf::<Sha256>::new(None, text);
191 let mut out = [0u8; 32];
192 let r = h.expand(&EMPTY_BYTES, &mut out);
193
194 assert!(r.is_ok());
195 assert_eq!(
196 out.to_vec(),
197 decode_hex("2f34e5ff91ec85d53ca9b543683174d0cf550b60d5f52b24c97b386cfcf6cbbf")
198 );
199
200 let mut two = [0u8; 32];
201 let mut three = [0u8; 32];
202 two[31] = 2u8;
203 three[31] = 3u8;
204
205 let sk2 = SecretKey::parse_slice(&two).unwrap();
206 let pk2 = PublicKey::from_secret_key(&sk2);
207 let sk3 = SecretKey::parse_slice(&three).unwrap();
208 let pk3 = PublicKey::from_secret_key(&sk3);
209
210 assert_eq!(encapsulate(&sk2, &pk3), decapsulate(&pk2, &sk3));
211 assert_eq!(
212 encapsulate(&sk2, &pk3).to_vec(),
213 decode_hex("6f982d63e8590c9d9b5b4c1959ff80315d772edd8f60287c9361d548d5200f82")
214 );
215 }
216}