From 2435e29dbe57724ab3ae02fc5ea2a9cb83009f89 Mon Sep 17 00:00:00 2001 From: Jack O'Connor Date: Sat, 9 Mar 2024 15:56:45 -0800 Subject: [PATCH] avoid using constant_time_eq under Miri --- src/lib.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 1fe47bf54..d661cb2db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -305,10 +305,28 @@ impl core::str::FromStr for Hash { } } +// A proper implementation of constant time equality is tricky, and we get it from the +// constant_time_eq crate instead of rolling our own. However, that crate isn't compatible with +// Miri, so we roll our own just for that. +#[cfg(miri)] +fn constant_time_eq_miri(a: &[u8], b: &[u8]) -> bool { + if a.len() != b.len() { + return false; + } + let mut x = 0; + for i in 0..a.len() { + x |= a[i] ^ b[i]; + } + x == 0 +} + /// This implementation is constant-time. impl PartialEq for Hash { #[inline] fn eq(&self, other: &Hash) -> bool { + #[cfg(miri)] + return constant_time_eq_miri(&self.0, &other.0); + #[cfg(not(miri))] constant_time_eq::constant_time_eq_32(&self.0, &other.0) } } @@ -317,6 +335,9 @@ impl PartialEq for Hash { impl PartialEq<[u8; OUT_LEN]> for Hash { #[inline] fn eq(&self, other: &[u8; OUT_LEN]) -> bool { + #[cfg(miri)] + return constant_time_eq_miri(&self.0, other); + #[cfg(not(miri))] constant_time_eq::constant_time_eq_32(&self.0, other) } } @@ -325,6 +346,9 @@ impl PartialEq<[u8; OUT_LEN]> for Hash { impl PartialEq<[u8]> for Hash { #[inline] fn eq(&self, other: &[u8]) -> bool { + #[cfg(miri)] + return constant_time_eq_miri(&self.0, other); + #[cfg(not(miri))] constant_time_eq::constant_time_eq(&self.0, other) } }