1use super::*;
17
18impl<E: Environment, const RATE: usize> Hash for Poseidon<E, RATE> {
19 type Input = Field<E>;
20 type Output = Field<E>;
21
22 #[inline]
23 fn hash(&self, input: &[Self::Input]) -> Self::Output {
24 self.hash_many(input, 1).swap_remove(0)
25 }
26}
27
28#[cfg(all(test, feature = "console"))]
29mod tests {
30 use super::*;
31 use snarkvm_circuit_types::environment::Circuit;
32
33 use anyhow::Result;
34
35 const DOMAIN: &str = "PoseidonCircuit0";
36 const ITERATIONS: usize = 10;
37 const RATE: usize = 4;
38
39 fn check_hash(
40 mode: Mode,
41 num_inputs: usize,
42 num_constants: u64,
43 num_public: u64,
44 num_private: u64,
45 num_constraints: u64,
46 rng: &mut TestRng,
47 ) -> Result<()> {
48 use console::Hash as H;
49
50 let native = console::Poseidon::<<Circuit as Environment>::Network, RATE>::setup(DOMAIN)?;
51 let poseidon = Poseidon::<Circuit, RATE>::constant(native.clone());
52
53 for i in 0..ITERATIONS {
54 let native_input = (0..num_inputs)
56 .map(|_| console::Field::<<Circuit as Environment>::Network>::rand(rng))
57 .collect::<Vec<_>>();
58 let input = native_input.iter().map(|v| Field::<Circuit>::new(mode, *v)).collect::<Vec<_>>();
59
60 let expected = native.hash(&native_input).expect("Failed to hash native input");
62
63 Circuit::scope(format!("Poseidon {mode} {i}"), || {
65 let candidate = poseidon.hash(&input);
66 assert_eq!(expected, candidate.eject_value());
67 let case = format!("(mode = {mode}, num_inputs = {num_inputs})");
68 assert_scope!(case, num_constants, num_public, num_private, num_constraints);
69 });
70 Circuit::reset();
71 }
72 Ok(())
73 }
74
75 #[test]
76 fn test_hash_constant() -> Result<()> {
77 let mut rng = TestRng::default();
78
79 for num_inputs in 0..=RATE {
80 check_hash(Mode::Constant, num_inputs, 1, 0, 0, 0, &mut rng)?;
81 }
82 Ok(())
83 }
84
85 #[test]
86 fn test_hash_public() -> Result<()> {
87 let mut rng = TestRng::default();
88
89 check_hash(Mode::Public, 0, 1, 0, 0, 0, &mut rng)?;
90 check_hash(Mode::Public, 1, 1, 0, 335, 335, &mut rng)?;
91 check_hash(Mode::Public, 2, 1, 0, 340, 340, &mut rng)?;
92 check_hash(Mode::Public, 3, 1, 0, 345, 345, &mut rng)?;
93 check_hash(Mode::Public, 4, 1, 0, 350, 350, &mut rng)?;
94 check_hash(Mode::Public, 5, 1, 0, 705, 705, &mut rng)?;
95 check_hash(Mode::Public, 6, 1, 0, 705, 705, &mut rng)?;
96 check_hash(Mode::Public, 7, 1, 0, 705, 705, &mut rng)?;
97 check_hash(Mode::Public, 8, 1, 0, 705, 705, &mut rng)?;
98 check_hash(Mode::Public, 9, 1, 0, 1060, 1060, &mut rng)?;
99 check_hash(Mode::Public, 10, 1, 0, 1060, 1060, &mut rng)
100 }
101
102 #[test]
103 fn test_hash_private() -> Result<()> {
104 let mut rng = TestRng::default();
105
106 check_hash(Mode::Private, 0, 1, 0, 0, 0, &mut rng)?;
107 check_hash(Mode::Private, 1, 1, 0, 335, 335, &mut rng)?;
108 check_hash(Mode::Private, 2, 1, 0, 340, 340, &mut rng)?;
109 check_hash(Mode::Private, 3, 1, 0, 345, 345, &mut rng)?;
110 check_hash(Mode::Private, 4, 1, 0, 350, 350, &mut rng)?;
111 check_hash(Mode::Private, 5, 1, 0, 705, 705, &mut rng)?;
112 check_hash(Mode::Private, 6, 1, 0, 705, 705, &mut rng)?;
113 check_hash(Mode::Private, 7, 1, 0, 705, 705, &mut rng)?;
114 check_hash(Mode::Private, 8, 1, 0, 705, 705, &mut rng)?;
115 check_hash(Mode::Private, 9, 1, 0, 1060, 1060, &mut rng)?;
116 check_hash(Mode::Private, 10, 1, 0, 1060, 1060, &mut rng)
117 }
118}