feat: add bindings for level 2 and 4; generate randomness from provided CSRNG
This commit is contained in:
60
Cargo.lock
generated
60
Cargo.lock
generated
@@ -69,18 +69,6 @@ version = "1.15.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "getrandom"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"wasi",
|
|
||||||
"windows-targets",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "glob"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@@ -141,9 +129,9 @@ name = "mlkem-native-rs"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"getrandom",
|
|
||||||
"libc",
|
|
||||||
"make-cmd",
|
"make-cmd",
|
||||||
|
"rand_core",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -184,6 +172,12 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
@@ -236,21 +230,32 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasi"
|
|
||||||
version = "0.13.3+wasi-0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
|
|
||||||
dependencies = [
|
|
||||||
"wit-bindgen-rt",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
@@ -314,12 +319,3 @@ name = "windows_x86_64_msvc"
|
|||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wit-bindgen-rt"
|
|
||||||
version = "0.33.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getrandom = "0.3.1"
|
rand_core = "0.9.3"
|
||||||
libc = "0.2.171"
|
thiserror = "2.0.12"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
bindgen = "0.71.1"
|
bindgen = "0.71.1"
|
||||||
|
|||||||
49
build.rs
49
build.rs
@@ -2,25 +2,19 @@ use std::env;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// This is the directory where the `c` library is located.
|
|
||||||
let libdir_path = PathBuf::from("mlkem-native")
|
let libdir_path = PathBuf::from("mlkem-native")
|
||||||
// Canonicalize the path as `rustc-link-search` requires an absolute
|
|
||||||
// path.
|
|
||||||
.canonicalize()
|
.canonicalize()
|
||||||
.expect("cannot canonicalize path");
|
.expect("cannot canonicalize path");
|
||||||
|
|
||||||
// This is the path to the `c` headers file.
|
|
||||||
let headers_path = libdir_path.join("mlkem/mlkem_native.h");
|
let headers_path = libdir_path.join("mlkem/mlkem_native.h");
|
||||||
let headers_path_str = headers_path.to_str().expect("Path is not a valid string");
|
let headers_path_str = headers_path.to_str().expect("Path is not a valid string");
|
||||||
|
|
||||||
// Tell cargo to look for shared libraries in the specified directory
|
|
||||||
println!(
|
println!(
|
||||||
"cargo:rustc-link-search={}",
|
"cargo:rustc-link-search={}",
|
||||||
libdir_path.join("test/build").to_str().unwrap()
|
libdir_path.join("test/build").to_str().unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Tell cargo to tell rustc to link our `hello` library. Cargo will
|
println!("cargo:rustc-link-lib=mlkem512");
|
||||||
// automatically know it must look for a `libhello.a` file.
|
|
||||||
println!("cargo:rustc-link-lib=mlkem768");
|
println!("cargo:rustc-link-lib=mlkem768");
|
||||||
println!("cargo:rustc-link-lib=mlkem1024");
|
println!("cargo:rustc-link-lib=mlkem1024");
|
||||||
|
|
||||||
@@ -37,24 +31,39 @@ fn main() {
|
|||||||
panic!("could not compile mlkem-native");
|
panic!("could not compile mlkem-native");
|
||||||
}
|
}
|
||||||
|
|
||||||
// The bindgen::Builder is the main entry point
|
let bindings_level2 = bindgen::Builder::default()
|
||||||
// to bindgen, and lets you build up options for
|
|
||||||
// the resulting bindings.
|
|
||||||
let bindings = bindgen::Builder::default()
|
|
||||||
// The input header we would like to generate
|
|
||||||
// bindings for.
|
|
||||||
.header(headers_path_str)
|
.header(headers_path_str)
|
||||||
// Tell cargo to invalidate the built crate whenever any of the
|
.clang_arg("-DMLKEM_K=2")
|
||||||
// included header files changed.
|
|
||||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||||
// Finish the builder and generate the bindings.
|
|
||||||
.generate()
|
.generate()
|
||||||
// Unwrap the Result and panic on failure.
|
|
||||||
.expect("Unable to generate bindings");
|
.expect("Unable to generate bindings");
|
||||||
|
|
||||||
// Write the bindings to the $OUT_DIR/bindings.rs file.
|
let bindings_level3 = bindgen::Builder::default()
|
||||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs");
|
.header(headers_path_str)
|
||||||
bindings
|
.clang_arg("-DMLKEM_K=3")
|
||||||
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||||
|
.generate()
|
||||||
|
.expect("Unable to generate bindings");
|
||||||
|
|
||||||
|
let bindings_level4 = bindgen::Builder::default()
|
||||||
|
.header(headers_path_str)
|
||||||
|
.clang_arg("-DMLKEM_K=4")
|
||||||
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||||
|
.generate()
|
||||||
|
.expect("Unable to generate bindings");
|
||||||
|
|
||||||
|
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings_level2.rs");
|
||||||
|
bindings_level2
|
||||||
|
.write_to_file(out_path)
|
||||||
|
.expect("Couldn't write bindings!");
|
||||||
|
|
||||||
|
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings_level3.rs");
|
||||||
|
bindings_level3
|
||||||
|
.write_to_file(out_path)
|
||||||
|
.expect("Couldn't write bindings!");
|
||||||
|
|
||||||
|
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings_level4.rs");
|
||||||
|
bindings_level4
|
||||||
.write_to_file(out_path)
|
.write_to_file(out_path)
|
||||||
.expect("Couldn't write bindings!");
|
.expect("Couldn't write bindings!");
|
||||||
}
|
}
|
||||||
|
|||||||
240
src/lib.rs
240
src/lib.rs
@@ -1,10 +1,22 @@
|
|||||||
|
use rand_core::TryCryptoRng;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
mod unsafe_bindings;
|
mod unsafe_bindings_level2;
|
||||||
|
mod unsafe_bindings_level3;
|
||||||
|
mod unsafe_bindings_level4;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum MLKEMNativeError {
|
||||||
|
#[error("the CSRNG failed due to insufficent entropy")]
|
||||||
|
InsufficentEntropy,
|
||||||
|
#[error("the library function encountered an internal error")]
|
||||||
|
LibraryError,
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! reexport_const {
|
macro_rules! reexport_const {
|
||||||
( $type_name:ident, $struct_name:ident ) => {
|
( $type_name:ident, $struct_name:ident ) => {
|
||||||
pub const $type_name: usize = unsafe_bindings::$type_name as usize;
|
pub const $type_name: usize = unsafe_bindings_level2::$type_name as usize;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct $struct_name([u8; $type_name]);
|
pub struct $struct_name([u8; $type_name]);
|
||||||
@@ -17,7 +29,7 @@ macro_rules! reexport_const {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
reexport_const!(MLKEM512_SECRETKEYBYTES, MLKEM512Secretkey);
|
reexport_const!(MLKEM512_SECRETKEYBYTES, MLKEM512SecretKey);
|
||||||
reexport_const!(MLKEM512_PUBLICKEYBYTES, MLKEM512PublicKey);
|
reexport_const!(MLKEM512_PUBLICKEYBYTES, MLKEM512PublicKey);
|
||||||
reexport_const!(MLKEM512_CIPHERTEXTBYTES, MLKEM512Ciphertext);
|
reexport_const!(MLKEM512_CIPHERTEXTBYTES, MLKEM512Ciphertext);
|
||||||
reexport_const!(MLKEM512_BYTES, MLKEM512SharedSecret);
|
reexport_const!(MLKEM512_BYTES, MLKEM512SharedSecret);
|
||||||
@@ -32,48 +44,66 @@ reexport_const!(MLKEM1024_PUBLICKEYBYTES, MLKEM1024PublicKey);
|
|||||||
reexport_const!(MLKEM1024_CIPHERTEXTBYTES, MLKEM1024Ciphertext);
|
reexport_const!(MLKEM1024_CIPHERTEXTBYTES, MLKEM1024Ciphertext);
|
||||||
reexport_const!(MLKEM1024_BYTES, MLKEM1024SharedSecret);
|
reexport_const!(MLKEM1024_BYTES, MLKEM1024SharedSecret);
|
||||||
|
|
||||||
pub fn mlkem768_keypair() -> Option<(MLKEM768SecretKey, MLKEM768PublicKey)> {
|
pub fn mlkem512_keypair(
|
||||||
let mut sk = MLKEM768SecretKey::default();
|
rng: &mut impl TryCryptoRng,
|
||||||
let mut pk = MLKEM768PublicKey::default();
|
) -> Result<(MLKEM512SecretKey, MLKEM512PublicKey), MLKEMNativeError> {
|
||||||
|
let mut sk = MLKEM512SecretKey::default();
|
||||||
|
let mut pk = MLKEM512PublicKey::default();
|
||||||
|
|
||||||
|
let mut coins = [0u8; 2 * (unsafe_bindings_level2::MLKEM512_SYMBYTES as usize)];
|
||||||
|
rng.try_fill_bytes(&mut coins)
|
||||||
|
.map_err(|_| MLKEMNativeError::InsufficentEntropy)?;
|
||||||
|
|
||||||
let success = unsafe {
|
let success = unsafe {
|
||||||
unsafe_bindings::PQCP_MLKEM_NATIVE_MLKEM768_keypair(pk.0.as_mut_ptr(), sk.0.as_mut_ptr())
|
unsafe_bindings_level2::PQCP_MLKEM_NATIVE_MLKEM512_keypair_derand(
|
||||||
};
|
pk.0.as_mut_ptr(),
|
||||||
|
sk.0.as_mut_ptr(),
|
||||||
if success == 0 {
|
coins.as_ptr(),
|
||||||
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 {
|
if success == 0 {
|
||||||
Some((ct, ss))
|
Ok((sk, pk))
|
||||||
} else {
|
} else {
|
||||||
None
|
Err(MLKEMNativeError::LibraryError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mlkem768_dec(
|
pub fn mlkem512_enc(
|
||||||
|
rng: &mut impl TryCryptoRng,
|
||||||
|
pk: &MLKEM768PublicKey,
|
||||||
|
) -> Result<(MLKEM768Ciphertext, MLKEM768SharedSecret), MLKEMNativeError> {
|
||||||
|
let mut ct = MLKEM768Ciphertext::default();
|
||||||
|
let mut ss = MLKEM768SharedSecret::default();
|
||||||
|
|
||||||
|
let mut coins = [0u8; unsafe_bindings_level2::MLKEM768_SYMBYTES as usize];
|
||||||
|
rng.try_fill_bytes(&mut coins)
|
||||||
|
.map_err(|_| MLKEMNativeError::InsufficentEntropy)?;
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
unsafe_bindings_level2::PQCP_MLKEM_NATIVE_MLKEM512_enc_derand(
|
||||||
|
ct.0.as_mut_ptr(),
|
||||||
|
ss.0.as_mut_ptr(),
|
||||||
|
pk.0.as_ptr(),
|
||||||
|
coins.as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if success == 0 {
|
||||||
|
Ok((ct, ss))
|
||||||
|
} else {
|
||||||
|
Err(MLKEMNativeError::LibraryError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mlkem512_dec(
|
||||||
sk: &MLKEM768SecretKey,
|
sk: &MLKEM768SecretKey,
|
||||||
ct: &MLKEM768Ciphertext,
|
ct: &MLKEM768Ciphertext,
|
||||||
) -> Option<MLKEM768SharedSecret> {
|
) -> Result<MLKEM768SharedSecret, MLKEMNativeError> {
|
||||||
let mut ss = MLKEM768SharedSecret::default();
|
let mut ss = MLKEM768SharedSecret::default();
|
||||||
|
|
||||||
let success = unsafe {
|
let success = unsafe {
|
||||||
unsafe_bindings::PQCP_MLKEM_NATIVE_MLKEM768_dec(
|
unsafe_bindings_level2::PQCP_MLKEM_NATIVE_MLKEM512_dec(
|
||||||
ss.0.as_mut_ptr(),
|
ss.0.as_mut_ptr(),
|
||||||
ct.0.as_ptr(),
|
ct.0.as_ptr(),
|
||||||
sk.0.as_ptr(),
|
sk.0.as_ptr(),
|
||||||
@@ -81,8 +111,154 @@ pub fn mlkem768_dec(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if success == 0 {
|
if success == 0 {
|
||||||
Some(ss)
|
Ok(ss)
|
||||||
} else {
|
} else {
|
||||||
None
|
Err(MLKEMNativeError::LibraryError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mlkem768_keypair(
|
||||||
|
rng: &mut impl TryCryptoRng,
|
||||||
|
) -> Result<(MLKEM768SecretKey, MLKEM768PublicKey), MLKEMNativeError> {
|
||||||
|
let mut sk = MLKEM768SecretKey::default();
|
||||||
|
let mut pk = MLKEM768PublicKey::default();
|
||||||
|
|
||||||
|
let mut coins = [0u8; 2 * (unsafe_bindings_level2::MLKEM768_SYMBYTES as usize)];
|
||||||
|
rng.try_fill_bytes(&mut coins)
|
||||||
|
.map_err(|_| MLKEMNativeError::InsufficentEntropy)?;
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
unsafe_bindings_level3::PQCP_MLKEM_NATIVE_MLKEM768_keypair_derand(
|
||||||
|
pk.0.as_mut_ptr(),
|
||||||
|
sk.0.as_mut_ptr(),
|
||||||
|
coins.as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if success == 0 {
|
||||||
|
Ok((sk, pk))
|
||||||
|
} else {
|
||||||
|
Err(MLKEMNativeError::LibraryError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mlkem768_enc(
|
||||||
|
rng: &mut impl TryCryptoRng,
|
||||||
|
pk: &MLKEM768PublicKey,
|
||||||
|
) -> Result<(MLKEM768Ciphertext, MLKEM768SharedSecret), MLKEMNativeError> {
|
||||||
|
let mut ct = MLKEM768Ciphertext::default();
|
||||||
|
let mut ss = MLKEM768SharedSecret::default();
|
||||||
|
|
||||||
|
let mut coins = [0u8; unsafe_bindings_level2::MLKEM768_SYMBYTES as usize];
|
||||||
|
rng.try_fill_bytes(&mut coins)
|
||||||
|
.map_err(|_| MLKEMNativeError::InsufficentEntropy)?;
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
unsafe_bindings_level3::PQCP_MLKEM_NATIVE_MLKEM768_enc_derand(
|
||||||
|
ct.0.as_mut_ptr(),
|
||||||
|
ss.0.as_mut_ptr(),
|
||||||
|
pk.0.as_ptr(),
|
||||||
|
coins.as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if success == 0 {
|
||||||
|
Ok((ct, ss))
|
||||||
|
} else {
|
||||||
|
Err(MLKEMNativeError::LibraryError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mlkem768_dec(
|
||||||
|
sk: &MLKEM768SecretKey,
|
||||||
|
ct: &MLKEM768Ciphertext,
|
||||||
|
) -> Result<MLKEM768SharedSecret, MLKEMNativeError> {
|
||||||
|
let mut ss = MLKEM768SharedSecret::default();
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
unsafe_bindings_level3::PQCP_MLKEM_NATIVE_MLKEM768_dec(
|
||||||
|
ss.0.as_mut_ptr(),
|
||||||
|
ct.0.as_ptr(),
|
||||||
|
sk.0.as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if success == 0 {
|
||||||
|
Ok(ss)
|
||||||
|
} else {
|
||||||
|
Err(MLKEMNativeError::LibraryError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mlkem1024_keypair(
|
||||||
|
rng: &mut impl TryCryptoRng,
|
||||||
|
) -> Result<(MLKEM768SecretKey, MLKEM768PublicKey), MLKEMNativeError> {
|
||||||
|
let mut sk = MLKEM768SecretKey::default();
|
||||||
|
let mut pk = MLKEM768PublicKey::default();
|
||||||
|
|
||||||
|
let mut coins = [0u8; 2 * (unsafe_bindings_level2::MLKEM1024_SYMBYTES as usize)];
|
||||||
|
rng.try_fill_bytes(&mut coins)
|
||||||
|
.map_err(|_| MLKEMNativeError::InsufficentEntropy)?;
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
unsafe_bindings_level4::PQCP_MLKEM_NATIVE_MLKEM1024_keypair_derand(
|
||||||
|
pk.0.as_mut_ptr(),
|
||||||
|
sk.0.as_mut_ptr(),
|
||||||
|
coins.as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if success == 0 {
|
||||||
|
Ok((sk, pk))
|
||||||
|
} else {
|
||||||
|
Err(MLKEMNativeError::LibraryError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mlkem1024_enc(
|
||||||
|
rng: &mut impl TryCryptoRng,
|
||||||
|
pk: &MLKEM768PublicKey,
|
||||||
|
) -> Result<(MLKEM768Ciphertext, MLKEM768SharedSecret), MLKEMNativeError> {
|
||||||
|
let mut ct = MLKEM768Ciphertext::default();
|
||||||
|
let mut ss = MLKEM768SharedSecret::default();
|
||||||
|
|
||||||
|
let mut coins = [0u8; unsafe_bindings_level2::MLKEM1024_SYMBYTES as usize];
|
||||||
|
rng.try_fill_bytes(&mut coins)
|
||||||
|
.map_err(|_| MLKEMNativeError::InsufficentEntropy)?;
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
unsafe_bindings_level4::PQCP_MLKEM_NATIVE_MLKEM1024_enc_derand(
|
||||||
|
ct.0.as_mut_ptr(),
|
||||||
|
ss.0.as_mut_ptr(),
|
||||||
|
pk.0.as_ptr(),
|
||||||
|
coins.as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if success == 0 {
|
||||||
|
Ok((ct, ss))
|
||||||
|
} else {
|
||||||
|
Err(MLKEMNativeError::LibraryError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mlkem1024_dec(
|
||||||
|
sk: &MLKEM768SecretKey,
|
||||||
|
ct: &MLKEM768Ciphertext,
|
||||||
|
) -> Result<MLKEM768SharedSecret, MLKEMNativeError> {
|
||||||
|
let mut ss = MLKEM768SharedSecret::default();
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
unsafe_bindings_level4::PQCP_MLKEM_NATIVE_MLKEM1024_dec(
|
||||||
|
ss.0.as_mut_ptr(),
|
||||||
|
ct.0.as_ptr(),
|
||||||
|
sk.0.as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if success == 0 {
|
||||||
|
Ok(ss)
|
||||||
|
} else {
|
||||||
|
Err(MLKEMNativeError::LibraryError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#![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
|
|
||||||
}
|
|
||||||
6
src/unsafe_bindings_level2.rs
Normal file
6
src/unsafe_bindings_level2.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/bindings_level2.rs"));
|
||||||
6
src/unsafe_bindings_level3.rs
Normal file
6
src/unsafe_bindings_level3.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/bindings_level3.rs"));
|
||||||
6
src/unsafe_bindings_level4.rs
Normal file
6
src/unsafe_bindings_level4.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/bindings_level4.rs"));
|
||||||
Reference in New Issue
Block a user