Keccak hashing module
alexander-camuto opened this issue · comments
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:
- 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>;
}
- 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,
}
- 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();
}
@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!