acvm_blackbox_solver/
hash.rs

1use acir::BlackBoxFunc;
2use blake2::{Blake2s256, Digest};
3
4use crate::BlackBoxResolutionError;
5
6/// Does a generic hash of the inputs returning the resulting 32 bytes separately.
7fn generic_hash_256<D: Digest>(message: &[u8]) -> Result<[u8; 32], String> {
8    let output_bytes: [u8; 32] =
9        D::digest(message).as_slice().try_into().map_err(|_| "digest should be 256 bits")?;
10
11    Ok(output_bytes)
12}
13
14pub fn blake2s(inputs: &[u8]) -> Result<[u8; 32], BlackBoxResolutionError> {
15    generic_hash_256::<Blake2s256>(inputs)
16        .map_err(|err| BlackBoxResolutionError::Failed(BlackBoxFunc::Blake2s, err))
17}
18
19pub fn blake3(inputs: &[u8]) -> Result<[u8; 32], BlackBoxResolutionError> {
20    Ok(blake3::hash(inputs).into())
21}
22
23pub fn sha256_compression(state: &mut [u32; 8], msg_blocks: &[u32; 16]) {
24    let mut blocks: [u8; 64] = [0_u8; 64];
25    for (i, block) in msg_blocks.iter().enumerate() {
26        let bytes = block.to_be_bytes();
27        blocks[i * 4..i * 4 + 4].copy_from_slice(&bytes);
28    }
29    sha2::block_api::compress256(state, &[blocks]);
30}
31
32const KECCAK_LANES: usize = 25;
33/// Keccak permutation for a state of size 1600 bits, represented by 25 lanes of 64 bits (25*64 = 1600)
34pub fn keccakf1600(
35    mut state: [u64; KECCAK_LANES],
36) -> Result<[u64; KECCAK_LANES], BlackBoxResolutionError> {
37    keccak::Keccak::new().with_f1600(|f1600| f1600(&mut state));
38    Ok(state)
39}
40
41#[cfg(test)]
42mod keccakf1600_tests {
43    use super::keccakf1600;
44
45    #[test]
46    fn sanity_check() {
47        // cSpell:disable-next-line
48        // Test vectors are copied from XKCP (eXtended Keccak Code Package)
49        // https://github.com/XKCP/XKCP/blob/master/tests/TestVectors/KeccakF-1600-IntermediateValues.txt
50        let zero_state = [0u64; 25];
51
52        let expected_state_first = [
53            0xF1258F7940E1DDE7,
54            0x84D5CCF933C0478A,
55            0xD598261EA65AA9EE,
56            0xBD1547306F80494D,
57            0x8B284E056253D057,
58            0xFF97A42D7F8E6FD4,
59            0x90FEE5A0A44647C4,
60            0x8C5BDA0CD6192E76,
61            0xAD30A6F71B19059C,
62            0x30935AB7D08FFC64,
63            0xEB5AA93F2317D635,
64            0xA9A6E6260D712103,
65            0x81A57C16DBCF555F,
66            0x43B831CD0347C826,
67            0x01F22F1A11A5569F,
68            0x05E5635A21D9AE61,
69            0x64BEFEF28CC970F2,
70            0x613670957BC46611,
71            0xB87C5A554FD00ECB,
72            0x8C3EE88A1CCF32C8,
73            0x940C7922AE3A2614,
74            0x1841F924A2C509E4,
75            0x16F53526E70465C2,
76            0x75F644E97F30A13B,
77            0xEAF1FF7B5CECA249,
78        ];
79        let expected_state_second = [
80            0x2D5C954DF96ECB3C,
81            0x6A332CD07057B56D,
82            0x093D8D1270D76B6C,
83            0x8A20D9B25569D094,
84            0x4F9C4F99E5E7F156,
85            0xF957B9A2DA65FB38,
86            0x85773DAE1275AF0D,
87            0xFAF4F247C3D810F7,
88            0x1F1B9EE6F79A8759,
89            0xE4FECC0FEE98B425,
90            0x68CE61B6B9CE68A1,
91            0xDEEA66C4BA8F974F,
92            0x33C43D836EAFB1F5,
93            0xE00654042719DBD9,
94            0x7CF8A9F009831265,
95            0xFD5449A6BF174743,
96            0x97DDAD33D8994B40,
97            0x48EAD5FC5D0BE774,
98            0xE3B8C8EE55B7B03C,
99            0x91A0226E649E42E9,
100            0x900E3129E7BADD7B,
101            0x202A9EC5FAA3CCE8,
102            0x5B3402464E1C3DB6,
103            0x609F4E62A44C1059,
104            0x20D06CD26A8FBF5C,
105        ];
106
107        let state_first = keccakf1600(zero_state).unwrap();
108        let state_second = keccakf1600(state_first).unwrap();
109
110        assert_eq!(state_first, expected_state_first);
111        assert_eq!(state_second, expected_state_second);
112    }
113}