Neptune-Crypto / twenty-first

Collection of mathematics routines and cryptography for the twenty-first century
GNU General Public License v2.0
74 stars 22 forks source link

Inconsistent byte encoding for `Digest` on big-endian host-machines #205

Closed Sword-Smith closed 6 months ago

Sword-Smith commented 7 months ago

Conversion from Digest to [u8, 40] happens through:

impl From<Digest> for [u8; Digest::BYTES] {
    fn from(item: Digest) -> Self {
        let u64s = item.0.iter().map(|x| x.value());
        u64s.map(|x| x.to_ne_bytes())
            .collect::<Vec<_>>()
            .concat()
            .try_into()
            .unwrap()
    }
}

To get the same byte encoding on all platforms, we should use x.to_le_bytes() instead, or at least be consistent with the opposite conversion. The opposite conversion currently uses u64::from_le_bytes(arr), so we might as well stay with little-endian encoding unless someone has a pronounced opinion about this.

The fix must include a test the verifies that digest conversion to and back from an array of 40 bytes is the identity operation. This new test should be added as a proptest using the #[proptest] pragma from the proptest crate that's already a dependency.