prf.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> PRF for Poseidon<E, RATE> { 19 type Input = Field<E>; 20 type Output = Field<E>; 21 type Seed = Field<E>; 22 23 #[inline] 24 fn prf(&self, seed: &Self::Seed, input: &[Self::Input]) -> Self::Output { 25 // Construct the preimage: seed || input. 26 let mut preimage = Vec::with_capacity(1 + input.len()); 27 preimage.push(seed.clone()); 28 preimage.extend_from_slice(input); 29 30 // Hash the preimage to derive the PRF output. 31 self.hash(&preimage) 32 } 33 } 34 35 #[cfg(test)] 36 mod tests { 37 use super::*; 38 use alphavm_circuit_types::environment::Circuit; 39 use alphavm_utilities::{TestRng, Uniform}; 40 41 use anyhow::Result; 42 43 const DOMAIN: &str = "PoseidonCircuit0"; 44 const ITERATIONS: usize = 10; 45 const RATE: usize = 4; 46 47 fn check_prf( 48 mode: Mode, 49 num_inputs: usize, 50 num_constants: u64, 51 num_public: u64, 52 num_private: u64, 53 num_constraints: u64, 54 rng: &mut TestRng, 55 ) -> Result<()> { 56 use console::PRF as P; 57 58 let native = console::Poseidon::<<Circuit as Environment>::Network, RATE>::setup(DOMAIN)?; 59 let poseidon = Poseidon::<Circuit, RATE>::constant(native.clone()); 60 61 for i in 0..ITERATIONS { 62 // Prepare the seed. 63 let native_seed = Uniform::rand(rng); 64 let seed = Field::new(mode, native_seed); 65 66 // Prepare the preimage. 67 let native_input = (0..num_inputs).map(|_| Uniform::rand(rng)).collect::<Vec<_>>(); 68 let input = native_input.iter().map(|v| Field::<Circuit>::new(mode, *v)).collect::<Vec<_>>(); 69 70 // Compute the native hash. 71 let expected = native.prf(&native_seed, &native_input).expect("Failed to PRF native input"); 72 73 // Compute the circuit hash. 74 Circuit::scope(format!("Poseidon PRF {mode} {i}"), || { 75 let candidate = poseidon.prf(&seed, &input); 76 assert_eq!(expected, candidate.eject_value()); 77 let case = format!("(mode = {mode}, num_inputs = {num_inputs})"); 78 assert_scope!(case, num_constants, num_public, num_private, num_constraints); 79 }); 80 Circuit::reset(); 81 } 82 Ok(()) 83 } 84 85 #[test] 86 fn test_prf_constant() -> Result<()> { 87 let mut rng = TestRng::default(); 88 89 for num_inputs in 0..=RATE { 90 check_prf(Mode::Constant, num_inputs, 1, 0, 0, 0, &mut rng)?; 91 } 92 Ok(()) 93 } 94 95 #[test] 96 fn test_prf_public() -> Result<()> { 97 let mut rng = TestRng::default(); 98 99 check_prf(Mode::Public, 0, 1, 0, 335, 335, &mut rng)?; 100 check_prf(Mode::Public, 1, 1, 0, 340, 340, &mut rng)?; 101 check_prf(Mode::Public, 2, 1, 0, 345, 345, &mut rng)?; 102 check_prf(Mode::Public, 3, 1, 0, 350, 350, &mut rng)?; 103 check_prf(Mode::Public, 4, 1, 0, 705, 705, &mut rng)?; 104 check_prf(Mode::Public, 5, 1, 0, 705, 705, &mut rng)?; 105 check_prf(Mode::Public, 6, 1, 0, 705, 705, &mut rng)?; 106 check_prf(Mode::Public, 7, 1, 0, 705, 705, &mut rng)?; 107 check_prf(Mode::Public, 8, 1, 0, 1060, 1060, &mut rng)?; 108 check_prf(Mode::Public, 9, 1, 0, 1060, 1060, &mut rng)?; 109 check_prf(Mode::Public, 10, 1, 0, 1060, 1060, &mut rng) 110 } 111 112 #[test] 113 fn test_prf_private() -> Result<()> { 114 let mut rng = TestRng::default(); 115 116 check_prf(Mode::Private, 0, 1, 0, 335, 335, &mut rng)?; 117 check_prf(Mode::Private, 1, 1, 0, 340, 340, &mut rng)?; 118 check_prf(Mode::Private, 2, 1, 0, 345, 345, &mut rng)?; 119 check_prf(Mode::Private, 3, 1, 0, 350, 350, &mut rng)?; 120 check_prf(Mode::Private, 4, 1, 0, 705, 705, &mut rng)?; 121 check_prf(Mode::Private, 5, 1, 0, 705, 705, &mut rng)?; 122 check_prf(Mode::Private, 6, 1, 0, 705, 705, &mut rng)?; 123 check_prf(Mode::Private, 7, 1, 0, 705, 705, &mut rng)?; 124 check_prf(Mode::Private, 8, 1, 0, 1060, 1060, &mut rng)?; 125 check_prf(Mode::Private, 9, 1, 0, 1060, 1060, &mut rng)?; 126 check_prf(Mode::Private, 10, 1, 0, 1060, 1060, &mut rng) 127 } 128 }