use cosmian_ffi_utils::{ffi_read_bytes, ffi_unwrap, ErrorCode};
use crate::core::{Float, KEY_LENGTH};
unsafe extern "C" fn fpe(
output: *mut f64,
input: f64,
key_ptr: *const i8,
key_len: i32,
tweak_ptr: *const i8,
tweak_len: i32,
encrypt_flag: bool,
) -> i32 {
let key_bytes = ffi_read_bytes!("key", key_ptr, key_len);
let tweak_bytes = ffi_read_bytes!("tweak", tweak_ptr, tweak_len);
let key: [u8; KEY_LENGTH] = ffi_unwrap!(
key_bytes.try_into(),
"key size is 32 bytes",
ErrorCode::Serialization
);
let itg = ffi_unwrap!(
Float::instantiate(),
"cannot instantiate FPE float",
ErrorCode::Fpe
);
let operation = match encrypt_flag {
true => itg.encrypt(&key, tweak_bytes, input),
false => itg.decrypt(&key, tweak_bytes, input),
};
*output = ffi_unwrap!(
operation,
"fpe encryption/decryption process",
ErrorCode::Fpe
);
0
}
#[no_mangle]
pub unsafe extern "C" fn h_fpe_encrypt_float(
output: *mut f64,
input: f64,
key_ptr: *const i8,
key_len: i32,
tweak_ptr: *const i8,
tweak_len: i32,
) -> i32 {
fpe(output, input, key_ptr, key_len, tweak_ptr, tweak_len, true)
}
#[no_mangle]
pub unsafe extern "C" fn h_fpe_decrypt_float(
output: *mut f64,
input: f64,
key_ptr: *const i8,
key_len: i32,
tweak_ptr: *const i8,
tweak_len: i32,
) -> i32 {
fpe(output, input, key_ptr, key_len, tweak_ptr, tweak_len, false)
}