#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "thiserror", derive(thiserror::Error))]
pub enum CborError {
#[cfg_attr(feature = "thiserror", error("Invalid CBOR encoding"))]
InvalidEncoding,
#[cfg_attr(feature = "thiserror", error("Unexpected CBOR structure"))]
UnexpectedStructure,
#[cfg_attr(feature = "thiserror", error("Serialization failed"))]
SerializationFailed,
#[cfg_attr(feature = "thiserror", error("Deserialization failed"))]
DeserializationFailed,
#[cfg_attr(feature = "thiserror", error("Invalid byte length"))]
InvalidLength,
#[cfg_attr(feature = "thiserror", error("Buffer too small"))]
BufferTooSmall,
#[cfg_attr(feature = "thiserror", error("Invalid UTF-8 encoding"))]
InvalidUtf8,
#[cfg_attr(feature = "thiserror", error("Unsupported CBOR feature"))]
Unsupported,
}
#[cfg(not(feature = "thiserror"))]
impl core::fmt::Display for CborError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
CborError::InvalidEncoding => write!(f, "Invalid CBOR encoding"),
CborError::UnexpectedStructure => write!(f, "Unexpected CBOR structure"),
CborError::SerializationFailed => write!(f, "Serialization failed"),
CborError::DeserializationFailed => write!(f, "Deserialization failed"),
CborError::InvalidLength => write!(f, "Invalid byte length"),
CborError::BufferTooSmall => write!(f, "Buffer too small"),
CborError::InvalidUtf8 => write!(f, "Invalid UTF-8 encoding"),
CborError::Unsupported => write!(f, "Unsupported CBOR feature"),
}
}
}
#[cfg(all(not(feature = "thiserror"), feature = "std"))]
impl std::error::Error for CborError {}
#[cfg(feature = "alloc")]
pub fn encode_bytes(bytes: &[u8]) -> Vec<u8> {
let len = bytes.len();
let mut result = Vec::new();
if len < 24 {
result.push(0x40 | len as u8); } else if len < 256 {
result.push(0x58); result.push(len as u8);
} else if len < 65536 {
result.push(0x59); result.extend_from_slice(&(len as u16).to_be_bytes());
} else {
result.push(0x5a); result.extend_from_slice(&(len as u32).to_be_bytes());
}
result.extend_from_slice(bytes);
result
}
#[cfg(feature = "alloc")]
pub fn decode_bytes(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
if cbor.is_empty() {
return Err(CborError::InvalidEncoding);
}
let header = cbor[0];
let major_type = (header >> 5) & 0x07;
if major_type != 2 {
return Err(CborError::UnexpectedStructure);
}
let additional_info = header & 0x1f;
let (length, offset) = if additional_info < 24 {
(additional_info as usize, 1)
} else if additional_info == 24 {
if cbor.len() < 2 {
return Err(CborError::BufferTooSmall);
}
(cbor[1] as usize, 2)
} else if additional_info == 25 {
if cbor.len() < 3 {
return Err(CborError::BufferTooSmall);
}
let len = u16::from_be_bytes([cbor[1], cbor[2]]) as usize;
(len, 3)
} else if additional_info == 26 {
if cbor.len() < 5 {
return Err(CborError::BufferTooSmall);
}
let len = u32::from_be_bytes([cbor[1], cbor[2], cbor[3], cbor[4]]) as usize;
(len, 5)
} else {
return Err(CborError::InvalidEncoding);
};
if cbor.len() < offset + length {
return Err(CborError::BufferTooSmall);
}
Ok(cbor[offset..offset + length].to_vec())
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_verification_key(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_verification_key(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_signature(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_signature(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_verification_key_kes(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_verification_key_kes(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_signature_kes(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_signature_kes(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_verification_key_vrf(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_verification_key_vrf(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_signing_key_vrf(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_signing_key_vrf(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_proof_vrf(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_proof_vrf(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_verification_key_dsign(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_verification_key_dsign(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_signing_key_dsign(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_signing_key_dsign(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_signature_dsign(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_signature_dsign(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_hash(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_hash(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_output_vrf(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_output_vrf(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn encode_signing_key_kes(raw_bytes: &[u8]) -> Vec<u8> {
encode_bytes(raw_bytes)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn decode_signing_key_kes(cbor: &[u8]) -> Result<Vec<u8>, CborError> {
decode_bytes(cbor)
}
#[must_use]
pub const fn encoded_size_bytes(len: usize) -> usize {
if len < 24 {
1 + len
} else if len < 256 {
2 + len
} else if len < 65536 {
3 + len
} else {
5 + len
}
}
#[must_use]
pub const fn encoded_verification_key_size(raw_size: usize) -> usize {
encoded_size_bytes(raw_size)
}
#[must_use]
pub const fn encoded_signature_size(raw_size: usize) -> usize {
encoded_size_bytes(raw_size)
}
#[must_use]
pub const fn encoded_verification_key_dsign_size() -> usize {
encoded_size_bytes(32)
}
#[must_use]
pub const fn encoded_signing_key_dsign_size() -> usize {
encoded_size_bytes(64)
}
#[must_use]
pub const fn encoded_signature_dsign_size() -> usize {
encoded_size_bytes(64)
}
#[must_use]
pub const fn encoded_verification_key_vrf_size() -> usize {
encoded_size_bytes(32)
}
#[must_use]
pub const fn encoded_signing_key_vrf_size() -> usize {
encoded_size_bytes(64)
}
#[must_use]
pub const fn encoded_proof_vrf_draft03_size() -> usize {
encoded_size_bytes(80)
}
#[must_use]
pub const fn encoded_proof_vrf_draft13_size() -> usize {
encoded_size_bytes(128)
}
#[must_use]
pub const fn encoded_output_vrf_size() -> usize {
encoded_size_bytes(64)
}
#[must_use]
pub const fn encoded_verification_key_kes_size() -> usize {
encoded_size_bytes(32)
}
#[must_use]
pub const fn encoded_signing_key_sum6kes_size() -> usize {
encoded_size_bytes(2112)
}
#[must_use]
pub const fn encoded_signature_sum6kes_size() -> usize {
encoded_size_bytes(448)
}
#[must_use]
pub const fn encoded_hash_blake2b224_size() -> usize {
encoded_size_bytes(28)
}
#[must_use]
pub const fn encoded_hash_blake2b256_size() -> usize {
encoded_size_bytes(32)
}
pub trait ToCbor {
#[cfg(feature = "alloc")]
fn to_cbor(&self) -> Vec<u8>;
fn encoded_size(&self) -> usize;
}
pub trait FromCbor: Sized {
fn from_cbor(bytes: &[u8]) -> Result<Self, CborError>;
}
impl ToCbor for [u8; 32] {
#[cfg(feature = "alloc")]
fn to_cbor(&self) -> Vec<u8> {
encode_bytes(self)
}
fn encoded_size(&self) -> usize {
encoded_size_bytes(32)
}
}
impl FromCbor for [u8; 32] {
fn from_cbor(bytes: &[u8]) -> Result<Self, CborError> {
let decoded = decode_bytes(bytes)?;
if decoded.len() != 32 {
return Err(CborError::InvalidLength);
}
let mut arr = [0u8; 32];
arr.copy_from_slice(&decoded);
Ok(arr)
}
}
impl ToCbor for [u8; 64] {
#[cfg(feature = "alloc")]
fn to_cbor(&self) -> Vec<u8> {
encode_bytes(self)
}
fn encoded_size(&self) -> usize {
encoded_size_bytes(64)
}
}
impl FromCbor for [u8; 64] {
fn from_cbor(bytes: &[u8]) -> Result<Self, CborError> {
let decoded = decode_bytes(bytes)?;
if decoded.len() != 64 {
return Err(CborError::InvalidLength);
}
let mut arr = [0u8; 64];
arr.copy_from_slice(&decoded);
Ok(arr)
}
}
impl ToCbor for [u8; 80] {
#[cfg(feature = "alloc")]
fn to_cbor(&self) -> Vec<u8> {
encode_bytes(self)
}
fn encoded_size(&self) -> usize {
encoded_size_bytes(80)
}
}
impl FromCbor for [u8; 80] {
fn from_cbor(bytes: &[u8]) -> Result<Self, CborError> {
let decoded = decode_bytes(bytes)?;
if decoded.len() != 80 {
return Err(CborError::InvalidLength);
}
let mut arr = [0u8; 80];
arr.copy_from_slice(&decoded);
Ok(arr)
}
}
#[cfg(feature = "alloc")]
impl ToCbor for Vec<u8> {
fn to_cbor(&self) -> Vec<u8> {
encode_bytes(self)
}
fn encoded_size(&self) -> usize {
encoded_size_bytes(self.len())
}
}
#[cfg(feature = "alloc")]
impl FromCbor for Vec<u8> {
fn from_cbor(bytes: &[u8]) -> Result<Self, CborError> {
decode_bytes(bytes)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cbor_encode_decode_short() {
let data = vec![0x01, 0x02, 0x03, 0x04, 0x05];
let encoded = encode_bytes(&data);
assert_eq!(encoded[0], 0x45);
assert_eq!(&encoded[1..], &data[..]);
let decoded = decode_bytes(&encoded).unwrap();
assert_eq!(decoded, data);
}
#[test]
fn test_cbor_encode_decode_medium() {
let data = vec![0xAB; 200];
let encoded = encode_bytes(&data);
assert_eq!(encoded[0], 0x58);
assert_eq!(encoded[1], 200);
let decoded = decode_bytes(&encoded).unwrap();
assert_eq!(decoded, data);
}
#[test]
fn test_cbor_encode_decode_large() {
let data = vec![0xCD; 500];
let encoded = encode_bytes(&data);
assert_eq!(encoded[0], 0x59);
assert_eq!(u16::from_be_bytes([encoded[1], encoded[2]]), 500);
let decoded = decode_bytes(&encoded).unwrap();
assert_eq!(decoded, data);
}
#[test]
fn test_cbor_verification_key_roundtrip() {
let vk_bytes = vec![0x12; 32];
let encoded = encode_verification_key(&vk_bytes);
let decoded = decode_verification_key(&encoded).unwrap();
assert_eq!(decoded, vk_bytes);
}
#[test]
fn test_cbor_signature_roundtrip() {
let sig_bytes = vec![0x34; 64];
let encoded = encode_signature(&sig_bytes);
let decoded = decode_signature(&encoded).unwrap();
assert_eq!(decoded, sig_bytes);
}
#[test]
fn test_cbor_invalid_major_type() {
let invalid = vec![0x00];
let result = decode_bytes(&invalid);
assert!(matches!(result, Err(CborError::UnexpectedStructure)));
}
#[test]
fn test_cbor_buffer_too_small() {
let invalid = vec![0x58];
let result = decode_bytes(&invalid);
assert!(matches!(result, Err(CborError::BufferTooSmall)));
}
#[test]
fn test_cbor_empty() {
let result = decode_bytes(&[]);
assert!(matches!(result, Err(CborError::InvalidEncoding)));
}
#[test]
fn test_encoded_size_bytes() {
assert_eq!(encoded_size_bytes(0), 1);
assert_eq!(encoded_size_bytes(23), 24);
assert_eq!(encoded_size_bytes(24), 26); assert_eq!(encoded_size_bytes(255), 257);
assert_eq!(encoded_size_bytes(256), 259); assert_eq!(encoded_size_bytes(65535), 65538);
assert_eq!(encoded_size_bytes(65536), 65541); }
#[test]
fn test_kes_verification_key_cbor() {
let vk_bytes = vec![0xAA; 64];
let encoded = encode_verification_key_kes(&vk_bytes);
let decoded = decode_verification_key_kes(&encoded).unwrap();
assert_eq!(decoded, vk_bytes);
}
#[test]
fn test_kes_signature_cbor() {
let sig_bytes = vec![0xBB; 448]; let encoded = encode_signature_kes(&sig_bytes);
let decoded = decode_signature_kes(&encoded).unwrap();
assert_eq!(decoded, sig_bytes);
}
#[test]
fn test_kes_signing_key_cbor() {
let sk_bytes = vec![0xCC; 128];
let encoded = encode_signing_key_kes(&sk_bytes);
let decoded = decode_signing_key_kes(&encoded).unwrap();
assert_eq!(decoded, sk_bytes);
}
#[test]
fn test_vrf_proof_cbor() {
let proof_bytes = vec![0xCC; 80];
let encoded = encode_proof_vrf(&proof_bytes);
let decoded = decode_proof_vrf(&encoded).unwrap();
assert_eq!(decoded, proof_bytes);
}
#[test]
fn test_vrf_output_cbor() {
let output_bytes = vec![0xDD; 64];
let encoded = encode_output_vrf(&output_bytes);
let decoded = decode_output_vrf(&encoded).unwrap();
assert_eq!(decoded, output_bytes);
}
#[test]
fn test_dsign_roundtrip() {
let vk = vec![0x11; 32];
let vk_cbor = encode_verification_key_dsign(&vk);
assert_eq!(decode_verification_key_dsign(&vk_cbor).unwrap(), vk);
let sig = vec![0x22; 64];
let sig_cbor = encode_signature_dsign(&sig);
assert_eq!(decode_signature_dsign(&sig_cbor).unwrap(), sig);
}
#[test]
fn test_hash_cbor() {
let hash = vec![0xDD; 32];
let encoded = encode_hash(&hash);
let decoded = decode_hash(&encoded).unwrap();
assert_eq!(decoded, hash);
}
#[test]
fn test_cbor_edge_cases() {
let empty: Vec<u8> = vec![];
let encoded = encode_bytes(&empty);
assert_eq!(encoded, vec![0x40]); assert_eq!(decode_bytes(&encoded).unwrap(), empty);
let data_23 = vec![0xFF; 23];
let encoded_23 = encode_bytes(&data_23);
assert_eq!(encoded_23[0], 0x57); assert_eq!(decode_bytes(&encoded_23).unwrap(), data_23);
let data_24 = vec![0xEE; 24];
let encoded_24 = encode_bytes(&data_24);
assert_eq!(encoded_24[0], 0x58);
assert_eq!(encoded_24[1], 24);
assert_eq!(decode_bytes(&encoded_24).unwrap(), data_24);
let data_255 = vec![0xDD; 255];
let encoded_255 = encode_bytes(&data_255);
assert_eq!(encoded_255[0], 0x58);
assert_eq!(encoded_255[1], 255);
assert_eq!(decode_bytes(&encoded_255).unwrap(), data_255);
let data_256 = vec![0xCC; 256];
let encoded_256 = encode_bytes(&data_256);
assert_eq!(encoded_256[0], 0x59);
assert_eq!(u16::from_be_bytes([encoded_256[1], encoded_256[2]]), 256);
assert_eq!(decode_bytes(&encoded_256).unwrap(), data_256);
}
#[test]
fn test_to_cbor_trait_array_32() {
let arr: [u8; 32] = [0x42; 32];
let encoded = arr.to_cbor();
let decoded = <[u8; 32]>::from_cbor(&encoded).unwrap();
assert_eq!(arr, decoded);
assert_eq!(arr.encoded_size(), encoded.len());
}
#[test]
fn test_to_cbor_trait_array_64() {
let arr: [u8; 64] = [0x43; 64];
let encoded = arr.to_cbor();
let decoded = <[u8; 64]>::from_cbor(&encoded).unwrap();
assert_eq!(arr, decoded);
assert_eq!(arr.encoded_size(), encoded.len());
}
#[test]
fn test_to_cbor_trait_array_80() {
let arr: [u8; 80] = [0x44; 80];
let encoded = arr.to_cbor();
let decoded = <[u8; 80]>::from_cbor(&encoded).unwrap();
assert_eq!(arr, decoded);
assert_eq!(arr.encoded_size(), encoded.len());
}
#[test]
fn test_to_cbor_trait_vec() {
let vec = vec![0x45u8; 100];
let encoded = vec.to_cbor();
let decoded = Vec::<u8>::from_cbor(&encoded).unwrap();
assert_eq!(vec, decoded);
assert_eq!(vec.encoded_size(), encoded.len());
}
#[test]
fn test_from_cbor_invalid_length() {
let data = vec![0x42u8; 31];
let encoded = encode_bytes(&data);
let result = <[u8; 32]>::from_cbor(&encoded);
assert!(matches!(result, Err(CborError::InvalidLength)));
}
#[test]
fn test_vrf_output_trait_roundtrip() {
use crate::vrf::{OutputVrf, VrfDraft03};
let seed = [42u8; 32];
let (secret_key, public_key) = VrfDraft03::keypair_from_seed(&seed);
let proof = VrfDraft03::prove(&secret_key, b"test").unwrap();
let output_bytes = VrfDraft03::verify(&public_key, &proof, b"test").unwrap();
let output = OutputVrf::new(output_bytes);
let encoded = output.to_cbor();
let decoded = OutputVrf::from_cbor(&encoded).unwrap();
assert_eq!(output.as_bytes(), decoded.as_bytes());
}
#[test]
fn test_certified_vrf_cbor_roundtrip() {
use crate::vrf::CertifiedVrf;
let seed = [42u8; 32];
let (secret_key, _) = crate::vrf::VrfDraft03::keypair_from_seed(&seed);
let certified = CertifiedVrf::eval(&secret_key, b"test message").unwrap();
let encoded = certified.to_cbor();
let decoded = CertifiedVrf::from_cbor(&encoded).unwrap();
assert_eq!(
certified.get_output().as_bytes(),
decoded.get_output().as_bytes()
);
assert_eq!(certified.get_proof(), decoded.get_proof());
}
#[test]
fn test_signed_dsign_cbor_roundtrip() {
use crate::dsign::{DsignAlgorithm, Ed25519, SignedDsign};
let signing_key = Ed25519::gen_key(&[42u8; 32]);
let signed = SignedDsign::<Ed25519>::sign(&signing_key, b"test message");
let encoded = signed.to_cbor();
let decoded = SignedDsign::<Ed25519>::from_cbor(&encoded).unwrap();
assert_eq!(
signed.get_signature().as_bytes(),
decoded.get_signature().as_bytes()
);
}
#[test]
fn test_ed25519_verification_key_cbor_roundtrip() {
use crate::dsign::ed25519::Ed25519VerificationKey;
use crate::dsign::{DsignAlgorithm, Ed25519};
let signing_key = Ed25519::gen_key(&[42u8; 32]);
let vk = Ed25519::derive_verification_key(&signing_key);
let encoded = vk.to_cbor();
let decoded = Ed25519VerificationKey::from_cbor(&encoded).unwrap();
assert_eq!(vk.as_bytes(), decoded.as_bytes());
}
#[test]
fn test_ed25519_signature_cbor_roundtrip() {
use crate::dsign::ed25519::Ed25519Signature;
use crate::dsign::{DsignAlgorithm, Ed25519};
let signing_key = Ed25519::gen_key(&[42u8; 32]);
let sig = Ed25519::sign(&signing_key, b"test message");
let encoded = sig.to_cbor();
let decoded = Ed25519Signature::from_cbor(&encoded).unwrap();
assert_eq!(sig.as_bytes(), decoded.as_bytes());
}
#[test]
fn test_dsign_size_expressions() {
assert_eq!(encoded_verification_key_dsign_size(), 34);
assert_eq!(encoded_signing_key_dsign_size(), 66);
assert_eq!(encoded_signature_dsign_size(), 66);
let vk = vec![0x42u8; 32];
assert_eq!(
encode_verification_key_dsign(&vk).len(),
encoded_verification_key_dsign_size()
);
let sig = vec![0x43u8; 64];
assert_eq!(
encode_signature_dsign(&sig).len(),
encoded_signature_dsign_size()
);
}
#[test]
fn test_vrf_size_expressions() {
assert_eq!(encoded_verification_key_vrf_size(), 34);
assert_eq!(encoded_signing_key_vrf_size(), 66);
assert_eq!(encoded_proof_vrf_draft03_size(), 82);
assert_eq!(encoded_proof_vrf_draft13_size(), 130);
assert_eq!(encoded_output_vrf_size(), 66);
let vk = vec![0x44u8; 32];
assert_eq!(
encode_verification_key_vrf(&vk).len(),
encoded_verification_key_vrf_size()
);
let proof = vec![0x45u8; 80];
assert_eq!(
encode_proof_vrf(&proof).len(),
encoded_proof_vrf_draft03_size()
);
let output = vec![0x46u8; 64];
assert_eq!(encode_output_vrf(&output).len(), encoded_output_vrf_size());
}
#[test]
fn test_kes_size_expressions() {
assert_eq!(encoded_verification_key_kes_size(), 34);
assert_eq!(encoded_signing_key_sum6kes_size(), 2115);
assert_eq!(encoded_signature_sum6kes_size(), 451);
let vk = vec![0x47u8; 32];
assert_eq!(
encode_verification_key_kes(&vk).len(),
encoded_verification_key_kes_size()
);
let sig = vec![0x48u8; 448];
assert_eq!(
encode_signature_kes(&sig).len(),
encoded_signature_sum6kes_size()
);
}
#[test]
fn test_hash_size_expressions() {
assert_eq!(encoded_hash_blake2b224_size(), 30);
assert_eq!(encoded_hash_blake2b256_size(), 34);
let hash224 = vec![0x49u8; 28];
assert_eq!(encode_hash(&hash224).len(), encoded_hash_blake2b224_size());
let hash256 = vec![0x4Au8; 32];
assert_eq!(encode_hash(&hash256).len(), encoded_hash_blake2b256_size());
}
#[test]
fn test_size_expression_generic() {
assert_eq!(encoded_verification_key_size(32), 34);
assert_eq!(encoded_verification_key_size(64), 66);
assert_eq!(encoded_signature_size(64), 66);
assert_eq!(encoded_signature_size(448), 451);
}
#[test]
fn test_size_expression_boundaries() {
assert_eq!(encoded_size_bytes(0), 1);
assert_eq!(encoded_size_bytes(23), 24);
assert_eq!(encoded_size_bytes(24), 26);
assert_eq!(encoded_size_bytes(255), 257);
assert_eq!(encoded_size_bytes(256), 259);
assert_eq!(encoded_size_bytes(65535), 65538);
assert_eq!(encoded_size_bytes(65536), 65541);
}
#[test]
fn test_dsign_verification_key_serialization_roundtrip() {
use crate::dsign::{DsignAlgorithm, Ed25519};
let signing_key = Ed25519::gen_key(&[0xABu8; 32]);
let vk = Ed25519::derive_verification_key(&signing_key);
let raw = Ed25519::raw_serialize_verification_key(&vk);
let recovered = Ed25519::raw_deserialize_verification_key(raw).unwrap();
assert_eq!(vk.as_bytes(), recovered.as_bytes());
let cbor = encode_verification_key_dsign(raw);
let decoded = decode_verification_key_dsign(&cbor).unwrap();
assert_eq!(raw, &decoded[..]);
}
#[test]
fn test_dsign_signature_serialization_roundtrip() {
use crate::dsign::{DsignAlgorithm, Ed25519};
let signing_key = Ed25519::gen_key(&[0xCDu8; 32]);
let sig = Ed25519::sign(&signing_key, b"test message");
let raw = Ed25519::raw_serialize_signature(&sig);
let recovered = Ed25519::raw_deserialize_signature(raw).unwrap();
assert_eq!(sig.as_bytes(), recovered.as_bytes());
let cbor = encode_signature_dsign(raw);
let decoded = decode_signature_dsign(&cbor).unwrap();
assert_eq!(raw, &decoded[..]);
}
#[test]
fn test_vrf_verification_key_serialization_roundtrip() {
use crate::vrf::{VrfAlgorithm, VrfDraft03};
let seed = [0xEFu8; 32];
let (_, vk) = VrfDraft03::keypair_from_seed(&seed);
let raw = VrfDraft03::raw_serialize_verification_key(&vk);
let recovered = VrfDraft03::raw_deserialize_verification_key(raw).unwrap();
assert_eq!(vk, recovered);
let cbor = encode_verification_key_vrf(raw);
let decoded = decode_verification_key_vrf(&cbor).unwrap();
assert_eq!(raw, &decoded[..]);
}
#[test]
fn test_vrf_proof_serialization_roundtrip() {
use crate::vrf::{VrfAlgorithm, VrfDraft03};
let seed = [0x12u8; 32];
let (sk, _) = VrfDraft03::keypair_from_seed(&seed);
let proof = VrfDraft03::prove(&sk, b"test input").unwrap();
let raw = VrfDraft03::raw_serialize_proof(&proof);
let recovered = VrfDraft03::raw_deserialize_proof(raw).unwrap();
assert_eq!(proof, recovered);
let cbor = encode_proof_vrf(raw);
let decoded = decode_proof_vrf(&cbor).unwrap();
assert_eq!(raw, &decoded[..]);
}
#[test]
fn test_kes_verification_key_serialization_roundtrip() {
use crate::kes::{KesAlgorithm, Sum6Kes};
let seed = [0x34u8; 32];
let signing_key = Sum6Kes::gen_key_kes_from_seed_bytes(&seed).unwrap();
let vk = Sum6Kes::derive_verification_key(&signing_key).unwrap();
let raw = Sum6Kes::raw_serialize_verification_key_kes(&vk);
let recovered = Sum6Kes::raw_deserialize_verification_key_kes(&raw).unwrap();
assert_eq!(vk, recovered);
let cbor = encode_verification_key_kes(&raw);
let decoded = decode_verification_key_kes(&cbor).unwrap();
assert_eq!(raw, decoded);
}
#[test]
fn test_kes_signature_serialization_roundtrip() {
use crate::kes::{KesAlgorithm, Sum6Kes};
let seed = [0x56u8; 32];
let signing_key = Sum6Kes::gen_key_kes_from_seed_bytes(&seed).unwrap();
let signature = Sum6Kes::sign_kes(&(), 0, b"test message", &signing_key).unwrap();
let raw = Sum6Kes::raw_serialize_signature_kes(&signature);
let _recovered = Sum6Kes::raw_deserialize_signature_kes(&raw).unwrap();
let cbor = encode_signature_kes(&raw);
let decoded = decode_signature_kes(&cbor).unwrap();
assert_eq!(raw, decoded);
}
}