use sframe::mls::{MlsKeyId, MlsKeyIdBitRange};
pub const EPOCH_BITS: u8 = 16;
pub const INDEX_BITS: u8 = 16;
const CONTEXT_ID: u64 = 0;
fn bit_range() -> MlsKeyIdBitRange {
MlsKeyIdBitRange::new(EPOCH_BITS, INDEX_BITS)
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SFrameHeader;
impl SFrameHeader {
#[inline]
pub fn kid_from(epoch: u64, leaf_index: u32) -> u64 {
MlsKeyId::new(CONTEXT_ID, epoch, u64::from(leaf_index), bit_range()).into()
}
#[inline]
pub fn epoch_from_kid(kid: u64) -> u64 {
MlsKeyId::from_key_id(kid, bit_range()).epoch_lsb()
}
#[inline]
pub fn epoch_lsb(epoch: u64) -> u64 {
Self::epoch_from_kid(Self::kid_from(epoch, 0))
}
#[inline]
pub fn leaf_from_kid(kid: u64) -> u32 {
MlsKeyId::from_key_id(kid, bit_range()).member_index() as u32
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn kid_round_trip() {
let epoch = 42u64;
let leaf = 7u32;
let kid = SFrameHeader::kid_from(epoch, leaf);
assert_eq!(SFrameHeader::epoch_from_kid(kid), epoch);
assert_eq!(SFrameHeader::leaf_from_kid(kid), leaf);
}
}