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
pub mod consts {
/// Private Key Size (64 bytes)
pub const X25519_PRIVATE_KEY_BYTELEN: usize = 32;
/// Public Key Size (32 bytes)
pub const X25519_PUBLIC_KEY_BYTELEN: usize = 32;
/// Shared Secret Size (32 bytes)
pub const X25519_SHARED_SECRET_BYTELEN: usize = 32;
}
pub mod algorithms {
unsafe extern "C" {
/// This function generates an x25519 keypair.
/// Parameters:
/// - pk (Public Key) <- mutable raw pointer to an array of 32 unsigned bytes
/// - sk (Private Key) <- mutable raw pointer to an array of 32 unsigned bytes
pub unsafe fn lib25519_dh_x25519_keypair(pk: *mut u8, sk: *mut u8);
// This function performs an Elliptic Curve Diffie-Hellman Key Exchange
/// and stores the output in `k`
/// Parameters:
/// - k (Shared Secret (output)) <- mutable raw pointer to an array of 32 unsigned bytes
/// - pk (Public Key) <- mutable raw pointer to an array of 32 unsigned bytes
/// - sk (Private Key) <- mutable raw pointer to an array of 32 unsigned bytes
pub unsafe fn lib25519_dh_x25519(k: *mut u8, pk: *const u8, sk: *const u8);
}
}
#[cfg(test)]
mod tests {
use crate::x25519::{
algorithms::{lib25519_dh_x25519, lib25519_dh_x25519_keypair},
consts::{
X25519_PRIVATE_KEY_BYTELEN, X25519_PUBLIC_KEY_BYTELEN, X25519_SHARED_SECRET_BYTELEN,
},
};
#[test]
fn test_key_exchange() {
// Allocate Memory for Private Keys
let mut sk_a: [u8; X25519_PRIVATE_KEY_BYTELEN] = [0; X25519_PRIVATE_KEY_BYTELEN];
let mut sk_b: [u8; X25519_PRIVATE_KEY_BYTELEN] = [0; X25519_PRIVATE_KEY_BYTELEN];
// Allocate Memory for Public Keys
let mut pk_a: [u8; X25519_PUBLIC_KEY_BYTELEN] = [0; X25519_PUBLIC_KEY_BYTELEN];
let mut pk_b: [u8; X25519_PUBLIC_KEY_BYTELEN] = [0; X25519_PUBLIC_KEY_BYTELEN];
// Allocate Memory for Shared Secrets
let mut shared_secret_a: [u8; X25519_SHARED_SECRET_BYTELEN] =
[0; X25519_SHARED_SECRET_BYTELEN];
let mut shared_secret_b: [u8; X25519_SHARED_SECRET_BYTELEN] =
[0; X25519_SHARED_SECRET_BYTELEN];
unsafe {
// Generate Keypairs
lib25519_dh_x25519_keypair(pk_a.as_mut_ptr(), sk_a.as_mut_ptr());
lib25519_dh_x25519_keypair(pk_b.as_mut_ptr(), sk_b.as_mut_ptr());
// Perform Key Exchange (twice)
lib25519_dh_x25519(shared_secret_a.as_mut_ptr(), pk_b.as_ptr(), sk_a.as_ptr());
lib25519_dh_x25519(shared_secret_b.as_mut_ptr(), pk_a.as_ptr(), sk_b.as_ptr());
};
// Check if the result of both key exchanges is the same
assert_eq!(shared_secret_a, shared_secret_b);
}
}