anemoi/jubjub/anemoi_2_1/
digest.rs

1//! Digest trait implementation for Anemoi
2
3#[cfg(not(feature = "std"))]
4use alloc::vec::Vec;
5
6use super::DIGEST_SIZE;
7
8use super::Felt;
9use ark_serialize::CanonicalSerialize;
10
11#[derive(Debug, Copy, Clone, Eq, PartialEq)]
12/// An Anemoi Digest for the Anemoi Hash over Felt
13pub struct AnemoiDigest([Felt; DIGEST_SIZE]);
14
15impl AnemoiDigest {
16    /// Returns a new Digest from a provided array
17    pub fn new(value: [Felt; DIGEST_SIZE]) -> Self {
18        Self(value)
19    }
20
21    /// Returns a reference to the wrapped digest
22    pub fn as_elements(&self) -> &[Felt; DIGEST_SIZE] {
23        &self.0
24    }
25
26    /// Returns the wrapped digest
27    pub fn to_elements(&self) -> [Felt; DIGEST_SIZE] {
28        self.0
29    }
30
31    /// Returns a `Vec<Felt>` from the provided digest slice
32    pub fn digests_to_elements(digests: &[Self]) -> Vec<Felt> {
33        let mut res = Vec::with_capacity(digests.len() * DIGEST_SIZE);
34        for digest in digests {
35            res.extend(digest.as_elements())
36        }
37
38        res
39    }
40
41    /// Returns an array of bytes corresponding to the digest
42    pub fn to_bytes(&self) -> [u8; 32] {
43        let mut bytes = [0u8; 32];
44        self.0[0].serialize_compressed(&mut bytes[..]).unwrap();
45        bytes
46    }
47}
48
49impl Default for AnemoiDigest {
50    fn default() -> Self {
51        AnemoiDigest([Felt::default(); DIGEST_SIZE])
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    #[cfg(not(feature = "std"))]
58    use alloc::vec;
59
60    use super::super::Zero;
61    use super::*;
62    use ark_ff::UniformRand;
63    use rand_core::OsRng;
64
65    #[test]
66    fn digest_elements() {
67        let mut rng = OsRng;
68
69        for _ in 0..100 {
70            let mut array = [Felt::zero(); DIGEST_SIZE];
71            for item in array.iter_mut() {
72                *item = Felt::rand(&mut rng);
73            }
74
75            let digest = AnemoiDigest::new(array);
76            assert_eq!(digest.to_elements(), array);
77            assert_eq!(&digest.to_elements(), digest.as_elements());
78            assert_eq!(
79                digest.as_elements(),
80                &AnemoiDigest::digests_to_elements(&[digest])[..]
81            );
82        }
83
84        let digest = AnemoiDigest::default();
85        assert_eq!(digest.to_elements(), [Felt::zero(); DIGEST_SIZE]);
86        assert_eq!(digest.as_elements(), &vec![Felt::zero(); DIGEST_SIZE][..]);
87        assert_eq!(digest.to_bytes(), [0u8; 32]);
88    }
89}