From bfd21e87daf20ab6d916d461b8271dfa89986039 Mon Sep 17 00:00:00 2001 From: guipublic Date: Fri, 28 Apr 2023 15:17:42 +0000 Subject: [PATCH] Add Keccak constraints to acir_format --- .../dsl/acir_format/CMakeLists.txt | 1 + .../dsl/acir_format/acir_format.cpp | 25 +++++++++ .../dsl/acir_format/acir_format.hpp | 4 ++ .../dsl/acir_format/acir_format.test.cpp | 3 ++ .../dsl/acir_format/keccak_constraint.cpp | 38 ++++++++++++++ .../dsl/acir_format/keccak_constraint.hpp | 52 +++++++++++++++++++ 6 files changed, 123 insertions(+) create mode 100644 cpp/src/barretenberg/dsl/acir_format/keccak_constraint.cpp create mode 100644 cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp diff --git a/cpp/src/barretenberg/dsl/acir_format/CMakeLists.txt b/cpp/src/barretenberg/dsl/acir_format/CMakeLists.txt index 01788f7561..425a59fbc0 100644 --- a/cpp/src/barretenberg/dsl/acir_format/CMakeLists.txt +++ b/cpp/src/barretenberg/dsl/acir_format/CMakeLists.txt @@ -4,6 +4,7 @@ barretenberg_module( stdlib_primitives stdlib_sha256 stdlib_blake2s + stdlib_keccak stdlib_pedersen_commitment stdlib_merkle_tree stdlib_schnorr diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 0f10fb87ed..3ea7b57c5a 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -70,6 +70,11 @@ void create_circuit(Composer& composer, const acir_format& constraint_system) create_blake2s_constraints(composer, constraint); } + // Add keccak constraints + for (const auto& constraint : constraint_system.keccak_constraints) { + create_keccak_constraints(composer, constraint); + } + // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { create_pedersen_constraint(composer, constraint); @@ -148,6 +153,11 @@ Composer create_circuit(const acir_format& constraint_system, create_blake2s_constraints(composer, constraint); } + // Add keccak constraints + for (const auto& constraint : constraint_system.keccak_constraints) { + create_keccak_constraints(composer, constraint); + } + // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { create_pedersen_constraint(composer, constraint); @@ -232,6 +242,11 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, create_blake2s_constraints(composer, constraint); } + // Add keccak constraints + for (const auto& constraint : constraint_system.keccak_constraints) { + create_keccak_constraints(composer, constraint); + } + // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { create_pedersen_constraint(composer, constraint); @@ -313,6 +328,11 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, std:: create_blake2s_constraints(composer, constraint); } + // Add keccak constraints + for (const auto& constraint : constraint_system.keccak_constraints) { + create_keccak_constraints(composer, constraint); + } + // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { create_pedersen_constraint(composer, constraint); @@ -392,6 +412,11 @@ void create_circuit_with_witness(Composer& composer, const acir_format& constrai create_blake2s_constraints(composer, constraint); } + // Add keccak constraints + for (const auto& constraint : constraint_system.keccak_constraints) { + create_keccak_constraints(composer, constraint); + } + // Add pedersen constraints for (const auto& constraint : constraint_system.pedersen_constraints) { create_pedersen_constraint(composer, constraint); diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index 0b326e922c..3056367a43 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -3,6 +3,7 @@ #include "range_constraint.hpp" #include "sha256_constraint.hpp" #include "blake2s_constraint.hpp" +#include "keccak_constraint.hpp" #include "fixed_base_scalar_mul.hpp" #include "schnorr_verify.hpp" #include "ecdsa_secp256k1.hpp" @@ -26,6 +27,7 @@ struct acir_format { std::vector ecdsa_constraints; std::vector sha256_constraints; std::vector blake2s_constraints; + std::vector keccak_constraints; std::vector hash_to_field_constraints; std::vector pedersen_constraints; std::vector merkle_membership_constraints; @@ -64,6 +66,7 @@ template inline void read(B& buf, acir_format& data) read(buf, data.schnorr_constraints); read(buf, data.ecdsa_constraints); read(buf, data.blake2s_constraints); + read(buf, data.keccak_constraints); read(buf, data.pedersen_constraints); read(buf, data.hash_to_field_constraints); read(buf, data.fixed_base_scalar_mul_constraints); @@ -82,6 +85,7 @@ template inline void write(B& buf, acir_format const& data) write(buf, data.schnorr_constraints); write(buf, data.ecdsa_constraints); write(buf, data.blake2s_constraints); + write(buf, data.keccak_constraints); write(buf, data.pedersen_constraints); write(buf, data.hash_to_field_constraints); write(buf, data.fixed_base_scalar_mul_constraints); diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index 586a82b03d..c007583c14 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -86,6 +86,7 @@ TEST(acir_format, test_logic_gate_from_noir_circuit) .ecdsa_constraints = {}, .sha256_constraints = {}, .blake2s_constraints = {}, + .keccak_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .merkle_membership_constraints = {}, @@ -150,6 +151,7 @@ TEST(acir_format, test_schnorr_verify_pass) .ecdsa_constraints = {}, .sha256_constraints = {}, .blake2s_constraints = {}, + .keccak_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .merkle_membership_constraints = {}, @@ -219,6 +221,7 @@ TEST(acir_format, test_schnorr_verify_small_range) .ecdsa_constraints = {}, .sha256_constraints = {}, .blake2s_constraints = {}, + .keccak_constraints = {}, .hash_to_field_constraints = {}, .pedersen_constraints = {}, .merkle_membership_constraints = {}, diff --git a/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.cpp new file mode 100644 index 0000000000..f89e530c10 --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.cpp @@ -0,0 +1,38 @@ +#include "keccak_constraint.hpp" +#include "round.hpp" +#include "barretenberg/stdlib/hash/keccak/keccak.hpp" + +namespace acir_format { + +void create_keccak_constraints(Composer& composer, const KeccakConstraint& constraint) +{ + + // Create byte array struct + byte_array_ct arr(&composer); + + // Get the witness assignment for each witness index + // Write the witness assignment to the byte_array + for (const auto& witness_index_num_bits : constraint.inputs) { + auto witness_index = witness_index_num_bits.witness; + auto num_bits = witness_index_num_bits.num_bits; + + // XXX: The implementation requires us to truncate the element to the nearest byte and not bit + auto num_bytes = round_to_nearest_byte(num_bits); + + field_ct element = field_ct::from_witness_index(&composer, witness_index); + byte_array_ct element_bytes(element, num_bytes); + + arr.write(element_bytes); + } + + byte_array_ct output_bytes = proof_system::plonk::stdlib::keccak::hash(arr); + + // Convert byte array to vector of field_t + auto bytes = output_bytes.bytes(); + + for (size_t i = 0; i < bytes.size(); ++i) { + composer.assert_equal(bytes[i].normalize().witness_index, constraint.result[i]); + } +} + +} // namespace acir_format diff --git a/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp new file mode 100644 index 0000000000..15322b6562 --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp @@ -0,0 +1,52 @@ +#pragma once +#include +#include +#include "barretenberg/dsl/types.hpp" + +namespace acir_format { + +struct HashInput { + uint32_t witness; + uint32_t num_bits; + + friend bool operator==(HashInput const& lhs, HashInput const& rhs) = default; +}; + +struct KeccakConstraint { + std::vector inputs; + std::vector result; + + friend bool operator==(KeccakConstraint const& lhs, KeccakConstraint const& rhs) = default; +}; + +void create_keccak_constraints(Composer& composer, const KeccakConstraint& constraint); + +template inline void read(B& buf, HashInput& constraint) +{ + using serialize::read; + read(buf, constraint.witness); + read(buf, constraint.num_bits); +} + +template inline void write(B& buf, HashInput const& constraint) +{ + using serialize::write; + write(buf, constraint.witness); + write(buf, constraint.num_bits); +} + +template inline void read(B& buf, KeccakConstraint& constraint) +{ + using serialize::read; + read(buf, constraint.inputs); + read(buf, constraint.result); +} + +template inline void write(B& buf, KeccakConstraint const& constraint) +{ + using serialize::write; + write(buf, constraint.inputs); + write(buf, constraint.result); +} + +} // namespace acir_format