diff --git a/src/lib.rs b/src/lib.rs index 5a29265..2a94af8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,87 @@ -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] +use std::default::Default; -use std::slice; +mod unsafe_bindings; -include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +macro_rules! reexport_const { + ( $type_name:ident, $struct_name:ident ) => { + pub const $type_name: usize = unsafe_bindings::$type_name as usize; -#[no_mangle] -pub unsafe extern "C" fn randombytes(buf: *mut u8, len: libc::size_t) -> libc::c_int { - let buf = slice::from_raw_parts_mut(buf, len); - getrandom::fill(buf).expect("RNG Failed"); - 0 + pub struct $struct_name([u8; $type_name]); + + impl Default for $struct_name { + fn default() -> Self { + Self([0u8; $type_name]) + } + } + }; +} + +reexport_const!(MLKEM512_SECRETKEYBYTES, MLKEM512Secretkey); +reexport_const!(MLKEM512_PUBLICKEYBYTES, MLKEM512PublicKey); +reexport_const!(MLKEM512_CIPHERTEXTBYTES, MLKEM512Ciphertext); +reexport_const!(MLKEM512_BYTES, MLKEM512SharedSecret); + +reexport_const!(MLKEM768_SECRETKEYBYTES, MLKEM768SecretKey); +reexport_const!(MLKEM768_PUBLICKEYBYTES, MLKEM768PublicKey); +reexport_const!(MLKEM768_CIPHERTEXTBYTES, MLKEM768Ciphertext); +reexport_const!(MLKEM768_BYTES, MLKEM768SharedSecret); + +reexport_const!(MLKEM1024_SECRETKEYBYTES, MLKEM1024SecretKey); +reexport_const!(MLKEM1024_PUBLICKEYBYTES, MLKEM1024PublicKey); +reexport_const!(MLKEM1024_CIPHERTEXTBYTES, MLKEM1024Ciphertext); +reexport_const!(MLKEM1024_BYTES, MLKEM1024SharedSecret); + +pub fn mlkem768_keypair() -> Option<(MLKEM768SecretKey, MLKEM768PublicKey)> { + let mut sk = MLKEM768SecretKey::default(); + let mut pk = MLKEM768PublicKey::default(); + + let success = unsafe { + unsafe_bindings::PQCP_MLKEM_NATIVE_MLKEM768_keypair(pk.0.as_mut_ptr(), sk.0.as_mut_ptr()) + }; + + if success == 0 { + Some((sk, pk)) + } else { + None + } +} + +pub fn mlkem768_enc(pk: &MLKEM768PublicKey) -> Option<(MLKEM768Ciphertext, MLKEM768SharedSecret)> { + let mut ct = MLKEM768Ciphertext::default(); + let mut ss = MLKEM768SharedSecret::default(); + + let success = unsafe { + unsafe_bindings::PQCP_MLKEM_NATIVE_MLKEM768_enc( + ct.0.as_mut_ptr(), + ss.0.as_mut_ptr(), + pk.0.as_ptr(), + ) + }; + + if success == 0 { + Some((ct, ss)) + } else { + None + } +} + +pub fn mlkem768_dec( + sk: &MLKEM768SecretKey, + ct: &MLKEM768Ciphertext, +) -> Option { + let mut ss = MLKEM768SharedSecret::default(); + + let success = unsafe { + unsafe_bindings::PQCP_MLKEM_NATIVE_MLKEM768_dec( + ss.0.as_mut_ptr(), + ct.0.as_ptr(), + sk.0.as_ptr(), + ) + }; + + if success == 0 { + Some(ss) + } else { + None + } } diff --git a/src/unsafe_bindings.rs b/src/unsafe_bindings.rs new file mode 100644 index 0000000..5a29265 --- /dev/null +++ b/src/unsafe_bindings.rs @@ -0,0 +1,14 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +use std::slice; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +#[no_mangle] +pub unsafe extern "C" fn randombytes(buf: *mut u8, len: libc::size_t) -> libc::c_int { + let buf = slice::from_raw_parts_mut(buf, len); + getrandom::fill(buf).expect("RNG Failed"); + 0 +}