use alloc::vec;
use serde::{Deserialize, Serialize};
use zeroize::ZeroizeOnDrop;
use super::backend::Backend;
use super::Algorithm;
use crate::primitive::Kind;
use crate::Rng;
use crate::{
key::{Key, KeyMaterial},
sensitive::Bytes,
};
#[derive(Clone, Debug, ZeroizeOnDrop, Eq, Serialize, Deserialize)]
pub(crate) struct Material {
value: Bytes,
#[zeroize(skip)]
#[serde(rename = "alg")]
algorithm: Algorithm,
}
impl PartialEq for Material {
fn eq(&self, other: &Self) -> bool {
self.algorithm == other.algorithm && self.value == other.value
}
}
impl KeyMaterial for Material {
type Algorithm = Algorithm;
fn algorithm(&self) -> Self::Algorithm {
self.algorithm
}
fn kind() -> Kind {
Kind::Aead
}
}
impl Material {
pub(super) fn generate<N>(rng: &N, algorithm: Algorithm) -> Self
where
N: Rng,
{
let mut bytes = vec![0u8; algorithm.key_len()];
rng.fill(&mut bytes).unwrap();
let value = bytes.into();
Self { value, algorithm }
}
pub(super) fn cipher(&self) -> Backend {
Backend::new(self.algorithm, &self.value)
}
pub(super) fn bytes(&self) -> &[u8] {
&self.value
}
}
impl Key<Material> {
pub(super) fn bytes(&self) -> &[u8] {
&self.material().value
}
pub(super) fn cipher(&self) -> Backend {
self.material().cipher()
}
pub fn len(&self) -> usize {
self.bytes().len()
}
}