mirror of
https://github.com/BLAKE3-team/BLAKE3
synced 2024-05-28 13:46:02 +02:00
Implement Ord and PartialOrd for Hash
This removes the dependencies on constant_time_eq and replaces it with subtle.
This commit is contained in:
parent
4d32708f51
commit
becc5039cf
|
@ -23,7 +23,7 @@ neon = []
|
||||||
# --no-default-features, the only way to use the SIMD implementations in this
|
# --no-default-features, the only way to use the SIMD implementations in this
|
||||||
# crate is to enable the corresponding instruction sets statically for the
|
# crate is to enable the corresponding instruction sets statically for the
|
||||||
# entire build, with e.g. RUSTFLAGS="-C target-cpu=native".
|
# entire build, with e.g. RUSTFLAGS="-C target-cpu=native".
|
||||||
std = []
|
std = ["subtle/std"]
|
||||||
|
|
||||||
# The `rayon` feature (disabled by default, but enabled for docs.rs) adds the
|
# The `rayon` feature (disabled by default, but enabled for docs.rs) adds the
|
||||||
# `update_rayon` and (in combination with `mmap` below) `update_mmap_rayon`
|
# `update_rayon` and (in combination with `mmap` below) `update_mmap_rayon`
|
||||||
|
@ -94,12 +94,12 @@ features = ["mmap", "rayon", "serde", "zeroize"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
arrayref = "0.3.5"
|
arrayref = "0.3.5"
|
||||||
arrayvec = { version = "0.7.4", default-features = false }
|
arrayvec = { version = "0.7.4", default-features = false }
|
||||||
constant_time_eq = "0.3.0"
|
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
digest = { version = "0.10.1", features = [ "mac" ], optional = true }
|
digest = { version = "0.10.1", features = [ "mac" ], optional = true }
|
||||||
memmap2 = { version = "0.7.1", optional = true }
|
memmap2 = { version = "0.7.1", optional = true }
|
||||||
rayon = { version = "1.2.1", optional = true }
|
rayon = { version = "1.2.1", optional = true }
|
||||||
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
|
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
|
||||||
|
subtle = { version = "2.5.0", default-features = false, features = ["i128"] }
|
||||||
zeroize = { version = "1", default-features = false, features = ["zeroize_derive"], optional = true }
|
zeroize = { version = "1", default-features = false, features = ["zeroize_derive"], optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
31
src/lib.rs
31
src/lib.rs
|
@ -135,9 +135,10 @@ mod join;
|
||||||
|
|
||||||
use arrayref::{array_mut_ref, array_ref};
|
use arrayref::{array_mut_ref, array_ref};
|
||||||
use arrayvec::{ArrayString, ArrayVec};
|
use arrayvec::{ArrayString, ArrayVec};
|
||||||
use core::cmp;
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
use core::{cmp, cmp::Ordering};
|
||||||
use platform::{Platform, MAX_SIMD_DEGREE, MAX_SIMD_DEGREE_OR_2};
|
use platform::{Platform, MAX_SIMD_DEGREE, MAX_SIMD_DEGREE_OR_2};
|
||||||
|
use subtle::{ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater};
|
||||||
|
|
||||||
/// The number of bytes in a [`Hash`](struct.Hash.html), 32.
|
/// The number of bytes in a [`Hash`](struct.Hash.html), 32.
|
||||||
pub const OUT_LEN: usize = 32;
|
pub const OUT_LEN: usize = 32;
|
||||||
|
@ -309,7 +310,7 @@ impl core::str::FromStr for Hash {
|
||||||
impl PartialEq for Hash {
|
impl PartialEq for Hash {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &Hash) -> bool {
|
fn eq(&self, other: &Hash) -> bool {
|
||||||
constant_time_eq::constant_time_eq_32(&self.0, &other.0)
|
self.0.ct_eq(&other.0).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +318,7 @@ impl PartialEq for Hash {
|
||||||
impl PartialEq<[u8; OUT_LEN]> for Hash {
|
impl PartialEq<[u8; OUT_LEN]> for Hash {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &[u8; OUT_LEN]) -> bool {
|
fn eq(&self, other: &[u8; OUT_LEN]) -> bool {
|
||||||
constant_time_eq::constant_time_eq_32(&self.0, other)
|
self.0.ct_eq(other).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,12 +326,34 @@ impl PartialEq<[u8; OUT_LEN]> for Hash {
|
||||||
impl PartialEq<[u8]> for Hash {
|
impl PartialEq<[u8]> for Hash {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &[u8]) -> bool {
|
fn eq(&self, other: &[u8]) -> bool {
|
||||||
constant_time_eq::constant_time_eq(&self.0, other)
|
self.0.ct_eq(other).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for Hash {}
|
impl Eq for Hash {}
|
||||||
|
|
||||||
|
/// This implementation is constant-time.
|
||||||
|
impl PartialOrd for Hash {
|
||||||
|
#[inline]
|
||||||
|
fn partial_cmp(&self, other: &Hash) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Hash {
|
||||||
|
#[inline]
|
||||||
|
fn cmp(&self, other: &Hash) -> Ordering {
|
||||||
|
let l0 = u128::from_le_bytes(self.0[..16].try_into().unwrap());
|
||||||
|
let h0 = u128::from_le_bytes(self.0[16..].try_into().unwrap());
|
||||||
|
let l1 = u128::from_le_bytes(other.0[..16].try_into().unwrap());
|
||||||
|
let h1 = u128::from_le_bytes(other.0[16..].try_into().unwrap());
|
||||||
|
let h0_gt_h1 = h0.ct_gt(&h1);
|
||||||
|
let l0_gt_l1 = l0.ct_gt(&l1);
|
||||||
|
// Return `Less` if `h0 < h1` and `l0 < l1`, otherwise, return `Greater`.
|
||||||
|
Ordering::conditional_select(&Ordering::Greater, &Ordering::Less, !h0_gt_h1 & !l0_gt_l1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Hash {
|
impl fmt::Display for Hash {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
// Formatting field as `&str` to reduce code size since the `Debug`
|
// Formatting field as `&str` to reduce code size since the `Debug`
|
||||||
|
|
Loading…
Reference in New Issue