use super::common::{PcStatus, guard, slice};
use crate::ec::x25519::X25519PrivateKey;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pc_x25519(scalar: *const u8, peer: *const u8, out: *mut u8) -> PcStatus {
guard(|| {
let (Some(s), Some(p)) = (unsafe { slice(scalar, 32) }, unsafe { slice(peer, 32) }) else {
return PcStatus::NullPointer;
};
if out.is_null() {
return PcStatus::NullPointer;
}
let scalar: [u8; 32] = s.try_into().unwrap();
let peer: [u8; 32] = p.try_into().unwrap();
let sk = X25519PrivateKey::from_bytes(scalar);
match sk.diffie_hellman(&peer) {
Ok(secret) => {
unsafe { core::ptr::copy_nonoverlapping(secret.as_ptr(), out, 32) };
PcStatus::Ok
}
Err(_) => PcStatus::Verification,
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pc_x25519_public(scalar: *const u8, out: *mut u8) -> PcStatus {
guard(|| {
let Some(s) = (unsafe { slice(scalar, 32) }) else {
return PcStatus::NullPointer;
};
if out.is_null() {
return PcStatus::NullPointer;
}
let scalar: [u8; 32] = s.try_into().unwrap();
let sk = X25519PrivateKey::from_bytes(scalar);
let pk = sk.public_key();
unsafe { core::ptr::copy_nonoverlapping(pk.as_ptr(), out, 32) };
PcStatus::Ok
})
}