101 lines
2.6 KiB
Rust
101 lines
2.6 KiB
Rust
use core::fmt::{Debug, Formatter, Result};
|
|
use rand_core::OsRng;
|
|
use serde::{Deserialize, Serialize};
|
|
use x25519_dalek::{PublicKey, SharedSecret, StaticSecret};
|
|
|
|
#[derive(Deserialize, Serialize, Clone)]
|
|
pub struct DhKeyPair {
|
|
pub private_key: StaticSecret,
|
|
pub public_key: PublicKey,
|
|
}
|
|
|
|
impl PartialEq for DhKeyPair {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
if self.private_key.to_bytes() != other.private_key.to_bytes() {
|
|
return false;
|
|
}
|
|
if self.public_key != other.public_key {
|
|
return false;
|
|
}
|
|
true
|
|
}
|
|
}
|
|
|
|
impl Debug for DhKeyPair {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
f.debug_struct("DhKeyPair")
|
|
.field("private_key", self.private_key.as_bytes())
|
|
.field("public_key", self.public_key.as_bytes())
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl Default for DhKeyPair {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl DhKeyPair {
|
|
pub fn new() -> Self {
|
|
let secret = StaticSecret::random_from_rng(OsRng);
|
|
let public = PublicKey::from(&secret);
|
|
DhKeyPair {
|
|
private_key: secret,
|
|
public_key: public,
|
|
}
|
|
}
|
|
|
|
pub fn key_agreement(&self, public_key: &PublicKey) -> SharedSecret {
|
|
self.private_key.diffie_hellman(public_key)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub fn gen_shared_secret() -> SharedSecret {
|
|
let alice_pair = DhKeyPair::new();
|
|
let bob_pair = DhKeyPair::new();
|
|
alice_pair.key_agreement(&bob_pair.public_key)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::dh::DhKeyPair;
|
|
|
|
#[test]
|
|
fn key_generation() {
|
|
let pair_1 = DhKeyPair::new();
|
|
let pair_2 = DhKeyPair::new();
|
|
assert_ne!(pair_1, pair_2)
|
|
}
|
|
|
|
#[test]
|
|
fn key_agreement() {
|
|
let alice_pair = DhKeyPair::new();
|
|
let bob_pair = DhKeyPair::new();
|
|
let alice_shared_secret = alice_pair.key_agreement(&bob_pair.public_key);
|
|
let bob_shared_secret = bob_pair.key_agreement(&alice_pair.public_key);
|
|
assert_eq!(alice_shared_secret.as_bytes(), bob_shared_secret.as_bytes())
|
|
}
|
|
|
|
#[test]
|
|
fn nq_key_pair() {
|
|
let key_pair1 = DhKeyPair::new();
|
|
let mut key_pair2 = DhKeyPair::new();
|
|
key_pair2.private_key = key_pair1.private_key.clone();
|
|
assert_ne!(key_pair1, key_pair2)
|
|
}
|
|
|
|
#[test]
|
|
fn eq_key_pair() {
|
|
let key_pair1 = DhKeyPair::new();
|
|
let key_pair2 = key_pair1.clone();
|
|
assert_eq!(key_pair1, key_pair2)
|
|
}
|
|
|
|
#[test]
|
|
fn test_format() {
|
|
let key_pair = DhKeyPair::default();
|
|
let _str = alloc::format!("{:?}", key_pair);
|
|
}
|
|
}
|