From dc2e82e011ed4263f7b9acfc768647e8d2afd323 Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Fri, 25 Nov 2022 00:04:39 +0100 Subject: [PATCH] feat: implement ord for rpo digest 256 closes #8 --- src/hash/rpo/digest.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/hash/rpo/digest.rs b/src/hash/rpo/digest.rs index f4e0aee..6b64130 100644 --- a/src/hash/rpo/digest.rs +++ b/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 // ================================================================================================ @@ -96,6 +96,36 @@ impl Deref for RpoDigest256 { } } +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 { + Some(self.cmp(other)) + } +} + // TESTS // ================================================================================================