1use num_bigint_dig::{BigUint, RandBigInt};
2use rand;
3
4use core::convert::TryInto;
5
6use crate::constants;
7
8pub fn unhexlify_to_bytearray<const N: usize>(prime: &str) -> [u8; N] {
14 let mut bytearray = [0; N];
15 let hex_string = prime;
16 for i in (0..hex_string.len()).step_by(2) {
17 if i > (2 * N - 2) {
18 break;
19 }
20 let substring = &hex_string[i..i + 2];
21 let z = (u8::from_str_radix(substring, 16)).unwrap();
22 bytearray[(i - (i / 2))] = z;
23 }
24 return bytearray;
25}
26
27pub fn get_dh(group: u8) -> DH {
29 if group == constants::SUPPORTED_DH_GROUPS[0] {
30 return DH::Dh5(DH5::new());
31 } else if group == constants::SUPPORTED_DH_GROUPS[1] {
32 return DH::Dh15(DH15::new());
33 } else {
34 return DH::UnSupported("UnSupported DH_GROUP");
35 }
36}
37
38#[derive(Debug, PartialEq, Clone)]
40pub enum DH {
41 Dh5(DH5),
43 Dh14(DH14),
45 Dh15(DH15),
47 Dh16(DH16),
49 Dh17(DH17),
51 Dh18(DH18),
53 UnSupported(&'static str),
55}
56#[derive(Debug, PartialEq, Clone)]
58pub struct DH5 {
59 prime_num: BigUint,
60 generator: usize,
61 exp_size: usize,
62 private_key: BigUint, public_key: BigUint,
64 shared_secret: BigUint, }
66
67impl DH5 {
68 pub fn new() -> Self {
70 DH5 {
71 prime_num: BigUint::default(),
72 generator: 0,
73 exp_size: 0,
74 private_key: BigUint::default(),
75 public_key: BigUint::default(),
76 shared_secret: BigUint::default(),
77 }
78 }
79
80 pub fn init_dh5(&mut self) {
82 let prime_byte_arr = unhexlify_to_bytearray::<192>(
83 &constants::DH_GROUP_5_PRIME
84 .replace(" ", "")
85 .replace("\n\t", ""),
86 );
87 self.prime_num = BigUint::from_bytes_be(&prime_byte_arr);
88 self.generator = constants::DH_GROUP_5_GENERATOR;
89 self.exp_size = constants::DH_GROUP_5_EXPONENT_LENGTH;
90 }
91
92 pub fn generate_private_key(&mut self) -> BigUint {
94 let mut rng = rand::thread_rng();
95 self.private_key = rng.gen_biguint((self.exp_size * 8 as usize) as usize);
96 return self.private_key.clone(); }
100
101 pub fn generate_pubic_key(&mut self) -> BigUint {
103 self.public_key = BigUint::from(self.generator).modpow(&self.private_key, &self.prime_num);
104 return self.public_key.clone(); }
106
107 pub fn compute_shared_secret(&mut self, other_public_key: BigUint) -> BigUint {
109 self.shared_secret = other_public_key.modpow(&self.private_key, &self.prime_num);
110 self.shared_secret.clone() }
112
113 pub fn encode_public_key<const N: usize>(&self) -> [u8; N] {
115 let pub_key_bytes: [u8; N] = BigUint::to_bytes_be(&self.public_key).try_into().unwrap();
116 pub_key_bytes
117 }
118
119 pub fn decode_public_key(buffer: &[u8]) -> BigUint {
121 BigUint::from_bytes_be(buffer)
122 }
123}
124
125#[derive(Debug, PartialEq, Clone)]
127pub struct DH14 {
128 prime_num: BigUint,
129 generator: usize,
130 exp_size: usize,
131 private_key: BigUint, public_key: BigUint,
133 shared_secret: BigUint, }
135
136impl DH14 {
137 pub fn new() -> Self {
139 DH14 {
140 prime_num: BigUint::default(),
141 generator: 0,
142 exp_size: 0,
143 private_key: BigUint::default(),
144 public_key: BigUint::default(),
145 shared_secret: BigUint::default(),
146 }
147 }
148
149 pub fn init_dh14(&mut self) {
151 let prime_byte_arr = unhexlify_to_bytearray::<256>(
152 &constants::DH_GROUP_14_PRIME
153 .replace(" ", "")
154 .replace("\n", "")
155 .replace("\t", ""),
156 );
157 self.prime_num = BigUint::from_bytes_le(&prime_byte_arr);
158 self.generator = constants::DH_GROUP_14_GENERATOR;
159 self.exp_size = constants::DH_GROUP_14_EXPONENT_LENGTH;
160 }
161
162 pub fn generate_private_key(&mut self) -> BigUint {
164 let mut rng = rand::thread_rng();
165 self.private_key = rng.gen_biguint((self.exp_size * 8 as usize) as usize);
166 return self.private_key.clone(); }
170
171 pub fn generate_pubic_key(&mut self) -> BigUint {
173 self.public_key = BigUint::from(self.generator).modpow(&self.private_key, &self.prime_num);
174 return self.public_key.clone(); }
176
177 pub fn compute_shared_secret(&mut self, other_public_key: BigUint) -> BigUint {
179 self.shared_secret = other_public_key.modpow(&self.private_key, &self.prime_num);
180 self.shared_secret.clone() }
182
183 pub fn encode_public_key<const N: usize>(&self) -> [u8; N] {
185 let pub_key_bytes: [u8; N] = BigUint::to_bytes_be(&self.public_key).try_into().unwrap();
186 pub_key_bytes
187 }
188
189 pub fn decode_public_key(buffer: &[u8]) -> BigUint {
191 BigUint::from_bytes_be(buffer)
192 }
193}
194
195#[derive(Debug, PartialEq, Clone)]
197pub struct DH15 {
198 prime_num: BigUint,
199 generator: usize,
200 exp_size: usize,
201 private_key: BigUint, public_key: BigUint,
203 shared_secret: BigUint, }
205
206impl DH15 {
207 pub fn new() -> Self {
209 DH15 {
210 prime_num: BigUint::default(),
211 generator: 0,
212 exp_size: 0,
213 private_key: BigUint::default(),
214 public_key: BigUint::default(),
215 shared_secret: BigUint::default(),
216 }
217 }
218
219 pub fn init_dh15(&mut self) {
221 let prime_byte_arr = unhexlify_to_bytearray::<384>(
222 &constants::DH_GROUP_15_PRIME
223 .replace(" ", "")
224 .replace("\n", "")
225 .replace("\t", ""),
226 );
227 self.prime_num = BigUint::from_bytes_le(&prime_byte_arr);
228 self.generator = constants::DH_GROUP_15_GENERATOR;
229 self.exp_size = constants::DH_GROUP_15_EXPONENT_LENGTH;
230 }
231
232 pub fn generate_private_key(&mut self) -> BigUint {
234 let mut rng = rand::thread_rng();
235 self.private_key = rng.gen_biguint((self.exp_size * 8 as usize) as usize);
236 return self.private_key.clone(); }
240
241 pub fn generate_pubic_key(&mut self) -> BigUint {
243 self.public_key = BigUint::from(self.generator).modpow(&self.private_key, &self.prime_num);
244 return self.public_key.clone(); }
246
247 pub fn compute_shared_secret(&mut self, other_public_key: BigUint) -> BigUint {
249 self.shared_secret = other_public_key.modpow(&self.private_key, &self.prime_num);
250 self.shared_secret.clone() }
252
253 pub fn encode_public_key<const N: usize>(&self) -> [u8; N] {
255 let pub_key_bytes: [u8; N] = BigUint::to_bytes_be(&self.public_key).try_into().unwrap();
256 pub_key_bytes
257 }
258
259 pub fn decode_public_key(buffer: &[u8]) -> BigUint {
261 BigUint::from_bytes_be(buffer)
262 }
263}
264
265#[derive(Debug, PartialEq, Clone)]
267pub struct DH16 {
268 prime_num: BigUint,
269 generator: usize,
270 exp_size: usize,
271 private_key: BigUint, public_key: BigUint,
273 shared_secret: BigUint, }
275
276impl DH16 {
277 pub fn new() -> Self {
279 DH16 {
280 prime_num: BigUint::default(),
281 generator: 0,
282 exp_size: 0,
283 private_key: BigUint::default(),
284 public_key: BigUint::default(),
285 shared_secret: BigUint::default(),
286 }
287 }
288
289 pub fn init_dh16(&mut self) {
291 let prime_byte_arr = unhexlify_to_bytearray::<512>(
292 &constants::DH_GROUP_16_PRIME
293 .replace(" ", "")
294 .replace("\n", "")
295 .replace("\t", ""),
296 );
297 self.prime_num = BigUint::from_bytes_le(&prime_byte_arr);
298 self.generator = constants::DH_GROUP_16_GENERATOR;
299 self.exp_size = constants::DH_GROUP_16_EXPONENT_LENGTH;
300 }
301
302 pub fn generate_private_key(&mut self) -> BigUint {
304 let mut rng = rand::thread_rng();
305 self.private_key = rng.gen_biguint((self.exp_size * 8 as usize) as usize);
306 return self.private_key.clone(); }
310
311 pub fn generate_pubic_key(&mut self) -> BigUint {
313 self.public_key = BigUint::from(self.generator).modpow(&self.private_key, &self.prime_num);
314 return self.public_key.clone(); }
316
317 pub fn compute_shared_secret(&mut self, other_public_key: BigUint) -> BigUint {
319 self.shared_secret = other_public_key.modpow(&self.private_key, &self.prime_num);
320 self.shared_secret.clone() }
322
323 pub fn encode_public_key<const N: usize>(&self) -> [u8; N] {
325 let pub_key_bytes: [u8; N] = BigUint::to_bytes_be(&self.public_key).try_into().unwrap();
326 pub_key_bytes
327 }
328
329 pub fn decode_public_key(buffer: &[u8]) -> BigUint {
331 BigUint::from_bytes_be(buffer)
332 }
333}
334
335#[derive(Debug, PartialEq, Clone)]
337pub struct DH17 {
338 prime_num: BigUint,
339 generator: usize,
340 exp_size: usize,
341 private_key: BigUint, public_key: BigUint,
343 shared_secret: BigUint, }
345
346impl DH17 {
347 pub fn new() -> Self {
349 DH17 {
350 prime_num: BigUint::default(),
351 generator: 0,
352 exp_size: 0,
353 private_key: BigUint::default(),
354 public_key: BigUint::default(),
355 shared_secret: BigUint::default(),
356 }
357 }
358
359 pub fn init_dh17(&mut self) {
361 let prime_byte_arr = unhexlify_to_bytearray::<768>(
362 &constants::DH_GROUP_17_PRIME
363 .replace(" ", "")
364 .replace("\n", "")
365 .replace("\t", ""),
366 );
367 self.prime_num = BigUint::from_bytes_le(&prime_byte_arr);
368 self.generator = constants::DH_GROUP_17_GENERATOR;
369 self.exp_size = constants::DH_GROUP_17_EXPONENT_LENGTH;
370 }
371
372 pub fn generate_private_key(&mut self) -> BigUint {
374 let mut rng = rand::thread_rng();
375 self.private_key = rng.gen_biguint((self.exp_size * 8 as usize) as usize);
376 return self.private_key.clone(); }
380
381 pub fn generate_pubic_key(&mut self) -> BigUint {
383 self.public_key = BigUint::from(self.generator).modpow(&self.private_key, &self.prime_num);
384 return self.public_key.clone(); }
386
387 pub fn compute_shared_secret(&mut self, other_public_key: BigUint) -> BigUint {
389 self.shared_secret = other_public_key.modpow(&self.private_key, &self.prime_num);
390 self.shared_secret.clone() }
392
393 pub fn encode_public_key<const N: usize>(&self) -> [u8; N] {
395 let pub_key_bytes: [u8; N] = BigUint::to_bytes_be(&self.public_key).try_into().unwrap();
396 pub_key_bytes
397 }
398
399 pub fn decode_public_key(buffer: &[u8]) -> BigUint {
401 BigUint::from_bytes_be(buffer)
402 }
403}
404
405#[derive(Debug, PartialEq, Clone)]
407pub struct DH18 {
408 prime_num: BigUint,
409 generator: usize,
410 exp_size: usize,
411 private_key: BigUint, public_key: BigUint,
413 shared_secret: BigUint, }
415
416impl DH18 {
417 pub fn new() -> Self {
419 DH18 {
420 prime_num: BigUint::default(),
421 generator: 0,
422 exp_size: 0,
423 private_key: BigUint::default(),
424 public_key: BigUint::default(),
425 shared_secret: BigUint::default(),
426 }
427 }
428
429 pub fn init_dh18(&mut self) {
431 let prime_byte_arr = unhexlify_to_bytearray::<1024>(
432 &constants::DH_GROUP_18_PRIME
433 .replace(" ", "")
434 .replace("\n", "")
435 .replace("\t", ""),
436 );
437 self.prime_num = BigUint::from_bytes_le(&prime_byte_arr);
438 self.generator = constants::DH_GROUP_18_GENERATOR;
439 self.exp_size = constants::DH_GROUP_18_EXPONENT_LENGTH;
440 }
441
442 pub fn generate_private_key(&mut self) -> BigUint {
444 let mut rng = rand::thread_rng();
445 self.private_key = rng.gen_biguint((self.exp_size * 8 as usize) as usize);
446 return self.private_key.clone(); }
450
451 pub fn generate_pubic_key(&mut self) -> BigUint {
453 self.public_key = BigUint::from(self.generator).modpow(&self.private_key, &self.prime_num);
454 return self.public_key.clone(); }
456
457 pub fn compute_shared_secret(&mut self, other_public_key: BigUint) -> BigUint {
459 self.shared_secret = other_public_key.modpow(&self.private_key, &self.prime_num);
460 self.shared_secret.clone() }
462
463 pub fn encode_public_key<const N: usize>(&self) -> [u8; N] {
465 let pub_key_bytes: [u8; N] = BigUint::to_bytes_be(&self.public_key).try_into().unwrap();
466 pub_key_bytes
467 }
468
469 pub fn decode_public_key(buffer: &[u8]) -> BigUint {
471 BigUint::from_bytes_be(buffer)
472 }
473}