#[cfg(feature = "ffi")]
#[diplomat::bridge]
#[allow(clippy::module_inception)]
pub mod ffi {
use alloc::boxed::Box;
use alloc::vec::Vec;
pub enum VaeaNttError {
InvalidSize,
NotPrime,
NotNttFriendly,
PrimeTooLarge,
InvalidBufferLength,
}
#[diplomat::opaque]
pub struct VaeaNtt32(crate::ntt32::Ntt32Context);
impl VaeaNtt32 {
pub fn try_new(n: usize, q: u32) -> Result<Box<VaeaNtt32>, VaeaNttError> {
match crate::ntt32::Ntt32Context::try_new(n, q) {
Ok(ctx) => Ok(Box::new(VaeaNtt32(ctx))),
Err(crate::NttError::InvalidSize(_)) => Err(VaeaNttError::InvalidSize),
Err(crate::NttError::NotPrime(_)) => Err(VaeaNttError::NotPrime),
Err(crate::NttError::NotNttFriendly { .. }) => Err(VaeaNttError::NotNttFriendly),
Err(crate::NttError::PrimeTooLarge(_)) => Err(VaeaNttError::PrimeTooLarge),
}
}
pub fn get_n(&self) -> usize {
self.0.n
}
pub fn get_q(&self) -> u32 {
self.0.q
}
pub fn forward(&self, data: &mut [u32]) -> Result<(), VaeaNttError> {
if data.len() != self.0.n {
return Err(VaeaNttError::InvalidBufferLength);
}
self.0.forward(data);
Ok(())
}
pub fn inverse(&self, data: &mut [u32]) -> Result<(), VaeaNttError> {
if data.len() != self.0.n {
return Err(VaeaNttError::InvalidBufferLength);
}
self.0.inverse(data);
Ok(())
}
pub fn inverse_lazy(&self, data: &mut [u32]) -> Result<(), VaeaNttError> {
if data.len() != self.0.n {
return Err(VaeaNttError::InvalidBufferLength);
}
self.0.inverse_lazy(data);
Ok(())
}
pub fn negacyclic_mul(
&self,
a: &mut [u32],
b: &mut [u32],
result: &mut [u32],
) -> Result<(), VaeaNttError> {
if a.len() != self.0.n || b.len() != self.0.n || result.len() != self.0.n {
return Err(VaeaNttError::InvalidBufferLength);
}
self.0.negacyclic_mul_into(a, b, result);
Ok(())
}
pub fn pointwise_mul(
&self,
a: &[u32],
b: &[u32],
result: &mut [u32],
) -> Result<(), VaeaNttError> {
if a.len() != self.0.n || b.len() != self.0.n || result.len() != self.0.n {
return Err(VaeaNttError::InvalidBufferLength);
}
self.0.pointwise_mul(a, b, result);
Ok(())
}
}
#[diplomat::opaque]
pub struct VaeaPrimeList(Vec<u32>);
impl VaeaPrimeList {
pub fn generate(n: usize, count: usize) -> Box<VaeaPrimeList> {
let primes = crate::ntt32::generate_primes_28(n, count);
Box::new(VaeaPrimeList(primes))
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn get(&self, index: usize) -> u32 {
self.0[index]
}
}
}