chore: minor code organization improvement

This commit is contained in:
Bobbin Threadbare 2023-08-12 09:59:02 -07:00
parent 854ade1bfc
commit 6d0c7567f0
2 changed files with 72 additions and 57 deletions

1
PQClean Submodule

@ -0,0 +1 @@
Subproject commit c3abebf4ab1ff516ffa71e6337f06d898952c299

View file

@ -50,35 +50,54 @@ impl Digest for RpoDigest {
} }
} }
impl Serializable for RpoDigest { impl Deref for RpoDigest {
fn write_into<W: ByteWriter>(&self, target: &mut W) { type Target = [Felt; DIGEST_SIZE];
target.write_bytes(&self.as_bytes());
fn deref(&self) -> &Self::Target {
&self.0
} }
} }
impl Deserializable for RpoDigest { impl Ord for RpoDigest {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> { fn cmp(&self, other: &Self) -> Ordering {
let mut inner: [Felt; DIGEST_SIZE] = [ZERO; DIGEST_SIZE]; // compare the inner u64 of both elements.
for inner in inner.iter_mut() { //
let e = source.read_u64()?; // it will iterate the elements and will return the first computation different than
if e >= Felt::MODULUS { // `Equal`. Otherwise, the ordering is equal.
return Err(DeserializationError::InvalidValue(String::from( //
"Value not in the appropriate range", // 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.
} //
*inner = Felt::new(e); // 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)`).
Ok(Self(inner)) 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 From<[Felt; DIGEST_SIZE]> for RpoDigest { impl PartialOrd for RpoDigest {
fn from(value: [Felt; DIGEST_SIZE]) -> Self { fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Self(value) Some(self.cmp(other))
} }
} }
impl Display for RpoDigest {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let encoded: String = self.into();
write!(f, "{}", encoded)?;
Ok(())
}
}
// CONVERSIONS: FROM RPO DIGEST
// ================================================================================================
impl From<&RpoDigest> for [Felt; DIGEST_SIZE] { impl From<&RpoDigest> for [Felt; DIGEST_SIZE] {
fn from(value: &RpoDigest) -> Self { fn from(value: &RpoDigest) -> Self {
value.0 value.0
@ -126,17 +145,28 @@ impl From<RpoDigest> for [u8; DIGEST_BYTES] {
} }
impl From<RpoDigest> for String { impl From<RpoDigest> for String {
/// The returned string starts with `0x`.
fn from(value: RpoDigest) -> Self { fn from(value: RpoDigest) -> Self {
bytes_to_hex_string(value.as_bytes()) bytes_to_hex_string(value.as_bytes())
} }
} }
impl From<&RpoDigest> for String { impl From<&RpoDigest> for String {
/// The returned string starts with `0x`.
fn from(value: &RpoDigest) -> Self { fn from(value: &RpoDigest) -> Self {
(*value).into() (*value).into()
} }
} }
// CONVERSIONS: TO DIGEST
// ================================================================================================
impl From<[Felt; DIGEST_SIZE]> for RpoDigest {
fn from(value: [Felt; DIGEST_SIZE]) -> Self {
Self(value)
}
}
impl TryFrom<[u8; DIGEST_BYTES]> for RpoDigest { impl TryFrom<[u8; DIGEST_BYTES]> for RpoDigest {
type Error = HexParseError; type Error = HexParseError;
@ -159,6 +189,7 @@ impl TryFrom<[u8; DIGEST_BYTES]> for RpoDigest {
impl TryFrom<&str> for RpoDigest { impl TryFrom<&str> for RpoDigest {
type Error = HexParseError; type Error = HexParseError;
/// Expects the string to start with `0x`.
fn try_from(value: &str) -> Result<Self, Self::Error> { fn try_from(value: &str) -> Result<Self, Self::Error> {
hex_to_bytes(value).and_then(|v| v.try_into()) hex_to_bytes(value).and_then(|v| v.try_into())
} }
@ -167,6 +198,7 @@ impl TryFrom<&str> for RpoDigest {
impl TryFrom<String> for RpoDigest { impl TryFrom<String> for RpoDigest {
type Error = HexParseError; type Error = HexParseError;
/// Expects the string to start with `0x`.
fn try_from(value: String) -> Result<Self, Self::Error> { fn try_from(value: String) -> Result<Self, Self::Error> {
value.as_str().try_into() value.as_str().try_into()
} }
@ -175,53 +207,35 @@ impl TryFrom<String> for RpoDigest {
impl TryFrom<&String> for RpoDigest { impl TryFrom<&String> for RpoDigest {
type Error = HexParseError; type Error = HexParseError;
/// Expects the string to start with `0x`.
fn try_from(value: &String) -> Result<Self, Self::Error> { fn try_from(value: &String) -> Result<Self, Self::Error> {
value.as_str().try_into() value.as_str().try_into()
} }
} }
impl Deref for RpoDigest { // SERIALIZATION / DESERIALIZATION
type Target = [Felt; DIGEST_SIZE]; // ================================================================================================
fn deref(&self) -> &Self::Target { impl Serializable for RpoDigest {
&self.0 fn write_into<W: ByteWriter>(&self, target: &mut W) {
target.write_bytes(&self.as_bytes());
} }
} }
impl Ord for RpoDigest { impl Deserializable for RpoDigest {
fn cmp(&self, other: &Self) -> Ordering { fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
// compare the inner u64 of both elements. let mut inner: [Felt; DIGEST_SIZE] = [ZERO; DIGEST_SIZE];
// for inner in inner.iter_mut() {
// it will iterate the elements and will return the first computation different than let e = source.read_u64()?;
// `Equal`. Otherwise, the ordering is equal. if e >= Felt::MODULUS {
// return Err(DeserializationError::InvalidValue(String::from(
// the endianness is irrelevant here because since, this being a cryptographically secure "Value not in the appropriate range",
// 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 *inner = Felt::new(e);
// 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 RpoDigest { Ok(Self(inner))
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Display for RpoDigest {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let encoded: String = self.into();
write!(f, "{}", encoded)?;
Ok(())
} }
} }