use ::hmac::{Hmac, Mac};
use sha2::Sha512;
use crate::error::{Error, Result};
use crate::signature::Signature;
#[derive(Clone)]
pub struct HmacSigner {
inner: Hmac<Sha512>,
}
impl HmacSigner {
pub fn new(secret: impl AsRef<[u8]>) -> Result<Self> {
let inner =
<Hmac<Sha512> as Mac>::new_from_slice(secret.as_ref()).map_err(|_| Error::InvalidSecretLength)?;
Ok(Self { inner })
}
pub fn sign(&self, payload: impl AsRef<[u8]>) -> Signature {
let mut mac = self.inner.clone();
Mac::update(&mut mac, payload.as_ref());
let bytes = Mac::finalize(mac).into_bytes().to_vec();
Signature::from_bytes(bytes)
}
pub fn verify(&self, sig: &Signature, payload: impl AsRef<[u8]>) -> Result<()> {
let mut mac = self.inner.clone();
Mac::update(&mut mac, payload.as_ref());
Mac::verify_slice(mac, sig.as_bytes()).map_err(|_| Error::SymmetricVerifyFailed)
}
}