midnight_circuits/hash/ripemd160/
mod.rs1#![allow(non_snake_case)]
17mod ripemd160_chip;
18mod types;
19mod utils;
20
21use midnight_proofs::{circuit::Layouter, plonk::Error};
22use ripemd::Digest;
23pub use ripemd160_chip::{
24 RipeMD160Chip, RipeMD160Config, NB_RIPEMD160_ADVICE_COLS, NB_RIPEMD160_FIXED_COLS,
25};
26
27use crate::{
28 instructions::{hash::HashCPU, DecompositionInstructions, HashInstructions},
29 types::AssignedByte,
30 CircuitField,
31};
32
33impl<F: CircuitField> HashCPU<u8, [u8; 20]> for RipeMD160Chip<F> {
34 fn hash(inputs: &[u8]) -> [u8; 20] {
35 let output = ripemd::Ripemd160::digest(inputs);
36 output.into_iter().collect::<Vec<_>>().try_into().unwrap()
37 }
38}
39
40impl<F: CircuitField> HashInstructions<F, AssignedByte<F>, [AssignedByte<F>; 20]>
41 for RipeMD160Chip<F>
42{
43 fn hash(
44 &self,
45 layouter: &mut impl Layouter<F>,
46 inputs: &[AssignedByte<F>],
47 ) -> Result<[AssignedByte<F>; 20], Error> {
48 let mut output_bytes = Vec::with_capacity(20);
49
50 for word in self.ripemd160(layouter, inputs)? {
52 let bytes = self.native_gadget.assigned_to_le_bytes(layouter, &word.0, Some(4))?;
53 output_bytes.extend(bytes)
54 }
55
56 Ok(output_bytes.try_into().unwrap())
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use midnight_curves::Fq as Scalar;
63
64 use crate::{
65 field::NativeGadget, hash::ripemd160::RipeMD160Chip, instructions::hash::tests::test_hash,
66 types::AssignedByte,
67 };
68
69 #[test]
70 fn test_ripemd160_hash() {
71 fn test_wrapper(input_size: usize, cost_model: bool) {
72 test_hash::<
73 Scalar,
74 AssignedByte<Scalar>,
75 [AssignedByte<Scalar>; 20],
76 RipeMD160Chip<Scalar>,
77 NativeGadget<Scalar, _, _>,
78 >(cost_model, "RIPEMD160", input_size)
79 }
80
81 const RIPEMD160_BLOCK_SIZE: usize = 64;
82 const RIPEMD160_EDGE_PADDING: usize = 55;
83 test_wrapper(2 * RIPEMD160_BLOCK_SIZE, true);
84
85 test_wrapper(RIPEMD160_BLOCK_SIZE, false);
86 test_wrapper(RIPEMD160_BLOCK_SIZE - 1, false);
87 test_wrapper(RIPEMD160_BLOCK_SIZE - 2, false);
88 test_wrapper(4 * RIPEMD160_BLOCK_SIZE, false);
89
90 test_wrapper(RIPEMD160_EDGE_PADDING, false);
91 test_wrapper(RIPEMD160_EDGE_PADDING - 1, false);
92
93 test_wrapper(0, false);
94 test_wrapper(1, false);
95 test_wrapper(2, false);
96 }
97}