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  }