arnaucube
arnaucube/miden-cryptoPublic Self-hosted repository
Rpo256: Add RpoDigest conversions (#311)

Augusto Hack hack.augusto@gmail.com
Mon, 06 May 2024 23:58:25 +0200
commit

c0743adac98e00ac64b372d54f50a698dcf9f7be

parent

f72add58cd813e3398e0b9b4c4e14a7c24aecdde

3 files changed, 474 insertions(+), 143 deletions(-)

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

@@ -118,26 +118,106 @@

// CONVERSIONS: FROM RPO DIGEST // ================================================================================================ -impl From<&RpoDigest> for [Felt; DIGEST_SIZE] { - fn from(value: &RpoDigest) -> Self { - value.0 +#[derive(Copy, Clone, Debug)] +pub enum RpoDigestError { + InvalidInteger, +} + +impl TryFrom<&RpoDigest> for [bool; DIGEST_SIZE] { + type Error = RpoDigestError; + + fn try_from(value: &RpoDigest) -> Result<Self, Self::Error> { + (*value).try_into() + } +} + +impl TryFrom<RpoDigest> for [bool; DIGEST_SIZE] { + type Error = RpoDigestError; + + fn try_from(value: RpoDigest) -> Result<Self, Self::Error> { + fn to_bool(v: u64) -> Option<bool> { + if v <= 1 { + Some(v == 1) + } else { + None + } + } + + Ok([ + to_bool(value.0[0].as_int()).ok_or(RpoDigestError::InvalidInteger)?, + to_bool(value.0[1].as_int()).ok_or(RpoDigestError::InvalidInteger)?, + to_bool(value.0[2].as_int()).ok_or(RpoDigestError::InvalidInteger)?, + to_bool(value.0[3].as_int()).ok_or(RpoDigestError::InvalidInteger)?, + ]) + } +} + +impl TryFrom<&RpoDigest> for [u8; DIGEST_SIZE] { + type Error = RpoDigestError; + + fn try_from(value: &RpoDigest) -> Result<Self, Self::Error> { + (*value).try_into() } } -impl From<RpoDigest> for [Felt; DIGEST_SIZE] { - fn from(value: RpoDigest) -> Self { - value.0 +impl TryFrom<RpoDigest> for [u8; DIGEST_SIZE] { + type Error = RpoDigestError; + + fn try_from(value: RpoDigest) -> Result<Self, Self::Error> { + Ok([ + value.0[0].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value.0[1].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value.0[2].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value.0[3].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + ]) + } +} + +impl TryFrom<&RpoDigest> for [u16; DIGEST_SIZE] { + type Error = RpoDigestError; + + fn try_from(value: &RpoDigest) -> Result<Self, Self::Error> { + (*value).try_into() + } +} + +impl TryFrom<RpoDigest> for [u16; DIGEST_SIZE] { + type Error = RpoDigestError; + + fn try_from(value: RpoDigest) -> Result<Self, Self::Error> { + Ok([ + value.0[0].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value.0[1].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value.0[2].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value.0[3].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + ]) + } +} + +impl TryFrom<&RpoDigest> for [u32; DIGEST_SIZE] { + type Error = RpoDigestError; + + fn try_from(value: &RpoDigest) -> Result<Self, Self::Error> { + (*value).try_into() + } +} + +impl TryFrom<RpoDigest> for [u32; DIGEST_SIZE] { + type Error = RpoDigestError; + + fn try_from(value: RpoDigest) -> Result<Self, Self::Error> { + Ok([ + value.0[0].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value.0[1].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value.0[2].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value.0[3].as_int().try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + ]) } } impl From<&RpoDigest> for [u64; DIGEST_SIZE] { fn from(value: &RpoDigest) -> Self { - [ - value.0[0].as_int(), - value.0[1].as_int(), - value.0[2].as_int(), - value.0[3].as_int(), - ] + (*value).into() } }

@@ -152,9 +232,21 @@ ]

} } +impl From<&RpoDigest> for [Felt; DIGEST_SIZE] { + fn from(value: &RpoDigest) -> Self { + (*value).into() + } +} + +impl From<RpoDigest> for [Felt; DIGEST_SIZE] { + fn from(value: RpoDigest) -> Self { + value.0 + } +} + impl From<&RpoDigest> for [u8; DIGEST_BYTES] { fn from(value: &RpoDigest) -> Self { - value.as_bytes() + (*value).into() } }

@@ -164,6 +256,13 @@ value.as_bytes()

} } +impl From<&RpoDigest> for String { + /// The returned string starts with `0x`. + fn from(value: &RpoDigest) -> Self { + (*value).into() + } +} + impl From<RpoDigest> for String { /// The returned string starts with `0x`. fn from(value: RpoDigest) -> Self {

@@ -171,20 +270,76 @@ value.to_hex()

} } -impl From<&RpoDigest> for String { - /// The returned string starts with `0x`. - fn from(value: &RpoDigest) -> Self { +// CONVERSIONS: TO RPO DIGEST +// ================================================================================================ + +impl From<&[bool; DIGEST_SIZE]> for RpoDigest { + fn from(value: &[bool; DIGEST_SIZE]) -> Self { (*value).into() } } -// CONVERSIONS: TO RPO DIGEST -// ================================================================================================ +impl From<[bool; DIGEST_SIZE]> for RpoDigest { + fn from(value: [bool; DIGEST_SIZE]) -> Self { + [value[0] as u32, value[1] as u32, value[2] as u32, value[3] as u32].into() + } +} -#[derive(Copy, Clone, Debug)] -pub enum RpoDigestError { - /// The provided u64 integer does not fit in the field's moduli. - InvalidInteger, +impl From<&[u8; DIGEST_SIZE]> for RpoDigest { + fn from(value: &[u8; DIGEST_SIZE]) -> Self { + (*value).into() + } +} + +impl From<[u8; DIGEST_SIZE]> for RpoDigest { + fn from(value: [u8; DIGEST_SIZE]) -> Self { + Self([value[0].into(), value[1].into(), value[2].into(), value[3].into()]) + } +} + +impl From<&[u16; DIGEST_SIZE]> for RpoDigest { + fn from(value: &[u16; DIGEST_SIZE]) -> Self { + (*value).into() + } +} + +impl From<[u16; DIGEST_SIZE]> for RpoDigest { + fn from(value: [u16; DIGEST_SIZE]) -> Self { + Self([value[0].into(), value[1].into(), value[2].into(), value[3].into()]) + } +} + +impl From<&[u32; DIGEST_SIZE]> for RpoDigest { + fn from(value: &[u32; DIGEST_SIZE]) -> Self { + (*value).into() + } +} + +impl From<[u32; DIGEST_SIZE]> for RpoDigest { + fn from(value: [u32; DIGEST_SIZE]) -> Self { + Self([value[0].into(), value[1].into(), value[2].into(), value[3].into()]) + } +} + +impl TryFrom<&[u64; DIGEST_SIZE]> for RpoDigest { + type Error = RpoDigestError; + + fn try_from(value: &[u64; DIGEST_SIZE]) -> Result<Self, RpoDigestError> { + (*value).try_into() + } +} + +impl TryFrom<[u64; DIGEST_SIZE]> for RpoDigest { + type Error = RpoDigestError; + + fn try_from(value: [u64; DIGEST_SIZE]) -> Result<Self, RpoDigestError> { + Ok(Self([ + value[0].try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value[1].try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value[2].try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + value[3].try_into().map_err(|_| RpoDigestError::InvalidInteger)?, + ])) + } } impl From<&[Felt; DIGEST_SIZE]> for RpoDigest {

@@ -199,6 +354,14 @@ Self(value)

} } +impl TryFrom<&[u8; DIGEST_BYTES]> for RpoDigest { + type Error = HexParseError; + + fn try_from(value: &[u8; DIGEST_BYTES]) -> Result<Self, Self::Error> { + (*value).try_into() + } +} + impl TryFrom<[u8; DIGEST_BYTES]> for RpoDigest { type Error = HexParseError;

@@ -218,14 +381,6 @@ Ok(RpoDigest([Felt::new(a), Felt::new(b), Felt::new(c), Felt::new(d)]))

} } -impl TryFrom<&[u8; DIGEST_BYTES]> for RpoDigest { - type Error = HexParseError; - - fn try_from(value: &[u8; DIGEST_BYTES]) -> Result<Self, Self::Error> { - (*value).try_into() - } -} - impl TryFrom<&[u8]> for RpoDigest { type Error = HexParseError;

@@ -234,33 +389,12 @@ (*value).try_into()

} } -impl TryFrom<[u64; DIGEST_SIZE]> for RpoDigest { - type Error = RpoDigestError; - - fn try_from(value: [u64; DIGEST_SIZE]) -> Result<Self, RpoDigestError> { - Ok(Self([ - value[0].try_into().map_err(|_| RpoDigestError::InvalidInteger)?, - value[1].try_into().map_err(|_| RpoDigestError::InvalidInteger)?, - value[2].try_into().map_err(|_| RpoDigestError::InvalidInteger)?, - value[3].try_into().map_err(|_| RpoDigestError::InvalidInteger)?, - ])) - } -} - -impl TryFrom<&[u64; DIGEST_SIZE]> for RpoDigest { - type Error = RpoDigestError; - - fn try_from(value: &[u64; DIGEST_SIZE]) -> Result<Self, RpoDigestError> { - (*value).try_into() - } -} - impl TryFrom<&str> for RpoDigest { type Error = HexParseError; /// Expects the string to start with `0x`. fn try_from(value: &str) -> Result<Self, Self::Error> { - hex_to_bytes(value).and_then(|v| v.try_into()) + hex_to_bytes::<DIGEST_BYTES>(value).and_then(RpoDigest::try_from) } }

@@ -373,43 +507,71 @@ Felt::new(rand_value()),

Felt::new(rand_value()), ]); - let v: [Felt; DIGEST_SIZE] = digest.into(); + // BY VALUE + // ---------------------------------------------------------------------------------------- + let v: [bool; DIGEST_SIZE] = [true, false, true, true]; let v2: RpoDigest = v.into(); - assert_eq!(digest, v2); + assert_eq!(v, <[bool; DIGEST_SIZE]>::try_from(v2).unwrap()); + + let v: [u8; DIGEST_SIZE] = [0_u8, 1_u8, 2_u8, 3_u8]; + let v2: RpoDigest = v.into(); + assert_eq!(v, <[u8; DIGEST_SIZE]>::try_from(v2).unwrap()); + + let v: [u16; DIGEST_SIZE] = [0_u16, 1_u16, 2_u16, 3_u16]; + let v2: RpoDigest = v.into(); + assert_eq!(v, <[u16; DIGEST_SIZE]>::try_from(v2).unwrap()); - let v: [Felt; DIGEST_SIZE] = (&digest).into(); + let v: [u32; DIGEST_SIZE] = [0_u32, 1_u32, 2_u32, 3_u32]; let v2: RpoDigest = v.into(); - assert_eq!(digest, v2); + assert_eq!(v, <[u32; DIGEST_SIZE]>::try_from(v2).unwrap()); let v: [u64; DIGEST_SIZE] = digest.into(); let v2: RpoDigest = v.try_into().unwrap(); assert_eq!(digest, v2); - let v: [u64; DIGEST_SIZE] = (&digest).into(); - let v2: RpoDigest = v.try_into().unwrap(); + let v: [Felt; DIGEST_SIZE] = digest.into(); + let v2: RpoDigest = v.into(); assert_eq!(digest, v2); let v: [u8; DIGEST_BYTES] = digest.into(); let v2: RpoDigest = v.try_into().unwrap(); assert_eq!(digest, v2); - let v: [u8; DIGEST_BYTES] = (&digest).into(); + let v: String = digest.into(); let v2: RpoDigest = v.try_into().unwrap(); assert_eq!(digest, v2); - let v: String = digest.into(); - let v2: RpoDigest = v.try_into().unwrap(); + // BY REF + // ---------------------------------------------------------------------------------------- + let v: [bool; DIGEST_SIZE] = [true, false, true, true]; + let v2: RpoDigest = (&v).into(); + assert_eq!(v, <[bool; DIGEST_SIZE]>::try_from(&v2).unwrap()); + + let v: [u8; DIGEST_SIZE] = [0_u8, 1_u8, 2_u8, 3_u8]; + let v2: RpoDigest = (&v).into(); + assert_eq!(v, <[u8; DIGEST_SIZE]>::try_from(&v2).unwrap()); + + let v: [u16; DIGEST_SIZE] = [0_u16, 1_u16, 2_u16, 3_u16]; + let v2: RpoDigest = (&v).into(); + assert_eq!(v, <[u16; DIGEST_SIZE]>::try_from(&v2).unwrap()); + + let v: [u32; DIGEST_SIZE] = [0_u32, 1_u32, 2_u32, 3_u32]; + let v2: RpoDigest = (&v).into(); + assert_eq!(v, <[u32; DIGEST_SIZE]>::try_from(&v2).unwrap()); + + let v: [u64; DIGEST_SIZE] = (&digest).into(); + let v2: RpoDigest = (&v).try_into().unwrap(); assert_eq!(digest, v2); - let v: String = (&digest).into(); - let v2: RpoDigest = v.try_into().unwrap(); + let v: [Felt; DIGEST_SIZE] = (&digest).into(); + let v2: RpoDigest = (&v).into(); assert_eq!(digest, v2); - let v: [u8; DIGEST_BYTES] = digest.into(); + let v: [u8; DIGEST_BYTES] = (&digest).into(); let v2: RpoDigest = (&v).try_into().unwrap(); assert_eq!(digest, v2); - let v: [u8; DIGEST_BYTES] = (&digest).into(); + let v: String = (&digest).into(); let v2: RpoDigest = (&v).try_into().unwrap(); assert_eq!(digest, v2); }
M src/hash/rescue/rpx/digest.rs → src/hash/rescue/rpx/digest.rs

@@ -118,26 +118,106 @@

// CONVERSIONS: FROM RPX DIGEST // ================================================================================================ -impl From<&RpxDigest> for [Felt; DIGEST_SIZE] { - fn from(value: &RpxDigest) -> Self { - value.0 +#[derive(Copy, Clone, Debug)] +pub enum RpxDigestError { + InvalidInteger, +} + +impl TryFrom<&RpxDigest> for [bool; DIGEST_SIZE] { + type Error = RpxDigestError; + + fn try_from(value: &RpxDigest) -> Result<Self, Self::Error> { + (*value).try_into() + } +} + +impl TryFrom<RpxDigest> for [bool; DIGEST_SIZE] { + type Error = RpxDigestError; + + fn try_from(value: RpxDigest) -> Result<Self, Self::Error> { + fn to_bool(v: u64) -> Option<bool> { + if v <= 1 { + Some(v == 1) + } else { + None + } + } + + Ok([ + to_bool(value.0[0].as_int()).ok_or(RpxDigestError::InvalidInteger)?, + to_bool(value.0[1].as_int()).ok_or(RpxDigestError::InvalidInteger)?, + to_bool(value.0[2].as_int()).ok_or(RpxDigestError::InvalidInteger)?, + to_bool(value.0[3].as_int()).ok_or(RpxDigestError::InvalidInteger)?, + ]) + } +} + +impl TryFrom<&RpxDigest> for [u8; DIGEST_SIZE] { + type Error = RpxDigestError; + + fn try_from(value: &RpxDigest) -> Result<Self, Self::Error> { + (*value).try_into() + } +} + +impl TryFrom<RpxDigest> for [u8; DIGEST_SIZE] { + type Error = RpxDigestError; + + fn try_from(value: RpxDigest) -> Result<Self, Self::Error> { + Ok([ + value.0[0].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value.0[1].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value.0[2].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value.0[3].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + ]) + } +} + +impl TryFrom<&RpxDigest> for [u16; DIGEST_SIZE] { + type Error = RpxDigestError; + + fn try_from(value: &RpxDigest) -> Result<Self, Self::Error> { + (*value).try_into() + } +} + +impl TryFrom<RpxDigest> for [u16; DIGEST_SIZE] { + type Error = RpxDigestError; + + fn try_from(value: RpxDigest) -> Result<Self, Self::Error> { + Ok([ + value.0[0].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value.0[1].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value.0[2].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value.0[3].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + ]) + } +} + +impl TryFrom<&RpxDigest> for [u32; DIGEST_SIZE] { + type Error = RpxDigestError; + + fn try_from(value: &RpxDigest) -> Result<Self, Self::Error> { + (*value).try_into() } } -impl From<RpxDigest> for [Felt; DIGEST_SIZE] { - fn from(value: RpxDigest) -> Self { - value.0 +impl TryFrom<RpxDigest> for [u32; DIGEST_SIZE] { + type Error = RpxDigestError; + + fn try_from(value: RpxDigest) -> Result<Self, Self::Error> { + Ok([ + value.0[0].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value.0[1].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value.0[2].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value.0[3].as_int().try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + ]) } } impl From<&RpxDigest> for [u64; DIGEST_SIZE] { fn from(value: &RpxDigest) -> Self { - [ - value.0[0].as_int(), - value.0[1].as_int(), - value.0[2].as_int(), - value.0[3].as_int(), - ] + (*value).into() } }

@@ -152,6 +232,18 @@ ]

} } +impl From<&RpxDigest> for [Felt; DIGEST_SIZE] { + fn from(value: &RpxDigest) -> Self { + value.0 + } +} + +impl From<RpxDigest> for [Felt; DIGEST_SIZE] { + fn from(value: RpxDigest) -> Self { + value.0 + } +} + impl From<&RpxDigest> for [u8; DIGEST_BYTES] { fn from(value: &RpxDigest) -> Self { value.as_bytes()

@@ -164,6 +256,13 @@ value.as_bytes()

} } +impl From<&RpxDigest> for String { + /// The returned string starts with `0x`. + fn from(value: &RpxDigest) -> Self { + (*value).into() + } +} + impl From<RpxDigest> for String { /// The returned string starts with `0x`. fn from(value: RpxDigest) -> Self {

@@ -171,20 +270,76 @@ value.to_hex()

} } -impl From<&RpxDigest> for String { - /// The returned string starts with `0x`. - fn from(value: &RpxDigest) -> Self { +// CONVERSIONS: TO RPX DIGEST +// ================================================================================================ + +impl From<&[bool; DIGEST_SIZE]> for RpxDigest { + fn from(value: &[bool; DIGEST_SIZE]) -> Self { (*value).into() } } -// CONVERSIONS: TO RPX DIGEST -// ================================================================================================ +impl From<[bool; DIGEST_SIZE]> for RpxDigest { + fn from(value: [bool; DIGEST_SIZE]) -> Self { + [value[0] as u32, value[1] as u32, value[2] as u32, value[3] as u32].into() + } +} -#[derive(Copy, Clone, Debug)] -pub enum RpxDigestError { - /// The provided u64 integer does not fit in the field's moduli. - InvalidInteger, +impl From<&[u8; DIGEST_SIZE]> for RpxDigest { + fn from(value: &[u8; DIGEST_SIZE]) -> Self { + (*value).into() + } +} + +impl From<[u8; DIGEST_SIZE]> for RpxDigest { + fn from(value: [u8; DIGEST_SIZE]) -> Self { + Self([value[0].into(), value[1].into(), value[2].into(), value[3].into()]) + } +} + +impl From<&[u16; DIGEST_SIZE]> for RpxDigest { + fn from(value: &[u16; DIGEST_SIZE]) -> Self { + (*value).into() + } +} + +impl From<[u16; DIGEST_SIZE]> for RpxDigest { + fn from(value: [u16; DIGEST_SIZE]) -> Self { + Self([value[0].into(), value[1].into(), value[2].into(), value[3].into()]) + } +} + +impl From<&[u32; DIGEST_SIZE]> for RpxDigest { + fn from(value: &[u32; DIGEST_SIZE]) -> Self { + (*value).into() + } +} + +impl From<[u32; DIGEST_SIZE]> for RpxDigest { + fn from(value: [u32; DIGEST_SIZE]) -> Self { + Self([value[0].into(), value[1].into(), value[2].into(), value[3].into()]) + } +} + +impl TryFrom<&[u64; DIGEST_SIZE]> for RpxDigest { + type Error = RpxDigestError; + + fn try_from(value: &[u64; DIGEST_SIZE]) -> Result<Self, RpxDigestError> { + (*value).try_into() + } +} + +impl TryFrom<[u64; DIGEST_SIZE]> for RpxDigest { + type Error = RpxDigestError; + + fn try_from(value: [u64; DIGEST_SIZE]) -> Result<Self, RpxDigestError> { + Ok(Self([ + value[0].try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value[1].try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value[2].try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + value[3].try_into().map_err(|_| RpxDigestError::InvalidInteger)?, + ])) + } } impl From<&[Felt; DIGEST_SIZE]> for RpxDigest {

@@ -199,6 +354,14 @@ Self(value)

} } +impl TryFrom<&[u8; DIGEST_BYTES]> for RpxDigest { + type Error = HexParseError; + + fn try_from(value: &[u8; DIGEST_BYTES]) -> Result<Self, Self::Error> { + (*value).try_into() + } +} + impl TryFrom<[u8; DIGEST_BYTES]> for RpxDigest { type Error = HexParseError;

@@ -218,14 +381,6 @@ Ok(RpxDigest([Felt::new(a), Felt::new(b), Felt::new(c), Felt::new(d)]))

} } -impl TryFrom<&[u8; DIGEST_BYTES]> for RpxDigest { - type Error = HexParseError; - - fn try_from(value: &[u8; DIGEST_BYTES]) -> Result<Self, Self::Error> { - (*value).try_into() - } -} - impl TryFrom<&[u8]> for RpxDigest { type Error = HexParseError;

@@ -234,50 +389,29 @@ (*value).try_into()

} } -impl TryFrom<[u64; DIGEST_SIZE]> for RpxDigest { - type Error = RpxDigestError; - - fn try_from(value: [u64; DIGEST_SIZE]) -> Result<Self, RpxDigestError> { - Ok(Self([ - value[0].try_into().map_err(|_| RpxDigestError::InvalidInteger)?, - value[1].try_into().map_err(|_| RpxDigestError::InvalidInteger)?, - value[2].try_into().map_err(|_| RpxDigestError::InvalidInteger)?, - value[3].try_into().map_err(|_| RpxDigestError::InvalidInteger)?, - ])) - } -} - -impl TryFrom<&[u64; DIGEST_SIZE]> for RpxDigest { - type Error = RpxDigestError; - - fn try_from(value: &[u64; DIGEST_SIZE]) -> Result<Self, RpxDigestError> { - (*value).try_into() - } -} - impl TryFrom<&str> for RpxDigest { type Error = HexParseError; /// Expects the string to start with `0x`. fn try_from(value: &str) -> Result<Self, Self::Error> { - hex_to_bytes(value).and_then(|v| v.try_into()) + hex_to_bytes::<DIGEST_BYTES>(value).and_then(RpxDigest::try_from) } } -impl TryFrom<String> for RpxDigest { +impl TryFrom<&String> for RpxDigest { 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() } } -impl TryFrom<&String> for RpxDigest { +impl TryFrom<String> for RpxDigest { 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() } }

@@ -308,6 +442,17 @@ Ok(Self(inner))

} } +// ITERATORS +// ================================================================================================ +impl IntoIterator for RpxDigest { + type Item = Felt; + type IntoIter = <[Felt; 4] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + // TESTS // ================================================================================================

@@ -338,7 +483,6 @@

assert_eq!(d1, d2); } - #[cfg(feature = "std")] #[test] fn digest_encoding() { let digest = RpxDigest([

@@ -363,43 +507,71 @@ Felt::new(rand_value()),

Felt::new(rand_value()), ]); - let v: [Felt; DIGEST_SIZE] = digest.into(); + // BY VALUE + // ---------------------------------------------------------------------------------------- + let v: [bool; DIGEST_SIZE] = [true, false, true, true]; + let v2: RpxDigest = v.into(); + assert_eq!(v, <[bool; DIGEST_SIZE]>::try_from(v2).unwrap()); + + let v: [u8; DIGEST_SIZE] = [0_u8, 1_u8, 2_u8, 3_u8]; + let v2: RpxDigest = v.into(); + assert_eq!(v, <[u8; DIGEST_SIZE]>::try_from(v2).unwrap()); + + let v: [u16; DIGEST_SIZE] = [0_u16, 1_u16, 2_u16, 3_u16]; let v2: RpxDigest = v.into(); - assert_eq!(digest, v2); + assert_eq!(v, <[u16; DIGEST_SIZE]>::try_from(v2).unwrap()); - let v: [Felt; DIGEST_SIZE] = (&digest).into(); + let v: [u32; DIGEST_SIZE] = [0_u32, 1_u32, 2_u32, 3_u32]; let v2: RpxDigest = v.into(); - assert_eq!(digest, v2); + assert_eq!(v, <[u32; DIGEST_SIZE]>::try_from(v2).unwrap()); let v: [u64; DIGEST_SIZE] = digest.into(); let v2: RpxDigest = v.try_into().unwrap(); assert_eq!(digest, v2); - let v: [u64; DIGEST_SIZE] = (&digest).into(); - let v2: RpxDigest = v.try_into().unwrap(); + let v: [Felt; DIGEST_SIZE] = digest.into(); + let v2: RpxDigest = v.into(); assert_eq!(digest, v2); let v: [u8; DIGEST_BYTES] = digest.into(); let v2: RpxDigest = v.try_into().unwrap(); assert_eq!(digest, v2); - let v: [u8; DIGEST_BYTES] = (&digest).into(); + let v: String = digest.into(); let v2: RpxDigest = v.try_into().unwrap(); assert_eq!(digest, v2); - let v: String = digest.into(); - let v2: RpxDigest = v.try_into().unwrap(); + // BY REF + // ---------------------------------------------------------------------------------------- + let v: [bool; DIGEST_SIZE] = [true, false, true, true]; + let v2: RpxDigest = (&v).into(); + assert_eq!(v, <[bool; DIGEST_SIZE]>::try_from(&v2).unwrap()); + + let v: [u8; DIGEST_SIZE] = [0_u8, 1_u8, 2_u8, 3_u8]; + let v2: RpxDigest = (&v).into(); + assert_eq!(v, <[u8; DIGEST_SIZE]>::try_from(&v2).unwrap()); + + let v: [u16; DIGEST_SIZE] = [0_u16, 1_u16, 2_u16, 3_u16]; + let v2: RpxDigest = (&v).into(); + assert_eq!(v, <[u16; DIGEST_SIZE]>::try_from(&v2).unwrap()); + + let v: [u32; DIGEST_SIZE] = [0_u32, 1_u32, 2_u32, 3_u32]; + let v2: RpxDigest = (&v).into(); + assert_eq!(v, <[u32; DIGEST_SIZE]>::try_from(&v2).unwrap()); + + let v: [u64; DIGEST_SIZE] = (&digest).into(); + let v2: RpxDigest = (&v).try_into().unwrap(); assert_eq!(digest, v2); - let v: String = (&digest).into(); - let v2: RpxDigest = v.try_into().unwrap(); + let v: [Felt; DIGEST_SIZE] = (&digest).into(); + let v2: RpxDigest = (&v).into(); assert_eq!(digest, v2); - let v: [u8; DIGEST_BYTES] = digest.into(); + let v: [u8; DIGEST_BYTES] = (&digest).into(); let v2: RpxDigest = (&v).try_into().unwrap(); assert_eq!(digest, v2); - let v: [u8; DIGEST_BYTES] = (&digest).into(); + let v: String = (&digest).into(); let v2: RpxDigest = (&v).try_into().unwrap(); assert_eq!(digest, v2); }
M src/merkle/smt/full/tests.rs → src/merkle/smt/full/tests.rs

@@ -287,8 +287,7 @@ /// Tests that `get_value()` works as expected

#[test] fn test_smt_get_value() { let key_1: RpoDigest = RpoDigest::from([ONE, ONE, ONE, ONE]); - let key_2: RpoDigest = - RpoDigest::from([2_u32.into(), 2_u32.into(), 2_u32.into(), 2_u32.into()]); + let key_2: RpoDigest = RpoDigest::from([2_u32, 2_u32, 2_u32, 2_u32]); let value_1 = [ONE; WORD_SIZE]; let value_2 = [2_u32.into(); WORD_SIZE];

@@ -302,8 +301,7 @@ assert_eq!(value_1, returned_value_1);

assert_eq!(value_2, returned_value_2); // Check that a key with no inserted value returns the empty word - let key_no_value = - RpoDigest::from([42_u32.into(), 42_u32.into(), 42_u32.into(), 42_u32.into()]); + let key_no_value = RpoDigest::from([42_u32, 42_u32, 42_u32, 42_u32]); assert_eq!(EMPTY_WORD, smt.get_value(&key_no_value)); }

@@ -312,8 +310,7 @@ /// Tests that `entries()` works as expected

#[test] fn test_smt_entries() { let key_1: RpoDigest = RpoDigest::from([ONE, ONE, ONE, ONE]); - let key_2: RpoDigest = - RpoDigest::from([2_u32.into(), 2_u32.into(), 2_u32.into(), 2_u32.into()]); + let key_2: RpoDigest = RpoDigest::from([2_u32, 2_u32, 2_u32, 2_u32]); let value_1 = [ONE; WORD_SIZE]; let value_2 = [2_u32.into(); WORD_SIZE];

@@ -347,7 +344,7 @@

#[test] fn test_single_smt_leaf_serialization() { let single_leaf = SmtLeaf::new_single( - RpoDigest::from([10_u32.into(), 11_u32.into(), 12_u32.into(), 13_u32.into()]), + RpoDigest::from([10_u32, 11_u32, 12_u32, 13_u32]), [1_u32.into(), 2_u32.into(), 3_u32.into(), 4_u32.into()], );

@@ -363,11 +360,11 @@ #[test]

fn test_multiple_smt_leaf_serialization_success() { let multiple_leaf = SmtLeaf::new_multiple(vec![ ( - RpoDigest::from([10_u32.into(), 11_u32.into(), 12_u32.into(), 13_u32.into()]), + RpoDigest::from([10_u32, 11_u32, 12_u32, 13_u32]), [1_u32.into(), 2_u32.into(), 3_u32.into(), 4_u32.into()], ), ( - RpoDigest::from([100_u32.into(), 101_u32.into(), 102_u32.into(), 13_u32.into()]), + RpoDigest::from([100_u32, 101_u32, 102_u32, 13_u32]), [11_u32.into(), 12_u32.into(), 13_u32.into(), 14_u32.into()], ), ])