hash.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use super::*; 17 18 impl<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(test)] 29 mod tests { 30 use super::*; 31 use alphavm_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 // Prepare the preimage. 55 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 // Compute the native hash. 61 let expected = native.hash(&native_input).expect("Failed to hash native input"); 62 63 // Compute the circuit hash. 64 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 }