zkonduit / ezkl

ezkl is an engine for doing inference for deep learning models and other computational graphs in a zk-snark (ZKML). Use it from Python, Javascript, or the command line.

Home Page:https://docs.ezkl.xyz/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Keccak hashing module

alexander-camuto opened this issue · comments

commented

To better support EVM-native hashing functions it would be great to have a keccak module within src/circuit/modules in a similar vein to the poseidon module.

This module should:

  1. implement the Module<F> trait, reproduced here:
/// Module trait used to extend ezkl functionality
pub trait Module<F: PrimeField + TensorType + PartialOrd> {
    /// Config
    type Config;
    /// The return type after an input assignment
    type InputAssignments;
    /// The inputs used in the run function
    type RunInputs;

    /// construct new module from config
    fn new(config: Self::Config) -> Self;
    /// Configure
    fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config;
    /// Name
    fn name(&self) -> &'static str;
    /// Run the operation the module represents
    fn run(input: Self::RunInputs) -> Result<Vec<Vec<F>>, Box<dyn std::error::Error>>;
    /// Layout inputs
    fn layout_inputs(
        &self,
        layouter: &mut impl Layouter<F>,
        input: &[ValTensor<F>],
    ) -> Result<Self::InputAssignments, Error>;
    /// Layout
    fn layout(
        &self,
        layouter: &mut impl Layouter<F>,
        input: &[ValTensor<F>],
        row_offsets: Vec<usize>,
    ) -> Result<ValTensor<F>, Error>;
    /// Number of instance values the module uses every time it is applied
    fn instance_increment_input(&self) -> Vec<usize>;
}
  1. we should extend the visibility param in src/graph/vars.rs to include "keccak". This would look something akin to:
/// Label enum to track whether model input, model parameters, and model output are public, private, or hashed
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Default)]
pub enum Visibility {
    /// Mark an item as private to the prover (not in the proof submitted for verification)
    #[default]
    Private,
    /// Mark an item as public (sent in the proof submitted for verification)
    Public,
    /// Mark an item as publicly committed to using poseidon hashing (hash sent in the proof submitted for verification)
    Poseidon,
    /// Mark an item as publicly committed to using keccak hashing (hash sent in the proof submitted for verification)
    Keccak,
    /// Mark an item as encrypted (public key and encrypted message sent in the proof submitted for verificatio)
    Encrypted,
}
  1. this should be supplemented by integration tests in tests/integration_tests.rs. As a reference you can see:
 #(#[test_case(TESTS[N])])*
fn kzg_prove_and_verify_hashed_output(test: &str) {
                crate::native_tests::init_binary();
                let test_dir = TempDir::new(test).unwrap();
                let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(test_dir.path().to_str().unwrap(), test);
               kzg_prove_and_verify(path, test.to_string(), "safe", "private", "private", "hashed");
               test_dir.close().unwrap();
            }

this would become two separate tests

 #(#[test_case(TESTS[N])])*
fn kzg_prove_and_verify_poseidon_output(test: &str) {
                crate::native_tests::init_binary();
                let test_dir = TempDir::new(test).unwrap();
                let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(test_dir.path().to_str().unwrap(), test);
               kzg_prove_and_verify(path, test.to_string(), "safe", "private", "private", "poseidon");
               test_dir.close().unwrap();
            }

 #(#[test_case(TESTS[N])])*
fn kzg_prove_and_verify_keccak_output(test: &str) {
                crate::native_tests::init_binary();
                let test_dir = TempDir::new(test).unwrap();
                let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(test_dir.path().to_str().unwrap(), test);
               kzg_prove_and_verify(path, test.to_string(), "safe", "private", "private", "keccak");
               test_dir.close().unwrap();
            }
commented

@CeciliaZ030 I know you had expressed interest in this

Hey, great work on ezkl!
I'm looking into ways to contribute and found this issue marked as "good first issue" by @JSeam2 . I see @CeciliaZ030 was working on this, so don't want to bother her work.

If this issue is still relevant, happy to help on this! I don't know a ton about Halo2 but willing to learn.

@gabrielfior feel free to take it on she is probably busy!