mod.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 mod commit; 17 mod commit_uncompressed; 18 mod hash; 19 mod hash_uncompressed; 20 21 #[cfg(test)] 22 use alphavm_circuit_types::environment::{assert_count, assert_output_mode, assert_scope}; 23 24 use crate::{Commit, CommitUncompressed, Hash, HashUncompressed}; 25 use alphavm_circuit_types::prelude::*; 26 27 /// Pedersen64 is an *additively-homomorphic* collision-resistant hash function that takes up to a 64-bit input. 28 pub type Pedersen64<E> = Pedersen<E, 64>; 29 /// Pedersen128 is an *additively-homomorphic* collision-resistant hash function that takes up to a 128-bit input. 30 pub type Pedersen128<E> = Pedersen<E, 128>; 31 32 /// Pedersen is a collision-resistant hash function that takes a variable-length input. 33 /// The Pedersen hash function does *not* behave like a random oracle, see Poseidon for one. 34 pub struct Pedersen<E: Environment, const NUM_BITS: u8> { 35 /// The base window for the Pedersen hash. 36 base_window: Vec<Group<E>>, 37 /// The random base window for the Pedersen commitment. 38 random_base: Vec<Group<E>>, 39 } 40 41 impl<E: Environment, const NUM_BITS: u8> Inject for Pedersen<E, NUM_BITS> { 42 type Primitive = console::Pedersen<E::Network, NUM_BITS>; 43 44 /// Initializes a new instance of Pedersen with the given Pedersen variant. 45 fn new(_mode: Mode, pedersen: Self::Primitive) -> Self { 46 // Initialize the base window. 47 let base_window = Vec::constant(pedersen.base_window().iter().copied().collect()); 48 assert_eq!(base_window.len(), NUM_BITS as usize); 49 50 // Initialize the random base. 51 let random_base = Vec::constant(pedersen.random_base_window().iter().copied().collect()); 52 assert_eq!(random_base.len(), E::ScalarField::size_in_bits()); 53 54 Self { base_window, random_base } 55 } 56 } 57 58 #[cfg(test)] 59 mod tests { 60 use super::*; 61 use alphavm_circuit_types::environment::Circuit; 62 63 const ITERATIONS: u64 = 10; 64 const MESSAGE: &str = "PedersenCircuit0"; 65 const NUM_BITS_MULTIPLIER: u8 = 8; 66 67 fn check_setup<const NUM_BITS: u8>(num_constants: u64, num_public: u64, num_private: u64, num_constraints: u64) { 68 for _ in 0..ITERATIONS { 69 // Initialize the native Pedersen hash. 70 let native = console::Pedersen::<<Circuit as Environment>::Network, NUM_BITS>::setup(MESSAGE); 71 72 Circuit::scope("Pedersen::setup", || { 73 // Perform the setup operation. 74 let circuit = Pedersen::<Circuit, NUM_BITS>::constant(native.clone()); 75 assert_scope!(num_constants, num_public, num_private, num_constraints); 76 77 // Check for equivalency of the bases. 78 native.base_window().iter().zip_eq(circuit.base_window.iter()).for_each(|(expected, candidate)| { 79 assert_eq!(*expected, candidate.eject_value()); 80 }); 81 82 // Check for equality of the random base. 83 native.random_base_window().iter().zip_eq(circuit.random_base.iter()).for_each( 84 |(expected, candidate)| { 85 assert_eq!(*expected, candidate.eject_value()); 86 }, 87 ); 88 }); 89 } 90 } 91 92 #[test] 93 fn test_setup_constant() { 94 // Set the number of windows, and modulate the window size. 95 check_setup::<NUM_BITS_MULTIPLIER>(2590, 0, 0, 0); 96 check_setup::<{ 2 * NUM_BITS_MULTIPLIER }>(2670, 0, 0, 0); 97 check_setup::<{ 3 * NUM_BITS_MULTIPLIER }>(2750, 0, 0, 0); 98 check_setup::<{ 4 * NUM_BITS_MULTIPLIER }>(2830, 0, 0, 0); 99 check_setup::<{ 5 * NUM_BITS_MULTIPLIER }>(2910, 0, 0, 0); 100 } 101 }