1use super::*;
17
18impl<E: Environment, const RATE: usize> HashToScalar for Poseidon<E, RATE> {
19 type Input = Field<E>;
20 type Scalar = Scalar<E>;
21
22 #[inline]
25 fn hash_to_scalar(&self, input: &[Self::Input]) -> Self::Scalar {
26 let output = self.hash(input);
28 Scalar::from_field_lossy(&output)
31 }
32}
33
34#[cfg(all(test, feature = "console"))]
35mod tests {
36 use super::*;
37 use snarkvm_circuit_types::environment::Circuit;
38
39 use anyhow::Result;
40
41 const DOMAIN: &str = "PoseidonCircuit0";
42 const ITERATIONS: usize = 10;
43 const RATE: usize = 4;
44
45 fn check_hash_to_scalar(
46 mode: Mode,
47 num_inputs: usize,
48 num_constants: u64,
49 num_public: u64,
50 num_private: u64,
51 num_constraints: u64,
52 rng: &mut TestRng,
53 ) -> Result<()> {
54 use console::HashToScalar as H;
55
56 let native = console::Poseidon::<<Circuit as Environment>::Network, RATE>::setup(DOMAIN)?;
57 let poseidon = Poseidon::<Circuit, RATE>::constant(native.clone());
58
59 for i in 0..ITERATIONS {
60 let native_input = (0..num_inputs).map(|_| Uniform::rand(rng)).collect::<Vec<_>>();
62 let input = native_input.iter().map(|v| Field::<Circuit>::new(mode, *v)).collect::<Vec<_>>();
63
64 let expected = native.hash_to_scalar(&native_input)?;
66
67 Circuit::scope(format!("Poseidon {mode} {i}"), || {
69 let candidate = poseidon.hash_to_scalar(&input);
70 assert_eq!(expected, candidate.eject_value());
71 let case = format!("(mode = {mode}, num_inputs = {num_inputs})");
72 assert_scope!(case, num_constants, num_public, num_private, num_constraints);
73 });
74 Circuit::reset();
75 }
76 Ok(())
77 }
78
79 #[test]
80 fn test_hash_to_scalar_constant() -> Result<()> {
81 let mut rng = TestRng::default();
82
83 for num_inputs in 0..=RATE {
84 check_hash_to_scalar(Mode::Constant, num_inputs, 254, 0, 0, 0, &mut rng)?;
85 }
86 Ok(())
87 }
88
89 #[test]
90 fn test_hash_to_scalar_public() -> Result<()> {
91 let mut rng = TestRng::default();
92
93 check_hash_to_scalar(Mode::Public, 0, 254, 0, 0, 0, &mut rng)?;
94 check_hash_to_scalar(Mode::Public, 1, 1, 0, 840, 842, &mut rng)?;
95 check_hash_to_scalar(Mode::Public, 2, 1, 0, 845, 847, &mut rng)?;
96 check_hash_to_scalar(Mode::Public, 3, 1, 0, 850, 852, &mut rng)?;
97 check_hash_to_scalar(Mode::Public, 4, 1, 0, 855, 857, &mut rng)?;
98 check_hash_to_scalar(Mode::Public, 5, 1, 0, 1210, 1212, &mut rng)?;
99 check_hash_to_scalar(Mode::Public, 6, 1, 0, 1210, 1212, &mut rng)?;
100 check_hash_to_scalar(Mode::Public, 7, 1, 0, 1210, 1212, &mut rng)?;
101 check_hash_to_scalar(Mode::Public, 8, 1, 0, 1210, 1212, &mut rng)?;
102 check_hash_to_scalar(Mode::Public, 9, 1, 0, 1565, 1567, &mut rng)?;
103 check_hash_to_scalar(Mode::Public, 10, 1, 0, 1565, 1567, &mut rng)
104 }
105
106 #[test]
107 fn test_hash_to_scalar_private() -> Result<()> {
108 let mut rng = TestRng::default();
109
110 check_hash_to_scalar(Mode::Private, 0, 254, 0, 0, 0, &mut rng)?;
111 check_hash_to_scalar(Mode::Private, 1, 1, 0, 840, 842, &mut rng)?;
112 check_hash_to_scalar(Mode::Private, 2, 1, 0, 845, 847, &mut rng)?;
113 check_hash_to_scalar(Mode::Private, 3, 1, 0, 850, 852, &mut rng)?;
114 check_hash_to_scalar(Mode::Private, 4, 1, 0, 855, 857, &mut rng)?;
115 check_hash_to_scalar(Mode::Private, 5, 1, 0, 1210, 1212, &mut rng)?;
116 check_hash_to_scalar(Mode::Private, 6, 1, 0, 1210, 1212, &mut rng)?;
117 check_hash_to_scalar(Mode::Private, 7, 1, 0, 1210, 1212, &mut rng)?;
118 check_hash_to_scalar(Mode::Private, 8, 1, 0, 1210, 1212, &mut rng)?;
119 check_hash_to_scalar(Mode::Private, 9, 1, 0, 1565, 1567, &mut rng)?;
120 check_hash_to_scalar(Mode::Private, 10, 1, 0, 1565, 1567, &mut rng)
121 }
122}