arnaucube
arnaucube/miden-cryptoPublic Self-hosted repository
feat: implement ord for rpo digest 256

closes #8
Victor Lopez victor@codx.io
Fri, 25 Nov 2022 00:04:39 +0100
commit

dc2e82e011ed4263f7b9acfc768647e8d2afd323

parent

6cf3b07e3f3a0f904c99ba5e3bdb981a6f1f27bf

1 files changed, 31 insertions(+), 1 deletions(-)

jump to
M src/hash/rpo/digest.rs → src/hash/rpo/digest.rs

@@ -3,7 +3,7 @@ use crate::{

ByteReader, ByteWriter, Deserializable, DeserializationError, Digest, Felt, Serializable, StarkField, String, ZERO, }; -use core::ops::Deref; +use core::{cmp::Ordering, ops::Deref}; // DIGEST TRAIT IMPLEMENTATIONS // ================================================================================================

@@ -93,6 +93,36 @@ type Target = [Felt; DIGEST_SIZE];

fn deref(&self) -> &Self::Target { &self.0 + } +} + +impl Ord for RpoDigest256 { + fn cmp(&self, other: &Self) -> Ordering { + // compare the inner u64 of both elements. + // + // it will iterate the elements and will return the first computation different than + // `Equal`. Otherwise, the ordering is equal. + // + // the endianness is irrelevant here because since, this being a cryptographically secure + // hash computation, the digest shouldn't have any ordered property of its input. + // + // finally, we use `Felt::inner` instead of `Felt::as_int` so we avoid performing a + // montgomery reduction for every limb. that is safe because every inner element of the + // digest is guaranteed to be in its canonical form (that is, `x in [0,p)`). + self.0 + .iter() + .map(Felt::inner) + .zip(other.0.iter().map(Felt::inner)) + .fold(Ordering::Equal, |ord, (a, b)| match ord { + Ordering::Equal => a.cmp(&b), + _ => ord, + }) + } +} + +impl PartialOrd for RpoDigest256 { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + Some(self.cmp(other)) } }