usecrate::{FixedOutput, FixedOutputReset, Update}; use crypto_common::{InvalidLength, Key, KeyInit, Output, OutputSizeUser, Reset};
#[cfg(feature = "rand_core")] usecrate::rand_core::{CryptoRng, RngCore}; use core::fmt; use crypto_common::typenum::Unsigned; use subtle::{Choice, ConstantTimeEq};
/// Convenience wrapper trait covering functionality of Message Authentication algorithms. /// /// This trait wraps [`KeyInit`], [`Update`], [`FixedOutput`], and [`MacMarker`] /// traits and provides additional convenience methods. #[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pubtrait Mac: OutputSizeUser + Sized { /// Create new value from fixed size key. fn new(key: &Key<Self>) -> Self where Self: KeyInit;
/// Generate random key using the provided [`CryptoRng`]. #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] fn generate_key(rng: impl CryptoRng + RngCore) -> Key<Self> where Self: KeyInit;
/// Create new value from variable size key. fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> where Self: KeyInit;
/// Update state using the provided data. fn update(&mutself, data: &[u8]);
/// Process input data in a chained manner. #[must_use] fn chain_update(self, data: impl AsRef<[u8]>) -> Self;
/// Obtain the result of a [`Mac`] computation as a [`CtOutput`] and consume /// [`Mac`] instance. fn finalize(self) -> CtOutput<Self>;
/// Obtain the result of a [`Mac`] computation as a [`CtOutput`] and reset /// [`Mac`] instance. fn finalize_reset(&mutself) -> CtOutput<Self> where Self: FixedOutputReset;
/// Reset MAC instance to its initial state. fn reset(&mutself) where Self: Reset;
/// Check if tag/code value is correct for the processed input. fn verify(self, tag: &Output<Self>) -> Result<(), MacError>;
/// Check if tag/code value is correct for the processed input and reset /// [`Mac`] instance. fn verify_reset(&mutself, tag: &Output<Self>) -> Result<(), MacError> where Self: FixedOutputReset;
/// Check truncated tag correctness using all bytes /// of calculated tag. /// /// Returns `Error` if `tag` is not valid or not equal in length /// to MAC's output. fn verify_slice(self, tag: &[u8]) -> Result<(), MacError>;
/// Check truncated tag correctness using all bytes /// of calculated tag and reset [`Mac`] instance. /// /// Returns `Error` if `tag` is not valid or not equal in length /// to MAC's output. fn verify_slice_reset(&mutself, tag: &[u8]) -> Result<(), MacError> where Self: FixedOutputReset;
/// Check truncated tag correctness using left side bytes /// (i.e. `tag[..n]`) of calculated tag. /// /// Returns `Error` if `tag` is not valid or empty. fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError>;
/// Check truncated tag correctness using right side bytes /// (i.e. `tag[n..]`) of calculated tag. /// /// Returns `Error` if `tag` is not valid or empty. fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError>;
}
impl<T: Update + FixedOutput + MacMarker> Mac for T { #[inline(always)] fn new(key: &Key<Self>) -> Self where Self: KeyInit,
{
KeyInit::new(key)
}
#[inline] fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> { let n = tag.len(); if n != Self::OutputSize::USIZE { return Err(MacError);
} let choice = self.finalize_fixed().ct_eq(tag); if choice.into() {
Ok(())
} else {
Err(MacError)
}
}
#[inline] fn verify_slice_reset(&mutself, tag: &[u8]) -> Result<(), MacError> where Self: FixedOutputReset,
{ let n = tag.len(); if n != Self::OutputSize::USIZE { return Err(MacError);
} let choice = self.finalize_fixed_reset().ct_eq(tag); if choice.into() {
Ok(())
} else {
Err(MacError)
}
}
fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> { let n = tag.len(); if n == 0 || n > Self::OutputSize::USIZE { return Err(MacError);
} let choice = self.finalize_fixed()[..n].ct_eq(tag);
if choice.into() {
Ok(())
} else {
Err(MacError)
}
}
fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError> { let n = tag.len(); if n == 0 || n > Self::OutputSize::USIZE { return Err(MacError);
} let m = Self::OutputSize::USIZE - n; let choice = self.finalize_fixed()[m..].ct_eq(tag);
if choice.into() {
Ok(())
} else {
Err(MacError)
}
}
/// Fixed size output value which provides a safe [`Eq`] implementation that /// runs in constant time. /// /// It is useful for implementing Message Authentication Codes (MACs). #[derive(Clone)] #[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pubstruct CtOutput<T: OutputSizeUser> {
bytes: Output<T>,
}
/// Error type for when the [`Output`] of a [`Mac`] /// is not equal to the expected value. #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pubstruct MacError;
impl fmt::Display for MacError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("MAC tag mismatch")
}
}
#[cfg(feature = "std")] impl std::error::Error for MacError {}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.