use openssl::{derive, pkey};
use crate::{PrivateKey, PublicKey};
impl PublicKey for pkey::PKey<pkey::Public> {
fn to_bytes(&self) -> [u8; 32] {
self.raw_public_key()
.expect("an X25519 key should be convertible to bytes")
.try_into()
.expect("raw public key should be 32 bytes long")
}
}
impl PrivateKey for pkey::PKey<pkey::Private> {
type PublicKey = pkey::PKey<pkey::Public>;
fn dh(&self, theirs: &Self::PublicKey) -> [u8; 32] {
let mut deriver = derive::Deriver::new(self)
.expect("should be able to create a deriver from an X25519 key");
deriver
.set_peer(theirs)
.expect("should be able to set an X25519 public key as peer");
let mut secret = [0u8; 32];
let n = deriver
.derive(&mut secret)
.expect("should be able to derive shared secret");
assert_eq!(n, 32);
secret
}
fn public_key(&self) -> Self::PublicKey {
let b: [u8; 32] = self
.raw_public_key()
.expect("an X25519 key should be convertible to bytes")
.try_into()
.expect("raw public key should be 32 bytes long");
pkey::PKey::public_key_from_raw_bytes(&b, pkey::Id::X25519).expect("TODO")
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::{run_vector_1, run_vector_2};
fn load_keypair(b: [u8; 32]) -> (pkey::PKey<pkey::Private>, pkey::PKey<pkey::Public>) {
let secret = pkey::PKey::private_key_from_raw_bytes(&b, pkey::Id::X25519).unwrap();
let public = secret.public_key();
(secret, public)
}
#[test]
fn test_vector_1() {
run_vector_1(&load_keypair);
}
#[test]
fn test_vector_2() {
run_vector_2(&load_keypair);
}
}