1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use bigint::{BigUint, RandBigInt};
use num::FromPrimitive;
use num::{One,Zero};
use rand;
use asymmetric::utils::modular::Power;
pub const RFC2409_PRIME_768: [u8; 96] = [
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
];
pub const RFC2409_GENERATOR_768: u64 = 2;
pub const RFC2409_PRIME_1024: [u8; 128] = [
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
];
pub const RFC2409_GENERATOR_1024: u64 = 2;
pub struct DHPublicKey {
pub_key: BigUint,
}
pub struct DHPrivateKey<'a> {
params: &'a DHParameters,
priv_key: BigUint,
}
impl DHPublicKey {
pub fn new(pub_key: BigUint) -> DHPublicKey {
DHPublicKey {
pub_key: pub_key
}
}
pub fn key(&self) -> BigUint {
self.pub_key.clone()
}
}
impl<'a> DHPrivateKey<'a> {
pub fn key(&self) -> BigUint {
self.priv_key.clone()
}
pub fn public_key(&self) -> DHPublicKey {
let pub_key = (&self.params.g).pow_mod(&self.priv_key, &self.params.p);
DHPublicKey {
pub_key: pub_key
}
}
pub fn exchange(&self, pub_key: &DHPublicKey) -> BigUint {
(&pub_key.pub_key).pow_mod(&self.priv_key, &self.params.p)
}
}
pub struct DHParameters {
p: BigUint,
g: BigUint,
}
impl DHParameters {
pub fn new(p: &[u8], g: u64) -> DHParameters {
DHParameters {
p: BigUint::from_bytes_be(p),
g: BigUint::from_u64(g).expect("Could not convert g")
}
}
pub fn key_length(&self) -> usize {
self.p.bits()
}
pub fn private_key(&self) -> DHPrivateKey {
let mut rng = match rand::OsRng::new() {
Ok(g) => g,
Err(e) => panic!("Could not load the OS' RNG! Error: {}", e)
};
let mut priv_key = rng.gen_biguint(self.key_length());
while (priv_key == BigUint::one()) || (priv_key == BigUint::zero()) {
priv_key = rng.gen_biguint(self.key_length());
}
DHPrivateKey {
params: self,
priv_key: priv_key
}
}
}