use p3_field::PrimeField32;
use p3_koala_bear::KoalaBear;
use crate::{
codecs::{Decoding, Encoding},
io::NargDeserialize,
VerificationError, VerificationResult,
};
const KOALABEAR_ZERO: KoalaBear = unsafe { core::mem::transmute(0u32) };
impl crate::Unit for KoalaBear {
const ZERO: Self = KOALABEAR_ZERO;
}
impl Decoding<[u8]> for KoalaBear {
type Repr = [u8; 8];
fn decode(buf: Self::Repr) -> Self {
let n = u64::from_le_bytes(buf);
Self::new((n % u64::from(Self::ORDER_U32)) as u32)
}
}
impl NargDeserialize for KoalaBear {
fn deserialize_from_narg(buf: &mut &[u8]) -> VerificationResult<Self> {
if buf.len() < 4 {
return Err(VerificationError);
}
let mut repr = [0u8; 4];
repr.copy_from_slice(&buf[..4]);
let value = u32::from_le_bytes(repr);
if value >= Self::ORDER_U32 {
return Err(VerificationError);
}
*buf = &buf[4..];
Ok(Self::new(value))
}
}
impl Encoding<[u8]> for KoalaBear {
fn encode(&self) -> impl AsRef<[u8]> {
self.as_canonical_u32().to_le_bytes()
}
}
#[cfg(test)]
mod tests {
use alloc::vec::Vec;
use super::*;
use crate::io::NargSerialize;
#[test]
fn test_koalabear_serialize_deserialize() {
let element = KoalaBear::new(12345);
let mut buf = Vec::new();
element.serialize_into_narg(&mut buf);
let deserialized = KoalaBear::deserialize_from_narg(&mut &buf[..]).unwrap();
assert_eq!(element, deserialized);
}
#[test]
fn test_koalabear_encoding() {
let element = KoalaBear::new(67890);
let encoded = element.encode();
let encoded_bytes = encoded.as_ref();
let deserialized = KoalaBear::deserialize_from_narg(&mut &encoded_bytes[..]).unwrap();
assert_eq!(element, deserialized);
}
#[test]
fn test_koalabear_out_of_range() {
let buf = KoalaBear::ORDER_U32.to_le_bytes();
let result = KoalaBear::deserialize_from_narg(&mut &buf[..]);
assert!(result.is_err());
}
}