From 14aa792f17649ff483ff64c1321c58b37ff601d9 Mon Sep 17 00:00:00 2001 From: iAmMichaelConnor Date: Fri, 7 Jun 2024 13:52:31 +0000 Subject: [PATCH] amortising table gates over all opcodes which use the table... ish --- .../dsl/acir_format/acir_format.cpp | 135 ++++++++++++++---- trickty/target/trickty.json | 2 +- 2 files changed, 108 insertions(+), 29 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 2e683fec218..22db381c9b7 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -1,5 +1,6 @@ #include "acir_format.hpp" #include "barretenberg/common/log.hpp" +#include "barretenberg/common/throw_or_abort.hpp" #include "barretenberg/stdlib/primitives/field/field_conversion.hpp" #include "barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp" @@ -20,161 +21,211 @@ void build_constraints(Builder& builder, { constraint_system.gates_per_opcode = std::vector(constraint_system.num_acir_opcodes); size_t prev_gate_count = 0; + size_t prev_table_size = 0; - auto compute_gate_diff = [&]() { + auto compute_gate_diff = [&](size_t const num_constraints_of_this_type, size_t& table_size_of_this_type) -> size_t { size_t new_gate_count = builder.get_total_circuit_size(); - size_t diff = new_gate_count - prev_gate_count; + size_t new_table_size = builder.get_tables_size(); + size_t gate_diff = new_gate_count - prev_gate_count; + size_t table_diff = new_table_size - prev_table_size; + + if (table_diff > 0 && table_size_of_this_type > 0) { + throw_or_abort( + "My current understanding is that tables shouldn't grow in size if the opcode has already been " + "encountered earlier."); + } + + if (gate_diff < table_diff) { + throw_or_abort("Unexpected error"); + } + + table_size_of_this_type += table_diff; + size_t amortised_gate_diff = + (gate_diff - table_diff) + (table_size_of_this_type / num_constraints_of_this_type); + prev_gate_count = new_gate_count; - return diff; + prev_table_size = new_table_size; + return amortised_gate_diff; }; // Add arithmetic gates + size_t table_size_for_poly_triple_constraints = 0; for (size_t i = 0; i < constraint_system.poly_triple_constraints.size(); ++i) { const auto& constraint = constraint_system.poly_triple_constraints[i]; builder.create_poly_gate(constraint); constraint_system.gates_per_opcode[constraint_system.poly_triple_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.poly_triple_constraints.size(), table_size_for_poly_triple_constraints); } + + size_t table_size_for_quad_constraints = 0; for (size_t i = 0; i < constraint_system.quad_constraints.size(); ++i) { const auto& constraint = constraint_system.quad_constraints[i]; builder.create_big_mul_gate(constraint); - constraint_system.gates_per_opcode[constraint_system.quad_constraints_original_index[i]] = compute_gate_diff(); + constraint_system.gates_per_opcode[constraint_system.quad_constraints_original_index[i]] = + compute_gate_diff(constraint_system.quad_constraints.size(), table_size_for_quad_constraints); } // Add logic constraint + size_t table_size_for_logic_constraints = 0; for (size_t i = 0; i < constraint_system.logic_constraints.size(); ++i) { const auto& constraint = constraint_system.logic_constraints[i]; create_logic_gate( builder, constraint.a, constraint.b, constraint.result, constraint.num_bits, constraint.is_xor_gate); - constraint_system.gates_per_opcode[constraint_system.logic_constraints_original_index[i]] = compute_gate_diff(); + constraint_system.gates_per_opcode[constraint_system.logic_constraints_original_index[i]] = + compute_gate_diff(constraint_system.logic_constraints.size(), table_size_for_logic_constraints); } // Add range constraint + size_t table_size_for_range_constraints = 0; for (size_t i = 0; i < constraint_system.range_constraints.size(); ++i) { const auto& constraint = constraint_system.range_constraints[i]; builder.create_range_constraint(constraint.witness, constraint.num_bits, ""); - constraint_system.gates_per_opcode[constraint_system.range_constraints_original_index[i]] = compute_gate_diff(); + constraint_system.gates_per_opcode[constraint_system.range_constraints_original_index[i]] = + compute_gate_diff(constraint_system.range_constraints.size(), table_size_for_range_constraints); } // Add aes128 constraints + size_t table_size_for_aes128_constraints = 0; for (size_t i = 0; i < constraint_system.aes128_constraints.size(); ++i) { const auto& constraint = constraint_system.aes128_constraints[i]; create_aes128_constraints(builder, constraint); constraint_system.gates_per_opcode[constraint_system.aes128_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.aes128_constraints.size(), table_size_for_aes128_constraints); } // Add sha256 constraints + size_t table_size_for_sha256_constraints = 0; for (size_t i = 0; i < constraint_system.sha256_constraints.size(); ++i) { const auto& constraint = constraint_system.sha256_constraints[i]; create_sha256_constraints(builder, constraint); constraint_system.gates_per_opcode[constraint_system.sha256_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.sha256_constraints.size(), table_size_for_sha256_constraints); } + + size_t table_size_for_sha256_compression_constraints = 0; for (size_t i = 0; i < constraint_system.sha256_compression.size(); ++i) { const auto& constraint = constraint_system.sha256_compression[i]; create_sha256_compression_constraints(builder, constraint); - constraint_system.gates_per_opcode[constraint_system.sha256_compression_original_index[i]] = - compute_gate_diff(); + constraint_system.gates_per_opcode[constraint_system.sha256_compression_original_index[i]] = compute_gate_diff( + constraint_system.sha256_compression.size(), table_size_for_sha256_compression_constraints); } // Add schnorr constraints + size_t table_size_for_schnorr_constraints = 0; for (size_t i = 0; i < constraint_system.schnorr_constraints.size(); ++i) { const auto& constraint = constraint_system.schnorr_constraints[i]; create_schnorr_verify_constraints(builder, constraint); constraint_system.gates_per_opcode[constraint_system.schnorr_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.schnorr_constraints.size(), table_size_for_schnorr_constraints); } // Add ECDSA k1 constraints + size_t table_size_for_ecdsa_k1_constraints = 0; for (size_t i = 0; i < constraint_system.ecdsa_k1_constraints.size(); ++i) { const auto& constraint = constraint_system.ecdsa_k1_constraints[i]; create_ecdsa_k1_verify_constraints(builder, constraint, has_valid_witness_assignments); constraint_system.gates_per_opcode[constraint_system.ecdsa_k1_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.ecdsa_k1_constraints.size(), table_size_for_ecdsa_k1_constraints); } // Add ECDSA r1 constraints + size_t table_size_for_ecdsa_r1_constraints = 0; for (size_t i = 0; i < constraint_system.ecdsa_r1_constraints.size(); ++i) { const auto& constraint = constraint_system.ecdsa_r1_constraints[i]; create_ecdsa_r1_verify_constraints(builder, constraint, has_valid_witness_assignments); constraint_system.gates_per_opcode[constraint_system.ecdsa_r1_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.ecdsa_r1_constraints.size(), table_size_for_ecdsa_r1_constraints); } // Add blake2s constraints + size_t table_size_for_blake2s_constraints = 0; for (size_t i = 0; i < constraint_system.blake2s_constraints.size(); ++i) { const auto& constraint = constraint_system.blake2s_constraints[i]; create_blake2s_constraints(builder, constraint); constraint_system.gates_per_opcode[constraint_system.blake2s_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.blake2s_constraints.size(), table_size_for_blake2s_constraints); } // Add blake3 constraints + size_t table_size_for_blake3_constraints = 0; for (size_t i = 0; i < constraint_system.blake3_constraints.size(); ++i) { const auto& constraint = constraint_system.blake3_constraints[i]; create_blake3_constraints(builder, constraint); constraint_system.gates_per_opcode[constraint_system.blake3_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.blake3_constraints.size(), table_size_for_blake3_constraints); } // Add keccak constraints + size_t table_size_for_keccak_constraints = 0; for (size_t i = 0; i < constraint_system.keccak_constraints.size(); ++i) { const auto& constraint = constraint_system.keccak_constraints[i]; create_keccak_constraints(builder, constraint); constraint_system.gates_per_opcode[constraint_system.keccak_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.keccak_constraints.size(), table_size_for_keccak_constraints); } + + size_t table_size_for_keccak_permutations = 0; for (size_t i = 0; i < constraint_system.keccak_permutations.size(); ++i) { const auto& constraint = constraint_system.keccak_permutations[i]; create_keccak_permutations(builder, constraint); constraint_system.gates_per_opcode[constraint_system.keccak_permutations_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.keccak_permutations.size(), table_size_for_keccak_permutations); } // Add pedersen constraints + size_t table_size_for_pedersen_constraints = 0; for (size_t i = 0; i < constraint_system.pedersen_constraints.size(); ++i) { const auto& constraint = constraint_system.pedersen_constraints[i]; create_pedersen_constraint(builder, constraint); constraint_system.gates_per_opcode[constraint_system.pedersen_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.pedersen_constraints.size(), table_size_for_pedersen_constraints); } + size_t table_size_for_pedersen_hash_constraints = 0; for (size_t i = 0; i < constraint_system.pedersen_hash_constraints.size(); ++i) { const auto& constraint = constraint_system.pedersen_hash_constraints[i]; create_pedersen_hash_constraint(builder, constraint); constraint_system.gates_per_opcode[constraint_system.pedersen_hash_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.pedersen_hash_constraints.size(), + table_size_for_pedersen_hash_constraints); } + size_t table_size_for_poseidon2_constraints = 0; for (size_t i = 0; i < constraint_system.poseidon2_constraints.size(); ++i) { const auto& constraint = constraint_system.poseidon2_constraints[i]; create_poseidon2_permutations(builder, constraint); constraint_system.gates_per_opcode[constraint_system.poseidon2_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.poseidon2_constraints.size(), table_size_for_poseidon2_constraints); } // Add multi scalar mul constraints + size_t table_size_for_multi_scalar_mul_constraints = 0; for (size_t i = 0; i < constraint_system.multi_scalar_mul_constraints.size(); ++i) { const auto& constraint = constraint_system.multi_scalar_mul_constraints[i]; create_multi_scalar_mul_constraint(builder, constraint); constraint_system.gates_per_opcode[constraint_system.multi_scalar_mul_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.multi_scalar_mul_constraints.size(), + table_size_for_multi_scalar_mul_constraints); } // Add ec add constraints + size_t table_size_for_ec_add_constraints = 0; for (size_t i = 0; i < constraint_system.ec_add_constraints.size(); ++i) { const auto& constraint = constraint_system.ec_add_constraints[i]; create_ec_add_constraint(builder, constraint, has_valid_witness_assignments); constraint_system.gates_per_opcode[constraint_system.ec_add_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.ec_add_constraints.size(), table_size_for_ec_add_constraints); } // Add block constraints - for (size_t i = 0; i < constraint_system.block_constraints.size(); ++i) { + size_t block_constraints_size = constraint_system.block_constraints.size(); + std::vector table_sizes_for_block_constraints(block_constraints_size, size_t(0)); + for (size_t i = 0; i < block_constraints_size; ++i) { const auto& constraint = constraint_system.block_constraints[i]; create_block_constraints(builder, constraint, has_valid_witness_assignments); - size_t delta_gates = compute_gate_diff(); + // Note sure about taking the size of `init`, like this. Got confused with all the vectors. + size_t delta_gates = + compute_gate_diff(constraint_system.block_constraints[i].init.size(), table_sizes_for_block_constraints[i]); size_t avg_gates_per_opcode = delta_gates / constraint_system.block_constraints_indices[i].size(); for (size_t opcode_index : constraint_system.block_constraints_indices[i]) { constraint_system.gates_per_opcode[opcode_index] = avg_gates_per_opcode; @@ -184,22 +235,30 @@ void build_constraints(Builder& builder, // Add big_int constraints DSLBigInts dsl_bigints; dsl_bigints.set_builder(&builder); + size_t table_size_for_bigint_from_le_bytes_constraints = 0; for (size_t i = 0; i < constraint_system.bigint_from_le_bytes_constraints.size(); ++i) { const auto& constraint = constraint_system.bigint_from_le_bytes_constraints[i]; create_bigint_from_le_bytes_constraint(builder, constraint, dsl_bigints); constraint_system.gates_per_opcode[constraint_system.bigint_from_le_bytes_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.bigint_from_le_bytes_constraints.size(), + table_size_for_bigint_from_le_bytes_constraints); } + + size_t table_size_for_bigint_operations = 0; for (size_t i = 0; i < constraint_system.bigint_operations.size(); ++i) { const auto& constraint = constraint_system.bigint_operations[i]; create_bigint_operations_constraint(constraint, dsl_bigints, has_valid_witness_assignments); - constraint_system.gates_per_opcode[constraint_system.bigint_operations_original_index[i]] = compute_gate_diff(); + constraint_system.gates_per_opcode[constraint_system.bigint_operations_original_index[i]] = + compute_gate_diff(constraint_system.bigint_operations.size(), table_size_for_bigint_operations); } + + size_t table_size_for_bigint_to_le_bytes_constraints = 0; for (size_t i = 0; i < constraint_system.bigint_to_le_bytes_constraints.size(); ++i) { const auto& constraint = constraint_system.bigint_to_le_bytes_constraints[i]; create_bigint_to_le_bytes_constraint(builder, constraint, dsl_bigints); constraint_system.gates_per_opcode[constraint_system.bigint_to_le_bytes_constraints_original_index[i]] = - compute_gate_diff(); + compute_gate_diff(constraint_system.bigint_to_le_bytes_constraints.size(), + table_size_for_bigint_to_le_bytes_constraints); } // RecursionConstraint @@ -230,6 +289,7 @@ void build_constraints(Builder& builder, auto proof_size_no_pub_inputs = recursion_proof_size_without_public_inputs(); // Add recursion constraints + size_t table_size_for_recursion_constraints = 0; for (auto constraint : constraint_system.recursion_constraints) { // A proof passed into the constraint should be stripped of its public inputs, except in the case where a // proof contains an aggregation object itself. We refer to this as the `nested_aggregation_object`. The @@ -265,12 +325,15 @@ void build_constraints(Builder& builder, constraint.proof.begin() + static_cast(RecursionConstraint::AGGREGATION_OBJECT_SIZE)); } + current_output_aggregation_object = create_recursion_constraints(builder, constraint, current_input_aggregation_object, nested_aggregation_object, has_valid_witness_assignments); current_input_aggregation_object = current_output_aggregation_object; + + compute_gate_diff(constraint_system.recursion_constraints.size(), table_size_for_recursion_constraints); } // Now that the circuit has been completely built, we add the output aggregation as public @@ -310,6 +373,7 @@ void build_constraints(Builder& builder, }; // Add recursion constraints + size_t table_size_for_honk_recursion_constraints = 0; for (auto constraint : constraint_system.honk_recursion_constraints) { // A proof passed into the constraint should be stripped of its inner public inputs, but not the nested // aggregation object itself. The verifier circuit requires that the indices to a nested proof aggregation @@ -334,6 +398,9 @@ void build_constraints(Builder& builder, current_aggregation_object, nested_aggregation_object, has_valid_witness_assignments); + + compute_gate_diff(constraint_system.honk_recursion_constraints.size(), + table_size_for_honk_recursion_constraints); } // Now that the circuit has been completely built, we add the output aggregation as public @@ -410,6 +477,18 @@ UltraCircuitBuilder create_circuit(AcirFormat& constraint_system, bool has_valid_witness_assignments = !witness.empty(); build_constraints(builder, constraint_system, has_valid_witness_assignments, honk_recursion); + // I was doing this to check whether the final gate count matches the sum of the amortised gate counts. It doesn't. + // size_t sum = 0; + // for (size_t i : constraint_system.gates_per_opcode) { + // sum += i; + // } + // // if (builder.get_total_circuit_size() != sum) { + // // throw_or_abort("Badly counted num gates!!"); + // // } + // constraint_system.gates_per_opcode[constraint_system.gates_per_opcode.size() - 1] = + // builder.get_total_circuit_size(); + // constraint_system.gates_per_opcode[constraint_system.gates_per_opcode.size() - 2] = sum; + return builder; }; diff --git a/trickty/target/trickty.json b/trickty/target/trickty.json index e4b0103f464..8afcf98ed9c 100644 --- a/trickty/target/trickty.json +++ b/trickty/target/trickty.json @@ -1 +1 @@ -{"noir_version":"0.30.0+06f03fdf73d9374b5d18d33cf1480f7748db016f","hash":13623433748087479528,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}]},"return_type":null,"return_witnesses":[],"error_types":{}},"bytecode":"H4sIAAAAAAAA/7XU1W5bQRRA0YaZmZnJ9jVch5mZGRw7//8FVRM1lXaj/VCp7ZaOZqQljc7T5H37WfZ93j7vee9T9nn+6jvsq+fB88Xz4QXiBfBC8UJ4kXgRvFi8GF4iXgIvFS+Fl4mXwcvFy+EV4hXwSvFKeJV4FbxavBpeI14DrxWvhdeJ18HrxevhDeIN8EbxRniTeBO8WbwZ3iLeAm8Vb4W3ibfB28Xb4R3iHfBO8U54l3gXvFu8G94j3gPvFe+F94n3wfvF++ED4gPwQfFB+JD4EHxYfBg+Ij4CHxUfhY+Jj8HHxcfhE+IT8EnxSfiU+BR8WnwaPiM+A4+IR+BR8Sg8Jh6DB+IBPC4ehyfEE/CkeBKeEk/BQ/EQnhZPw2fFZ+Fz4nPwefF5+IL4AnxRfBG+JL4EXxZfhq+Ir8BXxVfha+Jr8HXxdfiG+AZ8U3wTviW+Bd8W34bviO/Ad8V34Xvie/B98X34gfgB/FD8EH4kfgQ/Fj+Gn4ifwE/FT+Fn4mfwc/Fz+IX4BfxS/BJ+JX4Fvxa/ht+I38BvxW/hd+J38Hvxe/iD+AP8UfwR/iT+BH8Wf4a/iL/AM+IZ+Kv4Kzz77ff4B30U+btiWbwVRJLxeC4Vy0WD6Eskls6EiUg8kUmG0TCaCBPZWBgEuTAeptKZdCqSjsaDXPQtkQ5ybx/lEv9xz+Df7ZlNfexW+GXPP+oHWpQ5Cx0OAAA=","debug_symbols":"tdrPasJAEMfxd9lzDp3ZnZ3dvEopJWosAYmisVDEd29isVLq9XucZOZ3+5A/O5ew6Vfnj/dh3O5PoX29hN1+3U3DfpyrS3i5XTodunGpTlN3nELr3oR+3IRWJF6bsB12fWiTX5t/nSKPXhX7bdZ6fWuCkOFKhkcyPJHhRoZnMtzJ8EKGVxQRSxQ1KihSQZUKylRQp4JCFVSqoFQFtaqoVWWfp6hVRa0qalVRq4paVdSqolYVtRpRqxG1GtmXX9RqRK1G1GpErUbUakStRtRqQq0m1GpCrSb2SxW1mlCrCbWaUKsJtZpQq4ZaNdSqoVYNtWqoVUOtGmrVUKuGWjXUakatZtRqRq1m1GpGrWb2HzBqNaNWM2o1o1YdteqoVUetOmrVUauOWnX2wAa16qhVR60W1GpBrRbUakGtFtRqQa0W1GphT1dRqwW1WlGrFbVaUasVtVpRqxW1WlGrFbVa2VUIeBfiKVZRu88soY/828hTgWLxPuL2Z2QuPrvj0K12/bIhtdw7j+v7wtRcTl+Hnztz7zc=","file_map":{"29":{"source":"mod poseidon;\nmod mimc;\nmod poseidon2;\n\nuse crate::default::Default;\nuse crate::uint128::U128;\nuse crate::sha256::{digest, sha256_var};\n\n#[foreign(sha256)]\n// docs:start:sha256\npub fn sha256(input: [u8; N]) -> [u8; 32]\n// docs:end:sha256\n{}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n#[foreign(blake3)]\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{}\n\n// docs:start:pedersen_commitment\nstruct PedersenPoint {\n x : Field,\n y : Field,\n}\n\npub fn pedersen_commitment(input: [Field; N]) -> PedersenPoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[foreign(pedersen_commitment)]\npub fn __pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> [Field; 2] {}\n\npub fn pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> PedersenPoint {\n let values = __pedersen_commitment_with_separator(input, separator);\n PedersenPoint { x: values[0], y: values[1] }\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[foreign(pedersen_hash)]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {}\n\npub fn hash_to_field(inputs: [Field]) -> Field {\n let mut sum = 0;\n\n for input in inputs {\n let input_bytes: [u8; 32] = input.to_le_bytes(32).as_array();\n sum += crate::field::bytes32_to_field(blake2s(input_bytes));\n }\n\n sum\n}\n\n#[foreign(keccak256)]\n// docs:start:keccak256\npub fn keccak256(input: [u8; N], message_size: u32) -> [u8; 32]\n// docs:end:keccak256\n{}\n\n#[foreign(poseidon2_permutation)]\npub fn poseidon2_permutation(_input: [Field; N], _state_length: u32) -> [Field; N] {}\n\n#[foreign(sha256_compression)]\npub fn sha256_compression(_input: [u32; 16], _state: [u32; 8]) -> [u32; 8] {}\n\n// Generic hashing support. \n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\ntrait Hash{\n fn hash(self, state: &mut H) where H: Hasher;\n}\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\ntrait Hasher{\n fn finish(self) -> Field;\n \n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\ntrait BuildHasher where H: Hasher{\n fn build_hasher(self) -> H;\n}\n\nstruct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere \n H: Hasher + Default\n{\n fn build_hasher(_self: Self) -> H{\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere \n H: Hasher + Default\n{\n fn default() -> Self{\n BuildHasherDefault{}\n } \n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H) where H: Hasher {}\n}\n\nimpl Hash for U128 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self.lo as Field);\n H::write(state, self.hi as Field);\n }\n}\n\nimpl Hash for [T; N] where T: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T] where T: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B) where A: Hash, B: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C) where A: Hash, B: Hash, C: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D) where A: Hash, B: Hash, C: Hash, D: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: Hash, E: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n","path":"std/hash.nr"},"47":{"source":"fn main(x: Field) {\n let mut acc = x;\n for i in 0..100 {\n acc = dep::std::hash::pedersen_hash([acc]);\n }\n assert_eq(acc * 2, 28);\n assert_eq(acc * 3, 42);\n}\n\n","path":"/mnt/user-data/alvaro/aztec-packages/trickty/src/main.nr"}},"names":["main"]} \ No newline at end of file +{"noir_version":"0.30.0+f6d65afe6820d0d6e55ecae3bf8693b5ad9a9c48","hash":13623433748087479528,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}]},"return_type":null,"return_witnesses":[],"error_types":{}},"bytecode":"H4sIAAAAAAAA/7XU1W5bQRRA0YaZmZnJ9jVch5mZGRw7//8FVRM1lXaj/VCp7ZaOZqQljc7T5H37WfZ93j7vee9T9nn+6jvsq+fB88Xz4QXiBfBC8UJ4kXgRvFi8GF4iXgIvFS+Fl4mXwcvFy+EV4hXwSvFKeJV4FbxavBpeI14DrxWvhdeJ18HrxevhDeIN8EbxRniTeBO8WbwZ3iLeAm8Vb4W3ibfB28Xb4R3iHfBO8U54l3gXvFu8G94j3gPvFe+F94n3wfvF++ED4gPwQfFB+JD4EHxYfBg+Ij4CHxUfhY+Jj8HHxcfhE+IT8EnxSfiU+BR8WnwaPiM+A4+IR+BR8Sg8Jh6DB+IBPC4ehyfEE/CkeBKeEk/BQ/EQnhZPw2fFZ+Fz4nPwefF5+IL4AnxRfBG+JL4EXxZfhq+Ir8BXxVfha+Jr8HXxdfiG+AZ8U3wTviW+Bd8W34bviO/Ad8V34Xvie/B98X34gfgB/FD8EH4kfgQ/Fj+Gn4ifwE/FT+Fn4mfwc/Fz+IX4BfxS/BJ+JX4Fvxa/ht+I38BvxW/hd+J38Hvxe/iD+AP8UfwR/iT+BH8Wf4a/iL/AM+IZ+Kv4Kzz77ff4B30U+btiWbwVRJLxeC4Vy0WD6Eskls6EiUg8kUmG0TCaCBPZWBgEuTAeptKZdCqSjsaDXPQtkQ5ybx/lEv9xz+Df7ZlNfexW+GXPP+oHWpQ5Cx0OAAA=","debug_symbols":"tdrPasJAEMfxd9lzDp3ZnZ3dvEopJWosAYmisVDEd29isVLq9XucZOZ3+5A/O5ew6Vfnj/dh3O5PoX29hN1+3U3DfpyrS3i5XTodunGpTlN3nELr3oR+3IRWJF6bsB12fWiTX5t/nSKPXhX7bdZ6fWuCkOFKhkcyPJHhRoZnMtzJ8EKGVxQRSxQ1KihSQZUKylRQp4JCFVSqoFQFtaqoVWWfp6hVRa0qalVRq4paVdSqolYVtRpRqxG1GtmXX9RqRK1G1GpErUbUakStRtRqQq0m1GpCrSb2SxW1mlCrCbWaUKsJtZpQq4ZaNdSqoVYNtWqoVUOtGmrVUKuGWjXUakatZtRqRq1m1GpGrWb2HzBqNaNWM2o1o1YdteqoVUetOmrVUauOWnX2wAa16qhVR60W1GpBrRbUakGtFtRqQa0W1GphT1dRqwW1WlGrFbVaUasVtVpRqxW1WlGrFbVa2VUIeBfiKVZRu88soY/828hTgWLxPuL2Z2QuPrvj0K12/bIhtdw7j+v7wtRcTl+Hnztz7zc=","file_map":{"29":{"source":"mod poseidon;\nmod mimc;\nmod poseidon2;\n\nuse crate::default::Default;\nuse crate::uint128::U128;\nuse crate::sha256::{digest, sha256_var};\n\n#[foreign(sha256)]\n// docs:start:sha256\npub fn sha256(input: [u8; N]) -> [u8; 32]\n// docs:end:sha256\n{}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n#[foreign(blake3)]\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{}\n\n// docs:start:pedersen_commitment\nstruct PedersenPoint {\n x : Field,\n y : Field,\n}\n\npub fn pedersen_commitment(input: [Field; N]) -> PedersenPoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[foreign(pedersen_commitment)]\npub fn __pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> [Field; 2] {}\n\npub fn pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> PedersenPoint {\n let values = __pedersen_commitment_with_separator(input, separator);\n PedersenPoint { x: values[0], y: values[1] }\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[foreign(pedersen_hash)]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {}\n\npub fn hash_to_field(inputs: [Field]) -> Field {\n let mut sum = 0;\n\n for input in inputs {\n let input_bytes: [u8; 32] = input.to_le_bytes(32).as_array();\n sum += crate::field::bytes32_to_field(blake2s(input_bytes));\n }\n\n sum\n}\n\n#[foreign(keccak256)]\n// docs:start:keccak256\npub fn keccak256(input: [u8; N], message_size: u32) -> [u8; 32]\n// docs:end:keccak256\n{}\n\n#[foreign(poseidon2_permutation)]\npub fn poseidon2_permutation(_input: [Field; N], _state_length: u32) -> [Field; N] {}\n\n#[foreign(sha256_compression)]\npub fn sha256_compression(_input: [u32; 16], _state: [u32; 8]) -> [u32; 8] {}\n\n// Generic hashing support. \n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\ntrait Hash{\n fn hash(self, state: &mut H) where H: Hasher;\n}\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\ntrait Hasher{\n fn finish(self) -> Field;\n \n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\ntrait BuildHasher where H: Hasher{\n fn build_hasher(self) -> H;\n}\n\nstruct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere \n H: Hasher + Default\n{\n fn build_hasher(_self: Self) -> H{\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere \n H: Hasher + Default\n{\n fn default() -> Self{\n BuildHasherDefault{}\n } \n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H) where H: Hasher {}\n}\n\nimpl Hash for U128 {\n fn hash(self, state: &mut H) where H: Hasher{\n H::write(state, self.lo as Field);\n H::write(state, self.hi as Field);\n }\n}\n\nimpl Hash for [T; N] where T: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T] where T: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B) where A: Hash, B: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C) where A: Hash, B: Hash, C: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D) where A: Hash, B: Hash, C: Hash, D: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: Hash, E: Hash {\n fn hash(self, state: &mut H) where H: Hasher{\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n","path":"std/hash.nr"},"47":{"source":"fn main(x: Field) {\n let mut acc = x;\n for i in 0..100 {\n acc = dep::std::hash::pedersen_hash([acc]);\n }\n assert_eq(acc * 2, 28);\n assert_eq(acc * 3, 42);\n}\n\n","path":"/mnt/user-data/mike/packages/trickty/src/main.nr"}},"names":["main"]} \ No newline at end of file