snarkvm_circuit_algorithms/pedersen/
hash.rs1use super::*;
17
18impl<E: Environment, const NUM_BITS: u8> Hash for Pedersen<E, NUM_BITS> {
19 type Input = Boolean<E>;
20 type Output = Field<E>;
21
22 fn hash(&self, input: &[Self::Input]) -> Self::Output {
24 self.hash_uncompressed(input).to_x_coordinate()
26 }
27}
28
29impl<E: Environment, const NUM_BITS: u8> Metrics<dyn Hash<Input = Boolean<E>, Output = Field<E>>>
30 for Pedersen<E, NUM_BITS>
31{
32 type Case = Vec<Mode>;
33
34 #[inline]
35 fn count(case: &Self::Case) -> Count {
36 count!(Pedersen<E, NUM_BITS>, HashUncompressed<Input = Boolean<E>, Output = Group<E>>, case)
37 }
38}
39
40impl<E: Environment, const NUM_BITS: u8> OutputMode<dyn Hash<Input = Boolean<E>, Output = Field<E>>>
41 for Pedersen<E, NUM_BITS>
42{
43 type Case = Vec<Mode>;
44
45 #[inline]
46 fn output_mode(parameter: &Self::Case) -> Mode {
47 output_mode!(Pedersen<E, NUM_BITS>, HashUncompressed<Input = Boolean<E>, Output = Group<E>>, parameter)
48 }
49}
50
51#[cfg(all(test, feature = "console"))]
52mod tests {
53 use super::*;
54 use snarkvm_circuit_types::environment::Circuit;
55 use snarkvm_utilities::{TestRng, Uniform};
56
57 const ITERATIONS: u64 = 10;
58 const MESSAGE: &str = "PedersenCircuit0";
59 const NUM_BITS_MULTIPLIER: u8 = 8;
60
61 fn check_hash<const NUM_BITS: u8>(mode: Mode, rng: &mut TestRng) {
62 use console::Hash as H;
63
64 let native = console::Pedersen::<<Circuit as Environment>::Network, NUM_BITS>::setup(MESSAGE);
66 let circuit = Pedersen::<Circuit, NUM_BITS>::constant(native.clone());
67
68 for i in 0..ITERATIONS {
69 let input = (0..NUM_BITS).map(|_| bool::rand(rng)).collect::<Vec<bool>>();
71 let expected = native.hash(&input).expect("Failed to hash native input");
73 let circuit_input: Vec<Boolean<_>> = Inject::new(mode, input);
75
76 Circuit::scope(format!("Pedersen {mode} {i}"), || {
77 let candidate = circuit.hash(&circuit_input);
79 assert_eq!(expected, candidate.eject_value());
80
81 let modes = circuit_input.iter().map(|b| b.eject_mode()).collect::<Vec<_>>();
83 assert_count!(
84 Pedersen<Circuit, NUM_BITS>,
85 HashUncompressed<Input = Boolean<Circuit>, Output = Group<Circuit>>,
86 &modes
87 );
88 assert_output_mode!(
89 Pedersen<Circuit, NUM_BITS>,
90 HashUncompressed<Input = Boolean<Circuit>, Output = Group<Circuit>>,
91 &modes,
92 candidate
93 );
94 });
95 }
96 }
97
98 #[test]
99 fn test_hash_constant() {
100 let mut rng = TestRng::default();
102 check_hash::<NUM_BITS_MULTIPLIER>(Mode::Constant, &mut rng);
103 check_hash::<{ 2 * NUM_BITS_MULTIPLIER }>(Mode::Constant, &mut rng);
104 check_hash::<{ 3 * NUM_BITS_MULTIPLIER }>(Mode::Constant, &mut rng);
105 check_hash::<{ 4 * NUM_BITS_MULTIPLIER }>(Mode::Constant, &mut rng);
106 check_hash::<{ 5 * NUM_BITS_MULTIPLIER }>(Mode::Constant, &mut rng);
107 }
108
109 #[test]
110 fn test_hash_public() {
111 let mut rng = TestRng::default();
113 check_hash::<NUM_BITS_MULTIPLIER>(Mode::Public, &mut rng);
114 check_hash::<{ 2 * NUM_BITS_MULTIPLIER }>(Mode::Public, &mut rng);
115 check_hash::<{ 3 * NUM_BITS_MULTIPLIER }>(Mode::Public, &mut rng);
116 check_hash::<{ 4 * NUM_BITS_MULTIPLIER }>(Mode::Public, &mut rng);
117 check_hash::<{ 5 * NUM_BITS_MULTIPLIER }>(Mode::Public, &mut rng);
118 }
119
120 #[test]
121 fn test_hash_private() {
122 let mut rng = TestRng::default();
124 check_hash::<NUM_BITS_MULTIPLIER>(Mode::Private, &mut rng);
125 check_hash::<{ 2 * NUM_BITS_MULTIPLIER }>(Mode::Private, &mut rng);
126 check_hash::<{ 3 * NUM_BITS_MULTIPLIER }>(Mode::Private, &mut rng);
127 check_hash::<{ 4 * NUM_BITS_MULTIPLIER }>(Mode::Private, &mut rng);
128 check_hash::<{ 5 * NUM_BITS_MULTIPLIER }>(Mode::Private, &mut rng);
129 }
130}