From ee310314cd2002903d75864adda15b66ad9ee784 Mon Sep 17 00:00:00 2001 From: William Batista Date: Mon, 9 Oct 2023 17:04:43 -0400 Subject: [PATCH] Add support for rkyv --- Cargo.toml | 3 ++- src/lib.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a98cb6a..3977786 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,7 +89,7 @@ no_neon = [] [package.metadata.docs.rs] # Document the rayon/mmap methods and the Serialize/Deserialize/Zeroize impls on docs.rs. -features = ["mmap", "rayon", "serde", "zeroize"] +features = ["mmap", "rayon", "serde", "zeroize", "rkyv"] [dependencies] arrayref = "0.3.5" @@ -101,6 +101,7 @@ memmap2 = { version = "0.7.1", optional = true } rayon = { version = "1.2.1", optional = true } serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } zeroize = { version = "1", default-features = false, features = ["zeroize_derive"], optional = true } +rkyv = { version = "0.7", features = ["validation"], optional = true } [dev-dependencies] hmac = "0.12.0" diff --git a/src/lib.rs b/src/lib.rs index 1fe47bf..199f21d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -218,6 +218,11 @@ fn counter_high(counter: u64) -> u32 { /// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html #[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[cfg_attr( + feature = "rkyv", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] +#[cfg_attr(feature = "rkyv", archive(check_bytes))] #[derive(Clone, Copy, Hash)] pub struct Hash([u8; OUT_LEN]); @@ -331,6 +336,45 @@ impl PartialEq<[u8]> for Hash { impl Eq for Hash {} +#[cfg(feature = "rkyv")] +/// This implementation is constant-time. +impl PartialEq for ArchivedHash { + #[inline] + fn eq(&self, other: &ArchivedHash) -> bool { + constant_time_eq::constant_time_eq_32(&self.0, &other.0) + } +} + +#[cfg(feature = "rkyv")] +/// This implementation is constant-time. +impl PartialEq<[u8; OUT_LEN]> for ArchivedHash { + #[inline] + fn eq(&self, other: &[u8; OUT_LEN]) -> bool { + constant_time_eq::constant_time_eq_32(&self.0, other) + } +} + +#[cfg(feature = "rkyv")] +/// This implementation is constant-time if the target is 32 bytes long. +impl PartialEq<[u8]> for ArchivedHash { + #[inline] + fn eq(&self, other: &[u8]) -> bool { + constant_time_eq::constant_time_eq(&self.0, other) + } +} + +#[cfg(feature = "rkyv")] +/// This implementation is constant-time if the target is 32 bytes long. +impl PartialEq for ArchivedHash { + #[inline] + fn eq(&self, other: &Hash) -> bool { + constant_time_eq::constant_time_eq(&self.0, &other.0) + } +} + +#[cfg(feature = "rkyv")] +impl Eq for ArchivedHash {} + impl fmt::Display for Hash { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Formatting field as `&str` to reduce code size since the `Debug`