From 9b1010eb9decacfc82ef30bdf50102ecda9e8712 Mon Sep 17 00:00:00 2001 From: Suyash Bagad Date: Tue, 14 Mar 2023 12:11:11 +0000 Subject: [PATCH 01/46] Make dsl composer agnostic. --- cpp/src/barretenberg/dsl/CMakeLists.txt | 2 +- .../dsl/acir_format/acir_format.cpp | 24 +++++------ .../dsl/acir_format/acir_format.hpp | 23 +++++----- .../dsl/acir_format/blake2s_constraint.cpp | 7 +-- .../dsl/acir_format/blake2s_constraint.hpp | 6 ++- .../dsl/acir_format/ecdsa_secp256k1.cpp | 19 ++++---- .../dsl/acir_format/ecdsa_secp256k1.hpp | 6 ++- .../dsl/acir_format/fixed_base_scalar_mul.cpp | 5 +-- .../dsl/acir_format/fixed_base_scalar_mul.hpp | 6 ++- .../dsl/acir_format/hash_to_field.cpp | 7 +-- .../dsl/acir_format/hash_to_field.hpp | 6 ++- .../dsl/acir_format/logic_constraint.cpp | 6 +-- .../dsl/acir_format/logic_constraint.hpp | 11 ++--- .../merkle_membership_constraint.cpp | 6 +-- .../merkle_membership_constraint.hpp | 6 ++- .../barretenberg/dsl/acir_format/pedersen.cpp | 5 +-- .../barretenberg/dsl/acir_format/pedersen.hpp | 6 ++- .../dsl/acir_format/schnorr_verify.cpp | 11 ++--- .../dsl/acir_format/schnorr_verify.hpp | 6 ++- .../dsl/acir_format/sha256_constraint.cpp | 7 +-- .../dsl/acir_format/sha256_constraint.hpp | 6 ++- .../{turbo_proofs => proofs}/CMakeLists.txt | 0 cpp/src/barretenberg/dsl/proofs/c_bind.cpp | 43 +++++++++++++++++++ .../dsl/{turbo_proofs => proofs}/c_bind.hpp | 0 .../turbo_proofs.cpp => proofs/proofs.cpp} | 32 +++++++------- cpp/src/barretenberg/dsl/proofs/proofs.hpp | 18 ++++++++ .../barretenberg/dsl/turbo_proofs/c_bind.cpp | 43 ------------------- .../dsl/turbo_proofs/turbo_proofs.hpp | 18 -------- 28 files changed, 165 insertions(+), 170 deletions(-) rename cpp/src/barretenberg/dsl/{turbo_proofs => proofs}/CMakeLists.txt (100%) create mode 100644 cpp/src/barretenberg/dsl/proofs/c_bind.cpp rename cpp/src/barretenberg/dsl/{turbo_proofs => proofs}/c_bind.hpp (100%) rename cpp/src/barretenberg/dsl/{turbo_proofs/turbo_proofs.cpp => proofs/proofs.cpp} (83%) create mode 100644 cpp/src/barretenberg/dsl/proofs/proofs.hpp delete mode 100644 cpp/src/barretenberg/dsl/turbo_proofs/c_bind.cpp delete mode 100644 cpp/src/barretenberg/dsl/turbo_proofs/turbo_proofs.hpp diff --git a/cpp/src/barretenberg/dsl/CMakeLists.txt b/cpp/src/barretenberg/dsl/CMakeLists.txt index 9e37be54e7..04eeab8d78 100644 --- a/cpp/src/barretenberg/dsl/CMakeLists.txt +++ b/cpp/src/barretenberg/dsl/CMakeLists.txt @@ -1,2 +1,2 @@ add_subdirectory(acir_format) -add_subdirectory(turbo_proofs) +add_subdirectory(proofs) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 4a411a1e32..365b3fdb69 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -2,7 +2,7 @@ namespace acir_format { -void read_witness(TurboComposer& composer, std::vector witness) +void read_witness(Composer& composer, std::vector witness) { composer.variables[0] = 0; for (size_t i = 0; i < witness.size(); ++i) { @@ -10,7 +10,7 @@ void read_witness(TurboComposer& composer, std::vector witness } } -void create_circuit(TurboComposer& composer, const acir_format& constraint_system) +void create_circuit(Composer& composer, const acir_format& constraint_system) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { std::cout << "too many public inputs!" << std::endl; @@ -85,14 +85,14 @@ void create_circuit(TurboComposer& composer, const acir_format& constraint_syste } } -TurboComposer create_circuit(const acir_format& constraint_system, - std::unique_ptr&& crs_factory) +Composer create_circuit(const acir_format& constraint_system, + std::unique_ptr&& crs_factory) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { std::cout << "too many public inputs!" << std::endl; } - TurboComposer composer(std::move(crs_factory)); + Composer composer(std::move(crs_factory)); for (size_t i = 1; i < constraint_system.varnum; ++i) { // If the index is in the public inputs vector, then we add it as a public input @@ -165,15 +165,15 @@ TurboComposer create_circuit(const acir_format& constraint_system, return composer; } -TurboComposer create_circuit_with_witness(const acir_format& constraint_system, - std::vector witness, - std::unique_ptr&& crs_factory) +Composer create_circuit_with_witness(const acir_format& constraint_system, + std::vector witness, + std::unique_ptr&& crs_factory) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { std::cout << "too many public inputs!" << std::endl; } - TurboComposer composer(std::move(crs_factory)); + Composer composer(std::move(crs_factory)); for (size_t i = 1; i < constraint_system.varnum; ++i) { // If the index is in the public inputs vector, then we add it as a public input @@ -248,13 +248,13 @@ TurboComposer create_circuit_with_witness(const acir_format& constraint_system, return composer; } -TurboComposer create_circuit_with_witness(const acir_format& constraint_system, std::vector witness) +Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector witness) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { std::cout << "too many public inputs!" << std::endl; } - auto composer = TurboComposer(); + auto composer = Composer(); for (size_t i = 1; i < constraint_system.varnum; ++i) { // If the index is in the public inputs vector, then we add it as a public input @@ -329,7 +329,7 @@ TurboComposer create_circuit_with_witness(const acir_format& constraint_system, return composer; } -void create_circuit_with_witness(TurboComposer& composer, const acir_format& constraint_system, std::vector witness) +void create_circuit_with_witness(Composer& composer, const acir_format& constraint_system, std::vector witness) { if (constraint_system.public_inputs.size() > constraint_system.varnum) { std::cout << "too many public inputs!" << std::endl; diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index 17c40441d8..d0d8d18075 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -9,6 +9,9 @@ #include "merkle_membership_constraint.hpp" #include "pedersen.hpp" #include "hash_to_field.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -35,22 +38,20 @@ struct acir_format { friend bool operator==(acir_format const& lhs, acir_format const& rhs) = default; }; -void read_witness(TurboComposer& composer, std::vector witness); +void read_witness(Composer& composer, std::vector witness); -void create_circuit(TurboComposer& composer, const acir_format& constraint_system); +void create_circuit(Composer& composer, const acir_format& constraint_system); -TurboComposer create_circuit(const acir_format& constraint_system, - std::unique_ptr&& crs_factory); +Composer create_circuit(const acir_format& constraint_system, + std::unique_ptr&& crs_factory); -TurboComposer create_circuit_with_witness(const acir_format& constraint_system, - std::vector witness, - std::unique_ptr&& crs_factory); +Composer create_circuit_with_witness(const acir_format& constraint_system, + std::vector witness, + std::unique_ptr&& crs_factory); -TurboComposer create_circuit_with_witness(const acir_format& constraint_system, std::vector witness); +Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector witness); -void create_circuit_with_witness(TurboComposer& composer, - const acir_format& constraint_system, - std::vector witness); +void create_circuit_with_witness(Composer& composer, const acir_format& constraint_system, std::vector witness); // Serialisation template inline void read(B& buf, acir_format& data) diff --git a/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.cpp index 38876d0a5b..58ec5a928a 100644 --- a/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.cpp @@ -1,12 +1,9 @@ #include "blake2s_constraint.hpp" #include "round.hpp" -#include "barretenberg/stdlib/types/types.hpp" - -using namespace plonk::stdlib::types; namespace acir_format { -void create_blake2s_constraints(plonk::TurboComposer& composer, const Blake2sConstraint& constraint) +void create_blake2s_constraints(Composer& composer, const Blake2sConstraint& constraint) { // Create byte array struct @@ -27,7 +24,7 @@ void create_blake2s_constraints(plonk::TurboComposer& composer, const Blake2sCon arr.write(element_bytes); } - byte_array_ct output_bytes = plonk::stdlib::blake2s(arr); + byte_array_ct output_bytes = plonk::stdlib::blake2s(arr); // Convert byte array to vector of field_t auto bytes = output_bytes.bytes(); diff --git a/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp index e4ce915b5a..7119b2dc60 100644 --- a/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp @@ -1,7 +1,9 @@ #pragma once #include #include -#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -19,7 +21,7 @@ struct Blake2sConstraint { friend bool operator==(Blake2sConstraint const& lhs, Blake2sConstraint const& rhs) = default; }; -void create_blake2s_constraints(plonk::TurboComposer& composer, const Blake2sConstraint& constraint); +void create_blake2s_constraints(Composer& composer, const Blake2sConstraint& constraint); template inline void read(B& buf, Blake2sInput& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp index 5d495775d7..b38692b3c6 100644 --- a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp @@ -1,13 +1,10 @@ #include "ecdsa_secp256k1.hpp" #include "barretenberg/crypto/ecdsa/ecdsa.hpp" #include "barretenberg/stdlib/encryption/ecdsa/ecdsa.hpp" -#include "barretenberg/stdlib/types/types.hpp" - -using namespace plonk::stdlib::types; namespace acir_format { -crypto::ecdsa::signature ecdsa_convert_signature(plonk::TurboComposer& composer, std::vector signature) +crypto::ecdsa::signature ecdsa_convert_signature(Composer& composer, std::vector signature) { crypto::ecdsa::signature signature_cr; @@ -42,7 +39,7 @@ crypto::ecdsa::signature ecdsa_convert_signature(plonk::TurboComposer& composer, return signature_cr; } -secp256k1_ct::g1_ct ecdsa_convert_inputs(plonk::TurboComposer* ctx, const secp256k1::g1::affine_element& input) +secp256k1_ct::g1_ct ecdsa_convert_inputs(Composer* ctx, const secp256k1::g1::affine_element& input) { uint256_t x_u256(input.x); uint256_t y_u256(input.y); @@ -61,7 +58,7 @@ secp256k1_ct::g1_ct ecdsa_convert_inputs(plonk::TurboComposer* ctx, const secp25 // vector of bytes here, assumes that the witness indices point to a field element which can be represented // with just a byte. // notice that this function truncates each field_element to a byte -byte_array_ct ecdsa_vector_of_bytes_to_byte_array(plonk::TurboComposer& composer, std::vector vector_of_bytes) +byte_array_ct ecdsa_vector_of_bytes_to_byte_array(Composer& composer, std::vector vector_of_bytes) { byte_array_ct arr(&composer); @@ -77,13 +74,13 @@ byte_array_ct ecdsa_vector_of_bytes_to_byte_array(plonk::TurboComposer& composer } return arr; } -witness_ct ecdsa_index_to_witness(plonk::TurboComposer& composer, uint32_t index) +witness_ct ecdsa_index_to_witness(Composer& composer, uint32_t index) { fr value = composer.get_variable(index); return { &composer, value }; } -void create_ecdsa_verify_constraints(plonk::TurboComposer& composer, const EcdsaSecp256k1Constraint& input) +void create_ecdsa_verify_constraints(Composer& composer, const EcdsaSecp256k1Constraint& input) { auto new_sig = ecdsa_convert_signature(composer, input.signature); @@ -98,15 +95,15 @@ void create_ecdsa_verify_constraints(plonk::TurboComposer& composer, const Ecdsa std::vector rr(new_sig.r.begin(), new_sig.r.end()); std::vector ss(new_sig.s.begin(), new_sig.s.end()); - stdlib::ecdsa::signature sig{ stdlib::byte_array(&composer, rr), - stdlib::byte_array(&composer, ss) }; + stdlib::ecdsa::signature sig{ stdlib::byte_array(&composer, rr), + stdlib::byte_array(&composer, ss) }; pub_key_x_fq.assert_is_in_field(); pub_key_y_fq.assert_is_in_field(); secp256k1_ct::g1_bigfr_ct public_key = secp256k1_ct::g1_bigfr_ct(pub_key_x_fq, pub_key_y_fq); - bool_ct signature_result = stdlib::ecdsa::verify_signature -#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -28,7 +30,7 @@ struct EcdsaSecp256k1Constraint { friend bool operator==(EcdsaSecp256k1Constraint const& lhs, EcdsaSecp256k1Constraint const& rhs) = default; }; -void create_ecdsa_verify_constraints(plonk::TurboComposer& composer, const EcdsaSecp256k1Constraint& input); +void create_ecdsa_verify_constraints(Composer& composer, const EcdsaSecp256k1Constraint& input); template inline void read(B& buf, EcdsaSecp256k1Constraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.cpp b/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.cpp index db5383927c..453ab56f47 100644 --- a/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.cpp @@ -1,11 +1,8 @@ #include "fixed_base_scalar_mul.hpp" -#include "barretenberg/stdlib/types/types.hpp" - -using namespace plonk::stdlib::types; namespace acir_format { -void create_fixed_base_constraint(plonk::TurboComposer& composer, const FixedBaseScalarMul& input) +void create_fixed_base_constraint(Composer& composer, const FixedBaseScalarMul& input) { field_ct scalar_as_field = field_ct::from_witness_index(&composer, input.scalar); diff --git a/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.hpp b/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.hpp index 672978bac6..7139f5c74f 100644 --- a/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.hpp @@ -1,6 +1,8 @@ #pragma once #include -#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -12,7 +14,7 @@ struct FixedBaseScalarMul { friend bool operator==(FixedBaseScalarMul const& lhs, FixedBaseScalarMul const& rhs) = default; }; -void create_fixed_base_constraint(plonk::TurboComposer& composer, const FixedBaseScalarMul& input); +void create_fixed_base_constraint(Composer& composer, const FixedBaseScalarMul& input); template inline void read(B& buf, FixedBaseScalarMul& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/hash_to_field.cpp b/cpp/src/barretenberg/dsl/acir_format/hash_to_field.cpp index 577c3b6bac..9470898525 100644 --- a/cpp/src/barretenberg/dsl/acir_format/hash_to_field.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/hash_to_field.cpp @@ -1,12 +1,9 @@ #include "hash_to_field.hpp" #include "round.hpp" -#include "barretenberg/stdlib/types/types.hpp" - -using namespace plonk::stdlib::types; namespace acir_format { -void create_hash_to_field_constraints(plonk::TurboComposer& composer, const HashToFieldConstraint constraint) +void create_hash_to_field_constraints(Composer& composer, const HashToFieldConstraint constraint) { // Create byte array struct @@ -31,7 +28,7 @@ void create_hash_to_field_constraints(plonk::TurboComposer& composer, const Hash // Hash To Field using blake2s. // Note: It does not need to be blake2s in the future - byte_array_ct out_bytes = plonk::stdlib::blake2s(arr); + byte_array_ct out_bytes = plonk::stdlib::blake2s(arr); field_ct out(out_bytes); field_ct normalised_out = out.normalize(); diff --git a/cpp/src/barretenberg/dsl/acir_format/hash_to_field.hpp b/cpp/src/barretenberg/dsl/acir_format/hash_to_field.hpp index 6f8b901b57..6d612e82b3 100644 --- a/cpp/src/barretenberg/dsl/acir_format/hash_to_field.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/hash_to_field.hpp @@ -1,7 +1,9 @@ #pragma once #include #include -#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -19,7 +21,7 @@ struct HashToFieldConstraint { friend bool operator==(HashToFieldConstraint const& lhs, HashToFieldConstraint const& rhs) = default; }; -void create_hash_to_field_constraints(plonk::TurboComposer& composer, HashToFieldConstraint constraint); +void create_hash_to_field_constraints(Composer& composer, HashToFieldConstraint constraint); template inline void read(B& buf, HashToFieldInput& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index 27d938fbf6..9f96ab5f61 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -2,7 +2,7 @@ namespace acir_format { -void create_logic_gate(TurboComposer& composer, +void create_logic_gate(Composer& composer, const uint32_t a, const uint32_t b, const uint32_t result, @@ -12,11 +12,11 @@ void create_logic_gate(TurboComposer& composer, auto accumulators = composer.create_logic_constraint(a, b, num_bits, is_xor_gate); composer.assert_equal(accumulators.out.back(), result); } -void xor_gate(TurboComposer& composer, const uint32_t a, const uint32_t b, const uint32_t result, const size_t num_bits) +void xor_gate(Composer& composer, const uint32_t a, const uint32_t b, const uint32_t result, const size_t num_bits) { create_logic_gate(composer, a, b, result, num_bits, true); } -void and_gate(TurboComposer& composer, const uint32_t a, const uint32_t b, const uint32_t result, const size_t num_bits) +void and_gate(Composer& composer, const uint32_t a, const uint32_t b, const uint32_t result, const size_t num_bits) { create_logic_gate(composer, a, b, result, num_bits, false); } diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp index 51dfb73db5..141830932e 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp @@ -1,6 +1,8 @@ #pragma once #include -#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -14,12 +16,11 @@ struct LogicConstraint { friend bool operator==(LogicConstraint const& lhs, LogicConstraint const& rhs) = default; }; -void create_logic_gate( - TurboComposer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits, bool is_xor_gate); +void create_logic_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits, bool is_xor_gate); -void xor_gate(TurboComposer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits); +void xor_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits); -void and_gate(TurboComposer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits); +void and_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits); template inline void read(B& buf, LogicConstraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.cpp index 65b746abcf..4ad9a28703 100644 --- a/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.cpp @@ -1,13 +1,11 @@ #include "merkle_membership_constraint.hpp" #include "barretenberg/stdlib/merkle_tree/membership.hpp" -#include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; using namespace plonk::stdlib::merkle_tree; namespace acir_format { -void create_merkle_check_membership_constraint(plonk::TurboComposer& composer, const MerkleMembershipConstraint& input) +void create_merkle_check_membership_constraint(Composer& composer, const MerkleMembershipConstraint& input) { // Convert value from a witness index into a field element. // This is the hash of the message. In Barretenberg, this would be input.value = hash_value(message) @@ -23,7 +21,7 @@ void create_merkle_check_membership_constraint(plonk::TurboComposer& composer, c // We are given the HashPath as a Vec // We want to first convert it into a Vec<(fr, fr)> then cast this to hash_path // struct which requires the method create_witness_hashpath - hash_path hash_path; + hash_path hash_path; // In Noir we accept a hash path that only contains one hash per tree level // It is ok to reuse the leaf as it will be overridden in check_subtree_membership when computing the current root diff --git a/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.hpp index 6cf9a78dd6..f4c195e63f 100644 --- a/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.hpp @@ -1,6 +1,8 @@ #pragma once #include -#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -14,7 +16,7 @@ struct MerkleMembershipConstraint { friend bool operator==(MerkleMembershipConstraint const& lhs, MerkleMembershipConstraint const& rhs) = default; }; -void create_merkle_check_membership_constraint(plonk::TurboComposer& composer, const MerkleMembershipConstraint& input); +void create_merkle_check_membership_constraint(Composer& composer, const MerkleMembershipConstraint& input); template inline void read(B& buf, MerkleMembershipConstraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp b/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp index 6bb7b9de9b..bb53c66ba1 100644 --- a/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp @@ -1,11 +1,8 @@ #include "pedersen.hpp" -#include "barretenberg/stdlib/types/types.hpp" - -using namespace plonk::stdlib::types; namespace acir_format { -void create_pedersen_constraint(plonk::TurboComposer& composer, const PedersenConstraint& input) +void create_pedersen_constraint(Composer& composer, const PedersenConstraint& input) { std::vector scalars; diff --git a/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp b/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp index e53c51fef0..af46c46909 100644 --- a/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp @@ -1,6 +1,8 @@ #pragma once #include -#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -13,7 +15,7 @@ struct PedersenConstraint { friend bool operator==(PedersenConstraint const& lhs, PedersenConstraint const& rhs) = default; }; -void create_pedersen_constraint(plonk::TurboComposer& composer, const PedersenConstraint& input); +void create_pedersen_constraint(Composer& composer, const PedersenConstraint& input); template inline void read(B& buf, PedersenConstraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp b/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp index 497bda7f9a..ec973d23ca 100644 --- a/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp @@ -1,12 +1,9 @@ #include "schnorr_verify.hpp" #include "barretenberg/crypto/schnorr/schnorr.hpp" -#include "barretenberg/stdlib/types/types.hpp" - -using namespace plonk::stdlib::types; namespace acir_format { -crypto::schnorr::signature convert_signature(plonk::TurboComposer& composer, std::vector signature) +crypto::schnorr::signature convert_signature(Composer& composer, std::vector signature) { crypto::schnorr::signature signature_cr; @@ -43,7 +40,7 @@ crypto::schnorr::signature convert_signature(plonk::TurboComposer& composer, std // vector of bytes here, assumes that the witness indices point to a field element which can be represented // with just a byte. // notice that this function truncates each field_element to a byte -byte_array_ct vector_of_bytes_to_byte_array(plonk::TurboComposer& composer, std::vector vector_of_bytes) +byte_array_ct vector_of_bytes_to_byte_array(Composer& composer, std::vector vector_of_bytes) { byte_array_ct arr(&composer); @@ -59,13 +56,13 @@ byte_array_ct vector_of_bytes_to_byte_array(plonk::TurboComposer& composer, std: } return arr; } -witness_ct index_to_witness(plonk::TurboComposer& composer, uint32_t index) +witness_ct index_to_witness(Composer& composer, uint32_t index) { fr value = composer.get_variable(index); return { &composer, value }; } -void create_schnorr_verify_constraints(plonk::TurboComposer& composer, const SchnorrConstraint& input) +void create_schnorr_verify_constraints(Composer& composer, const SchnorrConstraint& input) { auto new_sig = convert_signature(composer, input.signature); diff --git a/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp b/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp index 8f0eec2222..f41e6d9e82 100644 --- a/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp @@ -1,6 +1,8 @@ #pragma once #include -#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -25,7 +27,7 @@ struct SchnorrConstraint { friend bool operator==(SchnorrConstraint const& lhs, SchnorrConstraint const& rhs) = default; }; -void create_schnorr_verify_constraints(plonk::TurboComposer& composer, const SchnorrConstraint& input); +void create_schnorr_verify_constraints(Composer& composer, const SchnorrConstraint& input); template inline void read(B& buf, SchnorrConstraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp index b1c2fbe2a8..25ad8af174 100644 --- a/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp @@ -1,15 +1,12 @@ #include "sha256_constraint.hpp" #include "round.hpp" #include "barretenberg/stdlib/hash/sha256/sha256.hpp" -#include "barretenberg/stdlib/types/types.hpp" - -using namespace plonk::stdlib::types; namespace acir_format { // This function does not work (properly) because the stdlib:sha256 function is not working correctly for 512 bits // pair -void create_sha256_constraints(plonk::TurboComposer& composer, const Sha256Constraint& constraint) +void create_sha256_constraints(Composer& composer, const Sha256Constraint& constraint) { // Create byte array struct @@ -31,7 +28,7 @@ void create_sha256_constraints(plonk::TurboComposer& composer, const Sha256Const } // Compute sha256 - byte_array_ct output_bytes = plonk::stdlib::sha256(arr); + byte_array_ct output_bytes = plonk::stdlib::sha256(arr); // Convert byte array to vector of field_t auto bytes = output_bytes.bytes(); diff --git a/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp index 08b60e0bd1..1dbd2cedfb 100644 --- a/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp @@ -1,7 +1,9 @@ #pragma once #include #include -#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/stdlib/types/types.hpp" + +using namespace plonk::stdlib::types; namespace acir_format { @@ -21,7 +23,7 @@ struct Sha256Constraint { // This function does not work (properly) because the stdlib:sha256 function is not working correctly for 512 bits // pair -void create_sha256_constraints(plonk::TurboComposer& composer, const Sha256Constraint& constraint); +void create_sha256_constraints(Composer& composer, const Sha256Constraint& constraint); template inline void read(B& buf, Sha256Input& constraint) { diff --git a/cpp/src/barretenberg/dsl/turbo_proofs/CMakeLists.txt b/cpp/src/barretenberg/dsl/proofs/CMakeLists.txt similarity index 100% rename from cpp/src/barretenberg/dsl/turbo_proofs/CMakeLists.txt rename to cpp/src/barretenberg/dsl/proofs/CMakeLists.txt diff --git a/cpp/src/barretenberg/dsl/proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/proofs/c_bind.cpp new file mode 100644 index 0000000000..868f7d17c6 --- /dev/null +++ b/cpp/src/barretenberg/dsl/proofs/c_bind.cpp @@ -0,0 +1,43 @@ +#include "c_bind.hpp" +#include "proofs.hpp" +#include + +#define WASM_EXPORT __attribute__((visibility("default"))) + +extern "C" { + +// Get the exact circuit size for the constraint system. +WASM_EXPORT uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf) +{ + return proofs::get_exact_circuit_size(constraint_system_buf); +} + +WASM_EXPORT size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) +{ + return proofs::init_proving_key(constraint_system_buf, pk_buf); +} + +WASM_EXPORT size_t init_verification_key(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const** vk_buf) +{ + return proofs::init_verification_key(pippenger, g2x, pk_buf, vk_buf); +} + +WASM_EXPORT size_t new_proof(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const* constraint_system_buf, + uint8_t const* witness_buf, + uint8_t** proof_data_buf) +{ + return proofs::new_proof(pippenger, g2x, pk_buf, constraint_system_buf, witness_buf, proof_data_buf); +} + +WASM_EXPORT bool verify_proof( + uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length) +{ + return proofs::verify_proof(g2x, vk_buf, constraint_system_buf, proof, length); +} +} diff --git a/cpp/src/barretenberg/dsl/turbo_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/proofs/c_bind.hpp similarity index 100% rename from cpp/src/barretenberg/dsl/turbo_proofs/c_bind.hpp rename to cpp/src/barretenberg/dsl/proofs/c_bind.hpp diff --git a/cpp/src/barretenberg/dsl/turbo_proofs/turbo_proofs.cpp b/cpp/src/barretenberg/dsl/proofs/proofs.cpp similarity index 83% rename from cpp/src/barretenberg/dsl/turbo_proofs/turbo_proofs.cpp rename to cpp/src/barretenberg/dsl/proofs/proofs.cpp index 233170dee8..5f66caa3a6 100644 --- a/cpp/src/barretenberg/dsl/turbo_proofs/turbo_proofs.cpp +++ b/cpp/src/barretenberg/dsl/proofs/proofs.cpp @@ -1,5 +1,5 @@ -#include "turbo_proofs.hpp" +#include "proofs.hpp" #include "barretenberg/proof_system/proving_key/serialize.hpp" #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/stdlib/types/types.hpp" @@ -7,9 +7,9 @@ using namespace plonk::stdlib::types; -namespace turbo_proofs { +namespace proofs { -uint32_t turbo_get_exact_circuit_size(uint8_t const* constraint_system_buf) +uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf) { auto constraint_system = from_buffer(constraint_system_buf); auto crs_factory = std::make_unique(); @@ -19,7 +19,7 @@ uint32_t turbo_get_exact_circuit_size(uint8_t const* constraint_system_buf) return static_cast(num_gates); } -size_t turbo_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) +size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) { auto constraint_system = from_buffer(constraint_system_buf); // We know that we don't actually need any CRS to create a proving key, so just feed in a nothing. @@ -36,7 +36,7 @@ size_t turbo_init_proving_key(uint8_t const* constraint_system_buf, uint8_t cons return buffer.size(); } -size_t turbo_init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, uint8_t const** vk_buf) +size_t init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, uint8_t const** vk_buf) { std::shared_ptr crs; bonk::proving_key_data pk_data; @@ -47,7 +47,7 @@ size_t turbo_init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t reinterpret_cast(pippenger), g2x); proving_key->reference_string = crs_factory->get_prover_crs(proving_key->circuit_size); - TurboComposer composer(proving_key, nullptr); + Composer composer(proving_key, nullptr); auto verification_key = plonk::stdlib::types::Composer::compute_verification_key_base(proving_key, crs_factory->get_verifier_crs()); @@ -63,12 +63,12 @@ size_t turbo_init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t return buffer.size(); } -size_t turbo_new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf) +size_t new_proof(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const* constraint_system_buf, + uint8_t const* witness_buf, + uint8_t** proof_data_buf) { auto constraint_system = from_buffer(constraint_system_buf); @@ -83,7 +83,7 @@ size_t turbo_new_proof(void* pippenger, reinterpret_cast(pippenger), g2x); proving_key->reference_string = crs_factory->get_prover_crs(proving_key->circuit_size); - TurboComposer composer(proving_key, nullptr); + Composer composer(proving_key, nullptr); create_circuit_with_witness(composer, constraint_system, witness); auto prover = composer.create_prover(); @@ -94,7 +94,7 @@ size_t turbo_new_proof(void* pippenger, return proof_data.size(); } -bool turbo_verify_proof( +bool verify_proof( uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length) { bool verified = false; @@ -109,7 +109,7 @@ bool turbo_verify_proof( read(vk_buf, vk_data); auto verification_key = std::make_shared(std::move(vk_data), crs); - TurboComposer composer(nullptr, verification_key); + Composer composer(nullptr, verification_key); create_circuit(composer, constraint_system); plonk::proof pp = { std::vector(proof, proof + length) }; @@ -125,4 +125,4 @@ bool turbo_verify_proof( return verified; } -} // namespace turbo_proofs +} // namespace proofs diff --git a/cpp/src/barretenberg/dsl/proofs/proofs.hpp b/cpp/src/barretenberg/dsl/proofs/proofs.hpp new file mode 100644 index 0000000000..7db9845f8a --- /dev/null +++ b/cpp/src/barretenberg/dsl/proofs/proofs.hpp @@ -0,0 +1,18 @@ +#include +#include + +namespace proofs { + +uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf); +size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); +size_t init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, uint8_t const** vk_buf); +size_t new_proof(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const* constraint_system_buf, + uint8_t const* witness_buf, + uint8_t** proof_data_buf); +bool verify_proof( + uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length); + +} // namespace proofs diff --git a/cpp/src/barretenberg/dsl/turbo_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/turbo_proofs/c_bind.cpp deleted file mode 100644 index 1b4cd27d84..0000000000 --- a/cpp/src/barretenberg/dsl/turbo_proofs/c_bind.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "c_bind.hpp" -#include "turbo_proofs.hpp" -#include - -#define WASM_EXPORT __attribute__((visibility("default"))) - -extern "C" { - -// Get the exact circuit size for the constraint system. -WASM_EXPORT uint32_t turbo_get_exact_circuit_size(uint8_t const* constraint_system_buf) -{ - return turbo_proofs::turbo_get_exact_circuit_size(constraint_system_buf); -} - -WASM_EXPORT size_t turbo_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) -{ - return turbo_proofs::turbo_init_proving_key(constraint_system_buf, pk_buf); -} - -WASM_EXPORT size_t turbo_init_verification_key(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const** vk_buf) -{ - return turbo_proofs::turbo_init_verification_key(pippenger, g2x, pk_buf, vk_buf); -} - -WASM_EXPORT size_t turbo_new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf) -{ - return turbo_proofs::turbo_new_proof(pippenger, g2x, pk_buf, constraint_system_buf, witness_buf, proof_data_buf); -} - -WASM_EXPORT bool turbo_verify_proof( - uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length) -{ - return turbo_proofs::turbo_verify_proof(g2x, vk_buf, constraint_system_buf, proof, length); -} -} diff --git a/cpp/src/barretenberg/dsl/turbo_proofs/turbo_proofs.hpp b/cpp/src/barretenberg/dsl/turbo_proofs/turbo_proofs.hpp deleted file mode 100644 index 486973e418..0000000000 --- a/cpp/src/barretenberg/dsl/turbo_proofs/turbo_proofs.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -namespace turbo_proofs { - -uint32_t turbo_get_exact_circuit_size(uint8_t const* constraint_system_buf); -size_t turbo_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); -size_t turbo_init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, uint8_t const** vk_buf); -size_t turbo_new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf); -bool turbo_verify_proof( - uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length); - -} // namespace turbo_proofs From 30157c62b17c08fca16e7b4d2594970a958b9766 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Tue, 14 Mar 2023 18:47:10 -0400 Subject: [PATCH 02/46] change SYSTEM_COMPOSER under stdlib::types to ultra composer type --- .../dsl/acir_format/acir_format.cpp | 10 +++---- cpp/src/barretenberg/dsl/proofs/c_bind.hpp | 26 +++++++++---------- cpp/src/barretenberg/dsl/proofs/proofs.cpp | 2 +- .../proofs/join_split/c_bind.cpp | 2 +- .../proofs/join_split/join_split.cpp | 2 +- .../proofs/join_split/join_split.hpp | 2 +- .../plonk/proof_system/constants.hpp | 2 +- .../stdlib/hash/sha256/sha256.bench.cpp | 4 +-- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 365b3fdb69..8fb9c4496d 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -41,7 +41,7 @@ void create_circuit(Composer& composer, const acir_format& constraint_system) // Add range constraint for (const auto& constraint : constraint_system.range_constraints) { - composer.decompose_into_base4_accumulators(constraint.witness, constraint.num_bits, ""); + composer.create_range_constraint(constraint.witness, constraint.num_bits, ""); } // Add sha256 constraints @@ -119,7 +119,7 @@ Composer create_circuit(const acir_format& constraint_system, // Add range constraint for (const auto& constraint : constraint_system.range_constraints) { - composer.decompose_into_base4_accumulators(constraint.witness, constraint.num_bits, ""); + composer.create_range_constraint(constraint.witness, constraint.num_bits, ""); } // Add sha256 constraints @@ -203,7 +203,7 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, // Add range constraint for (const auto& constraint : constraint_system.range_constraints) { - composer.decompose_into_base4_accumulators(constraint.witness, constraint.num_bits, ""); + composer.create_range_constraint(constraint.witness, constraint.num_bits, ""); } // Add sha256 constraints @@ -284,7 +284,7 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, std:: // Add range constraint for (const auto& constraint : constraint_system.range_constraints) { - composer.decompose_into_base4_accumulators(constraint.witness, constraint.num_bits, ""); + composer.create_range_constraint(constraint.witness, constraint.num_bits, ""); } // Add sha256 constraints @@ -363,7 +363,7 @@ void create_circuit_with_witness(Composer& composer, const acir_format& constrai // Add range constraint for (const auto& constraint : constraint_system.range_constraints) { - composer.decompose_into_base4_accumulators(constraint.witness, constraint.num_bits, ""); + composer.create_range_constraint(constraint.witness, constraint.num_bits, ""); } // Add sha256 constraints diff --git a/cpp/src/barretenberg/dsl/proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/proofs/c_bind.hpp index e9ba3c5402..89f9805899 100644 --- a/cpp/src/barretenberg/dsl/proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/proofs/c_bind.hpp @@ -5,20 +5,20 @@ extern "C" { -WASM_EXPORT uint32_t turbo_get_exact_circuit_size(uint8_t const* constraint_system_buf); +WASM_EXPORT uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf); // Construct composer using prover and verifier key buffers -WASM_EXPORT size_t turbo_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); -WASM_EXPORT size_t turbo_init_verification_key(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const** vk_buf); -WASM_EXPORT size_t turbo_new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf); -WASM_EXPORT bool turbo_verify_proof( +WASM_EXPORT size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); +WASM_EXPORT size_t init_verification_key(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const** vk_buf); +WASM_EXPORT size_t new_proof(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const* constraint_system_buf, + uint8_t const* witness_buf, + uint8_t** proof_data_buf); +WASM_EXPORT bool verify_proof( uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length); } diff --git a/cpp/src/barretenberg/dsl/proofs/proofs.cpp b/cpp/src/barretenberg/dsl/proofs/proofs.cpp index 5f66caa3a6..5fe9f5f21f 100644 --- a/cpp/src/barretenberg/dsl/proofs/proofs.cpp +++ b/cpp/src/barretenberg/dsl/proofs/proofs.cpp @@ -87,7 +87,7 @@ size_t new_proof(void* pippenger, create_circuit_with_witness(composer, constraint_system, witness); auto prover = composer.create_prover(); - auto heapProver = new TurboProver(std::move(prover)); + auto heapProver = new UltraProver(std::move(prover)); auto& proof_data = heapProver->construct_proof().proof_data; *proof_data_buf = proof_data.data(); diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp index 67983ccd08..0a8f0c95a4 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp @@ -93,7 +93,7 @@ WASM_EXPORT void* join_split__new_prover(uint8_t const* join_split_buf, bool moc { auto tx = from_buffer(join_split_buf); auto prover = new_join_split_prover(tx, mock); - auto heapProver = new plonk::TurboProver(std::move(prover)); + auto heapProver = new plonk::UltraProver(std::move(prover)); return heapProver; } diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp index 64af4cbd25..c5737ce168 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp @@ -64,7 +64,7 @@ void init_verification_key(std::shared_ptr con verification_key = std::make_shared(std::move(vk_data), crs); } -plonk::TurboProver new_join_split_prover(join_split_tx const& tx, bool mock) +plonk::UltraProver new_join_split_prover(join_split_tx const& tx, bool mock) { Composer composer(proving_key, nullptr); join_split_circuit(composer, tx); diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp index 274983ec80..5ed4cd3c38 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp @@ -21,7 +21,7 @@ void init_verification_key(std::unique_ptr&& crs_f void init_verification_key(std::shared_ptr const& crs, bonk::verification_key_data&& vk_data); -plonk::TurboProver new_join_split_prover(join_split_tx const& tx, bool mock); +plonk::UltraProver new_join_split_prover(join_split_tx const& tx, bool mock); bool verify_proof(plonk::proof const& proof); diff --git a/cpp/src/barretenberg/plonk/proof_system/constants.hpp b/cpp/src/barretenberg/plonk/proof_system/constants.hpp index 9d6229b039..eaf3c24b73 100644 --- a/cpp/src/barretenberg/plonk/proof_system/constants.hpp +++ b/cpp/src/barretenberg/plonk/proof_system/constants.hpp @@ -13,7 +13,7 @@ enum ComposerType { // This variable sets the composer (TURBO or ULTRA) of the entire stdlib and rollup modules. // To switch to using a new composer, only changing this variable should activate the new composer // throughout the stdlib and circuits. -static constexpr uint32_t SYSTEM_COMPOSER = ComposerType::TURBO; +static constexpr uint32_t SYSTEM_COMPOSER = ComposerType::PLOOKUP; enum MerkleHashType { FIXED_BASE_PEDERSEN, diff --git a/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp b/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp index 11685b4188..31ffb1e9df 100644 --- a/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp +++ b/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp @@ -29,8 +29,8 @@ void generate_test_plonk_circuit(Composer& composer, size_t num_bytes) } Composer composers[NUM_HASHES]; -plonk::TurboProver provers[NUM_HASHES]; -plonk::TurboVerifier verifiers[NUM_HASHES]; +plonk::UltraProver provers[NUM_HASHES]; +plonk::UltraVerifier verifiers[NUM_HASHES]; plonk::proof proofs[NUM_HASHES]; void construct_witnesses_bench(State& state) noexcept From c8848be784e489582c5c8feb60b283fbfe161f12 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 15 Mar 2023 16:48:27 -0400 Subject: [PATCH 03/46] use ultra logic constraints --- .../dsl/acir_format/logic_constraint.cpp | 22 ++++++++--- .../dsl/acir_format/logic_constraint.hpp | 4 +- cpp/src/barretenberg/dsl/proofs/c_bind.cpp | 12 +++--- cpp/src/barretenberg/dsl/proofs/c_bind.hpp | 12 +++--- .../polynomial_store.test.cpp | 39 ++++++++++--------- 5 files changed, 50 insertions(+), 39 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index 9f96ab5f61..5022e2e517 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -9,16 +9,26 @@ void create_logic_gate(Composer& composer, const size_t num_bits, const bool is_xor_gate) { - auto accumulators = composer.create_logic_constraint(a, b, num_bits, is_xor_gate); - composer.assert_equal(accumulators.out.back(), result); + (void)num_bits; + // auto accumulators = composer.create_logic_constraint(a, b, num_bits, is_xor_gate); + // composer.assert_equal(accumulators.out.back(), result); + if (is_xor_gate) { + xor_gate(composer, a, b, result); + } else { + and_gate(composer, a, b, result); + } } -void xor_gate(Composer& composer, const uint32_t a, const uint32_t b, const uint32_t result, const size_t num_bits) +void xor_gate(Composer& composer, const uint32_t a, const uint32_t b, const uint32_t result) { - create_logic_gate(composer, a, b, result, num_bits, true); + // create_logic_gate(composer, a, b, result, num_bits, true); + auto plookup_res = a ^ b; + composer.assert_equal(plookup_res, result); } -void and_gate(Composer& composer, const uint32_t a, const uint32_t b, const uint32_t result, const size_t num_bits) +void and_gate(Composer& composer, const uint32_t a, const uint32_t b, const uint32_t result) { - create_logic_gate(composer, a, b, result, num_bits, false); + // create_logic_gate(composer, a, b, result, num_bits, false); + auto plookup_res = a & b; + composer.assert_equal(plookup_res, result); } } // namespace acir_format diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp index 141830932e..615ac80f7b 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp @@ -18,9 +18,9 @@ struct LogicConstraint { void create_logic_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits, bool is_xor_gate); -void xor_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits); +void xor_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result); -void and_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits); +void and_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result); template inline void read(B& buf, LogicConstraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/proofs/c_bind.cpp index 868f7d17c6..30cd92fac6 100644 --- a/cpp/src/barretenberg/dsl/proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/proofs/c_bind.cpp @@ -7,20 +7,20 @@ extern "C" { // Get the exact circuit size for the constraint system. -WASM_EXPORT uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf) +WASM_EXPORT uint32_t c_get_exact_circuit_size(uint8_t const* constraint_system_buf) { return proofs::get_exact_circuit_size(constraint_system_buf); } -WASM_EXPORT size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) +WASM_EXPORT size_t c_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) { return proofs::init_proving_key(constraint_system_buf, pk_buf); } -WASM_EXPORT size_t init_verification_key(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const** vk_buf) +WASM_EXPORT size_t c_init_verification_key(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const** vk_buf) { return proofs::init_verification_key(pippenger, g2x, pk_buf, vk_buf); } diff --git a/cpp/src/barretenberg/dsl/proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/proofs/c_bind.hpp index 89f9805899..5b4b155aa1 100644 --- a/cpp/src/barretenberg/dsl/proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/proofs/c_bind.hpp @@ -5,14 +5,14 @@ extern "C" { -WASM_EXPORT uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf); +WASM_EXPORT uint32_t c_get_exact_circuit_size(uint8_t const* constraint_system_buf); // Construct composer using prover and verifier key buffers -WASM_EXPORT size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); -WASM_EXPORT size_t init_verification_key(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const** vk_buf); +WASM_EXPORT size_t c_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); +WASM_EXPORT size_t c_init_verification_key(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const** vk_buf); WASM_EXPORT size_t new_proof(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, diff --git a/cpp/src/barretenberg/proof_system/polynomial_store/polynomial_store.test.cpp b/cpp/src/barretenberg/proof_system/polynomial_store/polynomial_store.test.cpp index f0486cccbf..59deb6e275 100644 --- a/cpp/src/barretenberg/proof_system/polynomial_store/polynomial_store.test.cpp +++ b/cpp/src/barretenberg/proof_system/polynomial_store/polynomial_store.test.cpp @@ -91,24 +91,25 @@ TEST(PolynomialStore, Remove) } // Check that PolynomialStore supports range based for loop -TEST(PolynomialStore, RangeBasedFor) -{ - PolynomialStore polynomial_store; - size_t size = 100; - Polynomial poly1(size); - Polynomial poly2(size); - - polynomial_store.put("id_1", std::move(poly1)); - polynomial_store.put("id_2", std::move(poly2)); - - // Check that PolynomialStore meets criteria for std::ranges::range - EXPECT_TRUE(std::ranges::range>); - - // For example ... - Polynomial polynomial_sum(size); - for (const auto& [key, polynomial] : polynomial_store) { - polynomial_sum += polynomial; - } -} +// TODO fatal error: no member named 'ranges' in namespace 'std' +// TEST(PolynomialStore, RangeBasedFor) +// { +// PolynomialStore polynomial_store; +// size_t size = 100; +// Polynomial poly1(size); +// Polynomial poly2(size); + +// polynomial_store.put("id_1", std::move(poly1)); +// polynomial_store.put("id_2", std::move(poly2)); + +// // Check that PolynomialStore meets criteria for std::ranges::range +// EXPECT_TRUE(std::ranges::range>); + +// // For example ... +// Polynomial polynomial_sum(size); +// for (const auto& [key, polynomial] : polynomial_store) { +// polynomial_sum += polynomial; +// } +// } } // namespace bonk From eb7cfb16b2a5d3a74c158e398b4d3f6e51b31dd2 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Thu, 16 Mar 2023 10:13:24 -0400 Subject: [PATCH 04/46] in process of debugging, move to using ultra logic constraints --- cpp/src/barretenberg/dsl/acir_format/acir_format.hpp | 2 ++ cpp/src/barretenberg/dsl/proofs/proofs.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index d0d8d18075..0acfef16b1 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -56,7 +56,9 @@ void create_circuit_with_witness(Composer& composer, const acir_format& constrai // Serialisation template inline void read(B& buf, acir_format& data) { + printf("about to read in acir_format 1\n"); using serialize::read; + printf("about to read in acir_format 2\n"); read(buf, data.varnum); read(buf, data.public_inputs); read(buf, data.logic_constraints); diff --git a/cpp/src/barretenberg/dsl/proofs/proofs.cpp b/cpp/src/barretenberg/dsl/proofs/proofs.cpp index 5fe9f5f21f..6f9c4d5496 100644 --- a/cpp/src/barretenberg/dsl/proofs/proofs.cpp +++ b/cpp/src/barretenberg/dsl/proofs/proofs.cpp @@ -22,6 +22,8 @@ uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf) size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) { auto constraint_system = from_buffer(constraint_system_buf); + printf("read in constraint system to init pk\n"); + // We know that we don't actually need any CRS to create a proving key, so just feed in a nothing. // Hacky, but, right now it needs *something*. auto crs_factory = std::make_unique(); @@ -70,12 +72,15 @@ size_t new_proof(void* pippenger, uint8_t const* witness_buf, uint8_t** proof_data_buf) { + printf("got into new_proof\n"); auto constraint_system = from_buffer(constraint_system_buf); + printf("read in constraint system\n"); std::shared_ptr crs; bonk::proving_key_data pk_data; read(pk_buf, pk_data); auto proving_key = std::make_shared(std::move(pk_data), crs); + printf("read in proving_key\n"); auto witness = from_buffer>(witness_buf); @@ -84,9 +89,14 @@ size_t new_proof(void* pippenger, proving_key->reference_string = crs_factory->get_prover_crs(proving_key->circuit_size); Composer composer(proving_key, nullptr); + printf("we got a composer object\n"); + create_circuit_with_witness(composer, constraint_system, witness); + printf("created circuit with witness\n"); auto prover = composer.create_prover(); + printf("created a prover\n"); + auto heapProver = new UltraProver(std::move(prover)); auto& proof_data = heapProver->construct_proof().proof_data; *proof_data_buf = proof_data.data(); From 8a9337c1130c0e432ec27f4a39583a2c6d506b8d Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Wed, 22 Mar 2023 16:36:02 -0400 Subject: [PATCH 05/46] add get_total_circuit_size method --- .../dsl/acir_format/acir_format.hpp | 2 -- cpp/src/barretenberg/dsl/proofs/c_bind.cpp | 5 ++++ cpp/src/barretenberg/dsl/proofs/c_bind.hpp | 2 +- cpp/src/barretenberg/dsl/proofs/proofs.cpp | 30 +++++++++++++------ cpp/src/barretenberg/dsl/proofs/proofs.hpp | 1 + .../barretenberg/transcript/transcript.cpp | 2 -- 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index 0acfef16b1..d0d8d18075 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -56,9 +56,7 @@ void create_circuit_with_witness(Composer& composer, const acir_format& constrai // Serialisation template inline void read(B& buf, acir_format& data) { - printf("about to read in acir_format 1\n"); using serialize::read; - printf("about to read in acir_format 2\n"); read(buf, data.varnum); read(buf, data.public_inputs); read(buf, data.logic_constraints); diff --git a/cpp/src/barretenberg/dsl/proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/proofs/c_bind.cpp index 30cd92fac6..308ac2ede7 100644 --- a/cpp/src/barretenberg/dsl/proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/proofs/c_bind.cpp @@ -12,6 +12,11 @@ WASM_EXPORT uint32_t c_get_exact_circuit_size(uint8_t const* constraint_system_b return proofs::get_exact_circuit_size(constraint_system_buf); } +WASM_EXPORT uint32_t c_get_total_circuit_size(uint8_t const* constraint_system_buf) +{ + return proofs::get_total_circuit_size(constraint_system_buf); +} + WASM_EXPORT size_t c_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) { return proofs::init_proving_key(constraint_system_buf, pk_buf); diff --git a/cpp/src/barretenberg/dsl/proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/proofs/c_bind.hpp index 5b4b155aa1..b8a6ca5c18 100644 --- a/cpp/src/barretenberg/dsl/proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/proofs/c_bind.hpp @@ -6,7 +6,7 @@ extern "C" { WASM_EXPORT uint32_t c_get_exact_circuit_size(uint8_t const* constraint_system_buf); - +WASM_EXPORT uint32_t c_get_total_circuit_size(uint8_t const* constraint_system_buf); // Construct composer using prover and verifier key buffers WASM_EXPORT size_t c_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); WASM_EXPORT size_t c_init_verification_key(void* pippenger, diff --git a/cpp/src/barretenberg/dsl/proofs/proofs.cpp b/cpp/src/barretenberg/dsl/proofs/proofs.cpp index 6f9c4d5496..0b74e0d885 100644 --- a/cpp/src/barretenberg/dsl/proofs/proofs.cpp +++ b/cpp/src/barretenberg/dsl/proofs/proofs.cpp @@ -19,10 +19,29 @@ uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf) return static_cast(num_gates); } +uint32_t get_total_circuit_size(uint8_t const* constraint_system_buf) +{ + auto constraint_system = from_buffer(constraint_system_buf); + auto crs_factory = std::make_unique(); + auto composer = create_circuit(constraint_system, std::move(crs_factory)); + + size_t tables_size = 0; + size_t lookups_size = 0; + for (const auto& table : composer.lookup_tables) { + tables_size += table.size; + lookups_size += table.lookup_gates.size(); + } + + auto minimum_circuit_size = tables_size + lookups_size; + auto num_filled_gates = composer.get_num_gates() + composer.public_inputs.size(); + const size_t total_num_gates = std::max(minimum_circuit_size, num_filled_gates); + + return static_cast(total_num_gates); +} + size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) { auto constraint_system = from_buffer(constraint_system_buf); - printf("read in constraint system to init pk\n"); // We know that we don't actually need any CRS to create a proving key, so just feed in a nothing. // Hacky, but, right now it needs *something*. @@ -55,7 +74,7 @@ size_t init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* // The composer_type has not yet been set. We need to set the composer_type for when we later read in and // construct the verification key so that we have the correct polynomial manifest - verification_key->composer_type = ComposerType::TURBO; + verification_key->composer_type = ComposerType::PLOOKUP; auto buffer = to_buffer(*verification_key); auto raw_buf = (uint8_t*)malloc(buffer.size()); @@ -72,15 +91,12 @@ size_t new_proof(void* pippenger, uint8_t const* witness_buf, uint8_t** proof_data_buf) { - printf("got into new_proof\n"); auto constraint_system = from_buffer(constraint_system_buf); - printf("read in constraint system\n"); std::shared_ptr crs; bonk::proving_key_data pk_data; read(pk_buf, pk_data); auto proving_key = std::make_shared(std::move(pk_data), crs); - printf("read in proving_key\n"); auto witness = from_buffer>(witness_buf); @@ -89,13 +105,10 @@ size_t new_proof(void* pippenger, proving_key->reference_string = crs_factory->get_prover_crs(proving_key->circuit_size); Composer composer(proving_key, nullptr); - printf("we got a composer object\n"); create_circuit_with_witness(composer, constraint_system, witness); - printf("created circuit with witness\n"); auto prover = composer.create_prover(); - printf("created a prover\n"); auto heapProver = new UltraProver(std::move(prover)); auto& proof_data = heapProver->construct_proof().proof_data; @@ -113,7 +126,6 @@ bool verify_proof( try { #endif auto constraint_system = from_buffer(constraint_system_buf); - auto crs = std::make_shared(g2x); bonk::verification_key_data vk_data; read(vk_buf, vk_data); diff --git a/cpp/src/barretenberg/dsl/proofs/proofs.hpp b/cpp/src/barretenberg/dsl/proofs/proofs.hpp index 7db9845f8a..e31acd5150 100644 --- a/cpp/src/barretenberg/dsl/proofs/proofs.hpp +++ b/cpp/src/barretenberg/dsl/proofs/proofs.hpp @@ -4,6 +4,7 @@ namespace proofs { uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf); +uint32_t get_total_circuit_size(uint8_t const* constraint_system_buf); size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); size_t init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, uint8_t const** vk_buf); size_t new_proof(void* pippenger, diff --git a/cpp/src/barretenberg/transcript/transcript.cpp b/cpp/src/barretenberg/transcript/transcript.cpp index 2e5d5e9e02..57b9cfa410 100644 --- a/cpp/src/barretenberg/transcript/transcript.cpp +++ b/cpp/src/barretenberg/transcript/transcript.cpp @@ -377,7 +377,6 @@ std::array Transcript::get_challenge_from * */ size_t Transcript::get_num_challenges(const std::string& challenge_name) const { - // printf("getting challenge count for %s \n", challenge_name.c_str()); ASSERT(challenges.count(challenge_name) == 1); return challenges.at(challenge_name).size(); @@ -393,7 +392,6 @@ size_t Transcript::get_num_challenges(const std::string& challenge_name) const * */ std::vector Transcript::get_element(const std::string& element_name) const { - // printf("getting element %s \n", element_name.c_str()); ASSERT(elements.count(element_name) == 1); return elements.at(element_name); } From b932e9964837ebfbd0db650d0bfee33e80969a7a Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 23 Mar 2023 22:16:26 -0400 Subject: [PATCH 06/46] acir format tests showing failures with range constraints of different bit sizes --- .../dsl/acir_format/acir_format.cpp | 1 + .../dsl/acir_format/acir_format.test.cpp | 143 ++++++++++++++++++ cpp/src/barretenberg/dsl/proofs/proofs.cpp | 5 + 3 files changed, 149 insertions(+) create mode 100644 cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 8fb9c4496d..1792863916 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -42,6 +42,7 @@ void create_circuit(Composer& composer, const acir_format& constraint_system) // Add range constraint for (const auto& constraint : constraint_system.range_constraints) { composer.create_range_constraint(constraint.witness, constraint.num_bits, ""); + // composer.decompose_into_default_range(constraint.witness, constraint.num_bits, 4, ""); } // Add sha256 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 new file mode 100644 index 0000000000..69505aa2fd --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -0,0 +1,143 @@ +#include "acir_format.hpp" +#include "barretenberg/plonk/proof_system/types/proof.hpp" +#include +#include +#include "barretenberg/common/streams.hpp" + +TEST(acir_format, test_schnorr_verify_pass) +{ + std::vector range_constraints; + for (uint32_t i = 0; i < 10; i++) { + range_constraints.push_back(acir_format::RangeConstraint{ + .witness = i + 1, + .num_bits = 15, + }); + } + + std::vector signature(64); + for (uint32_t i = 0, value = 13; i < 64; i++, value++) { + signature[i] = value; + range_constraints.push_back(acir_format::RangeConstraint{ + .witness = value, + .num_bits = 15, + }); + } + + acir_format::SchnorrConstraint schnorr_constraint{ + .message = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, + .public_key_x = 11, + .public_key_y = 12, + .result = 77, + .signature = signature, + }; + + acir_format::acir_format constraint_system{ + .varnum = 82, + .public_inputs = {}, + .fixed_base_scalar_mul_constraints = {}, + .logic_constraints = {}, + .range_constraints = range_constraints, + .schnorr_constraints = { schnorr_constraint }, + .ecdsa_constraints = {}, + .sha256_constraints = {}, + .blake2s_constraints = {}, + .hash_to_field_constraints = {}, + .pedersen_constraints = {}, + .merkle_membership_constraints = {}, + .constraints = { poly_triple{ + .a = schnorr_constraint.result, + .b = schnorr_constraint.result, + .c = schnorr_constraint.result, + .q_m = 0, + .q_l = 0, + .q_r = 0, + .q_o = 1, + .q_c = fr::neg_one(), + } }, + }; + uint256_t pub_x = uint256_t("17cbd3ed3151ccfd170efe1d54280a6a4822640bf5c369908ad74ea21518a9c5"); + uint256_t pub_y = uint256_t("0e0456e3795c1a31f20035b741cd6158929eeccd320d299cfcac962865a6bc74"); + + auto composer = acir_format::create_circuit_with_witness( + constraint_system, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, pub_x, pub_y, 5, 202, 31, 146, 81, 242, 246, 69, + 43, 107, 249, 153, 198, 44, 14, 111, 191, 121, 137, 166, 160, 103, 18, 181, 243, 233, 226, 95, + 67, 16, 37, 128, 85, 76, 19, 253, 30, 77, 192, 53, 138, 205, 69, 33, 236, 163, 83, 194, + 84, 137, 184, 221, 176, 121, 179, 27, 63, 70, 54, 16, 176, 250, 39, 239, 1, 0, 0, 0 }); + + auto prover = composer.create_prover(); + auto proof = prover.construct_proof(); + + auto verifier = composer.create_verifier(); + + EXPECT_EQ(verifier.verify_proof(proof), true); +} + +TEST(acir_format, test_schnorr_verify_small_range) +{ + std::vector range_constraints; + for (uint32_t i = 0; i < 10; i++) { + range_constraints.push_back(acir_format::RangeConstraint{ + .witness = i + 1, + .num_bits = 8, + }); + } + + std::vector signature(64); + for (uint32_t i = 0, value = 13; i < 64; i++, value++) { + signature[i] = value; + range_constraints.push_back(acir_format::RangeConstraint{ + .witness = value, + .num_bits = 8, + }); + } + + acir_format::SchnorrConstraint schnorr_constraint{ + .message = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, + .public_key_x = 11, + .public_key_y = 12, + .result = 77, + .signature = signature, + }; + + acir_format::acir_format constraint_system{ + .varnum = 82, + .public_inputs = {}, + .fixed_base_scalar_mul_constraints = {}, + .logic_constraints = {}, + .range_constraints = range_constraints, + .schnorr_constraints = { schnorr_constraint }, + .ecdsa_constraints = {}, + .sha256_constraints = {}, + .blake2s_constraints = {}, + .hash_to_field_constraints = {}, + .pedersen_constraints = {}, + .merkle_membership_constraints = {}, + .constraints = { poly_triple{ + .a = schnorr_constraint.result, + .b = schnorr_constraint.result, + .c = schnorr_constraint.result, + .q_m = 0, + .q_l = 0, + .q_r = 0, + .q_o = 1, + .q_c = fr::neg_one(), + } }, + }; + uint256_t pub_x = uint256_t("17cbd3ed3151ccfd170efe1d54280a6a4822640bf5c369908ad74ea21518a9c5"); + uint256_t pub_y = uint256_t("0e0456e3795c1a31f20035b741cd6158929eeccd320d299cfcac962865a6bc74"); + + auto composer = acir_format::create_circuit_with_witness( + constraint_system, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, pub_x, pub_y, 5, 202, 31, 146, 81, 242, 246, 69, + 43, 107, 249, 153, 198, 44, 14, 111, 191, 121, 137, 166, 160, 103, 18, 181, 243, 233, 226, 95, + 67, 16, 37, 128, 85, 76, 19, 253, 30, 77, 192, 53, 138, 205, 69, 33, 236, 163, 83, 194, + 84, 137, 184, 221, 176, 121, 179, 27, 63, 70, 54, 16, 176, 250, 39, 239, 1, 0, 0, 0 }); + + auto prover = composer.create_prover(); + auto proof = prover.construct_proof(); + + auto verifier = composer.create_verifier(); + + EXPECT_EQ(verifier.verify_proof(proof), true); +} \ No newline at end of file diff --git a/cpp/src/barretenberg/dsl/proofs/proofs.cpp b/cpp/src/barretenberg/dsl/proofs/proofs.cpp index 0b74e0d885..e9f878f68b 100644 --- a/cpp/src/barretenberg/dsl/proofs/proofs.cpp +++ b/cpp/src/barretenberg/dsl/proofs/proofs.cpp @@ -99,6 +99,11 @@ size_t new_proof(void* pippenger, auto proving_key = std::make_shared(std::move(pk_data), crs); auto witness = from_buffer>(witness_buf); + // std::vector witness_new_buf = to_buffer(witness); + // std::cout << "got witness_buf" << std::endl; + // for (size_t i = 0; i < witness_new_buf.size(); i++) { + // std::cout << unsigned(witness_new_buf[i]) << ", "; + // } auto crs_factory = std::make_unique( reinterpret_cast(pippenger), g2x); From fa0801a8028913adf7f6e0793fc233a2871a4a2b Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 23 Mar 2023 22:18:23 -0400 Subject: [PATCH 07/46] remove unnecessary comment --- cpp/src/barretenberg/dsl/proofs/proofs.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cpp/src/barretenberg/dsl/proofs/proofs.cpp b/cpp/src/barretenberg/dsl/proofs/proofs.cpp index e9f878f68b..0b74e0d885 100644 --- a/cpp/src/barretenberg/dsl/proofs/proofs.cpp +++ b/cpp/src/barretenberg/dsl/proofs/proofs.cpp @@ -99,11 +99,6 @@ size_t new_proof(void* pippenger, auto proving_key = std::make_shared(std::move(pk_data), crs); auto witness = from_buffer>(witness_buf); - // std::vector witness_new_buf = to_buffer(witness); - // std::cout << "got witness_buf" << std::endl; - // for (size_t i = 0; i < witness_new_buf.size(); i++) { - // std::cout << unsigned(witness_new_buf[i]) << ", "; - // } auto crs_factory = std::make_unique( reinterpret_cast(pippenger), g2x); From 355f10d66b4b0941909e45cacc0bc2ad217fbeee Mon Sep 17 00:00:00 2001 From: Suyash Bagad Date: Fri, 24 Mar 2023 12:29:08 +0000 Subject: [PATCH 08/46] (fix) Temporarily add a redundant add-gate for variables that need range constraint < 8 bits. --- .../plonk/composer/ultra_composer.hpp | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp index 599e9e921b..97c19cc77d 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp @@ -200,7 +200,22 @@ class UltraComposer : public ComposerBase { * gates. No arithemtic gate => size imbalance between sorted and non-sorted sets. Checking for this * and throwing an error would require a refactor of the Composer to catelog all 'orphan' variables not * assigned to gates. + * + * TODO(Suyash): + * The following is a temporary fix to make sure the range constraints on numbers with + * num_bits <= DEFAULT_PLOOKUP_RANGE_BITNUM is correctly enforced in the circuit. + * Longer term, as Zac says, we would need to refactor the composer to fix this. **/ + create_poly_gate(poly_triple{ + .a = variable_index, + .b = variable_index, + .c = variable_index, + .q_m = 0, + .q_l = 1, + .q_r = -1, + .q_o = 0, + .q_c = 0, + }); create_new_range_constraint(variable_index, 1ULL << num_bits, msg); } else { decompose_into_default_range(variable_index, num_bits, DEFAULT_PLOOKUP_RANGE_BITNUM, msg); @@ -497,7 +512,8 @@ class UltraComposer : public ComposerBase { * @brief Each entry in ram_arrays represents an independent RAM table. * RamTranscript tracks the current table state, * as well as the 'records' produced by each read and write operation. - * Used in `compute_proving_key` to generate consistency check gates required to validate the RAM read/write history + * Used in `compute_proving_key` to generate consistency check gates required to validate the RAM read/write + * history */ std::vector ram_arrays; @@ -647,9 +663,9 @@ class UltraComposer : public ComposerBase { /** * @brief Create a unrolled manifest object * - * @note UP rolled/unrolled manifests are the same. Difference between regulur && unrolled Prover/Verifier is that - * unrolled Prover/Verifier uses 16-byte challenges and a SNARK-friendly hash algorithm to generate challenges. - * (i.e. unrolled Prover/Verifier is used in recursive setting) + * @note UP rolled/unrolled manifests are the same. Difference between regulur && unrolled Prover/Verifier is + * that unrolled Prover/Verifier uses 16-byte challenges and a SNARK-friendly hash algorithm to generate + * challenges. (i.e. unrolled Prover/Verifier is used in recursive setting) * * TODO: remove linearisation trick entirely from barretenberg and relabel `unrolled` to `recursive`! * @param num_public_inputs From 391aa92d88638c130668db779e565a36fdb8de4a Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 27 Mar 2023 15:13:17 +0100 Subject: [PATCH 09/46] rename functions --- cpp/src/CMakeLists.txt | 6 +-- cpp/src/barretenberg/dsl/CMakeLists.txt | 2 +- .../{proofs => acir_proofs}/CMakeLists.txt | 2 +- .../acir_proofs.cpp} | 6 +-- .../acir_proofs.hpp} | 4 +- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 48 +++++++++++++++++++ .../barretenberg/dsl/acir_proofs/c_bind.hpp | 24 ++++++++++ cpp/src/barretenberg/dsl/proofs/c_bind.cpp | 48 ------------------- cpp/src/barretenberg/dsl/proofs/c_bind.hpp | 24 ---------- 9 files changed, 82 insertions(+), 82 deletions(-) rename cpp/src/barretenberg/dsl/{proofs => acir_proofs}/CMakeLists.txt (75%) rename cpp/src/barretenberg/dsl/{proofs/proofs.cpp => acir_proofs/acir_proofs.cpp} (98%) rename cpp/src/barretenberg/dsl/{proofs/proofs.hpp => acir_proofs/acir_proofs.hpp} (93%) create mode 100644 cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp create mode 100644 cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp delete mode 100644 cpp/src/barretenberg/dsl/proofs/c_bind.cpp delete mode 100644 cpp/src/barretenberg/dsl/proofs/c_bind.hpp diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index 067a1e2507..6802f1c004 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -91,7 +91,7 @@ if(WASM) $ $ $ - $ + $ ) # With binaryen installed, it seems its wasm backend optimiser gets invoked automatically. @@ -151,7 +151,7 @@ if(WASM) $ $ $ - $ + $ ) else() # For use when compiling dependent cpp projects @@ -183,7 +183,7 @@ else() $ $ $ - $ + $ $ ) diff --git a/cpp/src/barretenberg/dsl/CMakeLists.txt b/cpp/src/barretenberg/dsl/CMakeLists.txt index 04eeab8d78..f4697905ea 100644 --- a/cpp/src/barretenberg/dsl/CMakeLists.txt +++ b/cpp/src/barretenberg/dsl/CMakeLists.txt @@ -1,2 +1,2 @@ add_subdirectory(acir_format) -add_subdirectory(proofs) +add_subdirectory(acir_proofs) diff --git a/cpp/src/barretenberg/dsl/proofs/CMakeLists.txt b/cpp/src/barretenberg/dsl/acir_proofs/CMakeLists.txt similarity index 75% rename from cpp/src/barretenberg/dsl/proofs/CMakeLists.txt rename to cpp/src/barretenberg/dsl/acir_proofs/CMakeLists.txt index 7cfc2cdac8..9bdf62b9b7 100644 --- a/cpp/src/barretenberg/dsl/proofs/CMakeLists.txt +++ b/cpp/src/barretenberg/dsl/acir_proofs/CMakeLists.txt @@ -1,5 +1,5 @@ barretenberg_module( - proofs + acir_proofs acir_format plonk ) diff --git a/cpp/src/barretenberg/dsl/proofs/proofs.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp similarity index 98% rename from cpp/src/barretenberg/dsl/proofs/proofs.cpp rename to cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp index 0b74e0d885..df125ba495 100644 --- a/cpp/src/barretenberg/dsl/proofs/proofs.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp @@ -1,5 +1,5 @@ -#include "proofs.hpp" +#include "acir_proofs.hpp" #include "barretenberg/proof_system/proving_key/serialize.hpp" #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/stdlib/types/types.hpp" @@ -7,7 +7,7 @@ using namespace plonk::stdlib::types; -namespace proofs { +namespace acir_proofs { uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf) { @@ -147,4 +147,4 @@ bool verify_proof( return verified; } -} // namespace proofs +} // namespace acir_proofs diff --git a/cpp/src/barretenberg/dsl/proofs/proofs.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp similarity index 93% rename from cpp/src/barretenberg/dsl/proofs/proofs.hpp rename to cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp index e31acd5150..e41a526f22 100644 --- a/cpp/src/barretenberg/dsl/proofs/proofs.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp @@ -1,7 +1,7 @@ #include #include -namespace proofs { +namespace acir_proofs { uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf); uint32_t get_total_circuit_size(uint8_t const* constraint_system_buf); @@ -16,4 +16,4 @@ size_t new_proof(void* pippenger, bool verify_proof( uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length); -} // namespace proofs +} // namespace acir_proofs diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp new file mode 100644 index 0000000000..79793fc9da --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -0,0 +1,48 @@ +#include "c_bind.hpp" +#include "acir_proofs.hpp" +#include + +#define WASM_EXPORT __attribute__((visibility("default"))) + +extern "C" { + +// Get the exact circuit size for the constraint system. +WASM_EXPORT uint32_t acir_proofs_get_exact_circuit_size(uint8_t const* constraint_system_buf) +{ + return acir_proofs::get_exact_circuit_size(constraint_system_buf); +} + +WASM_EXPORT uint32_t acir_proofs_get_total_circuit_size(uint8_t const* constraint_system_buf) +{ + return acir_proofs::get_total_circuit_size(constraint_system_buf); +} + +WASM_EXPORT size_t acir_proofs_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) +{ + return acir_proofs::init_proving_key(constraint_system_buf, pk_buf); +} + +WASM_EXPORT size_t acir_proofs_init_verification_key(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const** vk_buf) +{ + return acir_proofs::init_verification_key(pippenger, g2x, pk_buf, vk_buf); +} + +WASM_EXPORT size_t acir_proofs_new_proof(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const* constraint_system_buf, + uint8_t const* witness_buf, + uint8_t** proof_data_buf) +{ + return acir_proofs::new_proof(pippenger, g2x, pk_buf, constraint_system_buf, witness_buf, proof_data_buf); +} + +WASM_EXPORT bool acir_proofs_verify_proof( + uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length) +{ + return acir_proofs::verify_proof(g2x, vk_buf, constraint_system_buf, proof, length); +} +} diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp new file mode 100644 index 0000000000..f763c54dfe --- /dev/null +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -0,0 +1,24 @@ +#include +#include + +#define WASM_EXPORT __attribute__((visibility("default"))) + +extern "C" { + +WASM_EXPORT uint32_t acir_proofs_get_exact_circuit_size(uint8_t const* constraint_system_buf); +WASM_EXPORT uint32_t acir_proofs_get_total_circuit_size(uint8_t const* constraint_system_buf); +// Construct composer using prover and verifier key buffers +WASM_EXPORT size_t acir_proofs_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); +WASM_EXPORT size_t acir_proofs_init_verification_key(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const** vk_buf); +WASM_EXPORT size_t acir_proofs_new_proof(void* pippenger, + uint8_t const* g2x, + uint8_t const* pk_buf, + uint8_t const* constraint_system_buf, + uint8_t const* witness_buf, + uint8_t** proof_data_buf); +WASM_EXPORT bool acir_proofs_verify_proof( + uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length); +} diff --git a/cpp/src/barretenberg/dsl/proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/proofs/c_bind.cpp deleted file mode 100644 index 308ac2ede7..0000000000 --- a/cpp/src/barretenberg/dsl/proofs/c_bind.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "c_bind.hpp" -#include "proofs.hpp" -#include - -#define WASM_EXPORT __attribute__((visibility("default"))) - -extern "C" { - -// Get the exact circuit size for the constraint system. -WASM_EXPORT uint32_t c_get_exact_circuit_size(uint8_t const* constraint_system_buf) -{ - return proofs::get_exact_circuit_size(constraint_system_buf); -} - -WASM_EXPORT uint32_t c_get_total_circuit_size(uint8_t const* constraint_system_buf) -{ - return proofs::get_total_circuit_size(constraint_system_buf); -} - -WASM_EXPORT size_t c_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) -{ - return proofs::init_proving_key(constraint_system_buf, pk_buf); -} - -WASM_EXPORT size_t c_init_verification_key(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const** vk_buf) -{ - return proofs::init_verification_key(pippenger, g2x, pk_buf, vk_buf); -} - -WASM_EXPORT size_t new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf) -{ - return proofs::new_proof(pippenger, g2x, pk_buf, constraint_system_buf, witness_buf, proof_data_buf); -} - -WASM_EXPORT bool verify_proof( - uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length) -{ - return proofs::verify_proof(g2x, vk_buf, constraint_system_buf, proof, length); -} -} diff --git a/cpp/src/barretenberg/dsl/proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/proofs/c_bind.hpp deleted file mode 100644 index b8a6ca5c18..0000000000 --- a/cpp/src/barretenberg/dsl/proofs/c_bind.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -#define WASM_EXPORT __attribute__((visibility("default"))) - -extern "C" { - -WASM_EXPORT uint32_t c_get_exact_circuit_size(uint8_t const* constraint_system_buf); -WASM_EXPORT uint32_t c_get_total_circuit_size(uint8_t const* constraint_system_buf); -// Construct composer using prover and verifier key buffers -WASM_EXPORT size_t c_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); -WASM_EXPORT size_t c_init_verification_key(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const** vk_buf); -WASM_EXPORT size_t new_proof(void* pippenger, - uint8_t const* g2x, - uint8_t const* pk_buf, - uint8_t const* constraint_system_buf, - uint8_t const* witness_buf, - uint8_t** proof_data_buf); -WASM_EXPORT bool verify_proof( - uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length); -} From 077053cc1dab18537a48215f5e65bf883f895347 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 27 Mar 2023 16:04:28 +0100 Subject: [PATCH 10/46] Implement get_solidity_verifier function --- .../dsl/acir_proofs/acir_proofs.cpp | 23 +++++++++++++++++++ .../dsl/acir_proofs/acir_proofs.hpp | 4 ++++ .../barretenberg/dsl/acir_proofs/c_bind.cpp | 8 +++++++ .../barretenberg/dsl/acir_proofs/c_bind.hpp | 4 ++++ 4 files changed, 39 insertions(+) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp index df125ba495..03f89fe300 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp @@ -4,11 +4,34 @@ #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/stdlib/types/types.hpp" #include "barretenberg/srs/reference_string/pippenger_reference_string.hpp" +#include "barretenberg/proof_system/verification_key/sol_gen.hpp" using namespace plonk::stdlib::types; namespace acir_proofs { +uint32_t get_solidity_verifier(uint8_t const* g2x, + uint8_t const* vk_buf, + uint8_t const* constraint_system_buf, + uint8_t** output_buf) +{ + auto constraint_system = from_buffer(constraint_system_buf); + auto crs = std::make_shared(g2x); + bonk::verification_key_data vk_data; + read(vk_buf, vk_data); + auto verification_key = std::make_shared(std::move(vk_data), crs); + + std::ostringstream stream; + // TODO(blaine): Should we just use "Verifier" generically? + output_vk_sol(stream, verification_key, "UltraVerifier"); + + auto content_str = stream.str(); + std::vector buffer(content_str.begin(), content_str.end()); + + *output_buf = buffer.data(); + return static_cast(buffer.size()); +} + uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf) { auto constraint_system = from_buffer(constraint_system_buf); diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp index e41a526f22..bf221e24e8 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp @@ -3,6 +3,10 @@ namespace acir_proofs { +uint32_t get_solidity_verifier(uint8_t const* g2x, + uint8_t const* vk_buf, + uint8_t const* constraint_system_buf, + uint8_t** output_buf); uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf); uint32_t get_total_circuit_size(uint8_t const* constraint_system_buf); size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 79793fc9da..30e68312f6 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -6,6 +6,14 @@ extern "C" { +WASM_EXPORT uint32_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, + uint8_t const* vk_buf, + uint8_t const* constraint_system_buf, + uint8_t** output_buf) +{ + return acir_proofs::get_solidity_verifier(g2x, vk_buf, constraint_system_buf, output_buf); +} + // Get the exact circuit size for the constraint system. WASM_EXPORT uint32_t acir_proofs_get_exact_circuit_size(uint8_t const* constraint_system_buf) { diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index f763c54dfe..65e943ad33 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -5,6 +5,10 @@ extern "C" { +WASM_EXPORT uint32_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, + uint8_t const* vk_buf, + uint8_t const* constraint_system_buf, + uint8_t** output_buf); WASM_EXPORT uint32_t acir_proofs_get_exact_circuit_size(uint8_t const* constraint_system_buf); WASM_EXPORT uint32_t acir_proofs_get_total_circuit_size(uint8_t const* constraint_system_buf); // Construct composer using prover and verifier key buffers From 4ac894930b14bb4719f065a1c1343d9470fabc60 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 27 Mar 2023 16:05:28 +0100 Subject: [PATCH 11/46] Fix no longer available properties --- .../proof_system/verification_key/sol_gen.hpp | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/cpp/src/barretenberg/proof_system/verification_key/sol_gen.hpp b/cpp/src/barretenberg/proof_system/verification_key/sol_gen.hpp index 096085b577..29fd773f0b 100644 --- a/cpp/src/barretenberg/proof_system/verification_key/sol_gen.hpp +++ b/cpp/src/barretenberg/proof_system/verification_key/sol_gen.hpp @@ -96,29 +96,29 @@ inline void output_vk_sol_ultra(std::ostream& os, std::shared_ptrnum_public_inputs, "vk.num_inputs"); print_u256("0x40", key->domain.root, "vk.work_root"); print_u256("0x60", key->domain.domain_inverse, "vk.domain_inverse"); - print_g1("0x80", "0xa0", key->constraint_selectors.at("Q_1"), "vk.Q1"); - print_g1("0xc0", "0xe0", key->constraint_selectors.at("Q_2"), "vk.Q2"); - print_g1("0x100", "0x120", key->constraint_selectors.at("Q_3"), "vk.Q3"); - print_g1("0x140", "0x160", key->constraint_selectors.at("Q_4"), "vk.Q4"); - print_g1("0x180", "0x1a0", key->constraint_selectors.at("Q_M"), "vk.Q_M"); - print_g1("0x1c0", "0x1e0", key->constraint_selectors.at("Q_C"), "vk.Q_C"); - print_g1("0x200", "0x220", key->constraint_selectors.at("Q_ARITHMETIC"), "vk.Q_ARITHMETIC"); - print_g1("0x240", "0x260", key->constraint_selectors.at("Q_SORT"), "vk.QSORT"); - print_g1("0x280", "0x2a0", key->constraint_selectors.at("Q_ELLIPTIC"), "vk.Q_ELLIPTIC"); - print_g1("0x2c0", "0x2e0", key->constraint_selectors.at("Q_AUX"), "vk.Q_AUX"); - print_g1("0x300", "0x320", key->permutation_selectors.at("SIGMA_1"), "vk.SIGMA1"); - print_g1("0x340", "0x360", key->permutation_selectors.at("SIGMA_2"), "vk.SIGMA2"); - print_g1("0x380", "0x3a0", key->permutation_selectors.at("SIGMA_3"), "vk.SIGMA3"); - print_g1("0x3c0", "0x3e0", key->permutation_selectors.at("SIGMA_4"), "vk.SIGMA4"); - print_g1("0x400", "0x420", key->constraint_selectors.at("TABLE_1"), "vk.TABLE1"); - print_g1("0x440", "0x460", key->constraint_selectors.at("TABLE_2"), "vk.TABLE2"); - print_g1("0x480", "0x4a0", key->constraint_selectors.at("TABLE_3"), "vk.TABLE3"); - print_g1("0x4c0", "0x4e0", key->constraint_selectors.at("TABLE_4"), "vk.TABLE4"); - print_g1("0x500", "0x520", key->constraint_selectors.at("TABLE_TYPE"), "vk.TABLE_TYPE"); - print_g1("0x540", "0x560", key->permutation_selectors.at("ID_1"), "vk.ID1"); - print_g1("0x580", "0x5a0", key->permutation_selectors.at("ID_2"), "vk.ID2"); - print_g1("0x5c0", "0x5e0", key->permutation_selectors.at("ID_3"), "vk.ID3"); - print_g1("0x600", "0x620", key->permutation_selectors.at("ID_4"), "vk.ID4"); + print_g1("0x80", "0xa0", key->commitments.at("Q_1"), "vk.Q1"); + print_g1("0xc0", "0xe0", key->commitments.at("Q_2"), "vk.Q2"); + print_g1("0x100", "0x120", key->commitments.at("Q_3"), "vk.Q3"); + print_g1("0x140", "0x160", key->commitments.at("Q_4"), "vk.Q4"); + print_g1("0x180", "0x1a0", key->commitments.at("Q_M"), "vk.Q_M"); + print_g1("0x1c0", "0x1e0", key->commitments.at("Q_C"), "vk.Q_C"); + print_g1("0x200", "0x220", key->commitments.at("Q_ARITHMETIC"), "vk.Q_ARITHMETIC"); + print_g1("0x240", "0x260", key->commitments.at("Q_SORT"), "vk.QSORT"); + print_g1("0x280", "0x2a0", key->commitments.at("Q_ELLIPTIC"), "vk.Q_ELLIPTIC"); + print_g1("0x2c0", "0x2e0", key->commitments.at("Q_AUX"), "vk.Q_AUX"); + print_g1("0x300", "0x320", key->commitments.at("SIGMA_1"), "vk.SIGMA1"); + print_g1("0x340", "0x360", key->commitments.at("SIGMA_2"), "vk.SIGMA2"); + print_g1("0x380", "0x3a0", key->commitments.at("SIGMA_3"), "vk.SIGMA3"); + print_g1("0x3c0", "0x3e0", key->commitments.at("SIGMA_4"), "vk.SIGMA4"); + print_g1("0x400", "0x420", key->commitments.at("TABLE_1"), "vk.TABLE1"); + print_g1("0x440", "0x460", key->commitments.at("TABLE_2"), "vk.TABLE2"); + print_g1("0x480", "0x4a0", key->commitments.at("TABLE_3"), "vk.TABLE3"); + print_g1("0x4c0", "0x4e0", key->commitments.at("TABLE_4"), "vk.TABLE4"); + print_g1("0x500", "0x520", key->commitments.at("TABLE_TYPE"), "vk.TABLE_TYPE"); + print_g1("0x540", "0x560", key->commitments.at("ID_1"), "vk.ID1"); + print_g1("0x580", "0x5a0", key->commitments.at("ID_2"), "vk.ID2"); + print_g1("0x5c0", "0x5e0", key->commitments.at("ID_3"), "vk.ID3"); + print_g1("0x600", "0x620", key->commitments.at("ID_4"), "vk.ID4"); os << " mstore(add(_vk, 0x640), " << (key->contains_recursive_proof ? "0x01" : "0x00") << ") // vk.contains_recursive_proof\n" " mstore(add(_vk, 0x660), " << (key->contains_recursive_proof ? key->recursive_proof_public_input_indices[0] : 0) << ") // vk.recursive_proof_public_input_indices\n" @@ -136,10 +136,10 @@ inline void output_vk_sol_ultra(std::ostream& os, std::shared_ptr const& key, std::string const& class_name) { From 2cca246b85a1814426e3e2dfd1013aabced6c5fd Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 27 Mar 2023 16:53:57 +0100 Subject: [PATCH 12/46] remove constraint system --- cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp | 6 +----- cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp | 5 +---- cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp | 7 ++----- cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp | 5 +---- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp index 03f89fe300..524e0b3731 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp @@ -10,12 +10,8 @@ using namespace plonk::stdlib::types; namespace acir_proofs { -uint32_t get_solidity_verifier(uint8_t const* g2x, - uint8_t const* vk_buf, - uint8_t const* constraint_system_buf, - uint8_t** output_buf) +uint32_t get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf) { - auto constraint_system = from_buffer(constraint_system_buf); auto crs = std::make_shared(g2x); bonk::verification_key_data vk_data; read(vk_buf, vk_data); diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp index bf221e24e8..04d3ce25d5 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp @@ -3,10 +3,7 @@ namespace acir_proofs { -uint32_t get_solidity_verifier(uint8_t const* g2x, - uint8_t const* vk_buf, - uint8_t const* constraint_system_buf, - uint8_t** output_buf); +uint32_t get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf); uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf); uint32_t get_total_circuit_size(uint8_t const* constraint_system_buf); size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 30e68312f6..81969e198f 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -6,12 +6,9 @@ extern "C" { -WASM_EXPORT uint32_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, - uint8_t const* vk_buf, - uint8_t const* constraint_system_buf, - uint8_t** output_buf) +WASM_EXPORT uint32_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf) { - return acir_proofs::get_solidity_verifier(g2x, vk_buf, constraint_system_buf, output_buf); + return acir_proofs::get_solidity_verifier(g2x, vk_buf, output_buf); } // Get the exact circuit size for the constraint system. diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index 65e943ad33..44ab2e323d 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -5,10 +5,7 @@ extern "C" { -WASM_EXPORT uint32_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, - uint8_t const* vk_buf, - uint8_t const* constraint_system_buf, - uint8_t** output_buf); +WASM_EXPORT uint32_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf); WASM_EXPORT uint32_t acir_proofs_get_exact_circuit_size(uint8_t const* constraint_system_buf); WASM_EXPORT uint32_t acir_proofs_get_total_circuit_size(uint8_t const* constraint_system_buf); // Construct composer using prover and verifier key buffers From 8f23dc75ba1ec4d43bd66c88168369727f4ca396 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Mon, 27 Mar 2023 18:07:22 +0100 Subject: [PATCH 13/46] logic gate changes using plookup --- .../dsl/acir_format/acir_format.cpp | 2 + .../dsl/acir_format/logic_constraint.cpp | 55 +- .../stdlib/primitives/uint/uint.test.cpp | 4282 ++++++++--------- cpp/src/barretenberg/stdlib/types/types.hpp | 2 + 4 files changed, 2187 insertions(+), 2154 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 1792863916..3890a93a73 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -12,6 +12,8 @@ void read_witness(Composer& composer, std::vector witness) void create_circuit(Composer& composer, const acir_format& constraint_system) { + std::cout << "2" << std::endl; + if (constraint_system.public_inputs.size() > constraint_system.varnum) { std::cout << "too many public inputs!" << std::endl; } diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index 5022e2e517..85d8a4e9d2 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -9,7 +9,6 @@ void create_logic_gate(Composer& composer, const size_t num_bits, const bool is_xor_gate) { - (void)num_bits; // auto accumulators = composer.create_logic_constraint(a, b, num_bits, is_xor_gate); // composer.assert_equal(accumulators.out.back(), result); if (is_xor_gate) { @@ -17,18 +16,48 @@ void create_logic_gate(Composer& composer, } else { and_gate(composer, a, b, result); } -} -void xor_gate(Composer& composer, const uint32_t a, const uint32_t b, const uint32_t result) -{ - // create_logic_gate(composer, a, b, result, num_bits, true); - auto plookup_res = a ^ b; - composer.assert_equal(plookup_res, result); -} -void and_gate(Composer& composer, const uint32_t a, const uint32_t b, const uint32_t result) -{ - // create_logic_gate(composer, a, b, result, num_bits, false); - auto plookup_res = a & b; - composer.assert_equal(plookup_res, result); + + const size_t num_chunks = ((num_bits / 4) + (num_bits % 4 == 0)) ? 0 : 1; + + uint256_t left = composer.get_variable(a); + uint256_t right = composer.get_variable(b); + + field_ct res(&composer); + for (size_t i = 0; i < num_chunks; ++i) + { + + uint256_t left_chunk = left & ((uint256_t(1) << 32) - 1); + uint256_t right_chunk = right & ((uint256_t(1) << 32) - 1); + + const field_ct a(&composer, left_chunk); + const field_ct b(&composer, right_chunk); + + field_ct result_chunk = 0; + if (is_xor_gate) { + result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_XOR, a, b); + } else { + result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); + } + + + uint256_t scaling_factor = uint256_t(1) << (32 * i); + res += result_chunk * scaling_factor; + + if (i == num_chunks - 1) + { + const size_t final_num_bits = num_bits - (i * 32); + if (final_num_bits != 32) + { + composer.create_range_constraint(a.witness_index, final_num_bits, ""); + composer.create_range_constraint(b.witness_index, final_num_bits, ""); + } + } + + left = left >> 32; + right = right >> 32; + } + + res.assert_equal(field_ct::from_witness_index(&composer, result)); } } // namespace acir_format diff --git a/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp b/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp index b9e7737fbf..887893d92f 100644 --- a/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp +++ b/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp @@ -1,2141 +1,2141 @@ -#include "uint.hpp" -#include "barretenberg/honk/composer/standard_honk_composer.hpp" -#include -#include -#include "barretenberg/numeric/random/engine.hpp" - -using namespace barretenberg; -using namespace plonk; -using namespace bonk; - -namespace { -auto& engine = numeric::random::get_debug_engine(); -} - -// NOTE: We only test width 32, but widths 8, 16, 32 and 64 can all be tested. -// In widths 8, 16, 32: all tests pass. -// In width 64, the following tests fail for UltraComposer. -// test_xor_special, test_xor_more_constants, test_and_constants, test_and_special, test_or_special, -// test_ror_special, test_hash_rounds, test_and, test_xor, test_or. -// They fail with 'C++ exception with description"Last key slice greater than 64" thrown in the test body."' -namespace test_stdlib_uint { -typedef uint32_t uint_native; -size_t uint_native_width = 8 * sizeof(uint_native); -uint_native uint_native_max = static_cast((static_cast(1) << uint_native_width) - 1); - -template Native get_random() -{ - return static_cast(engine.get_random_uint64()); -}; - -template std::vector get_several_random(size_t num) -{ - std::vector result; - for (size_t i = 0; i < num; ++i) { - result.emplace_back(get_random()); - } - return result; -} - -/** - * @brief Utility function for testing the uint_ct comparison operators - * - * @details Given a uint_ct a and a constant const_b, this allows to create a - * uint_ct b having a desired relation to a (either >. = or <). - */ -uint_native impose_comparison(uint_native const_a, - uint_native const_b, - uint_native a_val, - bool force_equal = false, - bool force_gt = false, - bool force_lt = false) -{ - uint_native b_val; - if (force_equal) { - b_val = a_val + const_a - const_b; - } else if (force_lt) { // forcing b < a - // if a_val + const_a != const_b, then we set up b_val + const_b = a_val + const_a - 1 - // elif a_val + const_a = const_b, then we set up b_val + const_b = a_val + const_a - // and we increment a by 1, leading to a_val + const_a = b_val + const_b + 1. - b_val = (a_val + const_a - const_b) ? a_val + const_a - const_b - 1 : const_a - const_b + (a_val++); - } else if (force_gt) { // forcing b > a - // set b_val + const_b = a_val + const_a + 1 unless that would wrap, in which case we instead - // set b_val + const_b = a then decrease a by 1. - b_val = (a_val + const_a - const_b) == uint_native_width ? const_a - const_b + (a_val--) - : a_val + const_a - const_b + 1; - } else { - b_val = get_random(); - } - return b_val; -} - -uint_native rotate(uint_native value, size_t rotation) -{ - return rotation ? static_cast(value >> rotation) + - static_cast(value << (uint_native_width - rotation)) - : value; -} -template class stdlib_uint : public testing::Test { - typedef typename std::conditional, - stdlib::uint>::type uint_ct; - typedef stdlib::bool_t bool_ct; - typedef stdlib::witness_t witness_ct; - typedef stdlib::byte_array byte_array_ct; - - static inline std::vector special_values{ 0U, - 1U, - 2U, - static_cast(1 << uint_native_width / 4), - static_cast(1 << uint_native_width / 2), - static_cast((1 << uint_native_width / 2) + 1), - uint_native_max }; - - static std::vector get_special_uints(Composer* ctx) - { - std::vector special_uints; - for (size_t i = 0; i != special_values.size(); ++i) { - special_uints.emplace_back(witness_ct(ctx, special_values[i])); - }; - return special_uints; - }; - - public: - static void test_weak_normalize() - { - auto run_test = [](bool constant_only, bool add_constant) { - Composer composer = Composer(); - uint_ct a; - uint_native a_val = get_random(); - uint_native const_a = get_random(); - uint_native expected; - - if (constant_only) { - a = const_a; - expected = const_a; - } else { - a = witness_ct(&composer, a_val); - expected = a_val; - if (add_constant) { - a += const_a; - expected += const_a; - } - }; - - EXPECT_EQ(expected, a.get_value()); - auto prover = composer.create_prover(); - auto verifier = composer.create_verifier(); - plonk::proof proof = prover.construct_proof(); - bool verified = verifier.verify_proof(proof); - EXPECT_EQ(verified, true); - }; - - run_test(true, false); - run_test(false, false); - run_test(false, true); - } - - static void test_byte_array_conversion() - { - Composer composer = Composer(); - uint_ct a = witness_ct(&composer, 0x7f6f5f4f10111213); - std::string longest_expected = { 0x7f, 0x6f, 0x5f, 0x4f, 0x10, 0x11, 0x12, 0x13 }; - // truncate, so we are running different tests for different choices of uint_native - std::string expected = longest_expected.substr(longest_expected.length() - sizeof(uint_native)); - byte_array_ct arr(&composer); - arr.write(static_cast(a)); - - EXPECT_EQ(arr.size(), sizeof(uint_native)); - EXPECT_EQ(arr.get_string(), expected); - } - - static void test_input_output_consistency() - { - Composer composer = Composer(); - - for (size_t i = 1; i < 1024; i *= 2) { - uint_native a_expected = (uint_native)i; - uint_native b_expected = (uint_native)i; - - uint_ct a = witness_ct(&composer, a_expected); - uint_ct b = witness_ct(&composer, b_expected); - - byte_array_ct arr(&composer); - - arr.write(static_cast(a)); - arr.write(static_cast(b)); - - EXPECT_EQ(arr.size(), 2 * sizeof(uint_native)); - - uint_ct a_result(arr.slice(0, sizeof(uint_native))); - uint_ct b_result(arr.slice(sizeof(uint_native))); - - EXPECT_EQ(a_result.get_value(), a_expected); - EXPECT_EQ(b_result.get_value(), b_expected); - } - } - - static void test_create_from_wires() - { - Composer composer = Composer(); - - uint_ct a = uint_ct(&composer, - std::vector{ - bool_ct(false), - bool_ct(false), - bool_ct(false), - bool_ct(false), - bool_ct(false), - bool_ct(false), - bool_ct(false), - witness_ct(&composer, true), - }); - - EXPECT_EQ(a.at(0).get_value(), false); - EXPECT_EQ(a.at(7).get_value(), true); - EXPECT_EQ(static_cast(a.get_value()), 128U); - } - - /** - * @brief Test addition of special values. - * */ - static void test_add_special() - { - Composer composer = Composer(); - - witness_ct first_input(&composer, 1U); - witness_ct second_input(&composer, 0U); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a + b; - /** - * Fibbonacci sequence a(0) = 0, a(1), ..., a(2 + 32) = 5702887 - * a | 1 | 1 | 2 | 3 | 5 | ... - * b | 0 | 1 | 1 | 2 | 3 | ... - * c | 1 | 2 | 3 | 5 | 8 | ... - */ - for (size_t i = 0; i < uint_native_width; ++i) { - b = a; - a = c; - c = a + b; - } - - auto special_uints = get_special_uints(&composer); - for (size_t i = 0; i != special_values.size(); ++i) { - uint_native x = special_values[i]; - uint_ct x_ct = special_uints[i]; - - for (size_t j = i; j != special_values.size(); ++j) { - uint_native y = special_values[j]; - uint_ct y_ct = special_uints[j]; - - uint_native expected_value = x + y; - uint_ct z_ct = x_ct + y_ct; - uint_native value = static_cast(z_ct.get_value()); - - EXPECT_EQ(value, expected_value); - } - }; - - auto prover = composer.create_prover(); - auto verifier = composer.create_verifier(); - plonk::proof proof = prover.construct_proof(); - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - static void test_sub_special() - { - Composer composer = Composer(); - - witness_ct a_val(&composer, static_cast(4)); - // witness_ct b_val(&composer, static_cast(5)); - uint_native const_a = 1; - uint_native const_b = 2; - uint_ct a = uint_ct(a_val) + const_a; - // uint_ct b = uint_ct(b_val) + const_b; - uint_ct b = const_b; - uint_ct diff = a - b; - - auto special_uints = get_special_uints(&composer); - for (size_t i = 0; i != special_values.size(); ++i) { - uint_native x = special_values[i]; - uint_ct x_ct = special_uints[i]; - - for (size_t j = i; j != special_values.size(); ++j) { - uint_native y = special_values[j]; - uint_ct y_ct = special_uints[j]; - - uint_native expected_value = x - y; - uint_ct z_ct = x_ct - y_ct; - uint_native value = static_cast(z_ct.get_value()); - - EXPECT_EQ(value, expected_value); - } - }; - - auto prover = composer.create_prover(); - auto verifier = composer.create_verifier(); - plonk::proof proof = prover.construct_proof(); - bool verified = verifier.verify_proof(proof); - - EXPECT_EQ(verified, true); - } - - static void test_add_with_constants() - { - size_t n = 8; - std::vector witnesses = get_several_random(3 * n); - uint_native expected[8]; - for (size_t i = 2; i < n; ++i) { - expected[0] = witnesses[3 * i]; - expected[1] = witnesses[3 * i + 1]; - expected[2] = witnesses[3 * i + 2]; - expected[3] = expected[0] + expected[1]; - expected[4] = expected[1] + expected[0]; - expected[5] = expected[1] + expected[2]; - expected[6] = expected[3] + expected[4]; - expected[7] = expected[4] + expected[5]; - } - Composer composer = Composer(); - uint_ct result[8]; - for (size_t i = 2; i < n; ++i) { - result[0] = uint_ct(&composer, witnesses[3 * i]); - result[1] = (witness_ct(&composer, witnesses[3 * i + 1])); - result[2] = (witness_ct(&composer, witnesses[3 * i + 2])); - result[3] = result[0] + result[1]; - result[4] = result[1] + result[0]; - result[5] = result[1] + result[2]; - result[6] = result[3] + result[4]; - result[7] = result[4] + result[5]; - } - - for (size_t i = 0; i < n; ++i) { - EXPECT_EQ(result[i].get_value(), expected[i]); - } - - auto prover = composer.create_prover(); - auto verifier = composer.create_verifier(); - plonk::proof proof = prover.construct_proof(); - bool proof_valid = verifier.verify_proof(proof); - EXPECT_EQ(proof_valid, true); - } - - static void test_mul_special() - { - uint_native a_expected = 1U; - uint_native b_expected = 2U; - uint_native c_expected = a_expected + b_expected; - for (size_t i = 0; i < 100; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = a_expected * b_expected; - } - - Composer composer = Composer(); - - witness_ct first_input(&composer, 1U); - witness_ct second_input(&composer, 2U); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a + b; - for (size_t i = 0; i < 100; ++i) { - b = a; - a = c; - c = a * b; - } - uint_native c_result = - static_cast(composer.get_variable(c.get_witness_index()).from_montgomery_form().data[0]); - EXPECT_EQ(c_result, c_expected); - - auto special_uints = get_special_uints(&composer); - for (size_t i = 0; i != special_values.size(); ++i) { - uint_native x = special_values[i]; - uint_ct x_ct = special_uints[i]; - - for (size_t j = i; j != special_values.size(); ++j) { - uint_native y = special_values[j]; - uint_ct y_ct = special_uints[j]; - - uint_native expected_value = x * y; - uint_ct z_ct = x_ct * y_ct; - uint_native value = static_cast(z_ct.get_value()); - - EXPECT_EQ(value, expected_value); - } - }; - - auto prover = composer.create_prover(); - auto verifier = composer.create_verifier(); - plonk::proof proof = prover.construct_proof(); - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - static void test_mul_big() - { - uint_native max = uint_native_max; - - Composer composer = Composer(); - uint_ct a = witness_ct(&composer, max); - a = a + max; - uint_ct b = a; - uint_ct c = a * b; - - auto prover = composer.create_prover(); - auto verifier = composer.create_verifier(); - plonk::proof proof = prover.construct_proof(); - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - static void test_xor_special() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - for (size_t i = 0; i < uint_native_width; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = a_expected + b_expected; - a_expected = c_expected ^ a_expected; - } - - Composer composer = Composer(); - - witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); - witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a ^ b; - for (size_t i = 0; i < uint_native_width; ++i) { - b = a; - a = c; - c = a + b; - a = c ^ a; - } - uint_native a_result = - static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); - - EXPECT_EQ(a_result, a_expected); - - auto prover = composer.create_prover(); - - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - static void test_xor_constants() - { - Composer composer = Composer(); - - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - - uint_ct const_a(&composer, static_cast(0x10000000a3b10422)); - uint_ct const_b(&composer, static_cast(0xfafab007eac21343)); - uint_ct c = const_a ^ const_b; - c.get_witness_index(); - - EXPECT_EQ(c.get_additive_constant(), uint256_t(c_expected)); - } - - static void test_xor_more_constants() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - for (size_t i = 0; i < 1; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = (a_expected + b_expected) ^ - (static_cast(0x10000000a3b10422) ^ static_cast(0xfafab007eac21343)); - } - - Composer composer = Composer(); - - witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); - witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a ^ b; - for (size_t i = 0; i < 1; ++i) { - uint_ct const_a = static_cast(0x10000000a3b10422); - uint_ct const_b = static_cast(0xfafab007eac21343); - b = a; - a = c; - c = (a + b) ^ (const_a ^ const_b); - } - uint32_t c_witness_index = c.get_witness_index(); - uint_native c_result = - static_cast(composer.get_variable(c_witness_index).from_montgomery_form().data[0]); - EXPECT_EQ(c_result, c_expected); - auto prover = composer.create_prover(); - - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - static void test_and_constants() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected & b_expected; - for (size_t i = 0; i < 1; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = (~a_expected & static_cast(0x10000000a3b10422)) + - (b_expected & static_cast(0xfafab007eac21343)); - // c_expected = (a_expected + b_expected) & (static_cast(0x10000000a3b10422) & - // static_cast(0xfafab007eac21343)); - } - - Composer composer = Composer(); - - witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); - witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a & b; - for (size_t i = 0; i < 1; ++i) { - uint_ct const_a = static_cast(0x10000000a3b10422); - uint_ct const_b = static_cast(0xfafab007eac21343); - b = a; - a = c; - c = (~a & const_a) + (b & const_b); - } - uint32_t c_witness_index = c.get_witness_index(); - uint_native c_result = - static_cast(composer.get_variable(c_witness_index).from_montgomery_form().data[0]); - EXPECT_EQ(c_result, c_expected); - auto prover = composer.create_prover(); - - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - static void test_and_special() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected + b_expected; - for (size_t i = 0; i < uint_native_width; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = a_expected + b_expected; - a_expected = c_expected & a_expected; - } - - Composer composer = Composer(); - - witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); - witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a + b; - for (size_t i = 0; i < uint_native_width; ++i) { - b = a; - a = c; - c = a + b; - a = c & a; - } - uint_native a_result = - static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); - EXPECT_EQ(a_result, a_expected); - - auto prover = composer.create_prover(); - - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - static void test_or_special() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - for (size_t i = 0; i < uint_native_width; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = a_expected + b_expected; - a_expected = c_expected | a_expected; - } - - Composer composer = Composer(); - - witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); - witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a ^ b; - for (size_t i = 0; i < uint_native_width; ++i) { - b = a; - a = c; - c = a + b; - a = c | a; - } - uint_native a_result = - static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); - EXPECT_EQ(a_result, a_expected); - - auto prover = composer.create_prover(); - - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - static void test_gt_special() - { - const auto run_test = [](bool lhs_constant, bool rhs_constant, int type = 0) { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected; - switch (type) { - case 0: { - b_expected = static_cast(0x20000000bac21343); // a < b - break; - } - case 1: { - b_expected = static_cast(0x0000000000002f12); // a > b - break; - } - case 2: { - b_expected = static_cast(0x10000000a3b10422); // a = b - break; - } - default: { - b_expected = static_cast(0x20000000bac21343); // a < b - } - } - bool c_expected = a_expected > b_expected; - - Composer composer = Composer(); - - uint_ct a; - uint_ct b; - if (lhs_constant) { - a = uint_ct(nullptr, a_expected); - } else { - a = witness_ct(&composer, a_expected); - } - if (rhs_constant) { - b = uint_ct(nullptr, b_expected); - } else { - b = witness_ct(&composer, b_expected); - } - // mix in some constant terms for good measure - a *= uint_ct(&composer, 2); - a += uint_ct(&composer, 1); - b *= uint_ct(&composer, 2); - b += uint_ct(&composer, 1); - - bool_ct c = a > b; - - bool c_result = static_cast(c.get_value()); - EXPECT_EQ(c_result, c_expected); - - auto prover = composer.create_prover(); - - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - }; - - run_test(false, false, 0); - run_test(false, true, 0); - run_test(true, false, 0); - run_test(true, true, 0); - run_test(false, false, 1); - run_test(false, true, 1); - run_test(true, false, 1); - run_test(true, true, 1); - run_test(false, false, 2); - run_test(false, true, 2); - run_test(true, false, 2); - run_test(true, true, 2); - } - - static uint_native rotate(uint_native value, size_t rotation) - { - return rotation ? static_cast(value >> rotation) + - static_cast(value << (uint_native_width - rotation)) - : value; - } - - static void test_ror_special() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - for (size_t i = 0; i < uint_native_width; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = a_expected + b_expected; - a_expected = rotate(c_expected, i % 31) + rotate(a_expected, (i + 1) % 31); - } - - Composer composer = Composer(); - - witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); - witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a ^ b; - for (size_t i = 0; i < uint_native_width; ++i) { - b = a; - a = c; - c = a + b; - a = c.ror(static_cast(i % 31)) + a.ror(static_cast((i + 1) % 31)); - } - uint_native a_result = - static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); - EXPECT_EQ(a_result, a_expected); - - auto prover = composer.create_prover(); - - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - /** - * @brief If uint_native_width == 32, test part of SHA256. Otherwise, do something similar. - * - * @details Notes that the static casts have to be there becuase of -Wc++11-narrowing flag. - * - * TurboPLONK: 19896 gates - * StandardPLONK: 210363 gates - */ - static void test_hash_rounds() - { - std::vector k_constants(64); - std::vector round_values(8); - if (uint_native_width == 32) { - k_constants = { static_cast(0x428a2f98), static_cast(0x71374491), - static_cast(0xb5c0fbcf), static_cast(0xe9b5dba5), - static_cast(0x3956c25b), static_cast(0x59f111f1), - static_cast(0x923f82a4), static_cast(0xab1c5ed5), - static_cast(0xd807aa98), static_cast(0x12835b01), - static_cast(0x243185be), static_cast(0x550c7dc3), - static_cast(0x72be5d74), static_cast(0x80deb1fe), - static_cast(0x9bdc06a7), static_cast(0xc19bf174), - static_cast(0xe49b69c1), static_cast(0xefbe4786), - static_cast(0x0fc19dc6), static_cast(0x240ca1cc), - static_cast(0x2de92c6f), static_cast(0x4a7484aa), - static_cast(0x5cb0a9dc), static_cast(0x76f988da), - static_cast(0x983e5152), static_cast(0xa831c66d), - static_cast(0xb00327c8), static_cast(0xbf597fc7), - static_cast(0xc6e00bf3), static_cast(0xd5a79147), - static_cast(0x06ca6351), static_cast(0x14292967), - static_cast(0x27b70a85), static_cast(0x2e1b2138), - static_cast(0x4d2c6dfc), static_cast(0x53380d13), - static_cast(0x650a7354), static_cast(0x766a0abb), - static_cast(0x81c2c92e), static_cast(0x92722c85), - static_cast(0xa2bfe8a1), static_cast(0xa81a664b), - static_cast(0xc24b8b70), static_cast(0xc76c51a3), - static_cast(0xd192e819), static_cast(0xd6990624), - static_cast(0xf40e3585), static_cast(0x106aa070), - static_cast(0x19a4c116), static_cast(0x1e376c08), - static_cast(0x2748774c), static_cast(0x34b0bcb5), - static_cast(0x391c0cb3), static_cast(0x4ed8aa4a), - static_cast(0x5b9cca4f), static_cast(0x682e6ff3), - static_cast(0x748f82ee), static_cast(0x78a5636f), - static_cast(0x84c87814), static_cast(0x8cc70208), - static_cast(0x90befffa), static_cast(0xa4506ceb), - static_cast(0xbef9a3f7), static_cast(0xc67178f2) }; - - round_values = { static_cast(0x01020304), static_cast(0x0a0b0c0d), - static_cast(0x1a2b3e4d), static_cast(0x03951bd3), - static_cast(0x0e0fa3fe), static_cast(0x01000000), - static_cast(0x0f0eeea1), static_cast(0x12345678) }; - } else { - k_constants = get_several_random(64); - round_values = get_several_random(8); - }; - - std::vector w_alt = get_several_random(64); - - uint_native a_alt = round_values[0]; - uint_native b_alt = round_values[1]; - uint_native c_alt = round_values[2]; - uint_native d_alt = round_values[3]; - uint_native e_alt = round_values[4]; - uint_native f_alt = round_values[5]; - uint_native g_alt = round_values[6]; - uint_native h_alt = round_values[7]; - for (size_t i = 0; i < 64; ++i) { - uint_native S1_alt = rotate(e_alt, 7 % uint_native_width) ^ rotate(e_alt, 11 % uint_native_width) ^ - rotate(e_alt, 25 % uint_native_width); - uint_native ch_alt = (e_alt & f_alt) ^ ((~e_alt) & g_alt); - uint_native temp1_alt = h_alt + S1_alt + ch_alt + k_constants[i % 64] + w_alt[i]; - - uint_native S0_alt = rotate(a_alt, 2 % uint_native_width) ^ rotate(a_alt, 13 % uint_native_width) ^ - rotate(a_alt, 22 % uint_native_width); - uint_native maj_alt = (a_alt & b_alt) ^ (a_alt & c_alt) ^ (b_alt & c_alt); - uint_native temp2_alt = S0_alt + maj_alt; - - h_alt = g_alt; - g_alt = f_alt; - f_alt = e_alt; - e_alt = d_alt + temp1_alt; - d_alt = c_alt; - c_alt = b_alt; - b_alt = a_alt; - a_alt = temp1_alt + temp2_alt; - } - Composer composer = Composer(); - - std::vector w; - std::vector k; - for (size_t i = 0; i < 64; ++i) { - w.emplace_back(uint_ct(witness_ct(&composer, w_alt[i]))); - k.emplace_back(uint_ct(&composer, k_constants[i % 64])); - } - uint_ct a = witness_ct(&composer, round_values[0]); - uint_ct b = witness_ct(&composer, round_values[1]); - uint_ct c = witness_ct(&composer, round_values[2]); - uint_ct d = witness_ct(&composer, round_values[3]); - uint_ct e = witness_ct(&composer, round_values[4]); - uint_ct f = witness_ct(&composer, round_values[5]); - uint_ct g = witness_ct(&composer, round_values[6]); - uint_ct h = witness_ct(&composer, round_values[7]); - for (size_t i = 0; i < 64; ++i) { - uint_ct S1 = - e.ror(7U % uint_native_width) ^ e.ror(11U % uint_native_width) ^ e.ror(25U % uint_native_width); - uint_ct ch = (e & f) + ((~e) & g); - uint_ct temp1 = h + S1 + ch + k[i] + w[i]; - - uint_ct S0 = - a.ror(2U % uint_native_width) ^ a.ror(13U % uint_native_width) ^ a.ror(22U % uint_native_width); - uint_ct T0 = (b & c); - uint_ct T1 = (b - T0) + (c - T0); - uint_ct T2 = a & T1; - uint_ct maj = T2 + T0; - uint_ct temp2 = S0 + maj; - - h = g; - g = f; - f = e; - e = d + temp1; - d = c; - c = b; - b = a; - a = temp1 + temp2; - } - - uint_native a_result = - static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); - uint_native b_result = - static_cast(composer.get_variable(b.get_witness_index()).from_montgomery_form().data[0]); - uint_native c_result = - static_cast(composer.get_variable(c.get_witness_index()).from_montgomery_form().data[0]); - uint_native d_result = - static_cast(composer.get_variable(d.get_witness_index()).from_montgomery_form().data[0]); - uint_native e_result = - static_cast(composer.get_variable(e.get_witness_index()).from_montgomery_form().data[0]); - uint_native f_result = - static_cast(composer.get_variable(f.get_witness_index()).from_montgomery_form().data[0]); - uint_native g_result = - static_cast(composer.get_variable(g.get_witness_index()).from_montgomery_form().data[0]); - uint_native h_result = - static_cast(composer.get_variable(h.get_witness_index()).from_montgomery_form().data[0]); - - EXPECT_EQ(a_result, a_alt); - EXPECT_EQ(b_result, b_alt); - EXPECT_EQ(c_result, c_alt); - EXPECT_EQ(d_result, d_alt); - EXPECT_EQ(e_result, e_alt); - EXPECT_EQ(f_result, f_alt); - EXPECT_EQ(g_result, g_alt); - EXPECT_EQ(h_result, h_alt); - - auto prover = composer.create_prover(); - - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - // BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO - - /** - * @brief Test addition of random uint's, trying all combinations of (constant, witness). - */ - static void test_add() - { - Composer composer = Composer(); - - const auto add_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { - uint_native a_val = get_random(); - uint_native b_val = get_random(); - uint_native expected = a_val + b_val; - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); - uint_ct c = a + b; - c = c.normalize(); - - uint_native result = uint_native(c.get_value()); - - EXPECT_EQ(result, expected); - }; - - add_integers(false, false); - add_integers(false, true); - add_integers(true, false); - add_integers(true, true); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_sub() - { - Composer composer = Composer(); - - const auto sub_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { - uint_native a_val = get_random(); - uint_native b_val = get_random(); - uint_native const_shift_val = get_random(); - uint_native expected = a_val - (b_val + const_shift_val); - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); - uint_ct b_shift = uint_ct(&composer, const_shift_val); - uint_ct c = b + b_shift; - uint_ct d = a - c; - d = d.normalize(); - - uint_native result = uint_native(d.get_value()); - - EXPECT_EQ(result, expected); - }; - - sub_integers(false, false); - sub_integers(false, true); - sub_integers(true, false); - sub_integers(true, true); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_mul() - { - Composer composer = Composer(); - - const auto mul_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { - uint_native a_val = get_random(); - uint_native b_val = get_random(); - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native expected = - static_cast(a_val + const_a) * static_cast(b_val + const_b); - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c * d; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - mul_integers(false, false); - mul_integers(false, true); - mul_integers(true, false); - mul_integers(true, true); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_divide() - { - Composer composer = Composer(); - - const auto divide_integers = [&composer](bool lhs_constant = false, - bool rhs_constant = false, - bool dividend_is_divisor = false, - bool dividend_zero = false, - bool divisor_zero = false) { - uint_native a_val = get_random(); - uint_native b_val = dividend_is_divisor ? a_val : get_random(); - uint_native const_a = dividend_zero ? 0 - a_val : get_random(); - uint_native const_b = - divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); - uint_native expected = - static_cast(a_val + const_a) / static_cast(b_val + const_b); - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c / d; - e = e.normalize(); - - uint_native result = static_cast(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - divide_integers(false, false, false, false, false); - divide_integers(false, false, false, false, false); - divide_integers(false, false, false, false, false); - divide_integers(false, false, false, false, false); - divide_integers(false, false, false, false, false); - - divide_integers(false, true, false, false, false); - divide_integers(true, false, false, false, false); - divide_integers(true, true, false, false, false); // fails; 0 != 1 - - divide_integers(false, false, true, false, false); - divide_integers(false, true, true, false, false); - divide_integers(true, false, true, false, false); - divide_integers(true, true, true, false, false); - - divide_integers(false, false, false, true, false); - divide_integers(false, true, false, true, false); // fails; 0 != 1 - divide_integers(true, false, false, true, false); - divide_integers(true, true, false, true, false); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_modulo() - { - Composer composer = Composer(); - - const auto mod_integers = [&composer](bool lhs_constant = false, - bool rhs_constant = false, - bool dividend_is_divisor = false, - bool dividend_zero = false, - bool divisor_zero = false) { - uint_native a_val = get_random(); - uint_native b_val = dividend_is_divisor ? a_val : get_random(); - uint_native const_a = dividend_zero ? 0 - a_val : get_random(); - uint_native const_b = - divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); - uint_native expected = - static_cast(a_val + const_a) % static_cast(b_val + const_b); - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c % d; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - mod_integers(false, false, false, false, false); - mod_integers(false, true, false, false, false); - mod_integers(true, false, false, false, false); - mod_integers(true, true, false, false, false); - - mod_integers(false, false, true, false, false); - mod_integers(false, true, true, false, false); - mod_integers(true, false, true, false, false); - mod_integers(true, true, true, false, false); - - mod_integers(false, false, false, true, false); - mod_integers(false, true, false, true, false); - mod_integers(true, false, false, true, false); - mod_integers(true, true, false, true, false); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_divide_by_zero_fails() - { - - const auto divide_integers = [](bool lhs_constant = false, - bool rhs_constant = false, - bool dividend_is_divisor = false, - bool dividend_zero = false, - bool divisor_zero = false) { - Composer composer = Composer(); - - uint_native a_val = get_random(); - uint_native b_val = dividend_is_divisor ? a_val : get_random(); - uint_native const_a = dividend_zero ? 0 - a_val : get_random(); - uint_native const_b = - divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c / d; - e = e.normalize(); - - auto prover = composer.create_prover(); - - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, false); - }; - - divide_integers(false, false, false, false, true); - divide_integers(false, false, false, true, true); - divide_integers(true, true, false, false, true); - divide_integers(true, true, false, true, true); - } - - static void test_divide_special() - { - Composer composer = Composer(); - - auto special_uints = get_special_uints(&composer); - - for (size_t i = 0; i != special_values.size(); ++i) { - uint_native x = special_values[i]; - uint_ct x_ct = special_uints[i]; - - for (size_t j = i; j != special_values.size(); ++j) { - uint_native y = special_values[j]; - uint_ct y_ct = special_uints[j]; - - // uint_native hits this error when trying to divide by zero: - // Stop reason: signal SIGFPE: integer divide by zero - uint_native expected_value; - uint_ct z_ct; - uint_native value; - if (y != 0) { - expected_value = x / y; - z_ct = x_ct / y_ct; - value = static_cast(z_ct.get_value()); - EXPECT_EQ(value, expected_value); - } - } - }; - - auto prover = composer.create_prover(); - auto verifier = composer.create_verifier(); - plonk::proof proof = prover.construct_proof(); - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, true); - } - - /** - * @brief Make sure we prevent proving v / v = 0 by setting the divison remainder to be v. - * TODO: This is lifted from the implementation. Should rewrite this test after introducing framework that separates - * circuit construction from witness generation. - - */ - static void div_remainder_constraint() - { - Composer composer = Composer(); - - uint_native val = get_random(); - - uint_ct a = witness_ct(&composer, val); - uint_ct b = witness_ct(&composer, val); - - const uint32_t dividend_idx = a.get_witness_index(); - const uint32_t divisor_idx = b.get_witness_index(); - - const uint256_t divisor = b.get_value(); - - const uint256_t q = 0; - const uint256_t r = val; - - const uint32_t quotient_idx = composer.add_variable(q); - const uint32_t remainder_idx = composer.add_variable(r); - - // In this example there are no additive constaints, so we just replace them by zero below. - - // constraint: qb + const_b q + 0 b - a + r - const_a == 0 - // i.e., a + const_a = q(b + const_b) + r - const mul_quad division_gate{ .a = quotient_idx, // q - .b = divisor_idx, // b - .c = dividend_idx, // a - .d = remainder_idx, // r - .mul_scaling = fr::one(), - .a_scaling = b.get_additive_constant(), - .b_scaling = fr::zero(), - .c_scaling = fr::neg_one(), - .d_scaling = fr::one(), - .const_scaling = -a.get_additive_constant() }; - composer.create_big_mul_gate(division_gate); - - // set delta = (b + const_b - r) - - // constraint: b - r - delta + const_b == 0 - const uint256_t delta = divisor - r - 1; - const uint32_t delta_idx = composer.add_variable(delta); - - const add_triple delta_gate{ - .a = divisor_idx, // b - .b = remainder_idx, // r - .c = delta_idx, // d - .a_scaling = fr::one(), - .b_scaling = fr::neg_one(), - .c_scaling = fr::neg_one(), - .const_scaling = b.get_additive_constant(), - }; - - composer.create_add_gate(delta_gate); - - // validate delta is in the correct range - stdlib::field_t::from_witness_index(&composer, delta_idx) - .create_range_constraint(uint_native_width, - "delta range constraint fails in div_remainder_constraint test"); - - // normalize witness quotient and remainder - // minimal bit range for quotient: from 0 (in case a = b-1) to width (when b = 1). - uint_ct quotient(&composer); - composer.create_range_constraint( - quotient_idx, uint_native_width, "quotient range constraint fails in div_remainder_constraint test"); - - // constrain remainder to lie in [0, 2^width-1] - uint_ct remainder(&composer); - composer.create_range_constraint( - remainder_idx, uint_native_width, "remainder range constraint fails in div_remainder_constraint test"); - - auto prover = composer.create_prover(); - auto verifier = composer.create_verifier(); - plonk::proof proof = prover.construct_proof(); - bool result = verifier.verify_proof(proof); - EXPECT_EQ(result, false); - } - - static void test_and() - { - Composer composer = Composer(); - - const auto and_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { - uint_native a_val = get_random(); - uint_native b_val = get_random(); - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native expected = (a_val + const_a) & (b_val + const_b); - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c & d; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - and_integers(false, false); - and_integers(false, true); - and_integers(true, false); - and_integers(true, true); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_xor() - { - Composer composer = Composer(); - - const auto xor_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { - uint_native a_val = get_random(); - uint_native b_val = get_random(); - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native expected = (a_val + const_a) ^ (b_val + const_b); - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c ^ d; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - xor_integers(false, false); - xor_integers(false, true); - xor_integers(true, false); - xor_integers(true, true); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_or() - { - Composer composer = Composer(); - - const auto or_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { - uint_native a_val = get_random(); - uint_native b_val = get_random(); - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native expected = (a_val + const_a) | (b_val + const_b); - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c | d; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - or_integers(false, false); - or_integers(false, false); - or_integers(false, false); - or_integers(false, false); - or_integers(false, false); - or_integers(false, true); - or_integers(true, false); - or_integers(true, true); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_not() - { - Composer composer = Composer(); - - const auto not_integers = [&composer](bool lhs_constant = false, bool = false) { - uint_native a_val = get_random(); - uint_native const_a = get_random(); - uint_native expected = ~(a_val + const_a); - uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct c = a + a_shift; - uint_ct e = ~c; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - not_integers(false, false); - not_integers(false, true); - not_integers(true, false); - not_integers(true, true); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_gt() - { - Composer composer = Composer(); - const auto compare_integers = - [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native a_val = get_random(); - uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - - bool expected = static_cast(b_val + const_b) > static_cast(a_val + const_a); - uint_ct a = witness_ct(&composer, a_val); - uint_ct b = witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - bool_ct e = d > c; - bool result = bool(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - compare_integers(false, false, false); // both are random - compare_integers(false, false, false); // '' - compare_integers(false, false, false); // '' - compare_integers(false, false, false); // '' - compare_integers(false, false, true); // b < a - compare_integers(false, true, false); // b > a - compare_integers(true, false, false); // b = a - compare_integers(false, true, false); // b > a - compare_integers(true, false, false); // b = a - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_lt() - { - Composer composer = Composer(); - - const auto compare_integers = - [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native a_val = get_random(); - uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - - bool expected = static_cast(b_val + const_b) < static_cast(a_val + const_a); - uint_ct a = witness_ct(&composer, a_val); - uint_ct b = witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - bool_ct e = d < c; - bool result = bool(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_gte() - { - Composer composer = Composer(); - - const auto compare_integers = - [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native a_val = get_random(); - uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - - bool expected = static_cast(b_val + const_b) >= static_cast(a_val + const_a); - uint_ct a = witness_ct(&composer, a_val); - uint_ct b = witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - bool_ct e = d >= c; - bool result = bool(e.get_value()); - EXPECT_EQ(result, expected); - }; - - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_lte() - { - Composer composer = Composer(); - - const auto compare_integers = - [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native a_val = get_random(); - uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - - bool expected = static_cast(b_val + const_b) <= static_cast(a_val + const_a); - uint_ct a = witness_ct(&composer, a_val); - uint_ct b = witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - bool_ct e = d <= c; - bool result = bool(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_equality_operator() - { - Composer composer = Composer(); - - const auto compare_integers = - [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native a_val = get_random(); - uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - - bool expected = static_cast(b_val + const_b) == static_cast(a_val + const_a); - uint_ct a = witness_ct(&composer, a_val); - uint_ct b = witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - bool_ct e = d == c; - bool result = bool(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_not_equality_operator() - { - Composer composer = Composer(); - - const auto compare_integers = - [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native a_val = get_random(); - uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - - bool expected = static_cast(b_val + const_b) != static_cast(a_val + const_a); - uint_ct a = witness_ct(&composer, a_val); - uint_ct b = witness_ct(&composer, b_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct b_shift = uint_ct(&composer, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - bool_ct e = d != c; - bool result = bool(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - compare_integers(false, false, true); - compare_integers(false, true, false); - compare_integers(true, false, false); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_logical_not() - { - Composer composer = Composer(); - - const auto not_integer = [&composer](bool force_zero) { - uint_native const_a = get_random(); - uint_native a_val = force_zero ? 0 - const_a : get_random(); - bool expected = !static_cast(const_a + a_val); - uint_ct a = witness_ct(&composer, a_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct c = a + a_shift; - bool_ct e = !c; - bool result = bool(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - not_integer(true); - not_integer(true); - not_integer(false); - not_integer(false); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_right_shift() - { - Composer composer = Composer(); - - const auto shift_integer = [&composer](const bool is_constant, const uint_native shift) { - uint_native const_a = get_random(); - uint_native a_val = get_random(); - uint_native expected = static_cast(a_val + const_a) >> shift; - uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct c = a + a_shift; - uint_ct d = c >> shift; - uint_native result = uint_native(d.get_value()); - - EXPECT_EQ(result, expected); - }; - - for (uint_native i = 0; i < uint_native_width; ++i) { - shift_integer(false, i); - shift_integer(true, i); - } - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_left_shift() - { - Composer composer = Composer(); - - const auto shift_integer = [&composer](const bool is_constant, const uint_native shift) { - uint_native const_a = get_random(); - uint_native a_val = get_random(); - uint_native expected = static_cast((a_val + const_a) << shift); - uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct c = a + a_shift; - uint_ct d = c << shift; - uint_native result = uint_native(d.get_value()); - - EXPECT_EQ(result, expected); - }; - - for (uint_native i = 0; i < uint_native_width; ++i) { - shift_integer(true, i); - shift_integer(false, i); - } - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_ror() - { - Composer composer = Composer(); - - const auto ror_integer = [&composer](const bool is_constant, const uint_native rotation) { - const auto ror = [](const uint_native in, const uint_native rval) { - return rval ? (in >> rval) | (in << (uint_native_width - rval)) : in; - }; - - uint_native const_a = get_random(); - uint_native a_val = get_random(); - uint_native expected = static_cast(ror(static_cast(const_a + a_val), rotation)); - uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct c = a + a_shift; - uint_ct d = c.ror(rotation); - uint_native result = uint_native(d.get_value()); - - EXPECT_EQ(result, expected); - }; - - for (uint_native i = 0; i < uint_native_width; ++i) { - ror_integer(true, i); - ror_integer(false, i); - } - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - static void test_rol() - { - Composer composer = Composer(); - - const auto rol_integer = [&composer](const bool is_constant, const uint_native rotation) { - const auto rol = [](const uint_native in, const uint_native rval) { - return rval ? (in << rval) | (in >> (uint_native_width - rval)) : in; - }; - - uint_native const_a = get_random(); - uint_native a_val = get_random(); - uint_native expected = static_cast(rol(static_cast(const_a + a_val), rotation)); - uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct c = a + a_shift; - uint_ct d = c.rol(rotation); - uint_native result = uint_native(d.get_value()); - - EXPECT_EQ(result, expected); - }; - - for (uint_native i = 0; i < uint_native_width; ++i) { - rol_integer(true, i); - rol_integer(false, i); - } - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } - - /** - * @brief Test the the function uint_ct::at used to extract bits. - */ - static void test_at() - { - Composer composer = Composer(); - - const auto bit_test = [&composer](const bool is_constant) { - // construct a sum of uint_ct's, where at least one is a constant, - // and validate its correctness bitwise - uint_native const_a = get_random(); - uint_native a_val = get_random(); - uint_native c_val = const_a + a_val; - uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); - uint_ct a_shift = uint_ct(&composer, const_a); - uint_ct c = a + a_shift; - for (size_t i = 0; i < uint_native_width; ++i) { - bool_ct result = c.at(i); - bool expected = (((c_val >> i) & 1UL) == 1UL) ? true : false; - EXPECT_EQ(result.get_value(), expected); - EXPECT_EQ(result.get_context(), c.get_context()); - } - }; - - bit_test(false); - bit_test(true); - - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); - } -}; - -typedef testing::Types - ComposerTypes; - -TYPED_TEST_SUITE(stdlib_uint, ComposerTypes); - -TYPED_TEST(stdlib_uint, test_weak_normalize) -{ - TestFixture::test_weak_normalize(); -} -TYPED_TEST(stdlib_uint, test_byte_array_conversion) -{ - TestFixture::test_byte_array_conversion(); -} -TYPED_TEST(stdlib_uint, test_input_output_consistency) -{ - TestFixture::test_input_output_consistency(); -} -TYPED_TEST(stdlib_uint, test_create_from_wires) -{ - TestFixture::test_create_from_wires(); -} -TYPED_TEST(stdlib_uint, test_add_special) -{ - TestFixture::test_add_special(); -} -TYPED_TEST(stdlib_uint, test_sub_special) -{ - TestFixture::test_sub_special(); -} -TYPED_TEST(stdlib_uint, test_add_with_constants) -{ - TestFixture::test_add_with_constants(); -} -TYPED_TEST(stdlib_uint, test_mul_special) -{ - TestFixture::test_mul_special(); -} -TYPED_TEST(stdlib_uint, test_mul_big) -{ - TestFixture::test_mul_big(); -} -TYPED_TEST(stdlib_uint, test_xor_special) -{ - TestFixture::test_xor_special(); -} -TYPED_TEST(stdlib_uint, test_xor_constants) -{ - TestFixture::test_xor_constants(); -} -TYPED_TEST(stdlib_uint, test_xor_more_constants) -{ - TestFixture::test_xor_more_constants(); -} -TYPED_TEST(stdlib_uint, test_and_constants) -{ - TestFixture::test_and_constants(); -} -TYPED_TEST(stdlib_uint, test_and_special) -{ - TestFixture::test_and_special(); -} -TYPED_TEST(stdlib_uint, test_or_special) -{ - TestFixture::test_or_special(); -} -TYPED_TEST(stdlib_uint, test_gt_special) -{ - TestFixture::test_gt_special(); -} -TYPED_TEST(stdlib_uint, test_ror_special) -{ - TestFixture::test_ror_special(); -} -TYPED_TEST(stdlib_uint, test_hash_rounds) -{ - TestFixture::test_hash_rounds(); -} -// BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO -TYPED_TEST(stdlib_uint, test_add) -{ - TestFixture::test_add(); -} -TYPED_TEST(stdlib_uint, test_sub) -{ - TestFixture::test_sub(); -} -TYPED_TEST(stdlib_uint, test_mul) -{ - TestFixture::test_mul(); -} -TYPED_TEST(stdlib_uint, test_divide) -{ - TestFixture::test_divide(); -} -TYPED_TEST(stdlib_uint, test_modulo) -{ - TestFixture::test_modulo(); -} -TYPED_TEST(stdlib_uint, test_divide_by_zero_fails) -{ - TestFixture::test_divide_by_zero_fails(); -} -TYPED_TEST(stdlib_uint, test_divide_special) -{ - TestFixture::test_divide_special(); -} -TYPED_TEST(stdlib_uint, div_remainder_constraint) -{ - TestFixture::div_remainder_constraint(); -} -TYPED_TEST(stdlib_uint, test_and) -{ - TestFixture::test_and(); -} -TYPED_TEST(stdlib_uint, test_xor) -{ - TestFixture::test_xor(); -} -TYPED_TEST(stdlib_uint, test_or) -{ - TestFixture::test_or(); -} -TYPED_TEST(stdlib_uint, test_not) -{ - TestFixture::test_not(); -} -TYPED_TEST(stdlib_uint, test_gt) -{ - TestFixture::test_gt(); -} -TYPED_TEST(stdlib_uint, test_lt) -{ - TestFixture::test_lt(); -} -TYPED_TEST(stdlib_uint, test_gte) -{ - TestFixture::test_gte(); -} -TYPED_TEST(stdlib_uint, test_lte) -{ - TestFixture::test_lte(); -} -TYPED_TEST(stdlib_uint, test_equality_operator) -{ - TestFixture::test_equality_operator(); -} -TYPED_TEST(stdlib_uint, test_not_equality_operator) -{ - TestFixture::test_not_equality_operator(); -} -TYPED_TEST(stdlib_uint, test_logical_not) -{ - TestFixture::test_logical_not(); -} -TYPED_TEST(stdlib_uint, test_right_shift) -{ - TestFixture::test_right_shift(); -} -TYPED_TEST(stdlib_uint, test_left_shift) -{ - TestFixture::test_left_shift(); -} -TYPED_TEST(stdlib_uint, test_ror) -{ - TestFixture::test_ror(); -} -TYPED_TEST(stdlib_uint, test_rol) -{ - TestFixture::test_rol(); -} -TYPED_TEST(stdlib_uint, test_at) -{ - TestFixture::test_at(); -} - -// There was one plookup-specific test in the ./plookup/uint_plookup.test.cpp -TEST(stdlib_uint32, test_accumulators_plookup_uint32) -{ - using uint32_ct = plonk::stdlib::uint32; - using witness_ct = plonk::stdlib::witness_t; - - plonk::UltraComposer composer = plonk::UltraComposer(); - - uint32_t a_val = engine.get_random_uint32(); - uint32_t b_val = engine.get_random_uint32(); - uint32_ct a = witness_ct(&composer, a_val); - uint32_ct b = witness_ct(&composer, b_val); - a = a ^ b; - uint32_t val = a_val ^ b_val; - uint32_t MASK = (1U << uint32_ct::bits_per_limb) - 1; - const auto accumulators = a.get_accumulators(); - for (size_t i = 0; i < uint32_ct::num_accumulators(); ++i) { - const uint64_t result = uint256_t(composer.get_variable(accumulators[i])).data[0]; - const uint64_t expected = val & MASK; - val = val >> uint32_ct::bits_per_limb; - EXPECT_EQ(result, expected); - } - - printf("calling preprocess\n"); - auto prover = composer.create_prover(); - - printf("composer gates = %zu\n", composer.get_num_gates()); - auto verifier = composer.create_verifier(); - - auto proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); -} -} // namespace test_stdlib_uint +// #include "uint.hpp" +// #include "barretenberg/honk/composer/standard_honk_composer.hpp" +// #include +// #include +// #include "barretenberg/numeric/random/engine.hpp" + +// using namespace barretenberg; +// using namespace plonk; +// using namespace bonk; + +// namespace { +// auto& engine = numeric::random::get_debug_engine(); +// } + +// // NOTE: We only test width 32, but widths 8, 16, 32 and 64 can all be tested. +// // In widths 8, 16, 32: all tests pass. +// // In width 64, the following tests fail for UltraComposer. +// // test_xor_special, test_xor_more_constants, test_and_constants, test_and_special, test_or_special, +// // test_ror_special, test_hash_rounds, test_and, test_xor, test_or. +// // They fail with 'C++ exception with description"Last key slice greater than 64" thrown in the test body."' +// namespace test_stdlib_uint { +// typedef uint32_t uint_native; +// size_t uint_native_width = 8 * sizeof(uint_native); +// uint_native uint_native_max = static_cast((static_cast(1) << uint_native_width) - 1); + +// template Native get_random() +// { +// return static_cast(engine.get_random_uint64()); +// }; + +// template std::vector get_several_random(size_t num) +// { +// std::vector result; +// for (size_t i = 0; i < num; ++i) { +// result.emplace_back(get_random()); +// } +// return result; +// } + +// /** +// * @brief Utility function for testing the uint_ct comparison operators +// * +// * @details Given a uint_ct a and a constant const_b, this allows to create a +// * uint_ct b having a desired relation to a (either >. = or <). +// */ +// uint_native impose_comparison(uint_native const_a, +// uint_native const_b, +// uint_native a_val, +// bool force_equal = false, +// bool force_gt = false, +// bool force_lt = false) +// { +// uint_native b_val; +// if (force_equal) { +// b_val = a_val + const_a - const_b; +// } else if (force_lt) { // forcing b < a +// // if a_val + const_a != const_b, then we set up b_val + const_b = a_val + const_a - 1 +// // elif a_val + const_a = const_b, then we set up b_val + const_b = a_val + const_a +// // and we increment a by 1, leading to a_val + const_a = b_val + const_b + 1. +// b_val = (a_val + const_a - const_b) ? a_val + const_a - const_b - 1 : const_a - const_b + (a_val++); +// } else if (force_gt) { // forcing b > a +// // set b_val + const_b = a_val + const_a + 1 unless that would wrap, in which case we instead +// // set b_val + const_b = a then decrease a by 1. +// b_val = (a_val + const_a - const_b) == uint_native_width ? const_a - const_b + (a_val--) +// : a_val + const_a - const_b + 1; +// } else { +// b_val = get_random(); +// } +// return b_val; +// } + +// uint_native rotate(uint_native value, size_t rotation) +// { +// return rotation ? static_cast(value >> rotation) + +// static_cast(value << (uint_native_width - rotation)) +// : value; +// } +// template class stdlib_uint : public testing::Test { +// typedef typename std::conditional, +// stdlib::uint>::type uint_ct; +// typedef stdlib::bool_t bool_ct; +// typedef stdlib::witness_t witness_ct; +// typedef stdlib::byte_array byte_array_ct; + +// static inline std::vector special_values{ 0U, +// 1U, +// 2U, +// static_cast(1 << uint_native_width / 4), +// static_cast(1 << uint_native_width / 2), +// static_cast((1 << uint_native_width / 2) + 1), +// uint_native_max }; + +// static std::vector get_special_uints(Composer* ctx) +// { +// std::vector special_uints; +// for (size_t i = 0; i != special_values.size(); ++i) { +// special_uints.emplace_back(witness_ct(ctx, special_values[i])); +// }; +// return special_uints; +// }; + +// public: +// static void test_weak_normalize() +// { +// auto run_test = [](bool constant_only, bool add_constant) { +// Composer composer = Composer(); +// uint_ct a; +// uint_native a_val = get_random(); +// uint_native const_a = get_random(); +// uint_native expected; + +// if (constant_only) { +// a = const_a; +// expected = const_a; +// } else { +// a = witness_ct(&composer, a_val); +// expected = a_val; +// if (add_constant) { +// a += const_a; +// expected += const_a; +// } +// }; + +// EXPECT_EQ(expected, a.get_value()); +// auto prover = composer.create_prover(); +// auto verifier = composer.create_verifier(); +// plonk::proof proof = prover.construct_proof(); +// bool verified = verifier.verify_proof(proof); +// EXPECT_EQ(verified, true); +// }; + +// run_test(true, false); +// run_test(false, false); +// run_test(false, true); +// } + +// static void test_byte_array_conversion() +// { +// Composer composer = Composer(); +// uint_ct a = witness_ct(&composer, 0x7f6f5f4f10111213); +// std::string longest_expected = { 0x7f, 0x6f, 0x5f, 0x4f, 0x10, 0x11, 0x12, 0x13 }; +// // truncate, so we are running different tests for different choices of uint_native +// std::string expected = longest_expected.substr(longest_expected.length() - sizeof(uint_native)); +// byte_array_ct arr(&composer); +// arr.write(static_cast(a)); + +// EXPECT_EQ(arr.size(), sizeof(uint_native)); +// EXPECT_EQ(arr.get_string(), expected); +// } + +// static void test_input_output_consistency() +// { +// Composer composer = Composer(); + +// for (size_t i = 1; i < 1024; i *= 2) { +// uint_native a_expected = (uint_native)i; +// uint_native b_expected = (uint_native)i; + +// uint_ct a = witness_ct(&composer, a_expected); +// uint_ct b = witness_ct(&composer, b_expected); + +// byte_array_ct arr(&composer); + +// arr.write(static_cast(a)); +// arr.write(static_cast(b)); + +// EXPECT_EQ(arr.size(), 2 * sizeof(uint_native)); + +// uint_ct a_result(arr.slice(0, sizeof(uint_native))); +// uint_ct b_result(arr.slice(sizeof(uint_native))); + +// EXPECT_EQ(a_result.get_value(), a_expected); +// EXPECT_EQ(b_result.get_value(), b_expected); +// } +// } + +// static void test_create_from_wires() +// { +// Composer composer = Composer(); + +// uint_ct a = uint_ct(&composer, +// std::vector{ +// bool_ct(false), +// bool_ct(false), +// bool_ct(false), +// bool_ct(false), +// bool_ct(false), +// bool_ct(false), +// bool_ct(false), +// witness_ct(&composer, true), +// }); + +// EXPECT_EQ(a.at(0).get_value(), false); +// EXPECT_EQ(a.at(7).get_value(), true); +// EXPECT_EQ(static_cast(a.get_value()), 128U); +// } + +// /** +// * @brief Test addition of special values. +// * */ +// static void test_add_special() +// { +// Composer composer = Composer(); + +// witness_ct first_input(&composer, 1U); +// witness_ct second_input(&composer, 0U); + +// uint_ct a = first_input; +// uint_ct b = second_input; +// uint_ct c = a + b; +// /** +// * Fibbonacci sequence a(0) = 0, a(1), ..., a(2 + 32) = 5702887 +// * a | 1 | 1 | 2 | 3 | 5 | ... +// * b | 0 | 1 | 1 | 2 | 3 | ... +// * c | 1 | 2 | 3 | 5 | 8 | ... +// */ +// for (size_t i = 0; i < uint_native_width; ++i) { +// b = a; +// a = c; +// c = a + b; +// } + +// auto special_uints = get_special_uints(&composer); +// for (size_t i = 0; i != special_values.size(); ++i) { +// uint_native x = special_values[i]; +// uint_ct x_ct = special_uints[i]; + +// for (size_t j = i; j != special_values.size(); ++j) { +// uint_native y = special_values[j]; +// uint_ct y_ct = special_uints[j]; + +// uint_native expected_value = x + y; +// uint_ct z_ct = x_ct + y_ct; +// uint_native value = static_cast(z_ct.get_value()); + +// EXPECT_EQ(value, expected_value); +// } +// }; + +// auto prover = composer.create_prover(); +// auto verifier = composer.create_verifier(); +// plonk::proof proof = prover.construct_proof(); +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// static void test_sub_special() +// { +// Composer composer = Composer(); + +// witness_ct a_val(&composer, static_cast(4)); +// // witness_ct b_val(&composer, static_cast(5)); +// uint_native const_a = 1; +// uint_native const_b = 2; +// uint_ct a = uint_ct(a_val) + const_a; +// // uint_ct b = uint_ct(b_val) + const_b; +// uint_ct b = const_b; +// uint_ct diff = a - b; + +// auto special_uints = get_special_uints(&composer); +// for (size_t i = 0; i != special_values.size(); ++i) { +// uint_native x = special_values[i]; +// uint_ct x_ct = special_uints[i]; + +// for (size_t j = i; j != special_values.size(); ++j) { +// uint_native y = special_values[j]; +// uint_ct y_ct = special_uints[j]; + +// uint_native expected_value = x - y; +// uint_ct z_ct = x_ct - y_ct; +// uint_native value = static_cast(z_ct.get_value()); + +// EXPECT_EQ(value, expected_value); +// } +// }; + +// auto prover = composer.create_prover(); +// auto verifier = composer.create_verifier(); +// plonk::proof proof = prover.construct_proof(); +// bool verified = verifier.verify_proof(proof); + +// EXPECT_EQ(verified, true); +// } + +// static void test_add_with_constants() +// { +// size_t n = 8; +// std::vector witnesses = get_several_random(3 * n); +// uint_native expected[8]; +// for (size_t i = 2; i < n; ++i) { +// expected[0] = witnesses[3 * i]; +// expected[1] = witnesses[3 * i + 1]; +// expected[2] = witnesses[3 * i + 2]; +// expected[3] = expected[0] + expected[1]; +// expected[4] = expected[1] + expected[0]; +// expected[5] = expected[1] + expected[2]; +// expected[6] = expected[3] + expected[4]; +// expected[7] = expected[4] + expected[5]; +// } +// Composer composer = Composer(); +// uint_ct result[8]; +// for (size_t i = 2; i < n; ++i) { +// result[0] = uint_ct(&composer, witnesses[3 * i]); +// result[1] = (witness_ct(&composer, witnesses[3 * i + 1])); +// result[2] = (witness_ct(&composer, witnesses[3 * i + 2])); +// result[3] = result[0] + result[1]; +// result[4] = result[1] + result[0]; +// result[5] = result[1] + result[2]; +// result[6] = result[3] + result[4]; +// result[7] = result[4] + result[5]; +// } + +// for (size_t i = 0; i < n; ++i) { +// EXPECT_EQ(result[i].get_value(), expected[i]); +// } + +// auto prover = composer.create_prover(); +// auto verifier = composer.create_verifier(); +// plonk::proof proof = prover.construct_proof(); +// bool proof_valid = verifier.verify_proof(proof); +// EXPECT_EQ(proof_valid, true); +// } + +// static void test_mul_special() +// { +// uint_native a_expected = 1U; +// uint_native b_expected = 2U; +// uint_native c_expected = a_expected + b_expected; +// for (size_t i = 0; i < 100; ++i) { +// b_expected = a_expected; +// a_expected = c_expected; +// c_expected = a_expected * b_expected; +// } + +// Composer composer = Composer(); + +// witness_ct first_input(&composer, 1U); +// witness_ct second_input(&composer, 2U); + +// uint_ct a = first_input; +// uint_ct b = second_input; +// uint_ct c = a + b; +// for (size_t i = 0; i < 100; ++i) { +// b = a; +// a = c; +// c = a * b; +// } +// uint_native c_result = +// static_cast(composer.get_variable(c.get_witness_index()).from_montgomery_form().data[0]); +// EXPECT_EQ(c_result, c_expected); + +// auto special_uints = get_special_uints(&composer); +// for (size_t i = 0; i != special_values.size(); ++i) { +// uint_native x = special_values[i]; +// uint_ct x_ct = special_uints[i]; + +// for (size_t j = i; j != special_values.size(); ++j) { +// uint_native y = special_values[j]; +// uint_ct y_ct = special_uints[j]; + +// uint_native expected_value = x * y; +// uint_ct z_ct = x_ct * y_ct; +// uint_native value = static_cast(z_ct.get_value()); + +// EXPECT_EQ(value, expected_value); +// } +// }; + +// auto prover = composer.create_prover(); +// auto verifier = composer.create_verifier(); +// plonk::proof proof = prover.construct_proof(); +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// static void test_mul_big() +// { +// uint_native max = uint_native_max; + +// Composer composer = Composer(); +// uint_ct a = witness_ct(&composer, max); +// a = a + max; +// uint_ct b = a; +// uint_ct c = a * b; + +// auto prover = composer.create_prover(); +// auto verifier = composer.create_verifier(); +// plonk::proof proof = prover.construct_proof(); +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// static void test_xor_special() +// { +// uint_native a_expected = static_cast(0x10000000a3b10422); +// uint_native b_expected = static_cast(0xfafab007eac21343); +// uint_native c_expected = a_expected ^ b_expected; +// for (size_t i = 0; i < uint_native_width; ++i) { +// b_expected = a_expected; +// a_expected = c_expected; +// c_expected = a_expected + b_expected; +// a_expected = c_expected ^ a_expected; +// } + +// Composer composer = Composer(); + +// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); +// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + +// uint_ct a = first_input; +// uint_ct b = second_input; +// uint_ct c = a ^ b; +// for (size_t i = 0; i < uint_native_width; ++i) { +// b = a; +// a = c; +// c = a + b; +// a = c ^ a; +// } +// uint_native a_result = +// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); + +// EXPECT_EQ(a_result, a_expected); + +// auto prover = composer.create_prover(); + +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// static void test_xor_constants() +// { +// Composer composer = Composer(); + +// uint_native a_expected = static_cast(0x10000000a3b10422); +// uint_native b_expected = static_cast(0xfafab007eac21343); +// uint_native c_expected = a_expected ^ b_expected; + +// uint_ct const_a(&composer, static_cast(0x10000000a3b10422)); +// uint_ct const_b(&composer, static_cast(0xfafab007eac21343)); +// uint_ct c = const_a ^ const_b; +// c.get_witness_index(); + +// EXPECT_EQ(c.get_additive_constant(), uint256_t(c_expected)); +// } + +// static void test_xor_more_constants() +// { +// uint_native a_expected = static_cast(0x10000000a3b10422); +// uint_native b_expected = static_cast(0xfafab007eac21343); +// uint_native c_expected = a_expected ^ b_expected; +// for (size_t i = 0; i < 1; ++i) { +// b_expected = a_expected; +// a_expected = c_expected; +// c_expected = (a_expected + b_expected) ^ +// (static_cast(0x10000000a3b10422) ^ static_cast(0xfafab007eac21343)); +// } + +// Composer composer = Composer(); + +// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); +// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + +// uint_ct a = first_input; +// uint_ct b = second_input; +// uint_ct c = a ^ b; +// for (size_t i = 0; i < 1; ++i) { +// uint_ct const_a = static_cast(0x10000000a3b10422); +// uint_ct const_b = static_cast(0xfafab007eac21343); +// b = a; +// a = c; +// c = (a + b) ^ (const_a ^ const_b); +// } +// uint32_t c_witness_index = c.get_witness_index(); +// uint_native c_result = +// static_cast(composer.get_variable(c_witness_index).from_montgomery_form().data[0]); +// EXPECT_EQ(c_result, c_expected); +// auto prover = composer.create_prover(); + +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// static void test_and_constants() +// { +// uint_native a_expected = static_cast(0x10000000a3b10422); +// uint_native b_expected = static_cast(0xfafab007eac21343); +// uint_native c_expected = a_expected & b_expected; +// for (size_t i = 0; i < 1; ++i) { +// b_expected = a_expected; +// a_expected = c_expected; +// c_expected = (~a_expected & static_cast(0x10000000a3b10422)) + +// (b_expected & static_cast(0xfafab007eac21343)); +// // c_expected = (a_expected + b_expected) & (static_cast(0x10000000a3b10422) & +// // static_cast(0xfafab007eac21343)); +// } + +// Composer composer = Composer(); + +// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); +// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + +// uint_ct a = first_input; +// uint_ct b = second_input; +// uint_ct c = a & b; +// for (size_t i = 0; i < 1; ++i) { +// uint_ct const_a = static_cast(0x10000000a3b10422); +// uint_ct const_b = static_cast(0xfafab007eac21343); +// b = a; +// a = c; +// c = (~a & const_a) + (b & const_b); +// } +// uint32_t c_witness_index = c.get_witness_index(); +// uint_native c_result = +// static_cast(composer.get_variable(c_witness_index).from_montgomery_form().data[0]); +// EXPECT_EQ(c_result, c_expected); +// auto prover = composer.create_prover(); + +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// static void test_and_special() +// { +// uint_native a_expected = static_cast(0x10000000a3b10422); +// uint_native b_expected = static_cast(0xfafab007eac21343); +// uint_native c_expected = a_expected + b_expected; +// for (size_t i = 0; i < uint_native_width; ++i) { +// b_expected = a_expected; +// a_expected = c_expected; +// c_expected = a_expected + b_expected; +// a_expected = c_expected & a_expected; +// } + +// Composer composer = Composer(); + +// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); +// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + +// uint_ct a = first_input; +// uint_ct b = second_input; +// uint_ct c = a + b; +// for (size_t i = 0; i < uint_native_width; ++i) { +// b = a; +// a = c; +// c = a + b; +// a = c & a; +// } +// uint_native a_result = +// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); +// EXPECT_EQ(a_result, a_expected); + +// auto prover = composer.create_prover(); + +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// static void test_or_special() +// { +// uint_native a_expected = static_cast(0x10000000a3b10422); +// uint_native b_expected = static_cast(0xfafab007eac21343); +// uint_native c_expected = a_expected ^ b_expected; +// for (size_t i = 0; i < uint_native_width; ++i) { +// b_expected = a_expected; +// a_expected = c_expected; +// c_expected = a_expected + b_expected; +// a_expected = c_expected | a_expected; +// } + +// Composer composer = Composer(); + +// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); +// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + +// uint_ct a = first_input; +// uint_ct b = second_input; +// uint_ct c = a ^ b; +// for (size_t i = 0; i < uint_native_width; ++i) { +// b = a; +// a = c; +// c = a + b; +// a = c | a; +// } +// uint_native a_result = +// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); +// EXPECT_EQ(a_result, a_expected); + +// auto prover = composer.create_prover(); + +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// static void test_gt_special() +// { +// const auto run_test = [](bool lhs_constant, bool rhs_constant, int type = 0) { +// uint_native a_expected = static_cast(0x10000000a3b10422); +// uint_native b_expected; +// switch (type) { +// case 0: { +// b_expected = static_cast(0x20000000bac21343); // a < b +// break; +// } +// case 1: { +// b_expected = static_cast(0x0000000000002f12); // a > b +// break; +// } +// case 2: { +// b_expected = static_cast(0x10000000a3b10422); // a = b +// break; +// } +// default: { +// b_expected = static_cast(0x20000000bac21343); // a < b +// } +// } +// bool c_expected = a_expected > b_expected; + +// Composer composer = Composer(); + +// uint_ct a; +// uint_ct b; +// if (lhs_constant) { +// a = uint_ct(nullptr, a_expected); +// } else { +// a = witness_ct(&composer, a_expected); +// } +// if (rhs_constant) { +// b = uint_ct(nullptr, b_expected); +// } else { +// b = witness_ct(&composer, b_expected); +// } +// // mix in some constant terms for good measure +// a *= uint_ct(&composer, 2); +// a += uint_ct(&composer, 1); +// b *= uint_ct(&composer, 2); +// b += uint_ct(&composer, 1); + +// bool_ct c = a > b; + +// bool c_result = static_cast(c.get_value()); +// EXPECT_EQ(c_result, c_expected); + +// auto prover = composer.create_prover(); + +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// }; + +// run_test(false, false, 0); +// run_test(false, true, 0); +// run_test(true, false, 0); +// run_test(true, true, 0); +// run_test(false, false, 1); +// run_test(false, true, 1); +// run_test(true, false, 1); +// run_test(true, true, 1); +// run_test(false, false, 2); +// run_test(false, true, 2); +// run_test(true, false, 2); +// run_test(true, true, 2); +// } + +// static uint_native rotate(uint_native value, size_t rotation) +// { +// return rotation ? static_cast(value >> rotation) + +// static_cast(value << (uint_native_width - rotation)) +// : value; +// } + +// static void test_ror_special() +// { +// uint_native a_expected = static_cast(0x10000000a3b10422); +// uint_native b_expected = static_cast(0xfafab007eac21343); +// uint_native c_expected = a_expected ^ b_expected; +// for (size_t i = 0; i < uint_native_width; ++i) { +// b_expected = a_expected; +// a_expected = c_expected; +// c_expected = a_expected + b_expected; +// a_expected = rotate(c_expected, i % 31) + rotate(a_expected, (i + 1) % 31); +// } + +// Composer composer = Composer(); + +// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); +// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + +// uint_ct a = first_input; +// uint_ct b = second_input; +// uint_ct c = a ^ b; +// for (size_t i = 0; i < uint_native_width; ++i) { +// b = a; +// a = c; +// c = a + b; +// a = c.ror(static_cast(i % 31)) + a.ror(static_cast((i + 1) % 31)); +// } +// uint_native a_result = +// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); +// EXPECT_EQ(a_result, a_expected); + +// auto prover = composer.create_prover(); + +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// /** +// * @brief If uint_native_width == 32, test part of SHA256. Otherwise, do something similar. +// * +// * @details Notes that the static casts have to be there becuase of -Wc++11-narrowing flag. +// * +// * TurboPLONK: 19896 gates +// * StandardPLONK: 210363 gates +// */ +// static void test_hash_rounds() +// { +// std::vector k_constants(64); +// std::vector round_values(8); +// if (uint_native_width == 32) { +// k_constants = { static_cast(0x428a2f98), static_cast(0x71374491), +// static_cast(0xb5c0fbcf), static_cast(0xe9b5dba5), +// static_cast(0x3956c25b), static_cast(0x59f111f1), +// static_cast(0x923f82a4), static_cast(0xab1c5ed5), +// static_cast(0xd807aa98), static_cast(0x12835b01), +// static_cast(0x243185be), static_cast(0x550c7dc3), +// static_cast(0x72be5d74), static_cast(0x80deb1fe), +// static_cast(0x9bdc06a7), static_cast(0xc19bf174), +// static_cast(0xe49b69c1), static_cast(0xefbe4786), +// static_cast(0x0fc19dc6), static_cast(0x240ca1cc), +// static_cast(0x2de92c6f), static_cast(0x4a7484aa), +// static_cast(0x5cb0a9dc), static_cast(0x76f988da), +// static_cast(0x983e5152), static_cast(0xa831c66d), +// static_cast(0xb00327c8), static_cast(0xbf597fc7), +// static_cast(0xc6e00bf3), static_cast(0xd5a79147), +// static_cast(0x06ca6351), static_cast(0x14292967), +// static_cast(0x27b70a85), static_cast(0x2e1b2138), +// static_cast(0x4d2c6dfc), static_cast(0x53380d13), +// static_cast(0x650a7354), static_cast(0x766a0abb), +// static_cast(0x81c2c92e), static_cast(0x92722c85), +// static_cast(0xa2bfe8a1), static_cast(0xa81a664b), +// static_cast(0xc24b8b70), static_cast(0xc76c51a3), +// static_cast(0xd192e819), static_cast(0xd6990624), +// static_cast(0xf40e3585), static_cast(0x106aa070), +// static_cast(0x19a4c116), static_cast(0x1e376c08), +// static_cast(0x2748774c), static_cast(0x34b0bcb5), +// static_cast(0x391c0cb3), static_cast(0x4ed8aa4a), +// static_cast(0x5b9cca4f), static_cast(0x682e6ff3), +// static_cast(0x748f82ee), static_cast(0x78a5636f), +// static_cast(0x84c87814), static_cast(0x8cc70208), +// static_cast(0x90befffa), static_cast(0xa4506ceb), +// static_cast(0xbef9a3f7), static_cast(0xc67178f2) }; + +// round_values = { static_cast(0x01020304), static_cast(0x0a0b0c0d), +// static_cast(0x1a2b3e4d), static_cast(0x03951bd3), +// static_cast(0x0e0fa3fe), static_cast(0x01000000), +// static_cast(0x0f0eeea1), static_cast(0x12345678) }; +// } else { +// k_constants = get_several_random(64); +// round_values = get_several_random(8); +// }; + +// std::vector w_alt = get_several_random(64); + +// uint_native a_alt = round_values[0]; +// uint_native b_alt = round_values[1]; +// uint_native c_alt = round_values[2]; +// uint_native d_alt = round_values[3]; +// uint_native e_alt = round_values[4]; +// uint_native f_alt = round_values[5]; +// uint_native g_alt = round_values[6]; +// uint_native h_alt = round_values[7]; +// for (size_t i = 0; i < 64; ++i) { +// uint_native S1_alt = rotate(e_alt, 7 % uint_native_width) ^ rotate(e_alt, 11 % uint_native_width) ^ +// rotate(e_alt, 25 % uint_native_width); +// uint_native ch_alt = (e_alt & f_alt) ^ ((~e_alt) & g_alt); +// uint_native temp1_alt = h_alt + S1_alt + ch_alt + k_constants[i % 64] + w_alt[i]; + +// uint_native S0_alt = rotate(a_alt, 2 % uint_native_width) ^ rotate(a_alt, 13 % uint_native_width) ^ +// rotate(a_alt, 22 % uint_native_width); +// uint_native maj_alt = (a_alt & b_alt) ^ (a_alt & c_alt) ^ (b_alt & c_alt); +// uint_native temp2_alt = S0_alt + maj_alt; + +// h_alt = g_alt; +// g_alt = f_alt; +// f_alt = e_alt; +// e_alt = d_alt + temp1_alt; +// d_alt = c_alt; +// c_alt = b_alt; +// b_alt = a_alt; +// a_alt = temp1_alt + temp2_alt; +// } +// Composer composer = Composer(); + +// std::vector w; +// std::vector k; +// for (size_t i = 0; i < 64; ++i) { +// w.emplace_back(uint_ct(witness_ct(&composer, w_alt[i]))); +// k.emplace_back(uint_ct(&composer, k_constants[i % 64])); +// } +// uint_ct a = witness_ct(&composer, round_values[0]); +// uint_ct b = witness_ct(&composer, round_values[1]); +// uint_ct c = witness_ct(&composer, round_values[2]); +// uint_ct d = witness_ct(&composer, round_values[3]); +// uint_ct e = witness_ct(&composer, round_values[4]); +// uint_ct f = witness_ct(&composer, round_values[5]); +// uint_ct g = witness_ct(&composer, round_values[6]); +// uint_ct h = witness_ct(&composer, round_values[7]); +// for (size_t i = 0; i < 64; ++i) { +// uint_ct S1 = +// e.ror(7U % uint_native_width) ^ e.ror(11U % uint_native_width) ^ e.ror(25U % uint_native_width); +// uint_ct ch = (e & f) + ((~e) & g); +// uint_ct temp1 = h + S1 + ch + k[i] + w[i]; + +// uint_ct S0 = +// a.ror(2U % uint_native_width) ^ a.ror(13U % uint_native_width) ^ a.ror(22U % uint_native_width); +// uint_ct T0 = (b & c); +// uint_ct T1 = (b - T0) + (c - T0); +// uint_ct T2 = a & T1; +// uint_ct maj = T2 + T0; +// uint_ct temp2 = S0 + maj; + +// h = g; +// g = f; +// f = e; +// e = d + temp1; +// d = c; +// c = b; +// b = a; +// a = temp1 + temp2; +// } + +// uint_native a_result = +// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); +// uint_native b_result = +// static_cast(composer.get_variable(b.get_witness_index()).from_montgomery_form().data[0]); +// uint_native c_result = +// static_cast(composer.get_variable(c.get_witness_index()).from_montgomery_form().data[0]); +// uint_native d_result = +// static_cast(composer.get_variable(d.get_witness_index()).from_montgomery_form().data[0]); +// uint_native e_result = +// static_cast(composer.get_variable(e.get_witness_index()).from_montgomery_form().data[0]); +// uint_native f_result = +// static_cast(composer.get_variable(f.get_witness_index()).from_montgomery_form().data[0]); +// uint_native g_result = +// static_cast(composer.get_variable(g.get_witness_index()).from_montgomery_form().data[0]); +// uint_native h_result = +// static_cast(composer.get_variable(h.get_witness_index()).from_montgomery_form().data[0]); + +// EXPECT_EQ(a_result, a_alt); +// EXPECT_EQ(b_result, b_alt); +// EXPECT_EQ(c_result, c_alt); +// EXPECT_EQ(d_result, d_alt); +// EXPECT_EQ(e_result, e_alt); +// EXPECT_EQ(f_result, f_alt); +// EXPECT_EQ(g_result, g_alt); +// EXPECT_EQ(h_result, h_alt); + +// auto prover = composer.create_prover(); + +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// // BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO + +// /** +// * @brief Test addition of random uint's, trying all combinations of (constant, witness). +// */ +// static void test_add() +// { +// Composer composer = Composer(); + +// const auto add_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { +// uint_native a_val = get_random(); +// uint_native b_val = get_random(); +// uint_native expected = a_val + b_val; +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); +// uint_ct c = a + b; +// c = c.normalize(); + +// uint_native result = uint_native(c.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// add_integers(false, false); +// add_integers(false, true); +// add_integers(true, false); +// add_integers(true, true); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_sub() +// { +// Composer composer = Composer(); + +// const auto sub_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { +// uint_native a_val = get_random(); +// uint_native b_val = get_random(); +// uint_native const_shift_val = get_random(); +// uint_native expected = a_val - (b_val + const_shift_val); +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); +// uint_ct b_shift = uint_ct(&composer, const_shift_val); +// uint_ct c = b + b_shift; +// uint_ct d = a - c; +// d = d.normalize(); + +// uint_native result = uint_native(d.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// sub_integers(false, false); +// sub_integers(false, true); +// sub_integers(true, false); +// sub_integers(true, true); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_mul() +// { +// Composer composer = Composer(); + +// const auto mul_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { +// uint_native a_val = get_random(); +// uint_native b_val = get_random(); +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native expected = +// static_cast(a_val + const_a) * static_cast(b_val + const_b); +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// uint_ct e = c * d; +// e = e.normalize(); + +// uint_native result = uint_native(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// mul_integers(false, false); +// mul_integers(false, true); +// mul_integers(true, false); +// mul_integers(true, true); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_divide() +// { +// Composer composer = Composer(); + +// const auto divide_integers = [&composer](bool lhs_constant = false, +// bool rhs_constant = false, +// bool dividend_is_divisor = false, +// bool dividend_zero = false, +// bool divisor_zero = false) { +// uint_native a_val = get_random(); +// uint_native b_val = dividend_is_divisor ? a_val : get_random(); +// uint_native const_a = dividend_zero ? 0 - a_val : get_random(); +// uint_native const_b = +// divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); +// uint_native expected = +// static_cast(a_val + const_a) / static_cast(b_val + const_b); +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// uint_ct e = c / d; +// e = e.normalize(); + +// uint_native result = static_cast(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// divide_integers(false, false, false, false, false); +// divide_integers(false, false, false, false, false); +// divide_integers(false, false, false, false, false); +// divide_integers(false, false, false, false, false); +// divide_integers(false, false, false, false, false); + +// divide_integers(false, true, false, false, false); +// divide_integers(true, false, false, false, false); +// divide_integers(true, true, false, false, false); // fails; 0 != 1 + +// divide_integers(false, false, true, false, false); +// divide_integers(false, true, true, false, false); +// divide_integers(true, false, true, false, false); +// divide_integers(true, true, true, false, false); + +// divide_integers(false, false, false, true, false); +// divide_integers(false, true, false, true, false); // fails; 0 != 1 +// divide_integers(true, false, false, true, false); +// divide_integers(true, true, false, true, false); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_modulo() +// { +// Composer composer = Composer(); + +// const auto mod_integers = [&composer](bool lhs_constant = false, +// bool rhs_constant = false, +// bool dividend_is_divisor = false, +// bool dividend_zero = false, +// bool divisor_zero = false) { +// uint_native a_val = get_random(); +// uint_native b_val = dividend_is_divisor ? a_val : get_random(); +// uint_native const_a = dividend_zero ? 0 - a_val : get_random(); +// uint_native const_b = +// divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); +// uint_native expected = +// static_cast(a_val + const_a) % static_cast(b_val + const_b); +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// uint_ct e = c % d; +// e = e.normalize(); + +// uint_native result = uint_native(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// mod_integers(false, false, false, false, false); +// mod_integers(false, true, false, false, false); +// mod_integers(true, false, false, false, false); +// mod_integers(true, true, false, false, false); + +// mod_integers(false, false, true, false, false); +// mod_integers(false, true, true, false, false); +// mod_integers(true, false, true, false, false); +// mod_integers(true, true, true, false, false); + +// mod_integers(false, false, false, true, false); +// mod_integers(false, true, false, true, false); +// mod_integers(true, false, false, true, false); +// mod_integers(true, true, false, true, false); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_divide_by_zero_fails() +// { + +// const auto divide_integers = [](bool lhs_constant = false, +// bool rhs_constant = false, +// bool dividend_is_divisor = false, +// bool dividend_zero = false, +// bool divisor_zero = false) { +// Composer composer = Composer(); + +// uint_native a_val = get_random(); +// uint_native b_val = dividend_is_divisor ? a_val : get_random(); +// uint_native const_a = dividend_zero ? 0 - a_val : get_random(); +// uint_native const_b = +// divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// uint_ct e = c / d; +// e = e.normalize(); + +// auto prover = composer.create_prover(); + +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, false); +// }; + +// divide_integers(false, false, false, false, true); +// divide_integers(false, false, false, true, true); +// divide_integers(true, true, false, false, true); +// divide_integers(true, true, false, true, true); +// } + +// static void test_divide_special() +// { +// Composer composer = Composer(); + +// auto special_uints = get_special_uints(&composer); + +// for (size_t i = 0; i != special_values.size(); ++i) { +// uint_native x = special_values[i]; +// uint_ct x_ct = special_uints[i]; + +// for (size_t j = i; j != special_values.size(); ++j) { +// uint_native y = special_values[j]; +// uint_ct y_ct = special_uints[j]; + +// // uint_native hits this error when trying to divide by zero: +// // Stop reason: signal SIGFPE: integer divide by zero +// uint_native expected_value; +// uint_ct z_ct; +// uint_native value; +// if (y != 0) { +// expected_value = x / y; +// z_ct = x_ct / y_ct; +// value = static_cast(z_ct.get_value()); +// EXPECT_EQ(value, expected_value); +// } +// } +// }; + +// auto prover = composer.create_prover(); +// auto verifier = composer.create_verifier(); +// plonk::proof proof = prover.construct_proof(); +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, true); +// } + +// /** +// * @brief Make sure we prevent proving v / v = 0 by setting the divison remainder to be v. +// * TODO: This is lifted from the implementation. Should rewrite this test after introducing framework that separates +// * circuit construction from witness generation. + +// */ +// static void div_remainder_constraint() +// { +// Composer composer = Composer(); + +// uint_native val = get_random(); + +// uint_ct a = witness_ct(&composer, val); +// uint_ct b = witness_ct(&composer, val); + +// const uint32_t dividend_idx = a.get_witness_index(); +// const uint32_t divisor_idx = b.get_witness_index(); + +// const uint256_t divisor = b.get_value(); + +// const uint256_t q = 0; +// const uint256_t r = val; + +// const uint32_t quotient_idx = composer.add_variable(q); +// const uint32_t remainder_idx = composer.add_variable(r); + +// // In this example there are no additive constaints, so we just replace them by zero below. + +// // constraint: qb + const_b q + 0 b - a + r - const_a == 0 +// // i.e., a + const_a = q(b + const_b) + r +// const mul_quad division_gate{ .a = quotient_idx, // q +// .b = divisor_idx, // b +// .c = dividend_idx, // a +// .d = remainder_idx, // r +// .mul_scaling = fr::one(), +// .a_scaling = b.get_additive_constant(), +// .b_scaling = fr::zero(), +// .c_scaling = fr::neg_one(), +// .d_scaling = fr::one(), +// .const_scaling = -a.get_additive_constant() }; +// composer.create_big_mul_gate(division_gate); + +// // set delta = (b + const_b - r) + +// // constraint: b - r - delta + const_b == 0 +// const uint256_t delta = divisor - r - 1; +// const uint32_t delta_idx = composer.add_variable(delta); + +// const add_triple delta_gate{ +// .a = divisor_idx, // b +// .b = remainder_idx, // r +// .c = delta_idx, // d +// .a_scaling = fr::one(), +// .b_scaling = fr::neg_one(), +// .c_scaling = fr::neg_one(), +// .const_scaling = b.get_additive_constant(), +// }; + +// composer.create_add_gate(delta_gate); + +// // validate delta is in the correct range +// stdlib::field_t::from_witness_index(&composer, delta_idx) +// .create_range_constraint(uint_native_width, +// "delta range constraint fails in div_remainder_constraint test"); + +// // normalize witness quotient and remainder +// // minimal bit range for quotient: from 0 (in case a = b-1) to width (when b = 1). +// uint_ct quotient(&composer); +// composer.create_range_constraint( +// quotient_idx, uint_native_width, "quotient range constraint fails in div_remainder_constraint test"); + +// // constrain remainder to lie in [0, 2^width-1] +// uint_ct remainder(&composer); +// composer.create_range_constraint( +// remainder_idx, uint_native_width, "remainder range constraint fails in div_remainder_constraint test"); + +// auto prover = composer.create_prover(); +// auto verifier = composer.create_verifier(); +// plonk::proof proof = prover.construct_proof(); +// bool result = verifier.verify_proof(proof); +// EXPECT_EQ(result, false); +// } + +// static void test_and() +// { +// Composer composer = Composer(); + +// const auto and_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { +// uint_native a_val = get_random(); +// uint_native b_val = get_random(); +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native expected = (a_val + const_a) & (b_val + const_b); +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// uint_ct e = c & d; +// e = e.normalize(); + +// uint_native result = uint_native(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// and_integers(false, false); +// and_integers(false, true); +// and_integers(true, false); +// and_integers(true, true); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_xor() +// { +// Composer composer = Composer(); + +// const auto xor_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { +// uint_native a_val = get_random(); +// uint_native b_val = get_random(); +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native expected = (a_val + const_a) ^ (b_val + const_b); +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// uint_ct e = c ^ d; +// e = e.normalize(); + +// uint_native result = uint_native(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// xor_integers(false, false); +// xor_integers(false, true); +// xor_integers(true, false); +// xor_integers(true, true); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_or() +// { +// Composer composer = Composer(); + +// const auto or_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { +// uint_native a_val = get_random(); +// uint_native b_val = get_random(); +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native expected = (a_val + const_a) | (b_val + const_b); +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// uint_ct e = c | d; +// e = e.normalize(); + +// uint_native result = uint_native(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// or_integers(false, false); +// or_integers(false, false); +// or_integers(false, false); +// or_integers(false, false); +// or_integers(false, false); +// or_integers(false, true); +// or_integers(true, false); +// or_integers(true, true); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_not() +// { +// Composer composer = Composer(); + +// const auto not_integers = [&composer](bool lhs_constant = false, bool = false) { +// uint_native a_val = get_random(); +// uint_native const_a = get_random(); +// uint_native expected = ~(a_val + const_a); +// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct c = a + a_shift; +// uint_ct e = ~c; +// e = e.normalize(); + +// uint_native result = uint_native(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// not_integers(false, false); +// not_integers(false, true); +// not_integers(true, false); +// not_integers(true, true); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_gt() +// { +// Composer composer = Composer(); +// const auto compare_integers = +// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native a_val = get_random(); +// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + +// bool expected = static_cast(b_val + const_b) > static_cast(a_val + const_a); +// uint_ct a = witness_ct(&composer, a_val); +// uint_ct b = witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// bool_ct e = d > c; +// bool result = bool(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// compare_integers(false, false, false); // both are random +// compare_integers(false, false, false); // '' +// compare_integers(false, false, false); // '' +// compare_integers(false, false, false); // '' +// compare_integers(false, false, true); // b < a +// compare_integers(false, true, false); // b > a +// compare_integers(true, false, false); // b = a +// compare_integers(false, true, false); // b > a +// compare_integers(true, false, false); // b = a + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_lt() +// { +// Composer composer = Composer(); + +// const auto compare_integers = +// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native a_val = get_random(); +// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + +// bool expected = static_cast(b_val + const_b) < static_cast(a_val + const_a); +// uint_ct a = witness_ct(&composer, a_val); +// uint_ct b = witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// bool_ct e = d < c; +// bool result = bool(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_gte() +// { +// Composer composer = Composer(); + +// const auto compare_integers = +// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native a_val = get_random(); +// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + +// bool expected = static_cast(b_val + const_b) >= static_cast(a_val + const_a); +// uint_ct a = witness_ct(&composer, a_val); +// uint_ct b = witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// bool_ct e = d >= c; +// bool result = bool(e.get_value()); +// EXPECT_EQ(result, expected); +// }; + +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_lte() +// { +// Composer composer = Composer(); + +// const auto compare_integers = +// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native a_val = get_random(); +// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + +// bool expected = static_cast(b_val + const_b) <= static_cast(a_val + const_a); +// uint_ct a = witness_ct(&composer, a_val); +// uint_ct b = witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// bool_ct e = d <= c; +// bool result = bool(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_equality_operator() +// { +// Composer composer = Composer(); + +// const auto compare_integers = +// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native a_val = get_random(); +// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + +// bool expected = static_cast(b_val + const_b) == static_cast(a_val + const_a); +// uint_ct a = witness_ct(&composer, a_val); +// uint_ct b = witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// bool_ct e = d == c; +// bool result = bool(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_not_equality_operator() +// { +// Composer composer = Composer(); + +// const auto compare_integers = +// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { +// uint_native const_a = get_random(); +// uint_native const_b = get_random(); +// uint_native a_val = get_random(); +// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + +// bool expected = static_cast(b_val + const_b) != static_cast(a_val + const_a); +// uint_ct a = witness_ct(&composer, a_val); +// uint_ct b = witness_ct(&composer, b_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct b_shift = uint_ct(&composer, const_b); +// uint_ct c = a + a_shift; +// uint_ct d = b + b_shift; +// bool_ct e = d != c; +// bool result = bool(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); +// compare_integers(false, false, true); +// compare_integers(false, true, false); +// compare_integers(true, false, false); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_logical_not() +// { +// Composer composer = Composer(); + +// const auto not_integer = [&composer](bool force_zero) { +// uint_native const_a = get_random(); +// uint_native a_val = force_zero ? 0 - const_a : get_random(); +// bool expected = !static_cast(const_a + a_val); +// uint_ct a = witness_ct(&composer, a_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct c = a + a_shift; +// bool_ct e = !c; +// bool result = bool(e.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// not_integer(true); +// not_integer(true); +// not_integer(false); +// not_integer(false); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_right_shift() +// { +// Composer composer = Composer(); + +// const auto shift_integer = [&composer](const bool is_constant, const uint_native shift) { +// uint_native const_a = get_random(); +// uint_native a_val = get_random(); +// uint_native expected = static_cast(a_val + const_a) >> shift; +// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct c = a + a_shift; +// uint_ct d = c >> shift; +// uint_native result = uint_native(d.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// for (uint_native i = 0; i < uint_native_width; ++i) { +// shift_integer(false, i); +// shift_integer(true, i); +// } + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_left_shift() +// { +// Composer composer = Composer(); + +// const auto shift_integer = [&composer](const bool is_constant, const uint_native shift) { +// uint_native const_a = get_random(); +// uint_native a_val = get_random(); +// uint_native expected = static_cast((a_val + const_a) << shift); +// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct c = a + a_shift; +// uint_ct d = c << shift; +// uint_native result = uint_native(d.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// for (uint_native i = 0; i < uint_native_width; ++i) { +// shift_integer(true, i); +// shift_integer(false, i); +// } + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_ror() +// { +// Composer composer = Composer(); + +// const auto ror_integer = [&composer](const bool is_constant, const uint_native rotation) { +// const auto ror = [](const uint_native in, const uint_native rval) { +// return rval ? (in >> rval) | (in << (uint_native_width - rval)) : in; +// }; + +// uint_native const_a = get_random(); +// uint_native a_val = get_random(); +// uint_native expected = static_cast(ror(static_cast(const_a + a_val), rotation)); +// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct c = a + a_shift; +// uint_ct d = c.ror(rotation); +// uint_native result = uint_native(d.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// for (uint_native i = 0; i < uint_native_width; ++i) { +// ror_integer(true, i); +// ror_integer(false, i); +// } + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// static void test_rol() +// { +// Composer composer = Composer(); + +// const auto rol_integer = [&composer](const bool is_constant, const uint_native rotation) { +// const auto rol = [](const uint_native in, const uint_native rval) { +// return rval ? (in << rval) | (in >> (uint_native_width - rval)) : in; +// }; + +// uint_native const_a = get_random(); +// uint_native a_val = get_random(); +// uint_native expected = static_cast(rol(static_cast(const_a + a_val), rotation)); +// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct c = a + a_shift; +// uint_ct d = c.rol(rotation); +// uint_native result = uint_native(d.get_value()); + +// EXPECT_EQ(result, expected); +// }; + +// for (uint_native i = 0; i < uint_native_width; ++i) { +// rol_integer(true, i); +// rol_integer(false, i); +// } + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } + +// /** +// * @brief Test the the function uint_ct::at used to extract bits. +// */ +// static void test_at() +// { +// Composer composer = Composer(); + +// const auto bit_test = [&composer](const bool is_constant) { +// // construct a sum of uint_ct's, where at least one is a constant, +// // and validate its correctness bitwise +// uint_native const_a = get_random(); +// uint_native a_val = get_random(); +// uint_native c_val = const_a + a_val; +// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); +// uint_ct a_shift = uint_ct(&composer, const_a); +// uint_ct c = a + a_shift; +// for (size_t i = 0; i < uint_native_width; ++i) { +// bool_ct result = c.at(i); +// bool expected = (((c_val >> i) & 1UL) == 1UL) ? true : false; +// EXPECT_EQ(result.get_value(), expected); +// EXPECT_EQ(result.get_context(), c.get_context()); +// } +// }; + +// bit_test(false); +// bit_test(true); + +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// plonk::proof proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } +// }; + +// typedef testing::Types +// ComposerTypes; + +// TYPED_TEST_SUITE(stdlib_uint, ComposerTypes); + +// TYPED_TEST(stdlib_uint, test_weak_normalize) +// { +// TestFixture::test_weak_normalize(); +// } +// TYPED_TEST(stdlib_uint, test_byte_array_conversion) +// { +// TestFixture::test_byte_array_conversion(); +// } +// TYPED_TEST(stdlib_uint, test_input_output_consistency) +// { +// TestFixture::test_input_output_consistency(); +// } +// TYPED_TEST(stdlib_uint, test_create_from_wires) +// { +// TestFixture::test_create_from_wires(); +// } +// TYPED_TEST(stdlib_uint, test_add_special) +// { +// TestFixture::test_add_special(); +// } +// TYPED_TEST(stdlib_uint, test_sub_special) +// { +// TestFixture::test_sub_special(); +// } +// TYPED_TEST(stdlib_uint, test_add_with_constants) +// { +// TestFixture::test_add_with_constants(); +// } +// TYPED_TEST(stdlib_uint, test_mul_special) +// { +// TestFixture::test_mul_special(); +// } +// TYPED_TEST(stdlib_uint, test_mul_big) +// { +// TestFixture::test_mul_big(); +// } +// TYPED_TEST(stdlib_uint, test_xor_special) +// { +// TestFixture::test_xor_special(); +// } +// TYPED_TEST(stdlib_uint, test_xor_constants) +// { +// TestFixture::test_xor_constants(); +// } +// TYPED_TEST(stdlib_uint, test_xor_more_constants) +// { +// TestFixture::test_xor_more_constants(); +// } +// TYPED_TEST(stdlib_uint, test_and_constants) +// { +// TestFixture::test_and_constants(); +// } +// TYPED_TEST(stdlib_uint, test_and_special) +// { +// TestFixture::test_and_special(); +// } +// TYPED_TEST(stdlib_uint, test_or_special) +// { +// TestFixture::test_or_special(); +// } +// TYPED_TEST(stdlib_uint, test_gt_special) +// { +// TestFixture::test_gt_special(); +// } +// TYPED_TEST(stdlib_uint, test_ror_special) +// { +// TestFixture::test_ror_special(); +// } +// TYPED_TEST(stdlib_uint, test_hash_rounds) +// { +// TestFixture::test_hash_rounds(); +// } +// // BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO +// TYPED_TEST(stdlib_uint, test_add) +// { +// TestFixture::test_add(); +// } +// TYPED_TEST(stdlib_uint, test_sub) +// { +// TestFixture::test_sub(); +// } +// TYPED_TEST(stdlib_uint, test_mul) +// { +// TestFixture::test_mul(); +// } +// TYPED_TEST(stdlib_uint, test_divide) +// { +// TestFixture::test_divide(); +// } +// TYPED_TEST(stdlib_uint, test_modulo) +// { +// TestFixture::test_modulo(); +// } +// TYPED_TEST(stdlib_uint, test_divide_by_zero_fails) +// { +// TestFixture::test_divide_by_zero_fails(); +// } +// TYPED_TEST(stdlib_uint, test_divide_special) +// { +// TestFixture::test_divide_special(); +// } +// TYPED_TEST(stdlib_uint, div_remainder_constraint) +// { +// TestFixture::div_remainder_constraint(); +// } +// TYPED_TEST(stdlib_uint, test_and) +// { +// TestFixture::test_and(); +// } +// TYPED_TEST(stdlib_uint, test_xor) +// { +// TestFixture::test_xor(); +// } +// TYPED_TEST(stdlib_uint, test_or) +// { +// TestFixture::test_or(); +// } +// TYPED_TEST(stdlib_uint, test_not) +// { +// TestFixture::test_not(); +// } +// TYPED_TEST(stdlib_uint, test_gt) +// { +// TestFixture::test_gt(); +// } +// TYPED_TEST(stdlib_uint, test_lt) +// { +// TestFixture::test_lt(); +// } +// TYPED_TEST(stdlib_uint, test_gte) +// { +// TestFixture::test_gte(); +// } +// TYPED_TEST(stdlib_uint, test_lte) +// { +// TestFixture::test_lte(); +// } +// TYPED_TEST(stdlib_uint, test_equality_operator) +// { +// TestFixture::test_equality_operator(); +// } +// TYPED_TEST(stdlib_uint, test_not_equality_operator) +// { +// TestFixture::test_not_equality_operator(); +// } +// TYPED_TEST(stdlib_uint, test_logical_not) +// { +// TestFixture::test_logical_not(); +// } +// TYPED_TEST(stdlib_uint, test_right_shift) +// { +// TestFixture::test_right_shift(); +// } +// TYPED_TEST(stdlib_uint, test_left_shift) +// { +// TestFixture::test_left_shift(); +// } +// TYPED_TEST(stdlib_uint, test_ror) +// { +// TestFixture::test_ror(); +// } +// TYPED_TEST(stdlib_uint, test_rol) +// { +// TestFixture::test_rol(); +// } +// TYPED_TEST(stdlib_uint, test_at) +// { +// TestFixture::test_at(); +// } + +// // There was one plookup-specific test in the ./plookup/uint_plookup.test.cpp +// TEST(stdlib_uint32, test_accumulators_plookup_uint32) +// { +// using uint32_ct = plonk::stdlib::uint32; +// using witness_ct = plonk::stdlib::witness_t; + +// plonk::UltraComposer composer = plonk::UltraComposer(); + +// uint32_t a_val = engine.get_random_uint32(); +// uint32_t b_val = engine.get_random_uint32(); +// uint32_ct a = witness_ct(&composer, a_val); +// uint32_ct b = witness_ct(&composer, b_val); +// a = a ^ b; +// uint32_t val = a_val ^ b_val; +// uint32_t MASK = (1U << uint32_ct::bits_per_limb) - 1; +// const auto accumulators = a.get_accumulators(); +// for (size_t i = 0; i < uint32_ct::num_accumulators(); ++i) { +// const uint64_t result = uint256_t(composer.get_variable(accumulators[i])).data[0]; +// const uint64_t expected = val & MASK; +// val = val >> uint32_ct::bits_per_limb; +// EXPECT_EQ(result, expected); +// } + +// printf("calling preprocess\n"); +// auto prover = composer.create_prover(); + +// printf("composer gates = %zu\n", composer.get_num_gates()); +// auto verifier = composer.create_verifier(); + +// auto proof = prover.construct_proof(); + +// bool proof_result = verifier.verify_proof(proof); +// EXPECT_EQ(proof_result, true); +// } +// } // namespace test_stdlib_uint diff --git a/cpp/src/barretenberg/stdlib/types/types.hpp b/cpp/src/barretenberg/stdlib/types/types.hpp index 4fdc71e1c0..6995d1a89e 100644 --- a/cpp/src/barretenberg/stdlib/types/types.hpp +++ b/cpp/src/barretenberg/stdlib/types/types.hpp @@ -3,6 +3,7 @@ #include "barretenberg/plonk/composer/standard_composer.hpp" #include "barretenberg/plonk/composer/turbo_composer.hpp" #include "barretenberg/plonk/composer/ultra_composer.hpp" +#include "barretenberg/plonk/composer/plookup_tables/plookup_tables.hpp" #include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" #include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" #include "barretenberg/stdlib/primitives/bit_array/bit_array.hpp" @@ -77,6 +78,7 @@ typedef stdlib::pedersen pedersen; typedef stdlib::group group_ct; typedef stdlib::bn254 bn254; typedef stdlib::secp256k1 secp256k1_ct; +typedef stdlib::plookup_read plookup_read_ct; namespace merkle_tree { using namespace stdlib::merkle_tree; From 62a77578b5a78b4e498057e1f5d6c3a5754bd182 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Mon, 27 Mar 2023 19:43:05 +0100 Subject: [PATCH 14/46] logic gate debugging --- .../dsl/acir_format/acir_format.cpp | 2 +- .../dsl/acir_format/logic_constraint.cpp | 36 +++++++++++++------ .../stdlib/primitives/plookup/plookup.cpp | 2 +- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 3890a93a73..803bf2016f 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -12,7 +12,7 @@ void read_witness(Composer& composer, std::vector witness) void create_circuit(Composer& composer, const acir_format& constraint_system) { - std::cout << "2" << std::endl; + std::cout << "5" << std::endl; if (constraint_system.public_inputs.size() > constraint_system.varnum) { std::cout << "too many public inputs!" << std::endl; diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index 85d8a4e9d2..1a78dffd8f 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -11,14 +11,15 @@ void create_logic_gate(Composer& composer, { // auto accumulators = composer.create_logic_constraint(a, b, num_bits, is_xor_gate); // composer.assert_equal(accumulators.out.back(), result); - if (is_xor_gate) { - xor_gate(composer, a, b, result); - } else { - and_gate(composer, a, b, result); - } - - const size_t num_chunks = ((num_bits / 4) + (num_bits % 4 == 0)) ? 0 : 1; + // if (is_xor_gate) { + // xor_gate(composer, a, b, result); + // } else { + // and_gate(composer, a, b, result); + // } + std::cout << "num_bits = " << num_bits << std::endl; + const size_t num_chunks = (num_bits / 32) + ((num_bits % 32 == 0) ? 0 : 1); + std::cout << "num_chunks = " << num_chunks << std::endl; uint256_t left = composer.get_variable(a); uint256_t right = composer.get_variable(b); @@ -28,6 +29,8 @@ void create_logic_gate(Composer& composer, uint256_t left_chunk = left & ((uint256_t(1) << 32) - 1); uint256_t right_chunk = right & ((uint256_t(1) << 32) - 1); + std::cout << "left chunk = " << left_chunk << std::endl; + std::cout << "right chunk = " << right_chunk << std::endl; const field_ct a(&composer, left_chunk); const field_ct b(&composer, right_chunk); @@ -37,10 +40,14 @@ void create_logic_gate(Composer& composer, result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_XOR, a, b); } else { result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); - } + std::cout << "claimed result for AND = " << result_chunk << std::endl; + } + std::cout << "is xor = " << is_xor_gate << std::endl; + std::cout << "result chunk = " << result_chunk << std::endl; uint256_t scaling_factor = uint256_t(1) << (32 * i); + std::cout << "scaling_factor = " << scaling_factor << std::endl; res += result_chunk * scaling_factor; if (i == num_chunks - 1) @@ -48,8 +55,8 @@ void create_logic_gate(Composer& composer, const size_t final_num_bits = num_bits - (i * 32); if (final_num_bits != 32) { - composer.create_range_constraint(a.witness_index, final_num_bits, ""); - composer.create_range_constraint(b.witness_index, final_num_bits, ""); + composer.create_range_constraint(a.witness_index, final_num_bits, "bad range on a"); + composer.create_range_constraint(b.witness_index, final_num_bits, "bad range on b"); } } @@ -57,7 +64,14 @@ void create_logic_gate(Composer& composer, right = right >> 32; } - res.assert_equal(field_ct::from_witness_index(&composer, result)); + std::cout << "plookup res = " << res << std::endl; + auto our_res = field_ct::from_witness_index(&composer, result); + std::cout << "our res = " << our_res << std::endl; + res.assert_equal(our_res); + + std::cout << "composer fail = " << composer.failed() << std::endl; + std::cout << "composer err = " << composer.err() << std::endl; + } } // namespace acir_format diff --git a/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.cpp b/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.cpp index 76905d0753..ca69c95150 100644 --- a/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.cpp +++ b/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.cpp @@ -78,7 +78,7 @@ field_t plookup_::read_from_2_to_1_table(const MultiTableId { const auto lookup = get_lookup_accumulators(id, key_a, key_b, true); - return lookup[ColumnIdx::C2][0]; + return lookup[ColumnIdx::C3][0]; } template From 5472c56aceface2feaedd14ed872363fdf93f985 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Mon, 27 Mar 2023 21:15:45 +0100 Subject: [PATCH 15/46] test for logic gates passing --- .../dsl/acir_format/acir_format.test.cpp | 56 +++++++++++++++++++ .../dsl/acir_format/logic_constraint.cpp | 14 ++--- 2 files changed, 61 insertions(+), 9 deletions(-) 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 69505aa2fd..d3687713be 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -4,6 +4,62 @@ #include #include "barretenberg/common/streams.hpp" +TEST(acir_format, test_logic_gates) +{ + std::cout << "in the logic gate test" << std::endl; + + acir_format::LogicConstraint logic_constraint{ + .a = 8, + .b = 9, + .result = 7, + .num_bits = 32, + .is_xor_gate = 1, + }; + std::cout << "made struct" << std::endl; + + acir_format::acir_format constraint_system{ + .varnum = 12, + .public_inputs = {}, + .fixed_base_scalar_mul_constraints = {}, + .logic_constraints = { logic_constraint }, + .range_constraints = {}, + .schnorr_constraints = {}, + .ecdsa_constraints = {}, + .sha256_constraints = {}, + .blake2s_constraints = {}, + .hash_to_field_constraints = {}, + .pedersen_constraints = {}, + .merkle_membership_constraints = {}, + .constraints = {}, + }; + std::cout << "about to make some vals" << std::endl; + + uint256_t x = 5000000; + std::cout << "got 5000000 " << std::endl; + + // uint256_t y = uint256_t("a0000"); + uint256_t y = 0xa0000; + + uint256_t q = uint256_t("8AA49BCCC58DE750C8171A8595F2F4E71DADC04E079BC498EF70C5D0E21B36C"); + + uint256_t chunk_one = 0xFAF5FFFF; + uint256_t chunk_two = 0xFAFFFFFF; + uint256_t chunk_three = 0xFFF5FFFF; + uint256_t chunk_four = 0x509FFF6; + std::cout << "got some vals" << std::endl; + + auto composer = acir_format::create_circuit_with_witness( + constraint_system, { 5, 10, x, 0, y, 0, chunk_one, chunk_two, chunk_three, chunk_four, q, 1 }); + std::cout << "made composer" << std::endl; + + auto prover = composer.create_prover(); + auto proof = prover.construct_proof(); + + auto verifier = composer.create_verifier(); + + EXPECT_EQ(verifier.verify_proof(proof), true); +} + TEST(acir_format, test_schnorr_verify_pass) { std::vector range_constraints; diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index 1a78dffd8f..c75791a264 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -24,8 +24,9 @@ void create_logic_gate(Composer& composer, uint256_t right = composer.get_variable(b); field_ct res(&composer); - for (size_t i = 0; i < num_chunks; ++i) - { + for (size_t i = 0; i < num_chunks; ++i) { + std::cout << "left = " << left << std::endl; + std::cout << "right = " << right << std::endl; uint256_t left_chunk = left & ((uint256_t(1) << 32) - 1); uint256_t right_chunk = right & ((uint256_t(1) << 32) - 1); @@ -40,8 +41,6 @@ void create_logic_gate(Composer& composer, result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_XOR, a, b); } else { result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); - - std::cout << "claimed result for AND = " << result_chunk << std::endl; } std::cout << "is xor = " << is_xor_gate << std::endl; std::cout << "result chunk = " << result_chunk << std::endl; @@ -50,11 +49,9 @@ void create_logic_gate(Composer& composer, std::cout << "scaling_factor = " << scaling_factor << std::endl; res += result_chunk * scaling_factor; - if (i == num_chunks - 1) - { + if (i == num_chunks - 1) { const size_t final_num_bits = num_bits - (i * 32); - if (final_num_bits != 32) - { + if (final_num_bits != 32) { composer.create_range_constraint(a.witness_index, final_num_bits, "bad range on a"); composer.create_range_constraint(b.witness_index, final_num_bits, "bad range on b"); } @@ -71,7 +68,6 @@ void create_logic_gate(Composer& composer, std::cout << "composer fail = " << composer.failed() << std::endl; std::cout << "composer err = " << composer.err() << std::endl; - } } // namespace acir_format From ee6973b072494a8d25d1229b51c0b1409f894f6a Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Tue, 28 Mar 2023 11:21:54 +0100 Subject: [PATCH 16/46] last debug things XOR and AND returnign correct results, XOR still failing --- cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp | 6 +++--- cpp/src/barretenberg/plonk/composer/plookup_tables/uint.hpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index c75791a264..cd529a6633 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -38,7 +38,7 @@ void create_logic_gate(Composer& composer, field_ct result_chunk = 0; if (is_xor_gate) { - result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_XOR, a, b); + result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); } else { result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); } @@ -64,8 +64,8 @@ void create_logic_gate(Composer& composer, std::cout << "plookup res = " << res << std::endl; auto our_res = field_ct::from_witness_index(&composer, result); std::cout << "our res = " << our_res << std::endl; - res.assert_equal(our_res); - + // res.assert_equal(our_res); + (our_res + res); std::cout << "composer fail = " << composer.failed() << std::endl; std::cout << "composer err = " << composer.err() << std::endl; } diff --git a/cpp/src/barretenberg/plonk/composer/plookup_tables/uint.hpp b/cpp/src/barretenberg/plonk/composer/plookup_tables/uint.hpp index 41446d150b..05ccb4275e 100644 --- a/cpp/src/barretenberg/plonk/composer/plookup_tables/uint.hpp +++ b/cpp/src/barretenberg/plonk/composer/plookup_tables/uint.hpp @@ -64,7 +64,7 @@ inline BasicTable generate_and_rotate_table(BasicTableId id, const size_t table_ } } - table.get_values_from_key = &get_xor_rotate_values_from_key; + table.get_values_from_key = &get_and_rotate_values_from_key; table.column_1_step_size = base; table.column_2_step_size = base; From f031dd295cf47c29260965b14d28375c84d48b3f Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 28 Mar 2023 17:23:11 +0100 Subject: [PATCH 17/46] cleanup --- .../dsl/acir_format/acir_format.cpp | 3 --- .../dsl/acir_format/logic_constraint.cpp | 24 +------------------ 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 803bf2016f..8fb9c4496d 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -12,8 +12,6 @@ void read_witness(Composer& composer, std::vector witness) void create_circuit(Composer& composer, const acir_format& constraint_system) { - std::cout << "5" << std::endl; - if (constraint_system.public_inputs.size() > constraint_system.varnum) { std::cout << "too many public inputs!" << std::endl; } @@ -44,7 +42,6 @@ void create_circuit(Composer& composer, const acir_format& constraint_system) // Add range constraint for (const auto& constraint : constraint_system.range_constraints) { composer.create_range_constraint(constraint.witness, constraint.num_bits, ""); - // composer.decompose_into_default_range(constraint.witness, constraint.num_bits, 4, ""); } // Add sha256 constraints diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index cd529a6633..8840391fb9 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -2,6 +2,7 @@ namespace acir_format { +// TODO(maxim): This doesn't work correctly void create_logic_gate(Composer& composer, const uint32_t a, const uint32_t b, @@ -9,29 +10,14 @@ void create_logic_gate(Composer& composer, const size_t num_bits, const bool is_xor_gate) { - // auto accumulators = composer.create_logic_constraint(a, b, num_bits, is_xor_gate); - // composer.assert_equal(accumulators.out.back(), result); - // if (is_xor_gate) { - // xor_gate(composer, a, b, result); - // } else { - // and_gate(composer, a, b, result); - // } - std::cout << "num_bits = " << num_bits << std::endl; - const size_t num_chunks = (num_bits / 32) + ((num_bits % 32 == 0) ? 0 : 1); - std::cout << "num_chunks = " << num_chunks << std::endl; uint256_t left = composer.get_variable(a); uint256_t right = composer.get_variable(b); field_ct res(&composer); for (size_t i = 0; i < num_chunks; ++i) { - std::cout << "left = " << left << std::endl; - std::cout << "right = " << right << std::endl; - uint256_t left_chunk = left & ((uint256_t(1) << 32) - 1); uint256_t right_chunk = right & ((uint256_t(1) << 32) - 1); - std::cout << "left chunk = " << left_chunk << std::endl; - std::cout << "right chunk = " << right_chunk << std::endl; const field_ct a(&composer, left_chunk); const field_ct b(&composer, right_chunk); @@ -42,11 +28,8 @@ void create_logic_gate(Composer& composer, } else { result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); } - std::cout << "is xor = " << is_xor_gate << std::endl; - std::cout << "result chunk = " << result_chunk << std::endl; uint256_t scaling_factor = uint256_t(1) << (32 * i); - std::cout << "scaling_factor = " << scaling_factor << std::endl; res += result_chunk * scaling_factor; if (i == num_chunks - 1) { @@ -61,13 +44,8 @@ void create_logic_gate(Composer& composer, right = right >> 32; } - std::cout << "plookup res = " << res << std::endl; auto our_res = field_ct::from_witness_index(&composer, result); - std::cout << "our res = " << our_res << std::endl; - // res.assert_equal(our_res); (our_res + res); - std::cout << "composer fail = " << composer.failed() << std::endl; - std::cout << "composer err = " << composer.err() << std::endl; } } // namespace acir_format From 8a25d81ae1e192984f98eaa1c1161aa1fa4db98e Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 11:10:20 +0100 Subject: [PATCH 18/46] pedersen_plookup --- cpp/src/barretenberg/dsl/acir_format/pedersen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp b/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp index bb53c66ba1..371bf93ce5 100644 --- a/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp @@ -11,7 +11,7 @@ void create_pedersen_constraint(Composer& composer, const PedersenConstraint& in field_ct scalar_as_field = field_ct::from_witness_index(&composer, scalar); scalars.push_back(scalar_as_field); } - auto point = pedersen::commit(scalars); + auto point = stdlib::pedersen_plookup::commit(scalars); composer.assert_equal(point.x.witness_index, input.result_x); composer.assert_equal(point.y.witness_index, input.result_y); From 8f4a8aa6efe48b4ec291eed9687143766b97758b Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 11:17:58 +0100 Subject: [PATCH 19/46] plookup funcs --- .../barretenberg/crypto/pedersen/c_bind.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/cpp/src/barretenberg/crypto/pedersen/c_bind.cpp b/cpp/src/barretenberg/crypto/pedersen/c_bind.cpp index 8f8a9e6a74..320604d46b 100644 --- a/cpp/src/barretenberg/crypto/pedersen/c_bind.cpp +++ b/cpp/src/barretenberg/crypto/pedersen/c_bind.cpp @@ -1,5 +1,6 @@ #include "c_bind.hpp" #include "pedersen.hpp" +#include "pedersen_lookup.hpp" #include "barretenberg/common/serialize.hpp" #include "barretenberg/common/timer.hpp" #include "barretenberg/common/mem.hpp" @@ -21,6 +22,14 @@ WASM_EXPORT void pedersen__compress_fields(uint8_t const* left, uint8_t const* r barretenberg::fr::serialize_to_buffer(r, result); } +WASM_EXPORT void pedersen_plookup_compress_fields(uint8_t const* left, uint8_t const* right, uint8_t* result) +{ + auto lhs = barretenberg::fr::serialize_from_buffer(left); + auto rhs = barretenberg::fr::serialize_from_buffer(right); + auto r = crypto::pedersen::lookup::compress_native({ lhs, rhs }); + barretenberg::fr::serialize_to_buffer(r, result); +} + WASM_EXPORT void pedersen__compress(uint8_t const* inputs_buffer, uint8_t* output) { std::vector to_compress; @@ -29,6 +38,14 @@ WASM_EXPORT void pedersen__compress(uint8_t const* inputs_buffer, uint8_t* outpu barretenberg::fr::serialize_to_buffer(r, output); } +WASM_EXPORT void pedersen_plookup_compress(uint8_t const* inputs_buffer, uint8_t* output) +{ + std::vector to_compress; + read(inputs_buffer, to_compress); + auto r = crypto::pedersen::lookup::compress_native(to_compress); + barretenberg::fr::serialize_to_buffer(r, output); +} + WASM_EXPORT void pedersen__compress_with_hash_index(uint8_t const* inputs_buffer, uint8_t* output, uint32_t hash_index) { std::vector to_compress; @@ -46,6 +63,15 @@ WASM_EXPORT void pedersen__commit(uint8_t const* inputs_buffer, uint8_t* output) write(output, pedersen_hash); } +WASM_EXPORT void pedersen_plookup_commit(uint8_t const* inputs_buffer, uint8_t* output) +{ + std::vector to_compress; + read(inputs_buffer, to_compress); + grumpkin::g1::affine_element pedersen_hash = crypto::pedersen::lookup::commit_native(to_compress); + + write(output, pedersen_hash); +} + WASM_EXPORT void pedersen__buffer_to_field(uint8_t const* data, size_t length, uint8_t* r) { std::vector to_compress(data, data + length); From c51815ff301986559fa887e07c6a8dffbfb4e40c Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 11:21:02 +0100 Subject: [PATCH 20/46] add to header --- cpp/src/barretenberg/crypto/pedersen/c_bind.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpp/src/barretenberg/crypto/pedersen/c_bind.hpp b/cpp/src/barretenberg/crypto/pedersen/c_bind.hpp index 8e61135b9d..9b170cdd0b 100644 --- a/cpp/src/barretenberg/crypto/pedersen/c_bind.hpp +++ b/cpp/src/barretenberg/crypto/pedersen/c_bind.hpp @@ -9,12 +9,15 @@ extern "C" { WASM_EXPORT void pedersen__init(); WASM_EXPORT void pedersen__compress_fields(uint8_t const* left, uint8_t const* right, uint8_t* result); +WASM_EXPORT void pedersen_plookup_compress_fields(uint8_t const* left, uint8_t const* right, uint8_t* result); WASM_EXPORT void pedersen__compress(uint8_t const* inputs_buffer, uint8_t* output); +WASM_EXPORT void pedersen_plookup_compress(uint8_t const* inputs_buffer, uint8_t* output); WASM_EXPORT void pedersen__compress_with_hash_index(uint8_t const* inputs_buffer, uint8_t* output, uint32_t hash_index); WASM_EXPORT void pedersen__commit(uint8_t const* inputs_buffer, uint8_t* output); +WASM_EXPORT void pedersen_plookup_commit(uint8_t const* inputs_buffer, uint8_t* output); WASM_EXPORT void pedersen__buffer_to_field(uint8_t const* data, size_t length, uint8_t* r); From a28936823d26e2ee3e7ebf6c6d6ed6e78242db69 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 29 Mar 2023 12:07:07 +0000 Subject: [PATCH 21/46] fixed error in pedersen hash when RHS is a circuit constant --- cpp/src/barretenberg/stdlib/hash/pedersen/pedersen_plookup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen_plookup.cpp b/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen_plookup.cpp index 964f9e6371..f2f3d85148 100644 --- a/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen_plookup.cpp +++ b/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen_plookup.cpp @@ -54,7 +54,7 @@ template point pedersen_plookup::add_points(const point& p1, if (p1_constant || p2_constant) { field_t lambda = (p2.y - p1.y) / (p2.x - p1.x); field_t x_3 = lambda.madd(lambda, -(p2.x + p1.x)); - field_t y_3 = lambda.madd(p1.x - x_3, p1.y); + field_t y_3 = lambda.madd(p1.x - x_3, -p1.y); return point{ x_3, y_3 }; } From 343174ab7d7bcccbc1c2489ce2f36fade9a28688 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 29 Mar 2023 12:34:53 +0000 Subject: [PATCH 22/46] added ACIR test for XOR gate pedersen hash test now checks y coordinate --- .../dsl/acir_format/acir_format.test.cpp | 109 ++++++++++++++++++ .../stdlib/hash/pedersen/pedersen.test.cpp | 10 +- 2 files changed, 113 insertions(+), 6 deletions(-) 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 d3687713be..b5bec63263 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -4,6 +4,115 @@ #include #include "barretenberg/common/streams.hpp" +TEST(acir_format, test_logic_gate_from_noir_circuit) +{ + /** + * constraints produced by Noir program: + * fn main(x : u32, y : pub u32) { + * let z = x ^ y; + * + * constrain z != 10; + * } + **/ + acir_format::RangeConstraint range_a{ + .witness = 1, + .num_bits = 32, + }; + acir_format::RangeConstraint range_b{ + .witness = 2, + .num_bits = 32, + }; + + acir_format::LogicConstraint logic_constraint{ + .a = 1, + .b = 2, + .result = 3, + .num_bits = 32, + .is_xor_gate = 1, + }; + poly_triple expr_a{ + .a = 3, + .b = 4, + .c = 0, + .q_m = 0, + .q_l = 1, + .q_r = -1, + .q_o = 0, + .q_c = -10, + }; + poly_triple expr_b{ + .a = 4, + .b = 5, + .c = 6, + .q_m = 1, + .q_l = 0, + .q_r = 0, + .q_o = -1, + .q_c = 0, + }; + poly_triple expr_c{ + .a = 4, + .b = 6, + .c = 4, + .q_m = 1, + .q_l = 0, + .q_r = 0, + .q_o = -1, + .q_c = 0, + + }; + poly_triple expr_d{ + .a = 6, + .b = 0, + .c = 0, + .q_m = 0, + .q_l = -1, + .q_r = 0, + .q_o = 0, + .q_c = 1, + }; + // EXPR [ (1, _4, _5) (-1, _6) 0 ] + // EXPR [ (1, _4, _6) (-1, _4) 0 ] + // EXPR [ (-1, _6) 1 ] + std::cout << "made struct" << std::endl; + + acir_format::acir_format constraint_system{ + .varnum = 7, + .public_inputs = { 2 }, + .fixed_base_scalar_mul_constraints = {}, + .logic_constraints = { logic_constraint }, + .range_constraints = { range_a, range_b }, + .schnorr_constraints = {}, + .ecdsa_constraints = {}, + .sha256_constraints = {}, + .blake2s_constraints = {}, + .hash_to_field_constraints = {}, + .pedersen_constraints = {}, + .merkle_membership_constraints = {}, + .constraints = { expr_a, expr_b, expr_c, expr_d }, + }; + + uint256_t inverse_of_five = fr(5).invert(); + auto composer = acir_format::create_circuit_with_witness(constraint_system, + { + 5, + 10, + 15, + 5, + inverse_of_five, + 1, + }); + + std::cout << "made composer" << std::endl; + + auto prover = composer.create_prover(); + auto proof = prover.construct_proof(); + + auto verifier = composer.create_verifier(); + + EXPECT_EQ(verifier.verify_proof(proof), true); +} + TEST(acir_format, test_logic_gates) { std::cout << "in the logic gate test" << std::endl; diff --git a/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen.test.cpp b/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen.test.cpp index 9dc474f3ad..238035b7c0 100644 --- a/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen.test.cpp +++ b/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen.test.cpp @@ -515,21 +515,19 @@ TEST(stdlib_pedersen, test_merkle_damgard_compress_plookup) { plonk::UltraComposer composer = plonk::UltraComposer(); - std::vector input_values{ - fr::random_element(), fr::random_element(), fr::random_element(), - fr::random_element(), fr::random_element(), fr::random_element(), - }; + std::vector input_values{ 0, 1 }; std::vector inputs; for (const auto& input : input_values) { inputs.emplace_back(witness_ct(&composer, input)); } field_ct iv = witness_ct(&composer, fr(10)); - field_ct result = stdlib::pedersen_plookup::merkle_damgard_compress(inputs, iv).x; + auto result = stdlib::pedersen_plookup::merkle_damgard_compress(inputs, iv); auto expected = crypto::pedersen::lookup::merkle_damgard_compress(input_values, 10); - EXPECT_EQ(result.get_value(), expected.normalize().x); + EXPECT_EQ(result.x.get_value(), expected.normalize().x); + EXPECT_EQ(result.y.get_value(), expected.normalize().y); auto prover = composer.create_prover(); From 12589955d57020b1c0f2a00d2da25971bba60c54 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 14:31:35 +0100 Subject: [PATCH 23/46] temp disable wasm-opt --- cpp/src/CMakeLists.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index 6802f1c004..96db3412e8 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -105,18 +105,18 @@ if(WASM) -nostartfiles -O2 -Wl,--no-entry -Wl,--export-dynamic -Wl,--import-memory -Wl,--allow-undefined -Wl,--stack-first -Wl,-z,stack-size=1048576 ) - find_program(WASM_OPT wasm-opt) - - if(NOT WASM_OPT) - message(FATAL_ERROR "wasm-opt executable not found. Please install binaryen.") - endif() - - add_custom_command( - TARGET barretenberg.wasm - POST_BUILD - COMMAND wasm-opt "$" -O2 --asyncify -o "$" - VERBATIM - ) + # find_program(WASM_OPT wasm-opt) + + # if(NOT WASM_OPT) + # message(FATAL_ERROR "wasm-opt executable not found. Please install binaryen.") + # endif() + + # add_custom_command( + # TARGET barretenberg.wasm + # POST_BUILD + # COMMAND wasm-opt "$" -O2 --asyncify -o "$" + # VERBATIM + # ) if(INSTALL_BARRETENBERG) install(TARGETS barretenberg.wasm DESTINATION ${CMAKE_INSTALL_BINDIR}) From 016ba39eb0b5098f09f993e77cf9a65e5967bd29 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 16:52:26 +0100 Subject: [PATCH 24/46] Making everything compile with any composer & add a cmake flag to switch on turbo --- cpp/CMakeLists.txt | 8 ++ .../dsl/acir_format/logic_constraint.cpp | 78 ++++++++++--------- .../barretenberg/dsl/acir_format/pedersen.cpp | 4 + .../dsl/acir_proofs/acir_proofs.cpp | 15 +--- .../proofs/join_split/c_bind.cpp | 2 +- .../proofs/join_split/join_split.cpp | 4 +- .../proofs/join_split/join_split.hpp | 2 +- .../plonk/composer/composer_base.hpp | 1 + .../plonk/composer/ultra_composer.hpp | 14 ++++ .../plonk/proof_system/constants.hpp | 4 + .../stdlib/hash/sha256/sha256.bench.cpp | 6 +- 11 files changed, 82 insertions(+), 56 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 3b5d8dd016..b978b04d53 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -20,6 +20,14 @@ option(DISABLE_TBB "Intel Thread Building Blocks" ON) option(COVERAGE "Enable collecting coverage from tests" OFF) option(ENABLE_HEAVY_TESTS "Enable heavy tests when collecting coverage" OFF) option(INSTALL_BARRETENBERG "Enable installation of barretenberg. (Projects embedding barretenberg may want to turn this OFF.)" ON) +option(USE_TURBO "Enable the use of TurboPlonk in barretenberg." OFF) + +if(USE_TURBO) + message(STATUS "Building barretenberg for TurboPlonk Composer.") + add_definitions(-DUSE_TURBO) +else() + message(STATUS "Building barretenberg for UltraPlonk Composer.") +endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") message(STATUS "Compiling for ARM.") diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index 8840391fb9..ef279cc6b8 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -10,42 +10,48 @@ void create_logic_gate(Composer& composer, const size_t num_bits, const bool is_xor_gate) { - const size_t num_chunks = (num_bits / 32) + ((num_bits % 32 == 0) ? 0 : 1); - uint256_t left = composer.get_variable(a); - uint256_t right = composer.get_variable(b); - - field_ct res(&composer); - for (size_t i = 0; i < num_chunks; ++i) { - uint256_t left_chunk = left & ((uint256_t(1) << 32) - 1); - uint256_t right_chunk = right & ((uint256_t(1) << 32) - 1); - - const field_ct a(&composer, left_chunk); - const field_ct b(&composer, right_chunk); - - field_ct result_chunk = 0; - if (is_xor_gate) { - result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); - } else { - result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); - } - - uint256_t scaling_factor = uint256_t(1) << (32 * i); - res += result_chunk * scaling_factor; - - if (i == num_chunks - 1) { - const size_t final_num_bits = num_bits - (i * 32); - if (final_num_bits != 32) { - composer.create_range_constraint(a.witness_index, final_num_bits, "bad range on a"); - composer.create_range_constraint(b.witness_index, final_num_bits, "bad range on b"); - } - } - - left = left >> 32; - right = right >> 32; - } - - auto our_res = field_ct::from_witness_index(&composer, result); - (our_res + res); + (void)composer; + (void)a; + (void)b; + (void)result; + (void)num_bits; + (void)is_xor_gate; + // const size_t num_chunks = (num_bits / 32) + ((num_bits % 32 == 0) ? 0 : 1); + // uint256_t left = composer.get_variable(a); + // uint256_t right = composer.get_variable(b); + + // field_ct res(&composer); + // for (size_t i = 0; i < num_chunks; ++i) { + // uint256_t left_chunk = left & ((uint256_t(1) << 32) - 1); + // uint256_t right_chunk = right & ((uint256_t(1) << 32) - 1); + + // const field_ct a(&composer, left_chunk); + // const field_ct b(&composer, right_chunk); + + // field_ct result_chunk = 0; + // if (is_xor_gate) { + // result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); + // } else { + // result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); + // } + + // uint256_t scaling_factor = uint256_t(1) << (32 * i); + // res += result_chunk * scaling_factor; + + // if (i == num_chunks - 1) { + // const size_t final_num_bits = num_bits - (i * 32); + // if (final_num_bits != 32) { + // composer.create_range_constraint(a.witness_index, final_num_bits, "bad range on a"); + // composer.create_range_constraint(b.witness_index, final_num_bits, "bad range on b"); + // } + // } + + // left = left >> 32; + // right = right >> 32; + // } + + // auto our_res = field_ct::from_witness_index(&composer, result); + // (our_res + res); } } // namespace acir_format diff --git a/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp b/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp index 371bf93ce5..10f1ac10f5 100644 --- a/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp @@ -11,7 +11,11 @@ void create_pedersen_constraint(Composer& composer, const PedersenConstraint& in field_ct scalar_as_field = field_ct::from_witness_index(&composer, scalar); scalars.push_back(scalar_as_field); } +#ifdef USE_TURBO + auto point = pedersen::commit(scalars); +#else auto point = stdlib::pedersen_plookup::commit(scalars); +#endif composer.assert_equal(point.x.witness_index, input.result_x); composer.assert_equal(point.y.witness_index, input.result_y); diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp index 524e0b3731..4a2f9b47cb 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp @@ -44,18 +44,7 @@ uint32_t get_total_circuit_size(uint8_t const* constraint_system_buf) auto crs_factory = std::make_unique(); auto composer = create_circuit(constraint_system, std::move(crs_factory)); - size_t tables_size = 0; - size_t lookups_size = 0; - for (const auto& table : composer.lookup_tables) { - tables_size += table.size; - lookups_size += table.lookup_gates.size(); - } - - auto minimum_circuit_size = tables_size + lookups_size; - auto num_filled_gates = composer.get_num_gates() + composer.public_inputs.size(); - const size_t total_num_gates = std::max(minimum_circuit_size, num_filled_gates); - - return static_cast(total_num_gates); + return static_cast(composer.get_total_circuit_size()); } size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf) @@ -129,7 +118,7 @@ size_t new_proof(void* pippenger, auto prover = composer.create_prover(); - auto heapProver = new UltraProver(std::move(prover)); + auto heapProver = new stdlib::types::Prover(std::move(prover)); auto& proof_data = heapProver->construct_proof().proof_data; *proof_data_buf = proof_data.data(); diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp index 0a8f0c95a4..4fb767f1cd 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp @@ -93,7 +93,7 @@ WASM_EXPORT void* join_split__new_prover(uint8_t const* join_split_buf, bool moc { auto tx = from_buffer(join_split_buf); auto prover = new_join_split_prover(tx, mock); - auto heapProver = new plonk::UltraProver(std::move(prover)); + auto heapProver = new stdlib::types::Prover(std::move(prover)); return heapProver; } diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp index c5737ce168..e4b4e71d53 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp @@ -23,7 +23,7 @@ void init_proving_key(std::shared_ptr const& crs_f join_split_tx tx = noop_tx(); if (!mock) { - Composer composer(crs_factory); + stdlib::types::Composer composer(crs_factory); join_split_circuit(composer, tx); proving_key = composer.compute_proving_key(); } else { @@ -64,7 +64,7 @@ void init_verification_key(std::shared_ptr con verification_key = std::make_shared(std::move(vk_data), crs); } -plonk::UltraProver new_join_split_prover(join_split_tx const& tx, bool mock) +stdlib::types::Prover new_join_split_prover(join_split_tx const& tx, bool mock) { Composer composer(proving_key, nullptr); join_split_circuit(composer, tx); diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp index 5ed4cd3c38..e4fe781700 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp @@ -21,7 +21,7 @@ void init_verification_key(std::unique_ptr&& crs_f void init_verification_key(std::shared_ptr const& crs, bonk::verification_key_data&& vk_data); -plonk::UltraProver new_join_split_prover(join_split_tx const& tx, bool mock); +stdlib::types::Prover new_join_split_prover(join_split_tx const& tx, bool mock); bool verify_proof(plonk::proof const& proof); diff --git a/cpp/src/barretenberg/plonk/composer/composer_base.hpp b/cpp/src/barretenberg/plonk/composer/composer_base.hpp index cbee5892e3..d46017a1fa 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_base.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_base.hpp @@ -107,6 +107,7 @@ class ComposerBase { virtual ~ComposerBase(){}; virtual size_t get_num_gates() const { return num_gates; } + virtual size_t get_total_circuit_size() const { return num_gates; }; virtual void print_num_gates() const { std::cout << num_gates << std::endl; } virtual size_t get_num_variables() const { return variables.size(); } virtual std::shared_ptr compute_proving_key_base(const ComposerType type = STANDARD, diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp index 97c19cc77d..769ec09a34 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp @@ -342,6 +342,20 @@ class UltraComposer : public ComposerBase { return count + romcount + ramcount + rangecount; } + virtual size_t get_total_circuit_size() const override + { + size_t tables_size = 0; + size_t lookups_size = 0; + for (const auto& table : lookup_tables) { + tables_size += table.size; + lookups_size += table.lookup_gates.size(); + } + + auto minimum_circuit_size = tables_size + lookups_size; + auto num_filled_gates = num_gates + public_inputs.size(); + return std::max(minimum_circuit_size, num_filled_gates); + } + virtual void print_num_gates() const override { size_t count = 0; diff --git a/cpp/src/barretenberg/plonk/proof_system/constants.hpp b/cpp/src/barretenberg/plonk/proof_system/constants.hpp index eaf3c24b73..f919f636cf 100644 --- a/cpp/src/barretenberg/plonk/proof_system/constants.hpp +++ b/cpp/src/barretenberg/plonk/proof_system/constants.hpp @@ -13,7 +13,11 @@ enum ComposerType { // This variable sets the composer (TURBO or ULTRA) of the entire stdlib and rollup modules. // To switch to using a new composer, only changing this variable should activate the new composer // throughout the stdlib and circuits. +#ifdef USE_TURBO +static constexpr uint32_t SYSTEM_COMPOSER = ComposerType::TURBO; +#else static constexpr uint32_t SYSTEM_COMPOSER = ComposerType::PLOOKUP; +#endif enum MerkleHashType { FIXED_BASE_PEDERSEN, diff --git a/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp b/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp index 31ffb1e9df..00d00082e1 100644 --- a/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp +++ b/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp @@ -28,9 +28,9 @@ void generate_test_plonk_circuit(Composer& composer, size_t num_bytes) plonk::stdlib::sha256(input); } -Composer composers[NUM_HASHES]; -plonk::UltraProver provers[NUM_HASHES]; -plonk::UltraVerifier verifiers[NUM_HASHES]; +stdlib::types::Composer composers[NUM_HASHES]; +stdlib::types::Prover provers[NUM_HASHES]; +stdlib::types::Verifier verifiers[NUM_HASHES]; plonk::proof proofs[NUM_HASHES]; void construct_witnesses_bench(State& state) noexcept From c0cf208c707bed304fb7aac0450a22b5cc5191d5 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 16:57:59 +0100 Subject: [PATCH 25/46] enable wasm-opt for asyncify but disable optimizations --- cpp/src/CMakeLists.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index 96db3412e8..fc931844a6 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -105,18 +105,18 @@ if(WASM) -nostartfiles -O2 -Wl,--no-entry -Wl,--export-dynamic -Wl,--import-memory -Wl,--allow-undefined -Wl,--stack-first -Wl,-z,stack-size=1048576 ) - # find_program(WASM_OPT wasm-opt) - - # if(NOT WASM_OPT) - # message(FATAL_ERROR "wasm-opt executable not found. Please install binaryen.") - # endif() - - # add_custom_command( - # TARGET barretenberg.wasm - # POST_BUILD - # COMMAND wasm-opt "$" -O2 --asyncify -o "$" - # VERBATIM - # ) + find_program(WASM_OPT wasm-opt) + + if(NOT WASM_OPT) + message(FATAL_ERROR "wasm-opt executable not found. Please install binaryen.") + endif() + + add_custom_command( + TARGET barretenberg.wasm + POST_BUILD + COMMAND wasm-opt "$" -O0 --asyncify -o "$" + VERBATIM + ) if(INSTALL_BARRETENBERG) install(TARGETS barretenberg.wasm DESTINATION ${CMAKE_INSTALL_BINDIR}) From 75fe80c80518a54386d67b08328165924e759723 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 16:59:51 +0100 Subject: [PATCH 26/46] remove using in header --- cpp/src/barretenberg/dsl/acir_format/acir_format.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index d0d8d18075..5cfa9ecb56 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -11,8 +11,6 @@ #include "hash_to_field.hpp" #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { struct acir_format { From 840360c896ad91afa11c0cb10778116f466f8530 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 29 Mar 2023 17:00:54 +0000 Subject: [PATCH 27/46] fixed work queue bug with wasm wasm code path was not correctly storing fft outputs in proving key --- .../proof_system/work_queue/work_queue.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/cpp/src/barretenberg/proof_system/work_queue/work_queue.cpp b/cpp/src/barretenberg/proof_system/work_queue/work_queue.cpp index a6e2569cd5..ef8e51616b 100644 --- a/cpp/src/barretenberg/proof_system/work_queue/work_queue.cpp +++ b/cpp/src/barretenberg/proof_system/work_queue/work_queue.cpp @@ -247,18 +247,23 @@ void work_queue::process_queue() using namespace barretenberg; const size_t n = key->circuit_size; polynomial& wire = key->polynomial_store.get(item.tag); - polynomial wire_fft(4 * n + 4); polynomial wire_copy(wire, n); wire_copy.coset_fft_with_generator_shift(key->small_domain, item.constant); - for (size_t i = 0; i < n; ++i) { - wire_fft[4 * i + item.index] = wire_copy[i]; + if (item.index != 0) { + polynomial& old_wire_fft = key->polynomial_store.get(item.tag + "_fft"); + for (size_t i = 0; i < n; ++i) { + old_wire_fft[4 * i + item.index] = wire_copy[i]; + } + old_wire_fft[4 * n + item.index] = wire_copy[0]; + } else { + polynomial wire_fft(4 * n + 4); + for (size_t i = 0; i < n; ++i) { + wire_fft[4 * i + item.index] = wire_copy[i]; + } + key->polynomial_store.put(item.tag + "_fft", std::move(wire_fft)); } - wire_fft[4 * n + item.index] = wire_copy[0]; - - key->polynomial_store.put(item.tag + "_fft", 4 * n + 4); - break; } case WorkType::FFT: { From 952e2afc89ef7e15f7aae93c69ddbeff5e0e6a42 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 29 Mar 2023 17:01:33 +0000 Subject: [PATCH 28/46] added bitwise logic operations into stdlib stdlib method is utility method to provide Composer-agnostic interface due to the use of plookup tables if enabled --- .../stdlib/primitives/logic/logic.cpp | 94 ++++++++++++++++ .../stdlib/primitives/logic/logic.hpp | 22 ++++ .../stdlib/primitives/logic/logic.test.cpp | 101 ++++++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 cpp/src/barretenberg/stdlib/primitives/logic/logic.cpp create mode 100644 cpp/src/barretenberg/stdlib/primitives/logic/logic.hpp create mode 100644 cpp/src/barretenberg/stdlib/primitives/logic/logic.test.cpp diff --git a/cpp/src/barretenberg/stdlib/primitives/logic/logic.cpp b/cpp/src/barretenberg/stdlib/primitives/logic/logic.cpp new file mode 100644 index 0000000000..7a376636c1 --- /dev/null +++ b/cpp/src/barretenberg/stdlib/primitives/logic/logic.cpp @@ -0,0 +1,94 @@ +#include "logic.hpp" + +#include "../composers/composers.hpp" +#include "../plookup/plookup.hpp" + +namespace plonk { +namespace stdlib { + +/** + * @brief Constrants a logical AND or XOR over a variable number of bits. + * + * Defaults to basic Composer method if not using plookup-compatible composer + * + * @tparam Composer + * @param a + * @param b + * @param num_bits + * @param is_xor_gate + * @return field_t + */ +template +field_t logic::create_logic_constraint(field_pt& a, field_pt& b, size_t num_bits, bool is_xor_gate) +{ + // can't extend past field size! + ASSERT(num_bits < 254); + if (a.is_constant() && b.is_constant()) { + uint256_t a_native(a.get_value()); + uint256_t b_native(b.get_value()); + uint256_t c_native = is_xor_gate ? (a_native ^ b_native) : (a_native & b_native); + return field_t(c_native); + } + if (a.is_constant() && !b.is_constant()) { + Composer* ctx = b.get_context(); + uint256_t a_native(a.get_value()); + field_t a_witness = field_pt::from_witness_index(ctx, ctx->put_constant_variable(a_native)); + return create_logic_constraint(a_witness, b, num_bits, is_xor_gate); + } + if (!a.is_constant() && b.is_constant()) { + Composer* ctx = a.get_context(); + uint256_t b_native(b.get_value()); + field_pt b_witness = field_pt::from_witness_index(ctx, ctx->put_constant_variable(b_native)); + return create_logic_constraint(a, b_witness, num_bits, is_xor_gate); + } + if constexpr (Composer::type == ComposerType::PLOOKUP) { + Composer* ctx = a.get_context(); + + const size_t num_chunks = (num_bits / 32) + ((num_bits % 32 == 0) ? 0 : 1); + uint256_t left(a.get_value()); + uint256_t right(b.get_value()); + + field_pt res(ctx, 0); + for (size_t i = 0; i < num_chunks; ++i) { + uint256_t left_chunk = left & ((uint256_t(1) << 32) - 1); + uint256_t right_chunk = right & ((uint256_t(1) << 32) - 1); + + const field_pt a_chunk = witness_pt(ctx, left_chunk); + const field_pt b_chunk = witness_pt(ctx, right_chunk); + + field_pt result_chunk = 0; + if (is_xor_gate) { + result_chunk = + stdlib::plookup_read::read_from_2_to_1_table(plookup::MultiTableId::UINT32_XOR, a_chunk, b_chunk); + } else { + result_chunk = + stdlib::plookup_read::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a_chunk, b_chunk); + } + + uint256_t scaling_factor = uint256_t(1) << (32 * i); + res += result_chunk * scaling_factor; + + if (i == num_chunks - 1) { + const size_t final_num_bits = num_bits - (i * 32); + if (final_num_bits != 32) { + ctx->create_range_constraint(a_chunk.witness_index, final_num_bits, "bad range on a"); + ctx->create_range_constraint(b_chunk.witness_index, final_num_bits, "bad range on b"); + } + } + + left = left >> 32; + right = right >> 32; + } + + return res; + } else { + Composer* ctx = a.get_context(); + auto accumulator_triple = ctx->create_logic_constraint( + a.normalize().get_witness_index(), b.normalize().get_witness_index(), num_bits, is_xor_gate); + auto out_idx = accumulator_triple.out[accumulator_triple.out.size() - 1]; + return field_t::from_witness_index(ctx, out_idx); + } +} +INSTANTIATE_STDLIB_TYPE(logic); +} // namespace stdlib +} // namespace plonk diff --git a/cpp/src/barretenberg/stdlib/primitives/logic/logic.hpp b/cpp/src/barretenberg/stdlib/primitives/logic/logic.hpp new file mode 100644 index 0000000000..f359fbdff1 --- /dev/null +++ b/cpp/src/barretenberg/stdlib/primitives/logic/logic.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "../composers/composers_fwd.hpp" +#include "../field/field.hpp" + +namespace plonk { +namespace stdlib { + +// A runtime-defined read-only memory table. Table entries must be initialized in the constructor. +// N.B. Only works with the UltraComposer at the moment! +template class logic { + private: + typedef field_t field_pt; + typedef witness_t witness_pt; + + public: + static field_pt create_logic_constraint(field_pt& a, field_pt& b, size_t num_bits, bool is_xor_gate); +}; + +EXTERN_STDLIB_TYPE(logic); + +} // namespace stdlib +} // namespace plonk \ No newline at end of file diff --git a/cpp/src/barretenberg/stdlib/primitives/logic/logic.test.cpp b/cpp/src/barretenberg/stdlib/primitives/logic/logic.test.cpp new file mode 100644 index 0000000000..36f0384d2d --- /dev/null +++ b/cpp/src/barretenberg/stdlib/primitives/logic/logic.test.cpp @@ -0,0 +1,101 @@ +#include "../bool/bool.hpp" +#include "logic.hpp" +#include "barretenberg/plonk/proof_system/constants.hpp" +#include +#include "barretenberg/honk/composer/standard_honk_composer.hpp" +#include "barretenberg/plonk/composer/standard_composer.hpp" +#include "barretenberg/plonk/composer/ultra_composer.hpp" +#include "barretenberg/plonk/composer/turbo_composer.hpp" +#include "barretenberg/numeric/random/engine.hpp" + +using namespace bonk; + +namespace test_stdlib_logic { + +namespace { +auto& engine = numeric::random::get_debug_engine(); +} + +template void ignore_unused(T&) {} // use to ignore unused variables in lambdas + +using namespace barretenberg; +using namespace plonk; + +template class stdlib_logic : public testing::Test { + typedef stdlib::bool_t bool_ct; + typedef stdlib::field_t field_ct; + typedef stdlib::witness_t witness_ct; + typedef stdlib::public_witness_t public_witness_ct; + + public: + /** + * @brief Test logic + */ + static void test_logic() + { + Composer composer; + auto run_test = [&](size_t num_bits) { + uint256_t mask = (uint256_t(1) << num_bits) - 1; + + uint256_t a = engine.get_random_uint256() & mask; + uint256_t b = engine.get_random_uint256() & mask; + + uint256_t and_expected = a & b; + uint256_t xor_expected = a ^ b; + + field_ct x = witness_ct(&composer, a); + field_ct y = witness_ct(&composer, b); + + field_ct x_const(&composer, a); + field_ct y_const(&composer, b); + field_ct and_result = stdlib::logic::create_logic_constraint(x, y, num_bits, false); + field_ct xor_result = stdlib::logic::create_logic_constraint(x, y, num_bits, true); + + field_ct and_result_left_constant = + stdlib::logic::create_logic_constraint(x_const, y, num_bits, false); + field_ct xor_result_left_constant = + stdlib::logic::create_logic_constraint(x_const, y, num_bits, true); + + field_ct and_result_right_constant = + stdlib::logic::create_logic_constraint(x, y_const, num_bits, false); + field_ct xor_result_right_constant = + stdlib::logic::create_logic_constraint(x, y_const, num_bits, true); + + field_ct and_result_both_constant = + stdlib::logic::create_logic_constraint(x_const, y_const, num_bits, false); + field_ct xor_result_both_constant = + stdlib::logic::create_logic_constraint(x_const, y_const, num_bits, true); + + EXPECT_EQ(uint256_t(and_result.get_value()), and_expected); + EXPECT_EQ(uint256_t(and_result_left_constant.get_value()), and_expected); + EXPECT_EQ(uint256_t(and_result_right_constant.get_value()), and_expected); + EXPECT_EQ(uint256_t(and_result_both_constant.get_value()), and_expected); + + EXPECT_EQ(uint256_t(xor_result.get_value()), xor_expected); + EXPECT_EQ(uint256_t(xor_result_left_constant.get_value()), xor_expected); + EXPECT_EQ(uint256_t(xor_result_right_constant.get_value()), xor_expected); + EXPECT_EQ(uint256_t(xor_result_both_constant.get_value()), xor_expected); + }; + + for (size_t i = 8; i < 248; i += 8) { + run_test(i); + } + auto prover = composer.create_prover(); + plonk::proof proof = prover.construct_proof(); + auto verifier = composer.create_verifier(); + bool result = verifier.verify_proof(proof); + + EXPECT_EQ(result, true); + } +}; + +typedef testing::Types + ComposerTypes; + +TYPED_TEST_SUITE(stdlib_logic, ComposerTypes); + +TYPED_TEST(stdlib_logic, test_logic) +{ + TestFixture::test_logic(); +} +} // namespace test_stdlib_logic \ No newline at end of file From 592514e533d7aaf20f5631b3a2dfa38ea61c9c9c Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 29 Mar 2023 17:02:19 +0000 Subject: [PATCH 29/46] updated acir_format to use new stdlib logic class Updated ReadMe to include wasm example that supports gtest filtering --- README.md | 9 +++ .../dsl/acir_format/acir_format.test.cpp | 56 ------------------- .../dsl/acir_format/logic_constraint.cpp | 41 +++----------- 3 files changed, 16 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 2be12b4834..802392f5fc 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,12 @@ cmake --build --preset wasm --target ecc_tests wasmtime --dir=.. ./bin/ecc_tests ``` +To add gtest filter parameters in a wasm context: + +``` +wasmtime --dir=.. ./bin/ecc_tests run --gtest_filter=filtertext +``` + ### Fuzzing build For detailed instructions look in cpp/docs/Fuzzing.md @@ -160,11 +166,13 @@ cmake --build --preset coverage ``` Then run tests (on the mainframe always use taskset and nice to limit your influence on the server. Profiling instrumentation is very heavy): + ``` taskset 0xffffff nice -n10 make test ``` And generate report: + ``` make create_full_coverage_report ``` @@ -174,4 +182,5 @@ The report will land in the build directory in the all_test_coverage_report dire Alternatively you can build separate test binaries, e.g. honk_tests or numeric_tests and run **make test** just for them or even just for a single test. Then the report will just show coverage for those binaries. ### VS Code configuration + A default configuration for VS Code is provided by the file [`barretenberg.code-workspace`](barretenberg.code-workspace). These settings can be overridden by placing configuration files in `.vscode/`. 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 b5bec63263..ff957c6b9b 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -113,62 +113,6 @@ TEST(acir_format, test_logic_gate_from_noir_circuit) EXPECT_EQ(verifier.verify_proof(proof), true); } -TEST(acir_format, test_logic_gates) -{ - std::cout << "in the logic gate test" << std::endl; - - acir_format::LogicConstraint logic_constraint{ - .a = 8, - .b = 9, - .result = 7, - .num_bits = 32, - .is_xor_gate = 1, - }; - std::cout << "made struct" << std::endl; - - acir_format::acir_format constraint_system{ - .varnum = 12, - .public_inputs = {}, - .fixed_base_scalar_mul_constraints = {}, - .logic_constraints = { logic_constraint }, - .range_constraints = {}, - .schnorr_constraints = {}, - .ecdsa_constraints = {}, - .sha256_constraints = {}, - .blake2s_constraints = {}, - .hash_to_field_constraints = {}, - .pedersen_constraints = {}, - .merkle_membership_constraints = {}, - .constraints = {}, - }; - std::cout << "about to make some vals" << std::endl; - - uint256_t x = 5000000; - std::cout << "got 5000000 " << std::endl; - - // uint256_t y = uint256_t("a0000"); - uint256_t y = 0xa0000; - - uint256_t q = uint256_t("8AA49BCCC58DE750C8171A8595F2F4E71DADC04E079BC498EF70C5D0E21B36C"); - - uint256_t chunk_one = 0xFAF5FFFF; - uint256_t chunk_two = 0xFAFFFFFF; - uint256_t chunk_three = 0xFFF5FFFF; - uint256_t chunk_four = 0x509FFF6; - std::cout << "got some vals" << std::endl; - - auto composer = acir_format::create_circuit_with_witness( - constraint_system, { 5, 10, x, 0, y, 0, chunk_one, chunk_two, chunk_three, chunk_four, q, 1 }); - std::cout << "made composer" << std::endl; - - auto prover = composer.create_prover(); - auto proof = prover.construct_proof(); - - auto verifier = composer.create_verifier(); - - EXPECT_EQ(verifier.verify_proof(proof), true); -} - TEST(acir_format, test_schnorr_verify_pass) { std::vector range_constraints; diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index 8840391fb9..1490178a41 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -1,5 +1,7 @@ #include "logic_constraint.hpp" +#include "barretenberg/stdlib/primitives/logic/logic.hpp" + namespace acir_format { // TODO(maxim): This doesn't work correctly @@ -10,42 +12,13 @@ void create_logic_gate(Composer& composer, const size_t num_bits, const bool is_xor_gate) { - const size_t num_chunks = (num_bits / 32) + ((num_bits % 32 == 0) ? 0 : 1); - uint256_t left = composer.get_variable(a); - uint256_t right = composer.get_variable(b); - - field_ct res(&composer); - for (size_t i = 0; i < num_chunks; ++i) { - uint256_t left_chunk = left & ((uint256_t(1) << 32) - 1); - uint256_t right_chunk = right & ((uint256_t(1) << 32) - 1); - - const field_ct a(&composer, left_chunk); - const field_ct b(&composer, right_chunk); - - field_ct result_chunk = 0; - if (is_xor_gate) { - result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); - } else { - result_chunk = plookup_read_ct::read_from_2_to_1_table(plookup::MultiTableId::UINT32_AND, a, b); - } - - uint256_t scaling_factor = uint256_t(1) << (32 * i); - res += result_chunk * scaling_factor; - - if (i == num_chunks - 1) { - const size_t final_num_bits = num_bits - (i * 32); - if (final_num_bits != 32) { - composer.create_range_constraint(a.witness_index, final_num_bits, "bad range on a"); - composer.create_range_constraint(b.witness_index, final_num_bits, "bad range on b"); - } - } - left = left >> 32; - right = right >> 32; - } + field_ct left = field_ct::from_witness_index(&composer, a); + field_ct right = field_ct::from_witness_index(&composer, b); - auto our_res = field_ct::from_witness_index(&composer, result); - (our_res + res); + field_ct res = stdlib::logic::create_logic_constraint(left, right, num_bits, is_xor_gate); + field_ct our_res = field_ct::from_witness_index(&composer, result); + res.assert_equal(our_res); } } // namespace acir_format From 8f335a50ad032ac8f4990d73dc9c415bde622e20 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 17:29:47 +0100 Subject: [PATCH 30/46] reenable tests --- .../polynomial_store.test.cpp | 39 +- .../stdlib/primitives/uint/uint.test.cpp | 4282 ++++++++--------- 2 files changed, 2160 insertions(+), 2161 deletions(-) diff --git a/cpp/src/barretenberg/proof_system/polynomial_store/polynomial_store.test.cpp b/cpp/src/barretenberg/proof_system/polynomial_store/polynomial_store.test.cpp index 59deb6e275..f0486cccbf 100644 --- a/cpp/src/barretenberg/proof_system/polynomial_store/polynomial_store.test.cpp +++ b/cpp/src/barretenberg/proof_system/polynomial_store/polynomial_store.test.cpp @@ -91,25 +91,24 @@ TEST(PolynomialStore, Remove) } // Check that PolynomialStore supports range based for loop -// TODO fatal error: no member named 'ranges' in namespace 'std' -// TEST(PolynomialStore, RangeBasedFor) -// { -// PolynomialStore polynomial_store; -// size_t size = 100; -// Polynomial poly1(size); -// Polynomial poly2(size); - -// polynomial_store.put("id_1", std::move(poly1)); -// polynomial_store.put("id_2", std::move(poly2)); - -// // Check that PolynomialStore meets criteria for std::ranges::range -// EXPECT_TRUE(std::ranges::range>); - -// // For example ... -// Polynomial polynomial_sum(size); -// for (const auto& [key, polynomial] : polynomial_store) { -// polynomial_sum += polynomial; -// } -// } +TEST(PolynomialStore, RangeBasedFor) +{ + PolynomialStore polynomial_store; + size_t size = 100; + Polynomial poly1(size); + Polynomial poly2(size); + + polynomial_store.put("id_1", std::move(poly1)); + polynomial_store.put("id_2", std::move(poly2)); + + // Check that PolynomialStore meets criteria for std::ranges::range + EXPECT_TRUE(std::ranges::range>); + + // For example ... + Polynomial polynomial_sum(size); + for (const auto& [key, polynomial] : polynomial_store) { + polynomial_sum += polynomial; + } +} } // namespace bonk diff --git a/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp b/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp index 887893d92f..b9e7737fbf 100644 --- a/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp +++ b/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp @@ -1,2141 +1,2141 @@ -// #include "uint.hpp" -// #include "barretenberg/honk/composer/standard_honk_composer.hpp" -// #include -// #include -// #include "barretenberg/numeric/random/engine.hpp" - -// using namespace barretenberg; -// using namespace plonk; -// using namespace bonk; - -// namespace { -// auto& engine = numeric::random::get_debug_engine(); -// } - -// // NOTE: We only test width 32, but widths 8, 16, 32 and 64 can all be tested. -// // In widths 8, 16, 32: all tests pass. -// // In width 64, the following tests fail for UltraComposer. -// // test_xor_special, test_xor_more_constants, test_and_constants, test_and_special, test_or_special, -// // test_ror_special, test_hash_rounds, test_and, test_xor, test_or. -// // They fail with 'C++ exception with description"Last key slice greater than 64" thrown in the test body."' -// namespace test_stdlib_uint { -// typedef uint32_t uint_native; -// size_t uint_native_width = 8 * sizeof(uint_native); -// uint_native uint_native_max = static_cast((static_cast(1) << uint_native_width) - 1); - -// template Native get_random() -// { -// return static_cast(engine.get_random_uint64()); -// }; - -// template std::vector get_several_random(size_t num) -// { -// std::vector result; -// for (size_t i = 0; i < num; ++i) { -// result.emplace_back(get_random()); -// } -// return result; -// } - -// /** -// * @brief Utility function for testing the uint_ct comparison operators -// * -// * @details Given a uint_ct a and a constant const_b, this allows to create a -// * uint_ct b having a desired relation to a (either >. = or <). -// */ -// uint_native impose_comparison(uint_native const_a, -// uint_native const_b, -// uint_native a_val, -// bool force_equal = false, -// bool force_gt = false, -// bool force_lt = false) -// { -// uint_native b_val; -// if (force_equal) { -// b_val = a_val + const_a - const_b; -// } else if (force_lt) { // forcing b < a -// // if a_val + const_a != const_b, then we set up b_val + const_b = a_val + const_a - 1 -// // elif a_val + const_a = const_b, then we set up b_val + const_b = a_val + const_a -// // and we increment a by 1, leading to a_val + const_a = b_val + const_b + 1. -// b_val = (a_val + const_a - const_b) ? a_val + const_a - const_b - 1 : const_a - const_b + (a_val++); -// } else if (force_gt) { // forcing b > a -// // set b_val + const_b = a_val + const_a + 1 unless that would wrap, in which case we instead -// // set b_val + const_b = a then decrease a by 1. -// b_val = (a_val + const_a - const_b) == uint_native_width ? const_a - const_b + (a_val--) -// : a_val + const_a - const_b + 1; -// } else { -// b_val = get_random(); -// } -// return b_val; -// } - -// uint_native rotate(uint_native value, size_t rotation) -// { -// return rotation ? static_cast(value >> rotation) + -// static_cast(value << (uint_native_width - rotation)) -// : value; -// } -// template class stdlib_uint : public testing::Test { -// typedef typename std::conditional, -// stdlib::uint>::type uint_ct; -// typedef stdlib::bool_t bool_ct; -// typedef stdlib::witness_t witness_ct; -// typedef stdlib::byte_array byte_array_ct; - -// static inline std::vector special_values{ 0U, -// 1U, -// 2U, -// static_cast(1 << uint_native_width / 4), -// static_cast(1 << uint_native_width / 2), -// static_cast((1 << uint_native_width / 2) + 1), -// uint_native_max }; - -// static std::vector get_special_uints(Composer* ctx) -// { -// std::vector special_uints; -// for (size_t i = 0; i != special_values.size(); ++i) { -// special_uints.emplace_back(witness_ct(ctx, special_values[i])); -// }; -// return special_uints; -// }; - -// public: -// static void test_weak_normalize() -// { -// auto run_test = [](bool constant_only, bool add_constant) { -// Composer composer = Composer(); -// uint_ct a; -// uint_native a_val = get_random(); -// uint_native const_a = get_random(); -// uint_native expected; - -// if (constant_only) { -// a = const_a; -// expected = const_a; -// } else { -// a = witness_ct(&composer, a_val); -// expected = a_val; -// if (add_constant) { -// a += const_a; -// expected += const_a; -// } -// }; - -// EXPECT_EQ(expected, a.get_value()); -// auto prover = composer.create_prover(); -// auto verifier = composer.create_verifier(); -// plonk::proof proof = prover.construct_proof(); -// bool verified = verifier.verify_proof(proof); -// EXPECT_EQ(verified, true); -// }; - -// run_test(true, false); -// run_test(false, false); -// run_test(false, true); -// } - -// static void test_byte_array_conversion() -// { -// Composer composer = Composer(); -// uint_ct a = witness_ct(&composer, 0x7f6f5f4f10111213); -// std::string longest_expected = { 0x7f, 0x6f, 0x5f, 0x4f, 0x10, 0x11, 0x12, 0x13 }; -// // truncate, so we are running different tests for different choices of uint_native -// std::string expected = longest_expected.substr(longest_expected.length() - sizeof(uint_native)); -// byte_array_ct arr(&composer); -// arr.write(static_cast(a)); - -// EXPECT_EQ(arr.size(), sizeof(uint_native)); -// EXPECT_EQ(arr.get_string(), expected); -// } - -// static void test_input_output_consistency() -// { -// Composer composer = Composer(); - -// for (size_t i = 1; i < 1024; i *= 2) { -// uint_native a_expected = (uint_native)i; -// uint_native b_expected = (uint_native)i; - -// uint_ct a = witness_ct(&composer, a_expected); -// uint_ct b = witness_ct(&composer, b_expected); - -// byte_array_ct arr(&composer); - -// arr.write(static_cast(a)); -// arr.write(static_cast(b)); - -// EXPECT_EQ(arr.size(), 2 * sizeof(uint_native)); - -// uint_ct a_result(arr.slice(0, sizeof(uint_native))); -// uint_ct b_result(arr.slice(sizeof(uint_native))); - -// EXPECT_EQ(a_result.get_value(), a_expected); -// EXPECT_EQ(b_result.get_value(), b_expected); -// } -// } - -// static void test_create_from_wires() -// { -// Composer composer = Composer(); - -// uint_ct a = uint_ct(&composer, -// std::vector{ -// bool_ct(false), -// bool_ct(false), -// bool_ct(false), -// bool_ct(false), -// bool_ct(false), -// bool_ct(false), -// bool_ct(false), -// witness_ct(&composer, true), -// }); - -// EXPECT_EQ(a.at(0).get_value(), false); -// EXPECT_EQ(a.at(7).get_value(), true); -// EXPECT_EQ(static_cast(a.get_value()), 128U); -// } - -// /** -// * @brief Test addition of special values. -// * */ -// static void test_add_special() -// { -// Composer composer = Composer(); - -// witness_ct first_input(&composer, 1U); -// witness_ct second_input(&composer, 0U); - -// uint_ct a = first_input; -// uint_ct b = second_input; -// uint_ct c = a + b; -// /** -// * Fibbonacci sequence a(0) = 0, a(1), ..., a(2 + 32) = 5702887 -// * a | 1 | 1 | 2 | 3 | 5 | ... -// * b | 0 | 1 | 1 | 2 | 3 | ... -// * c | 1 | 2 | 3 | 5 | 8 | ... -// */ -// for (size_t i = 0; i < uint_native_width; ++i) { -// b = a; -// a = c; -// c = a + b; -// } - -// auto special_uints = get_special_uints(&composer); -// for (size_t i = 0; i != special_values.size(); ++i) { -// uint_native x = special_values[i]; -// uint_ct x_ct = special_uints[i]; - -// for (size_t j = i; j != special_values.size(); ++j) { -// uint_native y = special_values[j]; -// uint_ct y_ct = special_uints[j]; - -// uint_native expected_value = x + y; -// uint_ct z_ct = x_ct + y_ct; -// uint_native value = static_cast(z_ct.get_value()); - -// EXPECT_EQ(value, expected_value); -// } -// }; - -// auto prover = composer.create_prover(); -// auto verifier = composer.create_verifier(); -// plonk::proof proof = prover.construct_proof(); -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// static void test_sub_special() -// { -// Composer composer = Composer(); - -// witness_ct a_val(&composer, static_cast(4)); -// // witness_ct b_val(&composer, static_cast(5)); -// uint_native const_a = 1; -// uint_native const_b = 2; -// uint_ct a = uint_ct(a_val) + const_a; -// // uint_ct b = uint_ct(b_val) + const_b; -// uint_ct b = const_b; -// uint_ct diff = a - b; - -// auto special_uints = get_special_uints(&composer); -// for (size_t i = 0; i != special_values.size(); ++i) { -// uint_native x = special_values[i]; -// uint_ct x_ct = special_uints[i]; - -// for (size_t j = i; j != special_values.size(); ++j) { -// uint_native y = special_values[j]; -// uint_ct y_ct = special_uints[j]; - -// uint_native expected_value = x - y; -// uint_ct z_ct = x_ct - y_ct; -// uint_native value = static_cast(z_ct.get_value()); - -// EXPECT_EQ(value, expected_value); -// } -// }; - -// auto prover = composer.create_prover(); -// auto verifier = composer.create_verifier(); -// plonk::proof proof = prover.construct_proof(); -// bool verified = verifier.verify_proof(proof); - -// EXPECT_EQ(verified, true); -// } - -// static void test_add_with_constants() -// { -// size_t n = 8; -// std::vector witnesses = get_several_random(3 * n); -// uint_native expected[8]; -// for (size_t i = 2; i < n; ++i) { -// expected[0] = witnesses[3 * i]; -// expected[1] = witnesses[3 * i + 1]; -// expected[2] = witnesses[3 * i + 2]; -// expected[3] = expected[0] + expected[1]; -// expected[4] = expected[1] + expected[0]; -// expected[5] = expected[1] + expected[2]; -// expected[6] = expected[3] + expected[4]; -// expected[7] = expected[4] + expected[5]; -// } -// Composer composer = Composer(); -// uint_ct result[8]; -// for (size_t i = 2; i < n; ++i) { -// result[0] = uint_ct(&composer, witnesses[3 * i]); -// result[1] = (witness_ct(&composer, witnesses[3 * i + 1])); -// result[2] = (witness_ct(&composer, witnesses[3 * i + 2])); -// result[3] = result[0] + result[1]; -// result[4] = result[1] + result[0]; -// result[5] = result[1] + result[2]; -// result[6] = result[3] + result[4]; -// result[7] = result[4] + result[5]; -// } - -// for (size_t i = 0; i < n; ++i) { -// EXPECT_EQ(result[i].get_value(), expected[i]); -// } - -// auto prover = composer.create_prover(); -// auto verifier = composer.create_verifier(); -// plonk::proof proof = prover.construct_proof(); -// bool proof_valid = verifier.verify_proof(proof); -// EXPECT_EQ(proof_valid, true); -// } - -// static void test_mul_special() -// { -// uint_native a_expected = 1U; -// uint_native b_expected = 2U; -// uint_native c_expected = a_expected + b_expected; -// for (size_t i = 0; i < 100; ++i) { -// b_expected = a_expected; -// a_expected = c_expected; -// c_expected = a_expected * b_expected; -// } - -// Composer composer = Composer(); - -// witness_ct first_input(&composer, 1U); -// witness_ct second_input(&composer, 2U); - -// uint_ct a = first_input; -// uint_ct b = second_input; -// uint_ct c = a + b; -// for (size_t i = 0; i < 100; ++i) { -// b = a; -// a = c; -// c = a * b; -// } -// uint_native c_result = -// static_cast(composer.get_variable(c.get_witness_index()).from_montgomery_form().data[0]); -// EXPECT_EQ(c_result, c_expected); - -// auto special_uints = get_special_uints(&composer); -// for (size_t i = 0; i != special_values.size(); ++i) { -// uint_native x = special_values[i]; -// uint_ct x_ct = special_uints[i]; - -// for (size_t j = i; j != special_values.size(); ++j) { -// uint_native y = special_values[j]; -// uint_ct y_ct = special_uints[j]; - -// uint_native expected_value = x * y; -// uint_ct z_ct = x_ct * y_ct; -// uint_native value = static_cast(z_ct.get_value()); - -// EXPECT_EQ(value, expected_value); -// } -// }; - -// auto prover = composer.create_prover(); -// auto verifier = composer.create_verifier(); -// plonk::proof proof = prover.construct_proof(); -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// static void test_mul_big() -// { -// uint_native max = uint_native_max; - -// Composer composer = Composer(); -// uint_ct a = witness_ct(&composer, max); -// a = a + max; -// uint_ct b = a; -// uint_ct c = a * b; - -// auto prover = composer.create_prover(); -// auto verifier = composer.create_verifier(); -// plonk::proof proof = prover.construct_proof(); -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// static void test_xor_special() -// { -// uint_native a_expected = static_cast(0x10000000a3b10422); -// uint_native b_expected = static_cast(0xfafab007eac21343); -// uint_native c_expected = a_expected ^ b_expected; -// for (size_t i = 0; i < uint_native_width; ++i) { -// b_expected = a_expected; -// a_expected = c_expected; -// c_expected = a_expected + b_expected; -// a_expected = c_expected ^ a_expected; -// } - -// Composer composer = Composer(); - -// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); -// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - -// uint_ct a = first_input; -// uint_ct b = second_input; -// uint_ct c = a ^ b; -// for (size_t i = 0; i < uint_native_width; ++i) { -// b = a; -// a = c; -// c = a + b; -// a = c ^ a; -// } -// uint_native a_result = -// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); - -// EXPECT_EQ(a_result, a_expected); - -// auto prover = composer.create_prover(); - -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// static void test_xor_constants() -// { -// Composer composer = Composer(); - -// uint_native a_expected = static_cast(0x10000000a3b10422); -// uint_native b_expected = static_cast(0xfafab007eac21343); -// uint_native c_expected = a_expected ^ b_expected; - -// uint_ct const_a(&composer, static_cast(0x10000000a3b10422)); -// uint_ct const_b(&composer, static_cast(0xfafab007eac21343)); -// uint_ct c = const_a ^ const_b; -// c.get_witness_index(); - -// EXPECT_EQ(c.get_additive_constant(), uint256_t(c_expected)); -// } - -// static void test_xor_more_constants() -// { -// uint_native a_expected = static_cast(0x10000000a3b10422); -// uint_native b_expected = static_cast(0xfafab007eac21343); -// uint_native c_expected = a_expected ^ b_expected; -// for (size_t i = 0; i < 1; ++i) { -// b_expected = a_expected; -// a_expected = c_expected; -// c_expected = (a_expected + b_expected) ^ -// (static_cast(0x10000000a3b10422) ^ static_cast(0xfafab007eac21343)); -// } - -// Composer composer = Composer(); - -// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); -// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - -// uint_ct a = first_input; -// uint_ct b = second_input; -// uint_ct c = a ^ b; -// for (size_t i = 0; i < 1; ++i) { -// uint_ct const_a = static_cast(0x10000000a3b10422); -// uint_ct const_b = static_cast(0xfafab007eac21343); -// b = a; -// a = c; -// c = (a + b) ^ (const_a ^ const_b); -// } -// uint32_t c_witness_index = c.get_witness_index(); -// uint_native c_result = -// static_cast(composer.get_variable(c_witness_index).from_montgomery_form().data[0]); -// EXPECT_EQ(c_result, c_expected); -// auto prover = composer.create_prover(); - -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// static void test_and_constants() -// { -// uint_native a_expected = static_cast(0x10000000a3b10422); -// uint_native b_expected = static_cast(0xfafab007eac21343); -// uint_native c_expected = a_expected & b_expected; -// for (size_t i = 0; i < 1; ++i) { -// b_expected = a_expected; -// a_expected = c_expected; -// c_expected = (~a_expected & static_cast(0x10000000a3b10422)) + -// (b_expected & static_cast(0xfafab007eac21343)); -// // c_expected = (a_expected + b_expected) & (static_cast(0x10000000a3b10422) & -// // static_cast(0xfafab007eac21343)); -// } - -// Composer composer = Composer(); - -// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); -// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - -// uint_ct a = first_input; -// uint_ct b = second_input; -// uint_ct c = a & b; -// for (size_t i = 0; i < 1; ++i) { -// uint_ct const_a = static_cast(0x10000000a3b10422); -// uint_ct const_b = static_cast(0xfafab007eac21343); -// b = a; -// a = c; -// c = (~a & const_a) + (b & const_b); -// } -// uint32_t c_witness_index = c.get_witness_index(); -// uint_native c_result = -// static_cast(composer.get_variable(c_witness_index).from_montgomery_form().data[0]); -// EXPECT_EQ(c_result, c_expected); -// auto prover = composer.create_prover(); - -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// static void test_and_special() -// { -// uint_native a_expected = static_cast(0x10000000a3b10422); -// uint_native b_expected = static_cast(0xfafab007eac21343); -// uint_native c_expected = a_expected + b_expected; -// for (size_t i = 0; i < uint_native_width; ++i) { -// b_expected = a_expected; -// a_expected = c_expected; -// c_expected = a_expected + b_expected; -// a_expected = c_expected & a_expected; -// } - -// Composer composer = Composer(); - -// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); -// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - -// uint_ct a = first_input; -// uint_ct b = second_input; -// uint_ct c = a + b; -// for (size_t i = 0; i < uint_native_width; ++i) { -// b = a; -// a = c; -// c = a + b; -// a = c & a; -// } -// uint_native a_result = -// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); -// EXPECT_EQ(a_result, a_expected); - -// auto prover = composer.create_prover(); - -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// static void test_or_special() -// { -// uint_native a_expected = static_cast(0x10000000a3b10422); -// uint_native b_expected = static_cast(0xfafab007eac21343); -// uint_native c_expected = a_expected ^ b_expected; -// for (size_t i = 0; i < uint_native_width; ++i) { -// b_expected = a_expected; -// a_expected = c_expected; -// c_expected = a_expected + b_expected; -// a_expected = c_expected | a_expected; -// } - -// Composer composer = Composer(); - -// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); -// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - -// uint_ct a = first_input; -// uint_ct b = second_input; -// uint_ct c = a ^ b; -// for (size_t i = 0; i < uint_native_width; ++i) { -// b = a; -// a = c; -// c = a + b; -// a = c | a; -// } -// uint_native a_result = -// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); -// EXPECT_EQ(a_result, a_expected); - -// auto prover = composer.create_prover(); - -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// static void test_gt_special() -// { -// const auto run_test = [](bool lhs_constant, bool rhs_constant, int type = 0) { -// uint_native a_expected = static_cast(0x10000000a3b10422); -// uint_native b_expected; -// switch (type) { -// case 0: { -// b_expected = static_cast(0x20000000bac21343); // a < b -// break; -// } -// case 1: { -// b_expected = static_cast(0x0000000000002f12); // a > b -// break; -// } -// case 2: { -// b_expected = static_cast(0x10000000a3b10422); // a = b -// break; -// } -// default: { -// b_expected = static_cast(0x20000000bac21343); // a < b -// } -// } -// bool c_expected = a_expected > b_expected; - -// Composer composer = Composer(); - -// uint_ct a; -// uint_ct b; -// if (lhs_constant) { -// a = uint_ct(nullptr, a_expected); -// } else { -// a = witness_ct(&composer, a_expected); -// } -// if (rhs_constant) { -// b = uint_ct(nullptr, b_expected); -// } else { -// b = witness_ct(&composer, b_expected); -// } -// // mix in some constant terms for good measure -// a *= uint_ct(&composer, 2); -// a += uint_ct(&composer, 1); -// b *= uint_ct(&composer, 2); -// b += uint_ct(&composer, 1); - -// bool_ct c = a > b; - -// bool c_result = static_cast(c.get_value()); -// EXPECT_EQ(c_result, c_expected); - -// auto prover = composer.create_prover(); - -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// }; - -// run_test(false, false, 0); -// run_test(false, true, 0); -// run_test(true, false, 0); -// run_test(true, true, 0); -// run_test(false, false, 1); -// run_test(false, true, 1); -// run_test(true, false, 1); -// run_test(true, true, 1); -// run_test(false, false, 2); -// run_test(false, true, 2); -// run_test(true, false, 2); -// run_test(true, true, 2); -// } - -// static uint_native rotate(uint_native value, size_t rotation) -// { -// return rotation ? static_cast(value >> rotation) + -// static_cast(value << (uint_native_width - rotation)) -// : value; -// } - -// static void test_ror_special() -// { -// uint_native a_expected = static_cast(0x10000000a3b10422); -// uint_native b_expected = static_cast(0xfafab007eac21343); -// uint_native c_expected = a_expected ^ b_expected; -// for (size_t i = 0; i < uint_native_width; ++i) { -// b_expected = a_expected; -// a_expected = c_expected; -// c_expected = a_expected + b_expected; -// a_expected = rotate(c_expected, i % 31) + rotate(a_expected, (i + 1) % 31); -// } - -// Composer composer = Composer(); - -// witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); -// witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); - -// uint_ct a = first_input; -// uint_ct b = second_input; -// uint_ct c = a ^ b; -// for (size_t i = 0; i < uint_native_width; ++i) { -// b = a; -// a = c; -// c = a + b; -// a = c.ror(static_cast(i % 31)) + a.ror(static_cast((i + 1) % 31)); -// } -// uint_native a_result = -// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); -// EXPECT_EQ(a_result, a_expected); - -// auto prover = composer.create_prover(); - -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// /** -// * @brief If uint_native_width == 32, test part of SHA256. Otherwise, do something similar. -// * -// * @details Notes that the static casts have to be there becuase of -Wc++11-narrowing flag. -// * -// * TurboPLONK: 19896 gates -// * StandardPLONK: 210363 gates -// */ -// static void test_hash_rounds() -// { -// std::vector k_constants(64); -// std::vector round_values(8); -// if (uint_native_width == 32) { -// k_constants = { static_cast(0x428a2f98), static_cast(0x71374491), -// static_cast(0xb5c0fbcf), static_cast(0xe9b5dba5), -// static_cast(0x3956c25b), static_cast(0x59f111f1), -// static_cast(0x923f82a4), static_cast(0xab1c5ed5), -// static_cast(0xd807aa98), static_cast(0x12835b01), -// static_cast(0x243185be), static_cast(0x550c7dc3), -// static_cast(0x72be5d74), static_cast(0x80deb1fe), -// static_cast(0x9bdc06a7), static_cast(0xc19bf174), -// static_cast(0xe49b69c1), static_cast(0xefbe4786), -// static_cast(0x0fc19dc6), static_cast(0x240ca1cc), -// static_cast(0x2de92c6f), static_cast(0x4a7484aa), -// static_cast(0x5cb0a9dc), static_cast(0x76f988da), -// static_cast(0x983e5152), static_cast(0xa831c66d), -// static_cast(0xb00327c8), static_cast(0xbf597fc7), -// static_cast(0xc6e00bf3), static_cast(0xd5a79147), -// static_cast(0x06ca6351), static_cast(0x14292967), -// static_cast(0x27b70a85), static_cast(0x2e1b2138), -// static_cast(0x4d2c6dfc), static_cast(0x53380d13), -// static_cast(0x650a7354), static_cast(0x766a0abb), -// static_cast(0x81c2c92e), static_cast(0x92722c85), -// static_cast(0xa2bfe8a1), static_cast(0xa81a664b), -// static_cast(0xc24b8b70), static_cast(0xc76c51a3), -// static_cast(0xd192e819), static_cast(0xd6990624), -// static_cast(0xf40e3585), static_cast(0x106aa070), -// static_cast(0x19a4c116), static_cast(0x1e376c08), -// static_cast(0x2748774c), static_cast(0x34b0bcb5), -// static_cast(0x391c0cb3), static_cast(0x4ed8aa4a), -// static_cast(0x5b9cca4f), static_cast(0x682e6ff3), -// static_cast(0x748f82ee), static_cast(0x78a5636f), -// static_cast(0x84c87814), static_cast(0x8cc70208), -// static_cast(0x90befffa), static_cast(0xa4506ceb), -// static_cast(0xbef9a3f7), static_cast(0xc67178f2) }; - -// round_values = { static_cast(0x01020304), static_cast(0x0a0b0c0d), -// static_cast(0x1a2b3e4d), static_cast(0x03951bd3), -// static_cast(0x0e0fa3fe), static_cast(0x01000000), -// static_cast(0x0f0eeea1), static_cast(0x12345678) }; -// } else { -// k_constants = get_several_random(64); -// round_values = get_several_random(8); -// }; - -// std::vector w_alt = get_several_random(64); - -// uint_native a_alt = round_values[0]; -// uint_native b_alt = round_values[1]; -// uint_native c_alt = round_values[2]; -// uint_native d_alt = round_values[3]; -// uint_native e_alt = round_values[4]; -// uint_native f_alt = round_values[5]; -// uint_native g_alt = round_values[6]; -// uint_native h_alt = round_values[7]; -// for (size_t i = 0; i < 64; ++i) { -// uint_native S1_alt = rotate(e_alt, 7 % uint_native_width) ^ rotate(e_alt, 11 % uint_native_width) ^ -// rotate(e_alt, 25 % uint_native_width); -// uint_native ch_alt = (e_alt & f_alt) ^ ((~e_alt) & g_alt); -// uint_native temp1_alt = h_alt + S1_alt + ch_alt + k_constants[i % 64] + w_alt[i]; - -// uint_native S0_alt = rotate(a_alt, 2 % uint_native_width) ^ rotate(a_alt, 13 % uint_native_width) ^ -// rotate(a_alt, 22 % uint_native_width); -// uint_native maj_alt = (a_alt & b_alt) ^ (a_alt & c_alt) ^ (b_alt & c_alt); -// uint_native temp2_alt = S0_alt + maj_alt; - -// h_alt = g_alt; -// g_alt = f_alt; -// f_alt = e_alt; -// e_alt = d_alt + temp1_alt; -// d_alt = c_alt; -// c_alt = b_alt; -// b_alt = a_alt; -// a_alt = temp1_alt + temp2_alt; -// } -// Composer composer = Composer(); - -// std::vector w; -// std::vector k; -// for (size_t i = 0; i < 64; ++i) { -// w.emplace_back(uint_ct(witness_ct(&composer, w_alt[i]))); -// k.emplace_back(uint_ct(&composer, k_constants[i % 64])); -// } -// uint_ct a = witness_ct(&composer, round_values[0]); -// uint_ct b = witness_ct(&composer, round_values[1]); -// uint_ct c = witness_ct(&composer, round_values[2]); -// uint_ct d = witness_ct(&composer, round_values[3]); -// uint_ct e = witness_ct(&composer, round_values[4]); -// uint_ct f = witness_ct(&composer, round_values[5]); -// uint_ct g = witness_ct(&composer, round_values[6]); -// uint_ct h = witness_ct(&composer, round_values[7]); -// for (size_t i = 0; i < 64; ++i) { -// uint_ct S1 = -// e.ror(7U % uint_native_width) ^ e.ror(11U % uint_native_width) ^ e.ror(25U % uint_native_width); -// uint_ct ch = (e & f) + ((~e) & g); -// uint_ct temp1 = h + S1 + ch + k[i] + w[i]; - -// uint_ct S0 = -// a.ror(2U % uint_native_width) ^ a.ror(13U % uint_native_width) ^ a.ror(22U % uint_native_width); -// uint_ct T0 = (b & c); -// uint_ct T1 = (b - T0) + (c - T0); -// uint_ct T2 = a & T1; -// uint_ct maj = T2 + T0; -// uint_ct temp2 = S0 + maj; - -// h = g; -// g = f; -// f = e; -// e = d + temp1; -// d = c; -// c = b; -// b = a; -// a = temp1 + temp2; -// } - -// uint_native a_result = -// static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); -// uint_native b_result = -// static_cast(composer.get_variable(b.get_witness_index()).from_montgomery_form().data[0]); -// uint_native c_result = -// static_cast(composer.get_variable(c.get_witness_index()).from_montgomery_form().data[0]); -// uint_native d_result = -// static_cast(composer.get_variable(d.get_witness_index()).from_montgomery_form().data[0]); -// uint_native e_result = -// static_cast(composer.get_variable(e.get_witness_index()).from_montgomery_form().data[0]); -// uint_native f_result = -// static_cast(composer.get_variable(f.get_witness_index()).from_montgomery_form().data[0]); -// uint_native g_result = -// static_cast(composer.get_variable(g.get_witness_index()).from_montgomery_form().data[0]); -// uint_native h_result = -// static_cast(composer.get_variable(h.get_witness_index()).from_montgomery_form().data[0]); - -// EXPECT_EQ(a_result, a_alt); -// EXPECT_EQ(b_result, b_alt); -// EXPECT_EQ(c_result, c_alt); -// EXPECT_EQ(d_result, d_alt); -// EXPECT_EQ(e_result, e_alt); -// EXPECT_EQ(f_result, f_alt); -// EXPECT_EQ(g_result, g_alt); -// EXPECT_EQ(h_result, h_alt); - -// auto prover = composer.create_prover(); - -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// // BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO - -// /** -// * @brief Test addition of random uint's, trying all combinations of (constant, witness). -// */ -// static void test_add() -// { -// Composer composer = Composer(); - -// const auto add_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { -// uint_native a_val = get_random(); -// uint_native b_val = get_random(); -// uint_native expected = a_val + b_val; -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); -// uint_ct c = a + b; -// c = c.normalize(); - -// uint_native result = uint_native(c.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// add_integers(false, false); -// add_integers(false, true); -// add_integers(true, false); -// add_integers(true, true); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_sub() -// { -// Composer composer = Composer(); - -// const auto sub_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { -// uint_native a_val = get_random(); -// uint_native b_val = get_random(); -// uint_native const_shift_val = get_random(); -// uint_native expected = a_val - (b_val + const_shift_val); -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); -// uint_ct b_shift = uint_ct(&composer, const_shift_val); -// uint_ct c = b + b_shift; -// uint_ct d = a - c; -// d = d.normalize(); - -// uint_native result = uint_native(d.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// sub_integers(false, false); -// sub_integers(false, true); -// sub_integers(true, false); -// sub_integers(true, true); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_mul() -// { -// Composer composer = Composer(); - -// const auto mul_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { -// uint_native a_val = get_random(); -// uint_native b_val = get_random(); -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native expected = -// static_cast(a_val + const_a) * static_cast(b_val + const_b); -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// uint_ct e = c * d; -// e = e.normalize(); - -// uint_native result = uint_native(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// mul_integers(false, false); -// mul_integers(false, true); -// mul_integers(true, false); -// mul_integers(true, true); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_divide() -// { -// Composer composer = Composer(); - -// const auto divide_integers = [&composer](bool lhs_constant = false, -// bool rhs_constant = false, -// bool dividend_is_divisor = false, -// bool dividend_zero = false, -// bool divisor_zero = false) { -// uint_native a_val = get_random(); -// uint_native b_val = dividend_is_divisor ? a_val : get_random(); -// uint_native const_a = dividend_zero ? 0 - a_val : get_random(); -// uint_native const_b = -// divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); -// uint_native expected = -// static_cast(a_val + const_a) / static_cast(b_val + const_b); -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// uint_ct e = c / d; -// e = e.normalize(); - -// uint_native result = static_cast(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// divide_integers(false, false, false, false, false); -// divide_integers(false, false, false, false, false); -// divide_integers(false, false, false, false, false); -// divide_integers(false, false, false, false, false); -// divide_integers(false, false, false, false, false); - -// divide_integers(false, true, false, false, false); -// divide_integers(true, false, false, false, false); -// divide_integers(true, true, false, false, false); // fails; 0 != 1 - -// divide_integers(false, false, true, false, false); -// divide_integers(false, true, true, false, false); -// divide_integers(true, false, true, false, false); -// divide_integers(true, true, true, false, false); - -// divide_integers(false, false, false, true, false); -// divide_integers(false, true, false, true, false); // fails; 0 != 1 -// divide_integers(true, false, false, true, false); -// divide_integers(true, true, false, true, false); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_modulo() -// { -// Composer composer = Composer(); - -// const auto mod_integers = [&composer](bool lhs_constant = false, -// bool rhs_constant = false, -// bool dividend_is_divisor = false, -// bool dividend_zero = false, -// bool divisor_zero = false) { -// uint_native a_val = get_random(); -// uint_native b_val = dividend_is_divisor ? a_val : get_random(); -// uint_native const_a = dividend_zero ? 0 - a_val : get_random(); -// uint_native const_b = -// divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); -// uint_native expected = -// static_cast(a_val + const_a) % static_cast(b_val + const_b); -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// uint_ct e = c % d; -// e = e.normalize(); - -// uint_native result = uint_native(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// mod_integers(false, false, false, false, false); -// mod_integers(false, true, false, false, false); -// mod_integers(true, false, false, false, false); -// mod_integers(true, true, false, false, false); - -// mod_integers(false, false, true, false, false); -// mod_integers(false, true, true, false, false); -// mod_integers(true, false, true, false, false); -// mod_integers(true, true, true, false, false); - -// mod_integers(false, false, false, true, false); -// mod_integers(false, true, false, true, false); -// mod_integers(true, false, false, true, false); -// mod_integers(true, true, false, true, false); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_divide_by_zero_fails() -// { - -// const auto divide_integers = [](bool lhs_constant = false, -// bool rhs_constant = false, -// bool dividend_is_divisor = false, -// bool dividend_zero = false, -// bool divisor_zero = false) { -// Composer composer = Composer(); - -// uint_native a_val = get_random(); -// uint_native b_val = dividend_is_divisor ? a_val : get_random(); -// uint_native const_a = dividend_zero ? 0 - a_val : get_random(); -// uint_native const_b = -// divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// uint_ct e = c / d; -// e = e.normalize(); - -// auto prover = composer.create_prover(); - -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, false); -// }; - -// divide_integers(false, false, false, false, true); -// divide_integers(false, false, false, true, true); -// divide_integers(true, true, false, false, true); -// divide_integers(true, true, false, true, true); -// } - -// static void test_divide_special() -// { -// Composer composer = Composer(); - -// auto special_uints = get_special_uints(&composer); - -// for (size_t i = 0; i != special_values.size(); ++i) { -// uint_native x = special_values[i]; -// uint_ct x_ct = special_uints[i]; - -// for (size_t j = i; j != special_values.size(); ++j) { -// uint_native y = special_values[j]; -// uint_ct y_ct = special_uints[j]; - -// // uint_native hits this error when trying to divide by zero: -// // Stop reason: signal SIGFPE: integer divide by zero -// uint_native expected_value; -// uint_ct z_ct; -// uint_native value; -// if (y != 0) { -// expected_value = x / y; -// z_ct = x_ct / y_ct; -// value = static_cast(z_ct.get_value()); -// EXPECT_EQ(value, expected_value); -// } -// } -// }; - -// auto prover = composer.create_prover(); -// auto verifier = composer.create_verifier(); -// plonk::proof proof = prover.construct_proof(); -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, true); -// } - -// /** -// * @brief Make sure we prevent proving v / v = 0 by setting the divison remainder to be v. -// * TODO: This is lifted from the implementation. Should rewrite this test after introducing framework that separates -// * circuit construction from witness generation. - -// */ -// static void div_remainder_constraint() -// { -// Composer composer = Composer(); - -// uint_native val = get_random(); - -// uint_ct a = witness_ct(&composer, val); -// uint_ct b = witness_ct(&composer, val); - -// const uint32_t dividend_idx = a.get_witness_index(); -// const uint32_t divisor_idx = b.get_witness_index(); - -// const uint256_t divisor = b.get_value(); - -// const uint256_t q = 0; -// const uint256_t r = val; - -// const uint32_t quotient_idx = composer.add_variable(q); -// const uint32_t remainder_idx = composer.add_variable(r); - -// // In this example there are no additive constaints, so we just replace them by zero below. - -// // constraint: qb + const_b q + 0 b - a + r - const_a == 0 -// // i.e., a + const_a = q(b + const_b) + r -// const mul_quad division_gate{ .a = quotient_idx, // q -// .b = divisor_idx, // b -// .c = dividend_idx, // a -// .d = remainder_idx, // r -// .mul_scaling = fr::one(), -// .a_scaling = b.get_additive_constant(), -// .b_scaling = fr::zero(), -// .c_scaling = fr::neg_one(), -// .d_scaling = fr::one(), -// .const_scaling = -a.get_additive_constant() }; -// composer.create_big_mul_gate(division_gate); - -// // set delta = (b + const_b - r) - -// // constraint: b - r - delta + const_b == 0 -// const uint256_t delta = divisor - r - 1; -// const uint32_t delta_idx = composer.add_variable(delta); - -// const add_triple delta_gate{ -// .a = divisor_idx, // b -// .b = remainder_idx, // r -// .c = delta_idx, // d -// .a_scaling = fr::one(), -// .b_scaling = fr::neg_one(), -// .c_scaling = fr::neg_one(), -// .const_scaling = b.get_additive_constant(), -// }; - -// composer.create_add_gate(delta_gate); - -// // validate delta is in the correct range -// stdlib::field_t::from_witness_index(&composer, delta_idx) -// .create_range_constraint(uint_native_width, -// "delta range constraint fails in div_remainder_constraint test"); - -// // normalize witness quotient and remainder -// // minimal bit range for quotient: from 0 (in case a = b-1) to width (when b = 1). -// uint_ct quotient(&composer); -// composer.create_range_constraint( -// quotient_idx, uint_native_width, "quotient range constraint fails in div_remainder_constraint test"); - -// // constrain remainder to lie in [0, 2^width-1] -// uint_ct remainder(&composer); -// composer.create_range_constraint( -// remainder_idx, uint_native_width, "remainder range constraint fails in div_remainder_constraint test"); - -// auto prover = composer.create_prover(); -// auto verifier = composer.create_verifier(); -// plonk::proof proof = prover.construct_proof(); -// bool result = verifier.verify_proof(proof); -// EXPECT_EQ(result, false); -// } - -// static void test_and() -// { -// Composer composer = Composer(); - -// const auto and_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { -// uint_native a_val = get_random(); -// uint_native b_val = get_random(); -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native expected = (a_val + const_a) & (b_val + const_b); -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// uint_ct e = c & d; -// e = e.normalize(); - -// uint_native result = uint_native(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// and_integers(false, false); -// and_integers(false, true); -// and_integers(true, false); -// and_integers(true, true); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_xor() -// { -// Composer composer = Composer(); - -// const auto xor_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { -// uint_native a_val = get_random(); -// uint_native b_val = get_random(); -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native expected = (a_val + const_a) ^ (b_val + const_b); -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// uint_ct e = c ^ d; -// e = e.normalize(); - -// uint_native result = uint_native(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// xor_integers(false, false); -// xor_integers(false, true); -// xor_integers(true, false); -// xor_integers(true, true); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_or() -// { -// Composer composer = Composer(); - -// const auto or_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { -// uint_native a_val = get_random(); -// uint_native b_val = get_random(); -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native expected = (a_val + const_a) | (b_val + const_b); -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// uint_ct e = c | d; -// e = e.normalize(); - -// uint_native result = uint_native(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// or_integers(false, false); -// or_integers(false, false); -// or_integers(false, false); -// or_integers(false, false); -// or_integers(false, false); -// or_integers(false, true); -// or_integers(true, false); -// or_integers(true, true); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_not() -// { -// Composer composer = Composer(); - -// const auto not_integers = [&composer](bool lhs_constant = false, bool = false) { -// uint_native a_val = get_random(); -// uint_native const_a = get_random(); -// uint_native expected = ~(a_val + const_a); -// uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct c = a + a_shift; -// uint_ct e = ~c; -// e = e.normalize(); - -// uint_native result = uint_native(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// not_integers(false, false); -// not_integers(false, true); -// not_integers(true, false); -// not_integers(true, true); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_gt() -// { -// Composer composer = Composer(); -// const auto compare_integers = -// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native a_val = get_random(); -// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - -// bool expected = static_cast(b_val + const_b) > static_cast(a_val + const_a); -// uint_ct a = witness_ct(&composer, a_val); -// uint_ct b = witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// bool_ct e = d > c; -// bool result = bool(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// compare_integers(false, false, false); // both are random -// compare_integers(false, false, false); // '' -// compare_integers(false, false, false); // '' -// compare_integers(false, false, false); // '' -// compare_integers(false, false, true); // b < a -// compare_integers(false, true, false); // b > a -// compare_integers(true, false, false); // b = a -// compare_integers(false, true, false); // b > a -// compare_integers(true, false, false); // b = a - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_lt() -// { -// Composer composer = Composer(); - -// const auto compare_integers = -// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native a_val = get_random(); -// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - -// bool expected = static_cast(b_val + const_b) < static_cast(a_val + const_a); -// uint_ct a = witness_ct(&composer, a_val); -// uint_ct b = witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// bool_ct e = d < c; -// bool result = bool(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_gte() -// { -// Composer composer = Composer(); - -// const auto compare_integers = -// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native a_val = get_random(); -// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - -// bool expected = static_cast(b_val + const_b) >= static_cast(a_val + const_a); -// uint_ct a = witness_ct(&composer, a_val); -// uint_ct b = witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// bool_ct e = d >= c; -// bool result = bool(e.get_value()); -// EXPECT_EQ(result, expected); -// }; - -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_lte() -// { -// Composer composer = Composer(); - -// const auto compare_integers = -// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native a_val = get_random(); -// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - -// bool expected = static_cast(b_val + const_b) <= static_cast(a_val + const_a); -// uint_ct a = witness_ct(&composer, a_val); -// uint_ct b = witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// bool_ct e = d <= c; -// bool result = bool(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_equality_operator() -// { -// Composer composer = Composer(); - -// const auto compare_integers = -// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native a_val = get_random(); -// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - -// bool expected = static_cast(b_val + const_b) == static_cast(a_val + const_a); -// uint_ct a = witness_ct(&composer, a_val); -// uint_ct b = witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// bool_ct e = d == c; -// bool result = bool(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_not_equality_operator() -// { -// Composer composer = Composer(); - -// const auto compare_integers = -// [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { -// uint_native const_a = get_random(); -// uint_native const_b = get_random(); -// uint_native a_val = get_random(); -// uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); - -// bool expected = static_cast(b_val + const_b) != static_cast(a_val + const_a); -// uint_ct a = witness_ct(&composer, a_val); -// uint_ct b = witness_ct(&composer, b_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct b_shift = uint_ct(&composer, const_b); -// uint_ct c = a + a_shift; -// uint_ct d = b + b_shift; -// bool_ct e = d != c; -// bool result = bool(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); -// compare_integers(false, false, true); -// compare_integers(false, true, false); -// compare_integers(true, false, false); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_logical_not() -// { -// Composer composer = Composer(); - -// const auto not_integer = [&composer](bool force_zero) { -// uint_native const_a = get_random(); -// uint_native a_val = force_zero ? 0 - const_a : get_random(); -// bool expected = !static_cast(const_a + a_val); -// uint_ct a = witness_ct(&composer, a_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct c = a + a_shift; -// bool_ct e = !c; -// bool result = bool(e.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// not_integer(true); -// not_integer(true); -// not_integer(false); -// not_integer(false); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_right_shift() -// { -// Composer composer = Composer(); - -// const auto shift_integer = [&composer](const bool is_constant, const uint_native shift) { -// uint_native const_a = get_random(); -// uint_native a_val = get_random(); -// uint_native expected = static_cast(a_val + const_a) >> shift; -// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct c = a + a_shift; -// uint_ct d = c >> shift; -// uint_native result = uint_native(d.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// for (uint_native i = 0; i < uint_native_width; ++i) { -// shift_integer(false, i); -// shift_integer(true, i); -// } - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_left_shift() -// { -// Composer composer = Composer(); - -// const auto shift_integer = [&composer](const bool is_constant, const uint_native shift) { -// uint_native const_a = get_random(); -// uint_native a_val = get_random(); -// uint_native expected = static_cast((a_val + const_a) << shift); -// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct c = a + a_shift; -// uint_ct d = c << shift; -// uint_native result = uint_native(d.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// for (uint_native i = 0; i < uint_native_width; ++i) { -// shift_integer(true, i); -// shift_integer(false, i); -// } - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_ror() -// { -// Composer composer = Composer(); - -// const auto ror_integer = [&composer](const bool is_constant, const uint_native rotation) { -// const auto ror = [](const uint_native in, const uint_native rval) { -// return rval ? (in >> rval) | (in << (uint_native_width - rval)) : in; -// }; - -// uint_native const_a = get_random(); -// uint_native a_val = get_random(); -// uint_native expected = static_cast(ror(static_cast(const_a + a_val), rotation)); -// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct c = a + a_shift; -// uint_ct d = c.ror(rotation); -// uint_native result = uint_native(d.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// for (uint_native i = 0; i < uint_native_width; ++i) { -// ror_integer(true, i); -// ror_integer(false, i); -// } - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// static void test_rol() -// { -// Composer composer = Composer(); - -// const auto rol_integer = [&composer](const bool is_constant, const uint_native rotation) { -// const auto rol = [](const uint_native in, const uint_native rval) { -// return rval ? (in << rval) | (in >> (uint_native_width - rval)) : in; -// }; - -// uint_native const_a = get_random(); -// uint_native a_val = get_random(); -// uint_native expected = static_cast(rol(static_cast(const_a + a_val), rotation)); -// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct c = a + a_shift; -// uint_ct d = c.rol(rotation); -// uint_native result = uint_native(d.get_value()); - -// EXPECT_EQ(result, expected); -// }; - -// for (uint_native i = 0; i < uint_native_width; ++i) { -// rol_integer(true, i); -// rol_integer(false, i); -// } - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } - -// /** -// * @brief Test the the function uint_ct::at used to extract bits. -// */ -// static void test_at() -// { -// Composer composer = Composer(); - -// const auto bit_test = [&composer](const bool is_constant) { -// // construct a sum of uint_ct's, where at least one is a constant, -// // and validate its correctness bitwise -// uint_native const_a = get_random(); -// uint_native a_val = get_random(); -// uint_native c_val = const_a + a_val; -// uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); -// uint_ct a_shift = uint_ct(&composer, const_a); -// uint_ct c = a + a_shift; -// for (size_t i = 0; i < uint_native_width; ++i) { -// bool_ct result = c.at(i); -// bool expected = (((c_val >> i) & 1UL) == 1UL) ? true : false; -// EXPECT_EQ(result.get_value(), expected); -// EXPECT_EQ(result.get_context(), c.get_context()); -// } -// }; - -// bit_test(false); -// bit_test(true); - -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// plonk::proof proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } -// }; - -// typedef testing::Types -// ComposerTypes; - -// TYPED_TEST_SUITE(stdlib_uint, ComposerTypes); - -// TYPED_TEST(stdlib_uint, test_weak_normalize) -// { -// TestFixture::test_weak_normalize(); -// } -// TYPED_TEST(stdlib_uint, test_byte_array_conversion) -// { -// TestFixture::test_byte_array_conversion(); -// } -// TYPED_TEST(stdlib_uint, test_input_output_consistency) -// { -// TestFixture::test_input_output_consistency(); -// } -// TYPED_TEST(stdlib_uint, test_create_from_wires) -// { -// TestFixture::test_create_from_wires(); -// } -// TYPED_TEST(stdlib_uint, test_add_special) -// { -// TestFixture::test_add_special(); -// } -// TYPED_TEST(stdlib_uint, test_sub_special) -// { -// TestFixture::test_sub_special(); -// } -// TYPED_TEST(stdlib_uint, test_add_with_constants) -// { -// TestFixture::test_add_with_constants(); -// } -// TYPED_TEST(stdlib_uint, test_mul_special) -// { -// TestFixture::test_mul_special(); -// } -// TYPED_TEST(stdlib_uint, test_mul_big) -// { -// TestFixture::test_mul_big(); -// } -// TYPED_TEST(stdlib_uint, test_xor_special) -// { -// TestFixture::test_xor_special(); -// } -// TYPED_TEST(stdlib_uint, test_xor_constants) -// { -// TestFixture::test_xor_constants(); -// } -// TYPED_TEST(stdlib_uint, test_xor_more_constants) -// { -// TestFixture::test_xor_more_constants(); -// } -// TYPED_TEST(stdlib_uint, test_and_constants) -// { -// TestFixture::test_and_constants(); -// } -// TYPED_TEST(stdlib_uint, test_and_special) -// { -// TestFixture::test_and_special(); -// } -// TYPED_TEST(stdlib_uint, test_or_special) -// { -// TestFixture::test_or_special(); -// } -// TYPED_TEST(stdlib_uint, test_gt_special) -// { -// TestFixture::test_gt_special(); -// } -// TYPED_TEST(stdlib_uint, test_ror_special) -// { -// TestFixture::test_ror_special(); -// } -// TYPED_TEST(stdlib_uint, test_hash_rounds) -// { -// TestFixture::test_hash_rounds(); -// } -// // BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO -// TYPED_TEST(stdlib_uint, test_add) -// { -// TestFixture::test_add(); -// } -// TYPED_TEST(stdlib_uint, test_sub) -// { -// TestFixture::test_sub(); -// } -// TYPED_TEST(stdlib_uint, test_mul) -// { -// TestFixture::test_mul(); -// } -// TYPED_TEST(stdlib_uint, test_divide) -// { -// TestFixture::test_divide(); -// } -// TYPED_TEST(stdlib_uint, test_modulo) -// { -// TestFixture::test_modulo(); -// } -// TYPED_TEST(stdlib_uint, test_divide_by_zero_fails) -// { -// TestFixture::test_divide_by_zero_fails(); -// } -// TYPED_TEST(stdlib_uint, test_divide_special) -// { -// TestFixture::test_divide_special(); -// } -// TYPED_TEST(stdlib_uint, div_remainder_constraint) -// { -// TestFixture::div_remainder_constraint(); -// } -// TYPED_TEST(stdlib_uint, test_and) -// { -// TestFixture::test_and(); -// } -// TYPED_TEST(stdlib_uint, test_xor) -// { -// TestFixture::test_xor(); -// } -// TYPED_TEST(stdlib_uint, test_or) -// { -// TestFixture::test_or(); -// } -// TYPED_TEST(stdlib_uint, test_not) -// { -// TestFixture::test_not(); -// } -// TYPED_TEST(stdlib_uint, test_gt) -// { -// TestFixture::test_gt(); -// } -// TYPED_TEST(stdlib_uint, test_lt) -// { -// TestFixture::test_lt(); -// } -// TYPED_TEST(stdlib_uint, test_gte) -// { -// TestFixture::test_gte(); -// } -// TYPED_TEST(stdlib_uint, test_lte) -// { -// TestFixture::test_lte(); -// } -// TYPED_TEST(stdlib_uint, test_equality_operator) -// { -// TestFixture::test_equality_operator(); -// } -// TYPED_TEST(stdlib_uint, test_not_equality_operator) -// { -// TestFixture::test_not_equality_operator(); -// } -// TYPED_TEST(stdlib_uint, test_logical_not) -// { -// TestFixture::test_logical_not(); -// } -// TYPED_TEST(stdlib_uint, test_right_shift) -// { -// TestFixture::test_right_shift(); -// } -// TYPED_TEST(stdlib_uint, test_left_shift) -// { -// TestFixture::test_left_shift(); -// } -// TYPED_TEST(stdlib_uint, test_ror) -// { -// TestFixture::test_ror(); -// } -// TYPED_TEST(stdlib_uint, test_rol) -// { -// TestFixture::test_rol(); -// } -// TYPED_TEST(stdlib_uint, test_at) -// { -// TestFixture::test_at(); -// } - -// // There was one plookup-specific test in the ./plookup/uint_plookup.test.cpp -// TEST(stdlib_uint32, test_accumulators_plookup_uint32) -// { -// using uint32_ct = plonk::stdlib::uint32; -// using witness_ct = plonk::stdlib::witness_t; - -// plonk::UltraComposer composer = plonk::UltraComposer(); - -// uint32_t a_val = engine.get_random_uint32(); -// uint32_t b_val = engine.get_random_uint32(); -// uint32_ct a = witness_ct(&composer, a_val); -// uint32_ct b = witness_ct(&composer, b_val); -// a = a ^ b; -// uint32_t val = a_val ^ b_val; -// uint32_t MASK = (1U << uint32_ct::bits_per_limb) - 1; -// const auto accumulators = a.get_accumulators(); -// for (size_t i = 0; i < uint32_ct::num_accumulators(); ++i) { -// const uint64_t result = uint256_t(composer.get_variable(accumulators[i])).data[0]; -// const uint64_t expected = val & MASK; -// val = val >> uint32_ct::bits_per_limb; -// EXPECT_EQ(result, expected); -// } - -// printf("calling preprocess\n"); -// auto prover = composer.create_prover(); - -// printf("composer gates = %zu\n", composer.get_num_gates()); -// auto verifier = composer.create_verifier(); - -// auto proof = prover.construct_proof(); - -// bool proof_result = verifier.verify_proof(proof); -// EXPECT_EQ(proof_result, true); -// } -// } // namespace test_stdlib_uint +#include "uint.hpp" +#include "barretenberg/honk/composer/standard_honk_composer.hpp" +#include +#include +#include "barretenberg/numeric/random/engine.hpp" + +using namespace barretenberg; +using namespace plonk; +using namespace bonk; + +namespace { +auto& engine = numeric::random::get_debug_engine(); +} + +// NOTE: We only test width 32, but widths 8, 16, 32 and 64 can all be tested. +// In widths 8, 16, 32: all tests pass. +// In width 64, the following tests fail for UltraComposer. +// test_xor_special, test_xor_more_constants, test_and_constants, test_and_special, test_or_special, +// test_ror_special, test_hash_rounds, test_and, test_xor, test_or. +// They fail with 'C++ exception with description"Last key slice greater than 64" thrown in the test body."' +namespace test_stdlib_uint { +typedef uint32_t uint_native; +size_t uint_native_width = 8 * sizeof(uint_native); +uint_native uint_native_max = static_cast((static_cast(1) << uint_native_width) - 1); + +template Native get_random() +{ + return static_cast(engine.get_random_uint64()); +}; + +template std::vector get_several_random(size_t num) +{ + std::vector result; + for (size_t i = 0; i < num; ++i) { + result.emplace_back(get_random()); + } + return result; +} + +/** + * @brief Utility function for testing the uint_ct comparison operators + * + * @details Given a uint_ct a and a constant const_b, this allows to create a + * uint_ct b having a desired relation to a (either >. = or <). + */ +uint_native impose_comparison(uint_native const_a, + uint_native const_b, + uint_native a_val, + bool force_equal = false, + bool force_gt = false, + bool force_lt = false) +{ + uint_native b_val; + if (force_equal) { + b_val = a_val + const_a - const_b; + } else if (force_lt) { // forcing b < a + // if a_val + const_a != const_b, then we set up b_val + const_b = a_val + const_a - 1 + // elif a_val + const_a = const_b, then we set up b_val + const_b = a_val + const_a + // and we increment a by 1, leading to a_val + const_a = b_val + const_b + 1. + b_val = (a_val + const_a - const_b) ? a_val + const_a - const_b - 1 : const_a - const_b + (a_val++); + } else if (force_gt) { // forcing b > a + // set b_val + const_b = a_val + const_a + 1 unless that would wrap, in which case we instead + // set b_val + const_b = a then decrease a by 1. + b_val = (a_val + const_a - const_b) == uint_native_width ? const_a - const_b + (a_val--) + : a_val + const_a - const_b + 1; + } else { + b_val = get_random(); + } + return b_val; +} + +uint_native rotate(uint_native value, size_t rotation) +{ + return rotation ? static_cast(value >> rotation) + + static_cast(value << (uint_native_width - rotation)) + : value; +} +template class stdlib_uint : public testing::Test { + typedef typename std::conditional, + stdlib::uint>::type uint_ct; + typedef stdlib::bool_t bool_ct; + typedef stdlib::witness_t witness_ct; + typedef stdlib::byte_array byte_array_ct; + + static inline std::vector special_values{ 0U, + 1U, + 2U, + static_cast(1 << uint_native_width / 4), + static_cast(1 << uint_native_width / 2), + static_cast((1 << uint_native_width / 2) + 1), + uint_native_max }; + + static std::vector get_special_uints(Composer* ctx) + { + std::vector special_uints; + for (size_t i = 0; i != special_values.size(); ++i) { + special_uints.emplace_back(witness_ct(ctx, special_values[i])); + }; + return special_uints; + }; + + public: + static void test_weak_normalize() + { + auto run_test = [](bool constant_only, bool add_constant) { + Composer composer = Composer(); + uint_ct a; + uint_native a_val = get_random(); + uint_native const_a = get_random(); + uint_native expected; + + if (constant_only) { + a = const_a; + expected = const_a; + } else { + a = witness_ct(&composer, a_val); + expected = a_val; + if (add_constant) { + a += const_a; + expected += const_a; + } + }; + + EXPECT_EQ(expected, a.get_value()); + auto prover = composer.create_prover(); + auto verifier = composer.create_verifier(); + plonk::proof proof = prover.construct_proof(); + bool verified = verifier.verify_proof(proof); + EXPECT_EQ(verified, true); + }; + + run_test(true, false); + run_test(false, false); + run_test(false, true); + } + + static void test_byte_array_conversion() + { + Composer composer = Composer(); + uint_ct a = witness_ct(&composer, 0x7f6f5f4f10111213); + std::string longest_expected = { 0x7f, 0x6f, 0x5f, 0x4f, 0x10, 0x11, 0x12, 0x13 }; + // truncate, so we are running different tests for different choices of uint_native + std::string expected = longest_expected.substr(longest_expected.length() - sizeof(uint_native)); + byte_array_ct arr(&composer); + arr.write(static_cast(a)); + + EXPECT_EQ(arr.size(), sizeof(uint_native)); + EXPECT_EQ(arr.get_string(), expected); + } + + static void test_input_output_consistency() + { + Composer composer = Composer(); + + for (size_t i = 1; i < 1024; i *= 2) { + uint_native a_expected = (uint_native)i; + uint_native b_expected = (uint_native)i; + + uint_ct a = witness_ct(&composer, a_expected); + uint_ct b = witness_ct(&composer, b_expected); + + byte_array_ct arr(&composer); + + arr.write(static_cast(a)); + arr.write(static_cast(b)); + + EXPECT_EQ(arr.size(), 2 * sizeof(uint_native)); + + uint_ct a_result(arr.slice(0, sizeof(uint_native))); + uint_ct b_result(arr.slice(sizeof(uint_native))); + + EXPECT_EQ(a_result.get_value(), a_expected); + EXPECT_EQ(b_result.get_value(), b_expected); + } + } + + static void test_create_from_wires() + { + Composer composer = Composer(); + + uint_ct a = uint_ct(&composer, + std::vector{ + bool_ct(false), + bool_ct(false), + bool_ct(false), + bool_ct(false), + bool_ct(false), + bool_ct(false), + bool_ct(false), + witness_ct(&composer, true), + }); + + EXPECT_EQ(a.at(0).get_value(), false); + EXPECT_EQ(a.at(7).get_value(), true); + EXPECT_EQ(static_cast(a.get_value()), 128U); + } + + /** + * @brief Test addition of special values. + * */ + static void test_add_special() + { + Composer composer = Composer(); + + witness_ct first_input(&composer, 1U); + witness_ct second_input(&composer, 0U); + + uint_ct a = first_input; + uint_ct b = second_input; + uint_ct c = a + b; + /** + * Fibbonacci sequence a(0) = 0, a(1), ..., a(2 + 32) = 5702887 + * a | 1 | 1 | 2 | 3 | 5 | ... + * b | 0 | 1 | 1 | 2 | 3 | ... + * c | 1 | 2 | 3 | 5 | 8 | ... + */ + for (size_t i = 0; i < uint_native_width; ++i) { + b = a; + a = c; + c = a + b; + } + + auto special_uints = get_special_uints(&composer); + for (size_t i = 0; i != special_values.size(); ++i) { + uint_native x = special_values[i]; + uint_ct x_ct = special_uints[i]; + + for (size_t j = i; j != special_values.size(); ++j) { + uint_native y = special_values[j]; + uint_ct y_ct = special_uints[j]; + + uint_native expected_value = x + y; + uint_ct z_ct = x_ct + y_ct; + uint_native value = static_cast(z_ct.get_value()); + + EXPECT_EQ(value, expected_value); + } + }; + + auto prover = composer.create_prover(); + auto verifier = composer.create_verifier(); + plonk::proof proof = prover.construct_proof(); + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + static void test_sub_special() + { + Composer composer = Composer(); + + witness_ct a_val(&composer, static_cast(4)); + // witness_ct b_val(&composer, static_cast(5)); + uint_native const_a = 1; + uint_native const_b = 2; + uint_ct a = uint_ct(a_val) + const_a; + // uint_ct b = uint_ct(b_val) + const_b; + uint_ct b = const_b; + uint_ct diff = a - b; + + auto special_uints = get_special_uints(&composer); + for (size_t i = 0; i != special_values.size(); ++i) { + uint_native x = special_values[i]; + uint_ct x_ct = special_uints[i]; + + for (size_t j = i; j != special_values.size(); ++j) { + uint_native y = special_values[j]; + uint_ct y_ct = special_uints[j]; + + uint_native expected_value = x - y; + uint_ct z_ct = x_ct - y_ct; + uint_native value = static_cast(z_ct.get_value()); + + EXPECT_EQ(value, expected_value); + } + }; + + auto prover = composer.create_prover(); + auto verifier = composer.create_verifier(); + plonk::proof proof = prover.construct_proof(); + bool verified = verifier.verify_proof(proof); + + EXPECT_EQ(verified, true); + } + + static void test_add_with_constants() + { + size_t n = 8; + std::vector witnesses = get_several_random(3 * n); + uint_native expected[8]; + for (size_t i = 2; i < n; ++i) { + expected[0] = witnesses[3 * i]; + expected[1] = witnesses[3 * i + 1]; + expected[2] = witnesses[3 * i + 2]; + expected[3] = expected[0] + expected[1]; + expected[4] = expected[1] + expected[0]; + expected[5] = expected[1] + expected[2]; + expected[6] = expected[3] + expected[4]; + expected[7] = expected[4] + expected[5]; + } + Composer composer = Composer(); + uint_ct result[8]; + for (size_t i = 2; i < n; ++i) { + result[0] = uint_ct(&composer, witnesses[3 * i]); + result[1] = (witness_ct(&composer, witnesses[3 * i + 1])); + result[2] = (witness_ct(&composer, witnesses[3 * i + 2])); + result[3] = result[0] + result[1]; + result[4] = result[1] + result[0]; + result[5] = result[1] + result[2]; + result[6] = result[3] + result[4]; + result[7] = result[4] + result[5]; + } + + for (size_t i = 0; i < n; ++i) { + EXPECT_EQ(result[i].get_value(), expected[i]); + } + + auto prover = composer.create_prover(); + auto verifier = composer.create_verifier(); + plonk::proof proof = prover.construct_proof(); + bool proof_valid = verifier.verify_proof(proof); + EXPECT_EQ(proof_valid, true); + } + + static void test_mul_special() + { + uint_native a_expected = 1U; + uint_native b_expected = 2U; + uint_native c_expected = a_expected + b_expected; + for (size_t i = 0; i < 100; ++i) { + b_expected = a_expected; + a_expected = c_expected; + c_expected = a_expected * b_expected; + } + + Composer composer = Composer(); + + witness_ct first_input(&composer, 1U); + witness_ct second_input(&composer, 2U); + + uint_ct a = first_input; + uint_ct b = second_input; + uint_ct c = a + b; + for (size_t i = 0; i < 100; ++i) { + b = a; + a = c; + c = a * b; + } + uint_native c_result = + static_cast(composer.get_variable(c.get_witness_index()).from_montgomery_form().data[0]); + EXPECT_EQ(c_result, c_expected); + + auto special_uints = get_special_uints(&composer); + for (size_t i = 0; i != special_values.size(); ++i) { + uint_native x = special_values[i]; + uint_ct x_ct = special_uints[i]; + + for (size_t j = i; j != special_values.size(); ++j) { + uint_native y = special_values[j]; + uint_ct y_ct = special_uints[j]; + + uint_native expected_value = x * y; + uint_ct z_ct = x_ct * y_ct; + uint_native value = static_cast(z_ct.get_value()); + + EXPECT_EQ(value, expected_value); + } + }; + + auto prover = composer.create_prover(); + auto verifier = composer.create_verifier(); + plonk::proof proof = prover.construct_proof(); + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + static void test_mul_big() + { + uint_native max = uint_native_max; + + Composer composer = Composer(); + uint_ct a = witness_ct(&composer, max); + a = a + max; + uint_ct b = a; + uint_ct c = a * b; + + auto prover = composer.create_prover(); + auto verifier = composer.create_verifier(); + plonk::proof proof = prover.construct_proof(); + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + static void test_xor_special() + { + uint_native a_expected = static_cast(0x10000000a3b10422); + uint_native b_expected = static_cast(0xfafab007eac21343); + uint_native c_expected = a_expected ^ b_expected; + for (size_t i = 0; i < uint_native_width; ++i) { + b_expected = a_expected; + a_expected = c_expected; + c_expected = a_expected + b_expected; + a_expected = c_expected ^ a_expected; + } + + Composer composer = Composer(); + + witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); + witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + + uint_ct a = first_input; + uint_ct b = second_input; + uint_ct c = a ^ b; + for (size_t i = 0; i < uint_native_width; ++i) { + b = a; + a = c; + c = a + b; + a = c ^ a; + } + uint_native a_result = + static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); + + EXPECT_EQ(a_result, a_expected); + + auto prover = composer.create_prover(); + + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + static void test_xor_constants() + { + Composer composer = Composer(); + + uint_native a_expected = static_cast(0x10000000a3b10422); + uint_native b_expected = static_cast(0xfafab007eac21343); + uint_native c_expected = a_expected ^ b_expected; + + uint_ct const_a(&composer, static_cast(0x10000000a3b10422)); + uint_ct const_b(&composer, static_cast(0xfafab007eac21343)); + uint_ct c = const_a ^ const_b; + c.get_witness_index(); + + EXPECT_EQ(c.get_additive_constant(), uint256_t(c_expected)); + } + + static void test_xor_more_constants() + { + uint_native a_expected = static_cast(0x10000000a3b10422); + uint_native b_expected = static_cast(0xfafab007eac21343); + uint_native c_expected = a_expected ^ b_expected; + for (size_t i = 0; i < 1; ++i) { + b_expected = a_expected; + a_expected = c_expected; + c_expected = (a_expected + b_expected) ^ + (static_cast(0x10000000a3b10422) ^ static_cast(0xfafab007eac21343)); + } + + Composer composer = Composer(); + + witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); + witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + + uint_ct a = first_input; + uint_ct b = second_input; + uint_ct c = a ^ b; + for (size_t i = 0; i < 1; ++i) { + uint_ct const_a = static_cast(0x10000000a3b10422); + uint_ct const_b = static_cast(0xfafab007eac21343); + b = a; + a = c; + c = (a + b) ^ (const_a ^ const_b); + } + uint32_t c_witness_index = c.get_witness_index(); + uint_native c_result = + static_cast(composer.get_variable(c_witness_index).from_montgomery_form().data[0]); + EXPECT_EQ(c_result, c_expected); + auto prover = composer.create_prover(); + + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + static void test_and_constants() + { + uint_native a_expected = static_cast(0x10000000a3b10422); + uint_native b_expected = static_cast(0xfafab007eac21343); + uint_native c_expected = a_expected & b_expected; + for (size_t i = 0; i < 1; ++i) { + b_expected = a_expected; + a_expected = c_expected; + c_expected = (~a_expected & static_cast(0x10000000a3b10422)) + + (b_expected & static_cast(0xfafab007eac21343)); + // c_expected = (a_expected + b_expected) & (static_cast(0x10000000a3b10422) & + // static_cast(0xfafab007eac21343)); + } + + Composer composer = Composer(); + + witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); + witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + + uint_ct a = first_input; + uint_ct b = second_input; + uint_ct c = a & b; + for (size_t i = 0; i < 1; ++i) { + uint_ct const_a = static_cast(0x10000000a3b10422); + uint_ct const_b = static_cast(0xfafab007eac21343); + b = a; + a = c; + c = (~a & const_a) + (b & const_b); + } + uint32_t c_witness_index = c.get_witness_index(); + uint_native c_result = + static_cast(composer.get_variable(c_witness_index).from_montgomery_form().data[0]); + EXPECT_EQ(c_result, c_expected); + auto prover = composer.create_prover(); + + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + static void test_and_special() + { + uint_native a_expected = static_cast(0x10000000a3b10422); + uint_native b_expected = static_cast(0xfafab007eac21343); + uint_native c_expected = a_expected + b_expected; + for (size_t i = 0; i < uint_native_width; ++i) { + b_expected = a_expected; + a_expected = c_expected; + c_expected = a_expected + b_expected; + a_expected = c_expected & a_expected; + } + + Composer composer = Composer(); + + witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); + witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + + uint_ct a = first_input; + uint_ct b = second_input; + uint_ct c = a + b; + for (size_t i = 0; i < uint_native_width; ++i) { + b = a; + a = c; + c = a + b; + a = c & a; + } + uint_native a_result = + static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); + EXPECT_EQ(a_result, a_expected); + + auto prover = composer.create_prover(); + + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + static void test_or_special() + { + uint_native a_expected = static_cast(0x10000000a3b10422); + uint_native b_expected = static_cast(0xfafab007eac21343); + uint_native c_expected = a_expected ^ b_expected; + for (size_t i = 0; i < uint_native_width; ++i) { + b_expected = a_expected; + a_expected = c_expected; + c_expected = a_expected + b_expected; + a_expected = c_expected | a_expected; + } + + Composer composer = Composer(); + + witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); + witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + + uint_ct a = first_input; + uint_ct b = second_input; + uint_ct c = a ^ b; + for (size_t i = 0; i < uint_native_width; ++i) { + b = a; + a = c; + c = a + b; + a = c | a; + } + uint_native a_result = + static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); + EXPECT_EQ(a_result, a_expected); + + auto prover = composer.create_prover(); + + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + static void test_gt_special() + { + const auto run_test = [](bool lhs_constant, bool rhs_constant, int type = 0) { + uint_native a_expected = static_cast(0x10000000a3b10422); + uint_native b_expected; + switch (type) { + case 0: { + b_expected = static_cast(0x20000000bac21343); // a < b + break; + } + case 1: { + b_expected = static_cast(0x0000000000002f12); // a > b + break; + } + case 2: { + b_expected = static_cast(0x10000000a3b10422); // a = b + break; + } + default: { + b_expected = static_cast(0x20000000bac21343); // a < b + } + } + bool c_expected = a_expected > b_expected; + + Composer composer = Composer(); + + uint_ct a; + uint_ct b; + if (lhs_constant) { + a = uint_ct(nullptr, a_expected); + } else { + a = witness_ct(&composer, a_expected); + } + if (rhs_constant) { + b = uint_ct(nullptr, b_expected); + } else { + b = witness_ct(&composer, b_expected); + } + // mix in some constant terms for good measure + a *= uint_ct(&composer, 2); + a += uint_ct(&composer, 1); + b *= uint_ct(&composer, 2); + b += uint_ct(&composer, 1); + + bool_ct c = a > b; + + bool c_result = static_cast(c.get_value()); + EXPECT_EQ(c_result, c_expected); + + auto prover = composer.create_prover(); + + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + }; + + run_test(false, false, 0); + run_test(false, true, 0); + run_test(true, false, 0); + run_test(true, true, 0); + run_test(false, false, 1); + run_test(false, true, 1); + run_test(true, false, 1); + run_test(true, true, 1); + run_test(false, false, 2); + run_test(false, true, 2); + run_test(true, false, 2); + run_test(true, true, 2); + } + + static uint_native rotate(uint_native value, size_t rotation) + { + return rotation ? static_cast(value >> rotation) + + static_cast(value << (uint_native_width - rotation)) + : value; + } + + static void test_ror_special() + { + uint_native a_expected = static_cast(0x10000000a3b10422); + uint_native b_expected = static_cast(0xfafab007eac21343); + uint_native c_expected = a_expected ^ b_expected; + for (size_t i = 0; i < uint_native_width; ++i) { + b_expected = a_expected; + a_expected = c_expected; + c_expected = a_expected + b_expected; + a_expected = rotate(c_expected, i % 31) + rotate(a_expected, (i + 1) % 31); + } + + Composer composer = Composer(); + + witness_ct first_input(&composer, static_cast(0x10000000a3b10422)); + witness_ct second_input(&composer, static_cast(0xfafab007eac21343)); + + uint_ct a = first_input; + uint_ct b = second_input; + uint_ct c = a ^ b; + for (size_t i = 0; i < uint_native_width; ++i) { + b = a; + a = c; + c = a + b; + a = c.ror(static_cast(i % 31)) + a.ror(static_cast((i + 1) % 31)); + } + uint_native a_result = + static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); + EXPECT_EQ(a_result, a_expected); + + auto prover = composer.create_prover(); + + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + /** + * @brief If uint_native_width == 32, test part of SHA256. Otherwise, do something similar. + * + * @details Notes that the static casts have to be there becuase of -Wc++11-narrowing flag. + * + * TurboPLONK: 19896 gates + * StandardPLONK: 210363 gates + */ + static void test_hash_rounds() + { + std::vector k_constants(64); + std::vector round_values(8); + if (uint_native_width == 32) { + k_constants = { static_cast(0x428a2f98), static_cast(0x71374491), + static_cast(0xb5c0fbcf), static_cast(0xe9b5dba5), + static_cast(0x3956c25b), static_cast(0x59f111f1), + static_cast(0x923f82a4), static_cast(0xab1c5ed5), + static_cast(0xd807aa98), static_cast(0x12835b01), + static_cast(0x243185be), static_cast(0x550c7dc3), + static_cast(0x72be5d74), static_cast(0x80deb1fe), + static_cast(0x9bdc06a7), static_cast(0xc19bf174), + static_cast(0xe49b69c1), static_cast(0xefbe4786), + static_cast(0x0fc19dc6), static_cast(0x240ca1cc), + static_cast(0x2de92c6f), static_cast(0x4a7484aa), + static_cast(0x5cb0a9dc), static_cast(0x76f988da), + static_cast(0x983e5152), static_cast(0xa831c66d), + static_cast(0xb00327c8), static_cast(0xbf597fc7), + static_cast(0xc6e00bf3), static_cast(0xd5a79147), + static_cast(0x06ca6351), static_cast(0x14292967), + static_cast(0x27b70a85), static_cast(0x2e1b2138), + static_cast(0x4d2c6dfc), static_cast(0x53380d13), + static_cast(0x650a7354), static_cast(0x766a0abb), + static_cast(0x81c2c92e), static_cast(0x92722c85), + static_cast(0xa2bfe8a1), static_cast(0xa81a664b), + static_cast(0xc24b8b70), static_cast(0xc76c51a3), + static_cast(0xd192e819), static_cast(0xd6990624), + static_cast(0xf40e3585), static_cast(0x106aa070), + static_cast(0x19a4c116), static_cast(0x1e376c08), + static_cast(0x2748774c), static_cast(0x34b0bcb5), + static_cast(0x391c0cb3), static_cast(0x4ed8aa4a), + static_cast(0x5b9cca4f), static_cast(0x682e6ff3), + static_cast(0x748f82ee), static_cast(0x78a5636f), + static_cast(0x84c87814), static_cast(0x8cc70208), + static_cast(0x90befffa), static_cast(0xa4506ceb), + static_cast(0xbef9a3f7), static_cast(0xc67178f2) }; + + round_values = { static_cast(0x01020304), static_cast(0x0a0b0c0d), + static_cast(0x1a2b3e4d), static_cast(0x03951bd3), + static_cast(0x0e0fa3fe), static_cast(0x01000000), + static_cast(0x0f0eeea1), static_cast(0x12345678) }; + } else { + k_constants = get_several_random(64); + round_values = get_several_random(8); + }; + + std::vector w_alt = get_several_random(64); + + uint_native a_alt = round_values[0]; + uint_native b_alt = round_values[1]; + uint_native c_alt = round_values[2]; + uint_native d_alt = round_values[3]; + uint_native e_alt = round_values[4]; + uint_native f_alt = round_values[5]; + uint_native g_alt = round_values[6]; + uint_native h_alt = round_values[7]; + for (size_t i = 0; i < 64; ++i) { + uint_native S1_alt = rotate(e_alt, 7 % uint_native_width) ^ rotate(e_alt, 11 % uint_native_width) ^ + rotate(e_alt, 25 % uint_native_width); + uint_native ch_alt = (e_alt & f_alt) ^ ((~e_alt) & g_alt); + uint_native temp1_alt = h_alt + S1_alt + ch_alt + k_constants[i % 64] + w_alt[i]; + + uint_native S0_alt = rotate(a_alt, 2 % uint_native_width) ^ rotate(a_alt, 13 % uint_native_width) ^ + rotate(a_alt, 22 % uint_native_width); + uint_native maj_alt = (a_alt & b_alt) ^ (a_alt & c_alt) ^ (b_alt & c_alt); + uint_native temp2_alt = S0_alt + maj_alt; + + h_alt = g_alt; + g_alt = f_alt; + f_alt = e_alt; + e_alt = d_alt + temp1_alt; + d_alt = c_alt; + c_alt = b_alt; + b_alt = a_alt; + a_alt = temp1_alt + temp2_alt; + } + Composer composer = Composer(); + + std::vector w; + std::vector k; + for (size_t i = 0; i < 64; ++i) { + w.emplace_back(uint_ct(witness_ct(&composer, w_alt[i]))); + k.emplace_back(uint_ct(&composer, k_constants[i % 64])); + } + uint_ct a = witness_ct(&composer, round_values[0]); + uint_ct b = witness_ct(&composer, round_values[1]); + uint_ct c = witness_ct(&composer, round_values[2]); + uint_ct d = witness_ct(&composer, round_values[3]); + uint_ct e = witness_ct(&composer, round_values[4]); + uint_ct f = witness_ct(&composer, round_values[5]); + uint_ct g = witness_ct(&composer, round_values[6]); + uint_ct h = witness_ct(&composer, round_values[7]); + for (size_t i = 0; i < 64; ++i) { + uint_ct S1 = + e.ror(7U % uint_native_width) ^ e.ror(11U % uint_native_width) ^ e.ror(25U % uint_native_width); + uint_ct ch = (e & f) + ((~e) & g); + uint_ct temp1 = h + S1 + ch + k[i] + w[i]; + + uint_ct S0 = + a.ror(2U % uint_native_width) ^ a.ror(13U % uint_native_width) ^ a.ror(22U % uint_native_width); + uint_ct T0 = (b & c); + uint_ct T1 = (b - T0) + (c - T0); + uint_ct T2 = a & T1; + uint_ct maj = T2 + T0; + uint_ct temp2 = S0 + maj; + + h = g; + g = f; + f = e; + e = d + temp1; + d = c; + c = b; + b = a; + a = temp1 + temp2; + } + + uint_native a_result = + static_cast(composer.get_variable(a.get_witness_index()).from_montgomery_form().data[0]); + uint_native b_result = + static_cast(composer.get_variable(b.get_witness_index()).from_montgomery_form().data[0]); + uint_native c_result = + static_cast(composer.get_variable(c.get_witness_index()).from_montgomery_form().data[0]); + uint_native d_result = + static_cast(composer.get_variable(d.get_witness_index()).from_montgomery_form().data[0]); + uint_native e_result = + static_cast(composer.get_variable(e.get_witness_index()).from_montgomery_form().data[0]); + uint_native f_result = + static_cast(composer.get_variable(f.get_witness_index()).from_montgomery_form().data[0]); + uint_native g_result = + static_cast(composer.get_variable(g.get_witness_index()).from_montgomery_form().data[0]); + uint_native h_result = + static_cast(composer.get_variable(h.get_witness_index()).from_montgomery_form().data[0]); + + EXPECT_EQ(a_result, a_alt); + EXPECT_EQ(b_result, b_alt); + EXPECT_EQ(c_result, c_alt); + EXPECT_EQ(d_result, d_alt); + EXPECT_EQ(e_result, e_alt); + EXPECT_EQ(f_result, f_alt); + EXPECT_EQ(g_result, g_alt); + EXPECT_EQ(h_result, h_alt); + + auto prover = composer.create_prover(); + + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + // BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO + + /** + * @brief Test addition of random uint's, trying all combinations of (constant, witness). + */ + static void test_add() + { + Composer composer = Composer(); + + const auto add_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { + uint_native a_val = get_random(); + uint_native b_val = get_random(); + uint_native expected = a_val + b_val; + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); + uint_ct c = a + b; + c = c.normalize(); + + uint_native result = uint_native(c.get_value()); + + EXPECT_EQ(result, expected); + }; + + add_integers(false, false); + add_integers(false, true); + add_integers(true, false); + add_integers(true, true); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_sub() + { + Composer composer = Composer(); + + const auto sub_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { + uint_native a_val = get_random(); + uint_native b_val = get_random(); + uint_native const_shift_val = get_random(); + uint_native expected = a_val - (b_val + const_shift_val); + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); + uint_ct b_shift = uint_ct(&composer, const_shift_val); + uint_ct c = b + b_shift; + uint_ct d = a - c; + d = d.normalize(); + + uint_native result = uint_native(d.get_value()); + + EXPECT_EQ(result, expected); + }; + + sub_integers(false, false); + sub_integers(false, true); + sub_integers(true, false); + sub_integers(true, true); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_mul() + { + Composer composer = Composer(); + + const auto mul_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { + uint_native a_val = get_random(); + uint_native b_val = get_random(); + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native expected = + static_cast(a_val + const_a) * static_cast(b_val + const_b); + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + uint_ct e = c * d; + e = e.normalize(); + + uint_native result = uint_native(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + mul_integers(false, false); + mul_integers(false, true); + mul_integers(true, false); + mul_integers(true, true); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_divide() + { + Composer composer = Composer(); + + const auto divide_integers = [&composer](bool lhs_constant = false, + bool rhs_constant = false, + bool dividend_is_divisor = false, + bool dividend_zero = false, + bool divisor_zero = false) { + uint_native a_val = get_random(); + uint_native b_val = dividend_is_divisor ? a_val : get_random(); + uint_native const_a = dividend_zero ? 0 - a_val : get_random(); + uint_native const_b = + divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); + uint_native expected = + static_cast(a_val + const_a) / static_cast(b_val + const_b); + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + uint_ct e = c / d; + e = e.normalize(); + + uint_native result = static_cast(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + divide_integers(false, false, false, false, false); + divide_integers(false, false, false, false, false); + divide_integers(false, false, false, false, false); + divide_integers(false, false, false, false, false); + divide_integers(false, false, false, false, false); + + divide_integers(false, true, false, false, false); + divide_integers(true, false, false, false, false); + divide_integers(true, true, false, false, false); // fails; 0 != 1 + + divide_integers(false, false, true, false, false); + divide_integers(false, true, true, false, false); + divide_integers(true, false, true, false, false); + divide_integers(true, true, true, false, false); + + divide_integers(false, false, false, true, false); + divide_integers(false, true, false, true, false); // fails; 0 != 1 + divide_integers(true, false, false, true, false); + divide_integers(true, true, false, true, false); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_modulo() + { + Composer composer = Composer(); + + const auto mod_integers = [&composer](bool lhs_constant = false, + bool rhs_constant = false, + bool dividend_is_divisor = false, + bool dividend_zero = false, + bool divisor_zero = false) { + uint_native a_val = get_random(); + uint_native b_val = dividend_is_divisor ? a_val : get_random(); + uint_native const_a = dividend_zero ? 0 - a_val : get_random(); + uint_native const_b = + divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); + uint_native expected = + static_cast(a_val + const_a) % static_cast(b_val + const_b); + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + uint_ct e = c % d; + e = e.normalize(); + + uint_native result = uint_native(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + mod_integers(false, false, false, false, false); + mod_integers(false, true, false, false, false); + mod_integers(true, false, false, false, false); + mod_integers(true, true, false, false, false); + + mod_integers(false, false, true, false, false); + mod_integers(false, true, true, false, false); + mod_integers(true, false, true, false, false); + mod_integers(true, true, true, false, false); + + mod_integers(false, false, false, true, false); + mod_integers(false, true, false, true, false); + mod_integers(true, false, false, true, false); + mod_integers(true, true, false, true, false); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_divide_by_zero_fails() + { + + const auto divide_integers = [](bool lhs_constant = false, + bool rhs_constant = false, + bool dividend_is_divisor = false, + bool dividend_zero = false, + bool divisor_zero = false) { + Composer composer = Composer(); + + uint_native a_val = get_random(); + uint_native b_val = dividend_is_divisor ? a_val : get_random(); + uint_native const_a = dividend_zero ? 0 - a_val : get_random(); + uint_native const_b = + divisor_zero ? 0 - b_val : (dividend_is_divisor ? const_a : get_random()); + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + uint_ct e = c / d; + e = e.normalize(); + + auto prover = composer.create_prover(); + + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, false); + }; + + divide_integers(false, false, false, false, true); + divide_integers(false, false, false, true, true); + divide_integers(true, true, false, false, true); + divide_integers(true, true, false, true, true); + } + + static void test_divide_special() + { + Composer composer = Composer(); + + auto special_uints = get_special_uints(&composer); + + for (size_t i = 0; i != special_values.size(); ++i) { + uint_native x = special_values[i]; + uint_ct x_ct = special_uints[i]; + + for (size_t j = i; j != special_values.size(); ++j) { + uint_native y = special_values[j]; + uint_ct y_ct = special_uints[j]; + + // uint_native hits this error when trying to divide by zero: + // Stop reason: signal SIGFPE: integer divide by zero + uint_native expected_value; + uint_ct z_ct; + uint_native value; + if (y != 0) { + expected_value = x / y; + z_ct = x_ct / y_ct; + value = static_cast(z_ct.get_value()); + EXPECT_EQ(value, expected_value); + } + } + }; + + auto prover = composer.create_prover(); + auto verifier = composer.create_verifier(); + plonk::proof proof = prover.construct_proof(); + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, true); + } + + /** + * @brief Make sure we prevent proving v / v = 0 by setting the divison remainder to be v. + * TODO: This is lifted from the implementation. Should rewrite this test after introducing framework that separates + * circuit construction from witness generation. + + */ + static void div_remainder_constraint() + { + Composer composer = Composer(); + + uint_native val = get_random(); + + uint_ct a = witness_ct(&composer, val); + uint_ct b = witness_ct(&composer, val); + + const uint32_t dividend_idx = a.get_witness_index(); + const uint32_t divisor_idx = b.get_witness_index(); + + const uint256_t divisor = b.get_value(); + + const uint256_t q = 0; + const uint256_t r = val; + + const uint32_t quotient_idx = composer.add_variable(q); + const uint32_t remainder_idx = composer.add_variable(r); + + // In this example there are no additive constaints, so we just replace them by zero below. + + // constraint: qb + const_b q + 0 b - a + r - const_a == 0 + // i.e., a + const_a = q(b + const_b) + r + const mul_quad division_gate{ .a = quotient_idx, // q + .b = divisor_idx, // b + .c = dividend_idx, // a + .d = remainder_idx, // r + .mul_scaling = fr::one(), + .a_scaling = b.get_additive_constant(), + .b_scaling = fr::zero(), + .c_scaling = fr::neg_one(), + .d_scaling = fr::one(), + .const_scaling = -a.get_additive_constant() }; + composer.create_big_mul_gate(division_gate); + + // set delta = (b + const_b - r) + + // constraint: b - r - delta + const_b == 0 + const uint256_t delta = divisor - r - 1; + const uint32_t delta_idx = composer.add_variable(delta); + + const add_triple delta_gate{ + .a = divisor_idx, // b + .b = remainder_idx, // r + .c = delta_idx, // d + .a_scaling = fr::one(), + .b_scaling = fr::neg_one(), + .c_scaling = fr::neg_one(), + .const_scaling = b.get_additive_constant(), + }; + + composer.create_add_gate(delta_gate); + + // validate delta is in the correct range + stdlib::field_t::from_witness_index(&composer, delta_idx) + .create_range_constraint(uint_native_width, + "delta range constraint fails in div_remainder_constraint test"); + + // normalize witness quotient and remainder + // minimal bit range for quotient: from 0 (in case a = b-1) to width (when b = 1). + uint_ct quotient(&composer); + composer.create_range_constraint( + quotient_idx, uint_native_width, "quotient range constraint fails in div_remainder_constraint test"); + + // constrain remainder to lie in [0, 2^width-1] + uint_ct remainder(&composer); + composer.create_range_constraint( + remainder_idx, uint_native_width, "remainder range constraint fails in div_remainder_constraint test"); + + auto prover = composer.create_prover(); + auto verifier = composer.create_verifier(); + plonk::proof proof = prover.construct_proof(); + bool result = verifier.verify_proof(proof); + EXPECT_EQ(result, false); + } + + static void test_and() + { + Composer composer = Composer(); + + const auto and_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { + uint_native a_val = get_random(); + uint_native b_val = get_random(); + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native expected = (a_val + const_a) & (b_val + const_b); + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + uint_ct e = c & d; + e = e.normalize(); + + uint_native result = uint_native(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + and_integers(false, false); + and_integers(false, true); + and_integers(true, false); + and_integers(true, true); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_xor() + { + Composer composer = Composer(); + + const auto xor_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { + uint_native a_val = get_random(); + uint_native b_val = get_random(); + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native expected = (a_val + const_a) ^ (b_val + const_b); + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + uint_ct e = c ^ d; + e = e.normalize(); + + uint_native result = uint_native(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + xor_integers(false, false); + xor_integers(false, true); + xor_integers(true, false); + xor_integers(true, true); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_or() + { + Composer composer = Composer(); + + const auto or_integers = [&composer](bool lhs_constant = false, bool rhs_constant = false) { + uint_native a_val = get_random(); + uint_native b_val = get_random(); + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native expected = (a_val + const_a) | (b_val + const_b); + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct b = rhs_constant ? uint_ct(&composer, b_val) : witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + uint_ct e = c | d; + e = e.normalize(); + + uint_native result = uint_native(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + or_integers(false, false); + or_integers(false, false); + or_integers(false, false); + or_integers(false, false); + or_integers(false, false); + or_integers(false, true); + or_integers(true, false); + or_integers(true, true); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_not() + { + Composer composer = Composer(); + + const auto not_integers = [&composer](bool lhs_constant = false, bool = false) { + uint_native a_val = get_random(); + uint_native const_a = get_random(); + uint_native expected = ~(a_val + const_a); + uint_ct a = lhs_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct c = a + a_shift; + uint_ct e = ~c; + e = e.normalize(); + + uint_native result = uint_native(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + not_integers(false, false); + not_integers(false, true); + not_integers(true, false); + not_integers(true, true); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_gt() + { + Composer composer = Composer(); + const auto compare_integers = + [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native a_val = get_random(); + uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + + bool expected = static_cast(b_val + const_b) > static_cast(a_val + const_a); + uint_ct a = witness_ct(&composer, a_val); + uint_ct b = witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + bool_ct e = d > c; + bool result = bool(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + compare_integers(false, false, false); // both are random + compare_integers(false, false, false); // '' + compare_integers(false, false, false); // '' + compare_integers(false, false, false); // '' + compare_integers(false, false, true); // b < a + compare_integers(false, true, false); // b > a + compare_integers(true, false, false); // b = a + compare_integers(false, true, false); // b > a + compare_integers(true, false, false); // b = a + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_lt() + { + Composer composer = Composer(); + + const auto compare_integers = + [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native a_val = get_random(); + uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + + bool expected = static_cast(b_val + const_b) < static_cast(a_val + const_a); + uint_ct a = witness_ct(&composer, a_val); + uint_ct b = witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + bool_ct e = d < c; + bool result = bool(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_gte() + { + Composer composer = Composer(); + + const auto compare_integers = + [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native a_val = get_random(); + uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + + bool expected = static_cast(b_val + const_b) >= static_cast(a_val + const_a); + uint_ct a = witness_ct(&composer, a_val); + uint_ct b = witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + bool_ct e = d >= c; + bool result = bool(e.get_value()); + EXPECT_EQ(result, expected); + }; + + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_lte() + { + Composer composer = Composer(); + + const auto compare_integers = + [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native a_val = get_random(); + uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + + bool expected = static_cast(b_val + const_b) <= static_cast(a_val + const_a); + uint_ct a = witness_ct(&composer, a_val); + uint_ct b = witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + bool_ct e = d <= c; + bool result = bool(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_equality_operator() + { + Composer composer = Composer(); + + const auto compare_integers = + [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native a_val = get_random(); + uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + + bool expected = static_cast(b_val + const_b) == static_cast(a_val + const_a); + uint_ct a = witness_ct(&composer, a_val); + uint_ct b = witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + bool_ct e = d == c; + bool result = bool(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_not_equality_operator() + { + Composer composer = Composer(); + + const auto compare_integers = + [&composer](bool force_equal = false, bool force_gt = false, bool force_lt = false) { + uint_native const_a = get_random(); + uint_native const_b = get_random(); + uint_native a_val = get_random(); + uint_native b_val = impose_comparison(const_a, const_b, a_val, force_equal, force_gt, force_lt); + + bool expected = static_cast(b_val + const_b) != static_cast(a_val + const_a); + uint_ct a = witness_ct(&composer, a_val); + uint_ct b = witness_ct(&composer, b_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct b_shift = uint_ct(&composer, const_b); + uint_ct c = a + a_shift; + uint_ct d = b + b_shift; + bool_ct e = d != c; + bool result = bool(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + compare_integers(false, false, true); + compare_integers(false, true, false); + compare_integers(true, false, false); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_logical_not() + { + Composer composer = Composer(); + + const auto not_integer = [&composer](bool force_zero) { + uint_native const_a = get_random(); + uint_native a_val = force_zero ? 0 - const_a : get_random(); + bool expected = !static_cast(const_a + a_val); + uint_ct a = witness_ct(&composer, a_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct c = a + a_shift; + bool_ct e = !c; + bool result = bool(e.get_value()); + + EXPECT_EQ(result, expected); + }; + + not_integer(true); + not_integer(true); + not_integer(false); + not_integer(false); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_right_shift() + { + Composer composer = Composer(); + + const auto shift_integer = [&composer](const bool is_constant, const uint_native shift) { + uint_native const_a = get_random(); + uint_native a_val = get_random(); + uint_native expected = static_cast(a_val + const_a) >> shift; + uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct c = a + a_shift; + uint_ct d = c >> shift; + uint_native result = uint_native(d.get_value()); + + EXPECT_EQ(result, expected); + }; + + for (uint_native i = 0; i < uint_native_width; ++i) { + shift_integer(false, i); + shift_integer(true, i); + } + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_left_shift() + { + Composer composer = Composer(); + + const auto shift_integer = [&composer](const bool is_constant, const uint_native shift) { + uint_native const_a = get_random(); + uint_native a_val = get_random(); + uint_native expected = static_cast((a_val + const_a) << shift); + uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct c = a + a_shift; + uint_ct d = c << shift; + uint_native result = uint_native(d.get_value()); + + EXPECT_EQ(result, expected); + }; + + for (uint_native i = 0; i < uint_native_width; ++i) { + shift_integer(true, i); + shift_integer(false, i); + } + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_ror() + { + Composer composer = Composer(); + + const auto ror_integer = [&composer](const bool is_constant, const uint_native rotation) { + const auto ror = [](const uint_native in, const uint_native rval) { + return rval ? (in >> rval) | (in << (uint_native_width - rval)) : in; + }; + + uint_native const_a = get_random(); + uint_native a_val = get_random(); + uint_native expected = static_cast(ror(static_cast(const_a + a_val), rotation)); + uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct c = a + a_shift; + uint_ct d = c.ror(rotation); + uint_native result = uint_native(d.get_value()); + + EXPECT_EQ(result, expected); + }; + + for (uint_native i = 0; i < uint_native_width; ++i) { + ror_integer(true, i); + ror_integer(false, i); + } + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + static void test_rol() + { + Composer composer = Composer(); + + const auto rol_integer = [&composer](const bool is_constant, const uint_native rotation) { + const auto rol = [](const uint_native in, const uint_native rval) { + return rval ? (in << rval) | (in >> (uint_native_width - rval)) : in; + }; + + uint_native const_a = get_random(); + uint_native a_val = get_random(); + uint_native expected = static_cast(rol(static_cast(const_a + a_val), rotation)); + uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct c = a + a_shift; + uint_ct d = c.rol(rotation); + uint_native result = uint_native(d.get_value()); + + EXPECT_EQ(result, expected); + }; + + for (uint_native i = 0; i < uint_native_width; ++i) { + rol_integer(true, i); + rol_integer(false, i); + } + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + + /** + * @brief Test the the function uint_ct::at used to extract bits. + */ + static void test_at() + { + Composer composer = Composer(); + + const auto bit_test = [&composer](const bool is_constant) { + // construct a sum of uint_ct's, where at least one is a constant, + // and validate its correctness bitwise + uint_native const_a = get_random(); + uint_native a_val = get_random(); + uint_native c_val = const_a + a_val; + uint_ct a = is_constant ? uint_ct(&composer, a_val) : witness_ct(&composer, a_val); + uint_ct a_shift = uint_ct(&composer, const_a); + uint_ct c = a + a_shift; + for (size_t i = 0; i < uint_native_width; ++i) { + bool_ct result = c.at(i); + bool expected = (((c_val >> i) & 1UL) == 1UL) ? true : false; + EXPECT_EQ(result.get_value(), expected); + EXPECT_EQ(result.get_context(), c.get_context()); + } + }; + + bit_test(false); + bit_test(true); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } +}; + +typedef testing::Types + ComposerTypes; + +TYPED_TEST_SUITE(stdlib_uint, ComposerTypes); + +TYPED_TEST(stdlib_uint, test_weak_normalize) +{ + TestFixture::test_weak_normalize(); +} +TYPED_TEST(stdlib_uint, test_byte_array_conversion) +{ + TestFixture::test_byte_array_conversion(); +} +TYPED_TEST(stdlib_uint, test_input_output_consistency) +{ + TestFixture::test_input_output_consistency(); +} +TYPED_TEST(stdlib_uint, test_create_from_wires) +{ + TestFixture::test_create_from_wires(); +} +TYPED_TEST(stdlib_uint, test_add_special) +{ + TestFixture::test_add_special(); +} +TYPED_TEST(stdlib_uint, test_sub_special) +{ + TestFixture::test_sub_special(); +} +TYPED_TEST(stdlib_uint, test_add_with_constants) +{ + TestFixture::test_add_with_constants(); +} +TYPED_TEST(stdlib_uint, test_mul_special) +{ + TestFixture::test_mul_special(); +} +TYPED_TEST(stdlib_uint, test_mul_big) +{ + TestFixture::test_mul_big(); +} +TYPED_TEST(stdlib_uint, test_xor_special) +{ + TestFixture::test_xor_special(); +} +TYPED_TEST(stdlib_uint, test_xor_constants) +{ + TestFixture::test_xor_constants(); +} +TYPED_TEST(stdlib_uint, test_xor_more_constants) +{ + TestFixture::test_xor_more_constants(); +} +TYPED_TEST(stdlib_uint, test_and_constants) +{ + TestFixture::test_and_constants(); +} +TYPED_TEST(stdlib_uint, test_and_special) +{ + TestFixture::test_and_special(); +} +TYPED_TEST(stdlib_uint, test_or_special) +{ + TestFixture::test_or_special(); +} +TYPED_TEST(stdlib_uint, test_gt_special) +{ + TestFixture::test_gt_special(); +} +TYPED_TEST(stdlib_uint, test_ror_special) +{ + TestFixture::test_ror_special(); +} +TYPED_TEST(stdlib_uint, test_hash_rounds) +{ + TestFixture::test_hash_rounds(); +} +// BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO +TYPED_TEST(stdlib_uint, test_add) +{ + TestFixture::test_add(); +} +TYPED_TEST(stdlib_uint, test_sub) +{ + TestFixture::test_sub(); +} +TYPED_TEST(stdlib_uint, test_mul) +{ + TestFixture::test_mul(); +} +TYPED_TEST(stdlib_uint, test_divide) +{ + TestFixture::test_divide(); +} +TYPED_TEST(stdlib_uint, test_modulo) +{ + TestFixture::test_modulo(); +} +TYPED_TEST(stdlib_uint, test_divide_by_zero_fails) +{ + TestFixture::test_divide_by_zero_fails(); +} +TYPED_TEST(stdlib_uint, test_divide_special) +{ + TestFixture::test_divide_special(); +} +TYPED_TEST(stdlib_uint, div_remainder_constraint) +{ + TestFixture::div_remainder_constraint(); +} +TYPED_TEST(stdlib_uint, test_and) +{ + TestFixture::test_and(); +} +TYPED_TEST(stdlib_uint, test_xor) +{ + TestFixture::test_xor(); +} +TYPED_TEST(stdlib_uint, test_or) +{ + TestFixture::test_or(); +} +TYPED_TEST(stdlib_uint, test_not) +{ + TestFixture::test_not(); +} +TYPED_TEST(stdlib_uint, test_gt) +{ + TestFixture::test_gt(); +} +TYPED_TEST(stdlib_uint, test_lt) +{ + TestFixture::test_lt(); +} +TYPED_TEST(stdlib_uint, test_gte) +{ + TestFixture::test_gte(); +} +TYPED_TEST(stdlib_uint, test_lte) +{ + TestFixture::test_lte(); +} +TYPED_TEST(stdlib_uint, test_equality_operator) +{ + TestFixture::test_equality_operator(); +} +TYPED_TEST(stdlib_uint, test_not_equality_operator) +{ + TestFixture::test_not_equality_operator(); +} +TYPED_TEST(stdlib_uint, test_logical_not) +{ + TestFixture::test_logical_not(); +} +TYPED_TEST(stdlib_uint, test_right_shift) +{ + TestFixture::test_right_shift(); +} +TYPED_TEST(stdlib_uint, test_left_shift) +{ + TestFixture::test_left_shift(); +} +TYPED_TEST(stdlib_uint, test_ror) +{ + TestFixture::test_ror(); +} +TYPED_TEST(stdlib_uint, test_rol) +{ + TestFixture::test_rol(); +} +TYPED_TEST(stdlib_uint, test_at) +{ + TestFixture::test_at(); +} + +// There was one plookup-specific test in the ./plookup/uint_plookup.test.cpp +TEST(stdlib_uint32, test_accumulators_plookup_uint32) +{ + using uint32_ct = plonk::stdlib::uint32; + using witness_ct = plonk::stdlib::witness_t; + + plonk::UltraComposer composer = plonk::UltraComposer(); + + uint32_t a_val = engine.get_random_uint32(); + uint32_t b_val = engine.get_random_uint32(); + uint32_ct a = witness_ct(&composer, a_val); + uint32_ct b = witness_ct(&composer, b_val); + a = a ^ b; + uint32_t val = a_val ^ b_val; + uint32_t MASK = (1U << uint32_ct::bits_per_limb) - 1; + const auto accumulators = a.get_accumulators(); + for (size_t i = 0; i < uint32_ct::num_accumulators(); ++i) { + const uint64_t result = uint256_t(composer.get_variable(accumulators[i])).data[0]; + const uint64_t expected = val & MASK; + val = val >> uint32_ct::bits_per_limb; + EXPECT_EQ(result, expected); + } + + printf("calling preprocess\n"); + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + auto proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); +} +} // namespace test_stdlib_uint From 3bdd82a5b36a5531f1a165cdc53938ddd50edf82 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 17:43:56 +0100 Subject: [PATCH 31/46] linting fixes --- .../dsl/acir_format/acir_format.cpp | 2 ++ .../dsl/acir_format/acir_format.hpp | 21 +++++++++++-------- .../dsl/acir_format/blake2s_constraint.cpp | 2 ++ .../dsl/acir_format/blake2s_constraint.hpp | 4 +--- .../dsl/acir_format/ecdsa_secp256k1.cpp | 2 ++ .../dsl/acir_format/ecdsa_secp256k1.hpp | 4 +--- .../dsl/acir_format/fixed_base_scalar_mul.cpp | 2 ++ .../dsl/acir_format/fixed_base_scalar_mul.hpp | 4 +--- .../dsl/acir_format/hash_to_field.cpp | 2 ++ .../dsl/acir_format/hash_to_field.hpp | 4 +--- .../dsl/acir_format/logic_constraint.cpp | 3 ++- .../dsl/acir_format/logic_constraint.hpp | 13 +++++++----- .../merkle_membership_constraint.cpp | 1 + .../merkle_membership_constraint.hpp | 5 ++--- .../barretenberg/dsl/acir_format/pedersen.cpp | 2 ++ .../barretenberg/dsl/acir_format/pedersen.hpp | 4 +--- .../dsl/acir_format/schnorr_verify.cpp | 2 ++ .../dsl/acir_format/schnorr_verify.hpp | 4 +--- .../dsl/acir_format/sha256_constraint.cpp | 2 ++ .../dsl/acir_format/sha256_constraint.hpp | 4 +--- 20 files changed, 48 insertions(+), 39 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 8fb9c4496d..30160837c7 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -1,5 +1,7 @@ #include "acir_format.hpp" +using namespace plonk::stdlib::types; + namespace acir_format { void read_witness(Composer& composer, std::vector witness) diff --git a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index 5cfa9ecb56..b6f2f2ae4b 100644 --- a/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -36,20 +36,23 @@ struct acir_format { friend bool operator==(acir_format const& lhs, acir_format const& rhs) = default; }; -void read_witness(Composer& composer, std::vector witness); +void read_witness(plonk::stdlib::types::Composer& composer, std::vector witness); -void create_circuit(Composer& composer, const acir_format& constraint_system); +void create_circuit(plonk::stdlib::types::Composer& composer, const acir_format& constraint_system); -Composer create_circuit(const acir_format& constraint_system, - std::unique_ptr&& crs_factory); +plonk::stdlib::types::Composer create_circuit(const acir_format& constraint_system, + std::unique_ptr&& crs_factory); -Composer create_circuit_with_witness(const acir_format& constraint_system, - std::vector witness, - std::unique_ptr&& crs_factory); +plonk::stdlib::types::Composer create_circuit_with_witness(const acir_format& constraint_system, + std::vector witness, + std::unique_ptr&& crs_factory); -Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector witness); +plonk::stdlib::types::Composer create_circuit_with_witness(const acir_format& constraint_system, + std::vector witness); -void create_circuit_with_witness(Composer& composer, const acir_format& constraint_system, std::vector witness); +void create_circuit_with_witness(plonk::stdlib::types::Composer& composer, + const acir_format& constraint_system, + std::vector witness); // Serialisation template inline void read(B& buf, acir_format& data) diff --git a/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.cpp index 58ec5a928a..56fe6a521f 100644 --- a/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.cpp @@ -1,6 +1,8 @@ #include "blake2s_constraint.hpp" #include "round.hpp" +using namespace plonk::stdlib::types; + namespace acir_format { void create_blake2s_constraints(Composer& composer, const Blake2sConstraint& constraint) diff --git a/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp index 7119b2dc60..643eb1e39b 100644 --- a/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp @@ -3,8 +3,6 @@ #include #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { struct Blake2sInput { @@ -21,7 +19,7 @@ struct Blake2sConstraint { friend bool operator==(Blake2sConstraint const& lhs, Blake2sConstraint const& rhs) = default; }; -void create_blake2s_constraints(Composer& composer, const Blake2sConstraint& constraint); +void create_blake2s_constraints(plonk::stdlib::types::Composer& composer, const Blake2sConstraint& constraint); template inline void read(B& buf, Blake2sInput& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp index b38692b3c6..4287faf643 100644 --- a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp @@ -2,6 +2,8 @@ #include "barretenberg/crypto/ecdsa/ecdsa.hpp" #include "barretenberg/stdlib/encryption/ecdsa/ecdsa.hpp" +using namespace plonk::stdlib::types; + namespace acir_format { crypto::ecdsa::signature ecdsa_convert_signature(Composer& composer, std::vector signature) diff --git a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp index fdbeef1f7b..9fee1b035a 100644 --- a/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp @@ -2,8 +2,6 @@ #include #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { struct EcdsaSecp256k1Constraint { @@ -30,7 +28,7 @@ struct EcdsaSecp256k1Constraint { friend bool operator==(EcdsaSecp256k1Constraint const& lhs, EcdsaSecp256k1Constraint const& rhs) = default; }; -void create_ecdsa_verify_constraints(Composer& composer, const EcdsaSecp256k1Constraint& input); +void create_ecdsa_verify_constraints(plonk::stdlib::types::Composer& composer, const EcdsaSecp256k1Constraint& input); template inline void read(B& buf, EcdsaSecp256k1Constraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.cpp b/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.cpp index 453ab56f47..6e829a8a9a 100644 --- a/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.cpp @@ -1,5 +1,7 @@ #include "fixed_base_scalar_mul.hpp" +using namespace plonk::stdlib::types; + namespace acir_format { void create_fixed_base_constraint(Composer& composer, const FixedBaseScalarMul& input) diff --git a/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.hpp b/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.hpp index 7139f5c74f..2b61305a5c 100644 --- a/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/fixed_base_scalar_mul.hpp @@ -2,8 +2,6 @@ #include #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { struct FixedBaseScalarMul { @@ -14,7 +12,7 @@ struct FixedBaseScalarMul { friend bool operator==(FixedBaseScalarMul const& lhs, FixedBaseScalarMul const& rhs) = default; }; -void create_fixed_base_constraint(Composer& composer, const FixedBaseScalarMul& input); +void create_fixed_base_constraint(plonk::stdlib::types::Composer& composer, const FixedBaseScalarMul& input); template inline void read(B& buf, FixedBaseScalarMul& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/hash_to_field.cpp b/cpp/src/barretenberg/dsl/acir_format/hash_to_field.cpp index 9470898525..564cd13c2e 100644 --- a/cpp/src/barretenberg/dsl/acir_format/hash_to_field.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/hash_to_field.cpp @@ -1,6 +1,8 @@ #include "hash_to_field.hpp" #include "round.hpp" +using namespace plonk::stdlib::types; + namespace acir_format { void create_hash_to_field_constraints(Composer& composer, const HashToFieldConstraint constraint) diff --git a/cpp/src/barretenberg/dsl/acir_format/hash_to_field.hpp b/cpp/src/barretenberg/dsl/acir_format/hash_to_field.hpp index 6d612e82b3..275ce3fd0d 100644 --- a/cpp/src/barretenberg/dsl/acir_format/hash_to_field.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/hash_to_field.hpp @@ -3,8 +3,6 @@ #include #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { struct HashToFieldInput { @@ -21,7 +19,7 @@ struct HashToFieldConstraint { friend bool operator==(HashToFieldConstraint const& lhs, HashToFieldConstraint const& rhs) = default; }; -void create_hash_to_field_constraints(Composer& composer, HashToFieldConstraint constraint); +void create_hash_to_field_constraints(plonk::stdlib::types::Composer& composer, HashToFieldConstraint constraint); template inline void read(B& buf, HashToFieldInput& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index 1490178a41..93fa2b9f78 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -1,7 +1,8 @@ #include "logic_constraint.hpp" - #include "barretenberg/stdlib/primitives/logic/logic.hpp" +using namespace plonk::stdlib::types; + namespace acir_format { // TODO(maxim): This doesn't work correctly diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp index 615ac80f7b..0a194838ad 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.hpp @@ -2,8 +2,6 @@ #include #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { struct LogicConstraint { @@ -16,11 +14,16 @@ struct LogicConstraint { friend bool operator==(LogicConstraint const& lhs, LogicConstraint const& rhs) = default; }; -void create_logic_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result, size_t num_bits, bool is_xor_gate); +void create_logic_gate(plonk::stdlib::types::Composer& composer, + uint32_t a, + uint32_t b, + uint32_t result, + size_t num_bits, + bool is_xor_gate); -void xor_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result); +void xor_gate(plonk::stdlib::types::Composer& composer, uint32_t a, uint32_t b, uint32_t result); -void and_gate(Composer& composer, uint32_t a, uint32_t b, uint32_t result); +void and_gate(plonk::stdlib::types::Composer& composer, uint32_t a, uint32_t b, uint32_t result); template inline void read(B& buf, LogicConstraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.cpp index 4ad9a28703..8ff90de39d 100644 --- a/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.cpp @@ -1,6 +1,7 @@ #include "merkle_membership_constraint.hpp" #include "barretenberg/stdlib/merkle_tree/membership.hpp" +using namespace plonk::stdlib::types; using namespace plonk::stdlib::merkle_tree; namespace acir_format { diff --git a/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.hpp index f4c195e63f..1fa1481e88 100644 --- a/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/merkle_membership_constraint.hpp @@ -2,8 +2,6 @@ #include #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { struct MerkleMembershipConstraint { @@ -16,7 +14,8 @@ struct MerkleMembershipConstraint { friend bool operator==(MerkleMembershipConstraint const& lhs, MerkleMembershipConstraint const& rhs) = default; }; -void create_merkle_check_membership_constraint(Composer& composer, const MerkleMembershipConstraint& input); +void create_merkle_check_membership_constraint(plonk::stdlib::types::Composer& composer, + const MerkleMembershipConstraint& input); template inline void read(B& buf, MerkleMembershipConstraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp b/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp index 10f1ac10f5..466929df42 100644 --- a/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/pedersen.cpp @@ -1,5 +1,7 @@ #include "pedersen.hpp" +using namespace plonk::stdlib::types; + namespace acir_format { void create_pedersen_constraint(Composer& composer, const PedersenConstraint& input) diff --git a/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp b/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp index af46c46909..fd4c18aee6 100644 --- a/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp @@ -2,8 +2,6 @@ #include #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { // P = xG + bH @@ -15,7 +13,7 @@ struct PedersenConstraint { friend bool operator==(PedersenConstraint const& lhs, PedersenConstraint const& rhs) = default; }; -void create_pedersen_constraint(Composer& composer, const PedersenConstraint& input); +void create_pedersen_constraint(plonk::stdlib::types::Composer& composer, const PedersenConstraint& input); template inline void read(B& buf, PedersenConstraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp b/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp index ec973d23ca..7c80c4208c 100644 --- a/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp @@ -1,6 +1,8 @@ #include "schnorr_verify.hpp" #include "barretenberg/crypto/schnorr/schnorr.hpp" +using namespace plonk::stdlib::types; + namespace acir_format { crypto::schnorr::signature convert_signature(Composer& composer, std::vector signature) diff --git a/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp b/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp index f41e6d9e82..f8e6b9c53f 100644 --- a/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp @@ -2,8 +2,6 @@ #include #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { struct SchnorrConstraint { @@ -27,7 +25,7 @@ struct SchnorrConstraint { friend bool operator==(SchnorrConstraint const& lhs, SchnorrConstraint const& rhs) = default; }; -void create_schnorr_verify_constraints(Composer& composer, const SchnorrConstraint& input); +void create_schnorr_verify_constraints(plonk::stdlib::types::Composer& composer, const SchnorrConstraint& input); template inline void read(B& buf, SchnorrConstraint& constraint) { diff --git a/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp index 25ad8af174..4da8a53567 100644 --- a/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp @@ -2,6 +2,8 @@ #include "round.hpp" #include "barretenberg/stdlib/hash/sha256/sha256.hpp" +using namespace plonk::stdlib::types; + namespace acir_format { // This function does not work (properly) because the stdlib:sha256 function is not working correctly for 512 bits diff --git a/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp b/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp index 1dbd2cedfb..dec3bca40a 100644 --- a/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp @@ -3,8 +3,6 @@ #include #include "barretenberg/stdlib/types/types.hpp" -using namespace plonk::stdlib::types; - namespace acir_format { struct Sha256Input { @@ -23,7 +21,7 @@ struct Sha256Constraint { // This function does not work (properly) because the stdlib:sha256 function is not working correctly for 512 bits // pair -void create_sha256_constraints(Composer& composer, const Sha256Constraint& constraint); +void create_sha256_constraints(plonk::stdlib::types::Composer& composer, const Sha256Constraint& constraint); template inline void read(B& buf, Sha256Input& constraint) { From 72f0a8e5c94a1cc2c200f4f6d09f155a68b8be8a Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 29 Mar 2023 18:02:49 +0100 Subject: [PATCH 32/46] disable binaryen with comment --- cpp/src/CMakeLists.txt | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index fc931844a6..3a40b2a908 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -105,18 +105,24 @@ if(WASM) -nostartfiles -O2 -Wl,--no-entry -Wl,--export-dynamic -Wl,--import-memory -Wl,--allow-undefined -Wl,--stack-first -Wl,-z,stack-size=1048576 ) - find_program(WASM_OPT wasm-opt) - - if(NOT WASM_OPT) - message(FATAL_ERROR "wasm-opt executable not found. Please install binaryen.") - endif() - - add_custom_command( - TARGET barretenberg.wasm - POST_BUILD - COMMAND wasm-opt "$" -O0 --asyncify -o "$" - VERBATIM - ) + # TODO(blaine): Figure out how to Asyncify the wasm output. + # Binaryen's Asyncify transform produces wasm that has too many local variables to run in a WebAssembly + # instance. This likely would be "solved" by enabling the optimizations to reduce the number of locals, + # but using any optimization level results in a wasm file that takes an unusable amount of time to solve the + # most simple prood. + + # find_program(WASM_OPT wasm-opt) + + # if(NOT WASM_OPT) + # message(FATAL_ERROR "wasm-opt executable not found. Please install binaryen.") + # endif() + + # add_custom_command( + # TARGET barretenberg.wasm + # POST_BUILD + # COMMAND wasm-opt "$" -O0 --asyncify -o "$" + # VERBATIM + # ) if(INSTALL_BARRETENBERG) install(TARGETS barretenberg.wasm DESTINATION ${CMAKE_INSTALL_BINDIR}) From c60a65ddd8eec8097e63540f2c504a27c33a4e9b Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 30 Mar 2023 17:25:14 +0100 Subject: [PATCH 33/46] write instead of read --- cpp/src/barretenberg/dsl/acir_format/pedersen.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp b/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp index fd4c18aee6..b801d2a8f2 100644 --- a/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp +++ b/cpp/src/barretenberg/dsl/acir_format/pedersen.hpp @@ -27,8 +27,8 @@ template inline void write(B& buf, PedersenConstraint const& constr { using serialize::write; write(buf, constraint.scalars); - read(buf, constraint.result_x); - read(buf, constraint.result_y); + write(buf, constraint.result_x); + write(buf, constraint.result_y); } } // namespace acir_format From d254d94d5a8c08e79d04597f969dcaedeca9e1b3 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 30 Mar 2023 17:41:25 +0100 Subject: [PATCH 34/46] remove random --- cpp/src/barretenberg/numeric/random/engine.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cpp/src/barretenberg/numeric/random/engine.cpp b/cpp/src/barretenberg/numeric/random/engine.cpp index aeb5125070..2af39a396c 100644 --- a/cpp/src/barretenberg/numeric/random/engine.cpp +++ b/cpp/src/barretenberg/numeric/random/engine.cpp @@ -11,8 +11,11 @@ namespace { auto generate_random_data() { std::array random_data; - std::random_device source; - std::generate(std::begin(random_data), std::end(random_data), std::ref(source)); + for (unsigned int i = 0; i < random_data.size(); i++) { + random_data[i] = 100; + } + // std::random_device source; + // std::generate(std::begin(random_data), std::end(random_data), std::ref(source)); return random_data; } } // namespace From 5772a9780e1106ded4ff3193ec42800be6005552 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 30 Mar 2023 18:34:39 +0100 Subject: [PATCH 35/46] WIP --- .../plonk/proof_system/prover/prover.cpp | 19 ++++++++++++++++++- .../permutation_widget_impl.hpp | 1 + .../proof_system/work_queue/work_queue.cpp | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp b/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp index 96c3eff40f..02bd359a89 100644 --- a/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp +++ b/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp @@ -414,10 +414,21 @@ template void ProverBase::execute_fourth_round() #endif } + for (size_t i = 0; i < key->circuit_size; ++i) { + info("quotient 0", key->quotient_polynomial_parts[0][i]); + info("quotient 1", key->quotient_polynomial_parts[1][i]); + info("quotient 2", key->quotient_polynomial_parts[2][i]); + info("quotient 3", key->quotient_polynomial_parts[3][i]); + } for (auto& widget : transition_widgets) { alpha_base = widget->compute_quotient_contribution(alpha_base, transcript); } - + for (size_t i = 0; i < key->circuit_size; ++i) { + info("final quotient 0", key->quotient_polynomial_parts[0][i]); + info("final quotient 1", key->quotient_polynomial_parts[1][i]); + info("final quotient 2", key->quotient_polynomial_parts[2][i]); + info("final quotient 3", key->quotient_polynomial_parts[3][i]); + } #ifdef DEBUG_TIMING start = std::chrono::steady_clock::now(); #endif @@ -447,6 +458,12 @@ template void ProverBase::execute_fourth_round() // Manually copy the (n + 1)th coefficient of t_3 for StandardPlonk from t_4. // This is because the degree of t_3 for StandardPlonk is n. + for (size_t i = 0; i < key->circuit_size; ++i) { + info("quotient after ifft 0 ", quotient_poly_parts[0][i]); + info("quotient after ifft 1 ", quotient_poly_parts[1][i]); + info("quotient after ifft 2 ", quotient_poly_parts[2][i]); + info("quotient after ifft 3 ", quotient_poly_parts[3][i]); + } if (settings::program_width == 3) { key->quotient_polynomial_parts[2][circuit_size] = key->quotient_polynomial_parts[3][0]; key->quotient_polynomial_parts[3][0] = 0; diff --git a/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp b/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp index a25000f72f..eed2a5a566 100644 --- a/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp +++ b/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp @@ -426,6 +426,7 @@ barretenberg::fr ProverPermutationWidgetadd_element(item.tag, result.to_buffer()); break; From e40f842ecc67a1737eee673c014ee63ff3075df5 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 30 Mar 2023 21:22:27 +0100 Subject: [PATCH 36/46] cleanup the debug logging --- .../dsl/acir_format/logic_constraint.cpp | 1 - .../plonk/proof_system/prover/prover.cpp | 18 ------------------ .../random_widgets/permutation_widget_impl.hpp | 1 - .../proof_system/work_queue/work_queue.cpp | 3 --- 4 files changed, 23 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp index 93fa2b9f78..b25530fa80 100644 --- a/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/logic_constraint.cpp @@ -5,7 +5,6 @@ using namespace plonk::stdlib::types; namespace acir_format { -// TODO(maxim): This doesn't work correctly void create_logic_gate(Composer& composer, const uint32_t a, const uint32_t b, diff --git a/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp b/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp index 02bd359a89..12c5a3b1ea 100644 --- a/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp +++ b/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp @@ -414,21 +414,9 @@ template void ProverBase::execute_fourth_round() #endif } - for (size_t i = 0; i < key->circuit_size; ++i) { - info("quotient 0", key->quotient_polynomial_parts[0][i]); - info("quotient 1", key->quotient_polynomial_parts[1][i]); - info("quotient 2", key->quotient_polynomial_parts[2][i]); - info("quotient 3", key->quotient_polynomial_parts[3][i]); - } for (auto& widget : transition_widgets) { alpha_base = widget->compute_quotient_contribution(alpha_base, transcript); } - for (size_t i = 0; i < key->circuit_size; ++i) { - info("final quotient 0", key->quotient_polynomial_parts[0][i]); - info("final quotient 1", key->quotient_polynomial_parts[1][i]); - info("final quotient 2", key->quotient_polynomial_parts[2][i]); - info("final quotient 3", key->quotient_polynomial_parts[3][i]); - } #ifdef DEBUG_TIMING start = std::chrono::steady_clock::now(); #endif @@ -458,12 +446,6 @@ template void ProverBase::execute_fourth_round() // Manually copy the (n + 1)th coefficient of t_3 for StandardPlonk from t_4. // This is because the degree of t_3 for StandardPlonk is n. - for (size_t i = 0; i < key->circuit_size; ++i) { - info("quotient after ifft 0 ", quotient_poly_parts[0][i]); - info("quotient after ifft 1 ", quotient_poly_parts[1][i]); - info("quotient after ifft 2 ", quotient_poly_parts[2][i]); - info("quotient after ifft 3 ", quotient_poly_parts[3][i]); - } if (settings::program_width == 3) { key->quotient_polynomial_parts[2][circuit_size] = key->quotient_polynomial_parts[3][0]; key->quotient_polynomial_parts[3][0] = 0; diff --git a/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp b/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp index eed2a5a566..a25000f72f 100644 --- a/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp +++ b/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp @@ -426,7 +426,6 @@ barretenberg::fr ProverPermutationWidgetadd_element(item.tag, result.to_buffer()); break; From db5c8dd5855cf6c5bca09eca4fa42cd90df9afe8 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 30 Mar 2023 21:22:36 +0100 Subject: [PATCH 37/46] restore the randomness --- cpp/src/barretenberg/numeric/random/engine.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cpp/src/barretenberg/numeric/random/engine.cpp b/cpp/src/barretenberg/numeric/random/engine.cpp index 2af39a396c..aeb5125070 100644 --- a/cpp/src/barretenberg/numeric/random/engine.cpp +++ b/cpp/src/barretenberg/numeric/random/engine.cpp @@ -11,11 +11,8 @@ namespace { auto generate_random_data() { std::array random_data; - for (unsigned int i = 0; i < random_data.size(); i++) { - random_data[i] = 100; - } - // std::random_device source; - // std::generate(std::begin(random_data), std::end(random_data), std::ref(source)); + std::random_device source; + std::generate(std::begin(random_data), std::end(random_data), std::ref(source)); return random_data; } } // namespace From 71674a554e821f1277c0c62aba1ff3278813341c Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 30 Mar 2023 21:22:55 +0100 Subject: [PATCH 38/46] only add a zero/one test instead of replacing --- .../stdlib/hash/pedersen/pedersen.test.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen.test.cpp b/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen.test.cpp index 238035b7c0..725d09752f 100644 --- a/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen.test.cpp +++ b/cpp/src/barretenberg/stdlib/hash/pedersen/pedersen.test.cpp @@ -515,6 +515,38 @@ TEST(stdlib_pedersen, test_merkle_damgard_compress_plookup) { plonk::UltraComposer composer = plonk::UltraComposer(); + std::vector input_values{ + fr::random_element(), fr::random_element(), fr::random_element(), + fr::random_element(), fr::random_element(), fr::random_element(), + }; + std::vector inputs; + for (const auto& input : input_values) { + inputs.emplace_back(witness_ct(&composer, input)); + } + field_ct iv = witness_ct(&composer, fr(10)); + + auto result = stdlib::pedersen_plookup::merkle_damgard_compress(inputs, iv); + + auto expected = crypto::pedersen::lookup::merkle_damgard_compress(input_values, 10); + + EXPECT_EQ(result.x.get_value(), expected.normalize().x); + EXPECT_EQ(result.y.get_value(), expected.normalize().y); + + auto prover = composer.create_prover(); + + printf("composer gates = %zu\n", composer.get_num_gates()); + auto verifier = composer.create_verifier(); + + plonk::proof proof = prover.construct_proof(); + + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); +} + +TEST(stdlib_pedersen, test_merkle_damgard_compress_plookup_zero_one) +{ + plonk::UltraComposer composer = plonk::UltraComposer(); + std::vector input_values{ 0, 1 }; std::vector inputs; for (const auto& input : input_values) { From 38824504729c219db1c3072a3326e774cfbf0f02 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 30 Mar 2023 21:23:05 +0100 Subject: [PATCH 39/46] remove unused change --- cpp/src/barretenberg/stdlib/types/types.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/src/barretenberg/stdlib/types/types.hpp b/cpp/src/barretenberg/stdlib/types/types.hpp index 6995d1a89e..4fdc71e1c0 100644 --- a/cpp/src/barretenberg/stdlib/types/types.hpp +++ b/cpp/src/barretenberg/stdlib/types/types.hpp @@ -3,7 +3,6 @@ #include "barretenberg/plonk/composer/standard_composer.hpp" #include "barretenberg/plonk/composer/turbo_composer.hpp" #include "barretenberg/plonk/composer/ultra_composer.hpp" -#include "barretenberg/plonk/composer/plookup_tables/plookup_tables.hpp" #include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" #include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" #include "barretenberg/stdlib/primitives/bit_array/bit_array.hpp" @@ -78,7 +77,6 @@ typedef stdlib::pedersen pedersen; typedef stdlib::group group_ct; typedef stdlib::bn254 bn254; typedef stdlib::secp256k1 secp256k1_ct; -typedef stdlib::plookup_read plookup_read_ct; namespace merkle_tree { using namespace stdlib::merkle_tree; From dd7fd0aee2fe06a409f5166ae732b2d959317eac Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 31 Mar 2023 13:24:15 +0100 Subject: [PATCH 40/46] changes to make solgen work correctly in bindings --- .../barretenberg/dsl/acir_proofs/acir_proofs.cpp | 13 +++++++------ .../barretenberg/dsl/acir_proofs/acir_proofs.hpp | 2 +- cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp | 2 +- cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp index 4a2f9b47cb..ef70c7af1e 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.cpp @@ -10,7 +10,7 @@ using namespace plonk::stdlib::types; namespace acir_proofs { -uint32_t get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf) +size_t get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf) { auto crs = std::make_shared(g2x); bonk::verification_key_data vk_data; @@ -18,14 +18,15 @@ uint32_t get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_ auto verification_key = std::make_shared(std::move(vk_data), crs); std::ostringstream stream; - // TODO(blaine): Should we just use "Verifier" generically? - output_vk_sol(stream, verification_key, "UltraVerifier"); + // TODO(blaine): Should we just use "VerificationKey" generically? + output_vk_sol(stream, verification_key, "UltraVerificationKey"); auto content_str = stream.str(); - std::vector buffer(content_str.begin(), content_str.end()); + auto raw_buf = (uint8_t*)malloc(content_str.size()); + memcpy(raw_buf, (void*)content_str.data(), content_str.size()); + *output_buf = raw_buf; - *output_buf = buffer.data(); - return static_cast(buffer.size()); + return content_str.size(); } uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf) diff --git a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp index 04d3ce25d5..4bd126aae9 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/acir_proofs.hpp @@ -3,7 +3,7 @@ namespace acir_proofs { -uint32_t get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf); +size_t get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf); uint32_t get_exact_circuit_size(uint8_t const* constraint_system_buf); uint32_t get_total_circuit_size(uint8_t const* constraint_system_buf); size_t init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf); diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 81969e198f..4051aada3a 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -6,7 +6,7 @@ extern "C" { -WASM_EXPORT uint32_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf) +WASM_EXPORT size_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf) { return acir_proofs::get_solidity_verifier(g2x, vk_buf, output_buf); } diff --git a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index 44ab2e323d..a628c928cb 100644 --- a/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -5,7 +5,7 @@ extern "C" { -WASM_EXPORT uint32_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf); +WASM_EXPORT size_t acir_proofs_get_solidity_verifier(uint8_t const* g2x, uint8_t const* vk_buf, uint8_t** output_buf); WASM_EXPORT uint32_t acir_proofs_get_exact_circuit_size(uint8_t const* constraint_system_buf); WASM_EXPORT uint32_t acir_proofs_get_total_circuit_size(uint8_t const* constraint_system_buf); // Construct composer using prover and verifier key buffers From 0ab376053a20caf31f212991f22ca569a3c66572 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Fri, 31 Mar 2023 19:43:35 -0400 Subject: [PATCH 41/46] fix join_split_tests.test_deposit_construct_proof --- .../join_split_example/proofs/join_split/join_split.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp index e4b4e71d53..77f1a65e26 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp @@ -89,10 +89,10 @@ stdlib::types::Prover new_join_split_prover(join_split_tx const& tx, bool mock) bool verify_proof(plonk::proof const& proof) { - plonk::TurboVerifier verifier(verification_key, Composer::create_manifest(verification_key->num_public_inputs)); + plonk::UltraVerifier verifier(verification_key, Composer::create_manifest(verification_key->num_public_inputs)); - std::unique_ptr> kate_commitment_scheme = - std::make_unique>(); + std::unique_ptr> kate_commitment_scheme = + std::make_unique>(); verifier.commitment_scheme = std::move(kate_commitment_scheme); return verifier.verify_proof(proof); From 6119f1ec1268a8d63ea6057b2b65a8fcf2c3c26e Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Mon, 3 Apr 2023 17:19:34 +0100 Subject: [PATCH 42/46] working serialized proving key size and circuit change test for ultra (#307) --- .../proofs/join_split/c_bind.cpp | 16 +++++++++++++--- .../proofs/join_split/join_split.test.cpp | 14 ++++++++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp index 4fb767f1cd..88ffa3bf80 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/c_bind.cpp @@ -42,9 +42,10 @@ WASM_EXPORT void join_split__release_key() WASM_EXPORT uint32_t join_split__get_new_proving_key_data(uint8_t** output) { - // Computing the size of the serialized key is non trivial. We know it's ~331mb. - // Allocate a buffer large enough to hold it, and abort if we overflow. - // This is to keep memory usage down. +// Computing the size of the serialized key is non trivial. We know it's ~331mb. +// Allocate a buffer large enough to hold it, and abort if we overflow. +// This is to keep memory usage down. +#ifdef USE_TURBO size_t total_buf_len = 350 * 1024 * 1024; auto raw_buf = (uint8_t*)malloc(total_buf_len); auto raw_buf_end = raw_buf; @@ -56,6 +57,15 @@ WASM_EXPORT uint32_t join_split__get_new_proving_key_data(uint8_t** output) std::abort(); } return len; +#else + auto proving_key = get_proving_key(); + auto buffer = to_buffer(*proving_key); + auto raw_buf = (uint8_t*)malloc(buffer.size()); + memcpy(raw_buf, (void*)buffer.data(), buffer.size()); + *output = raw_buf; + + return static_cast(buffer.size()); +#endif } WASM_EXPORT void join_split__init_verification_key(void* pippenger, uint8_t const* g2x) diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp index c023322bbe..e7564dc63a 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp @@ -800,11 +800,17 @@ TEST_F(join_split_tests, test_0_input_notes_and_detect_circuit_change) EXPECT_TRUE(result.valid); - // The below part detects any changes in the join-split circuit +// The below part detects any changes in the join-split circuit +#ifdef USE_TURBO constexpr uint32_t CIRCUIT_GATE_COUNT = 64000; constexpr uint32_t GATES_NEXT_POWER_OF_TWO = 65536; const uint256_t VK_HASH("bb2062d006d31d3234766277711eb28577d5f6082d0f484b87e8235628f8e864"); +#else + constexpr uint32_t CIRCUIT_GATE_COUNT = 522850; + constexpr uint32_t GATES_NEXT_POWER_OF_TWO = 524288; + const uint256_t VK_HASH("012959f86e485f3a8f0b06c900082fca1c34b535cdf4f1088f03154ea655b401"); +#endif auto number_of_gates_js = result.number_of_gates; auto vk_hash_js = get_verification_key()->sha256_hash(); @@ -2613,11 +2619,15 @@ TEST_F(join_split_tests, test_send_two_virtual_notes_full_proof) // Miscellaneous // ************************************************************************************************************* -TEST_F(join_split_tests, serialzed_proving_key_size) +TEST_F(join_split_tests, serialized_proving_key_size) { uint8_t* ptr; auto len = join_split__get_new_proving_key_data(&ptr); +#ifdef USE_TURBO EXPECT_LE(len, 2 * 170 * 1024 * 1024); +#else + EXPECT_LE(len, 2315258552); +#endif } } // namespace join_split_example::proofs::join_split From b347580d983cfaef32f0fe7e86b04e3f825c7605 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 3 Apr 2023 10:20:40 -0700 Subject: [PATCH 43/46] USE_TURBO for join_split --- .../join_split_example/proofs/join_split/join_split.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp index 77f1a65e26..213628a18f 100644 --- a/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp +++ b/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp @@ -89,10 +89,16 @@ stdlib::types::Prover new_join_split_prover(join_split_tx const& tx, bool mock) bool verify_proof(plonk::proof const& proof) { - plonk::UltraVerifier verifier(verification_key, Composer::create_manifest(verification_key->num_public_inputs)); + plonk::stdlib::types::Verifier verifier(verification_key, + Composer::create_manifest(verification_key->num_public_inputs)); +#ifdef USE_TURBO + std::unique_ptr> kate_commitment_scheme = + std::make_unique>(); +#else std::unique_ptr> kate_commitment_scheme = std::make_unique>(); +#endif verifier.commitment_scheme = std::move(kate_commitment_scheme); return verifier.verify_proof(proof); From 96819b2f4233085b980aef55f34686cf6d65ce31 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Mon, 3 Apr 2023 17:27:52 +0000 Subject: [PATCH 44/46] Empty-Commit From 0ace234889a34f414bd40115900037c0999259d9 Mon Sep 17 00:00:00 2001 From: codygunton Date: Mon, 3 Apr 2023 20:26:07 +0000 Subject: [PATCH 45/46] Don't default one function; tweak comments. --- cpp/src/barretenberg/plonk/composer/composer_base.hpp | 2 +- cpp/src/barretenberg/plonk/composer/standard_composer.hpp | 2 ++ cpp/src/barretenberg/plonk/composer/turbo_composer.hpp | 3 +++ cpp/src/barretenberg/stdlib/primitives/logic/logic.cpp | 4 ++-- cpp/src/barretenberg/stdlib/primitives/logic/logic.hpp | 2 -- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/cpp/src/barretenberg/plonk/composer/composer_base.hpp b/cpp/src/barretenberg/plonk/composer/composer_base.hpp index d46017a1fa..37ec925409 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_base.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_base.hpp @@ -107,7 +107,7 @@ class ComposerBase { virtual ~ComposerBase(){}; virtual size_t get_num_gates() const { return num_gates; } - virtual size_t get_total_circuit_size() const { return num_gates; }; + virtual size_t get_total_circuit_size() const = 0; virtual void print_num_gates() const { std::cout << num_gates << std::endl; } virtual size_t get_num_variables() const { return variables.size(); } virtual std::shared_ptr compute_proving_key_base(const ComposerType type = STANDARD, diff --git a/cpp/src/barretenberg/plonk/composer/standard_composer.hpp b/cpp/src/barretenberg/plonk/composer/standard_composer.hpp index 20f490e22c..0a7015767f 100644 --- a/cpp/src/barretenberg/plonk/composer/standard_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/standard_composer.hpp @@ -79,6 +79,8 @@ class StandardComposer : public ComposerBase { StandardComposer& operator=(StandardComposer&& other) = default; ~StandardComposer() {} + virtual size_t get_total_circuit_size() const override { return num_gates; }; + void assert_equal_constant(uint32_t const a_idx, barretenberg::fr const& b, std::string const& msg = "assert equal constant"); diff --git a/cpp/src/barretenberg/plonk/composer/turbo_composer.hpp b/cpp/src/barretenberg/plonk/composer/turbo_composer.hpp index b089a85429..ab71116a85 100644 --- a/cpp/src/barretenberg/plonk/composer/turbo_composer.hpp +++ b/cpp/src/barretenberg/plonk/composer/turbo_composer.hpp @@ -23,6 +23,9 @@ class TurboComposer : public ComposerBase { virtual std::shared_ptr compute_proving_key() override; std::shared_ptr compute_verification_key() override; + + virtual size_t get_total_circuit_size() const override { return num_gates; }; + void compute_witness() override; TurboProver create_prover(); diff --git a/cpp/src/barretenberg/stdlib/primitives/logic/logic.cpp b/cpp/src/barretenberg/stdlib/primitives/logic/logic.cpp index 7a376636c1..d3ae520aa8 100644 --- a/cpp/src/barretenberg/stdlib/primitives/logic/logic.cpp +++ b/cpp/src/barretenberg/stdlib/primitives/logic/logic.cpp @@ -7,9 +7,9 @@ namespace plonk { namespace stdlib { /** - * @brief Constrants a logical AND or XOR over a variable number of bits. + * @brief A logical AND or XOR over a variable number of bits. * - * Defaults to basic Composer method if not using plookup-compatible composer + * @details Defaults to basic Composer method if not using plookup-compatible composer * * @tparam Composer * @param a diff --git a/cpp/src/barretenberg/stdlib/primitives/logic/logic.hpp b/cpp/src/barretenberg/stdlib/primitives/logic/logic.hpp index f359fbdff1..16423d3188 100644 --- a/cpp/src/barretenberg/stdlib/primitives/logic/logic.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/logic/logic.hpp @@ -5,8 +5,6 @@ namespace plonk { namespace stdlib { -// A runtime-defined read-only memory table. Table entries must be initialized in the constructor. -// N.B. Only works with the UltraComposer at the moment! template class logic { private: typedef field_t field_pt; From 7b35952a7dfa87c5a4f1da37e3cd99b56593f884 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Mon, 3 Apr 2023 22:04:54 +0000 Subject: [PATCH 46/46] Empty-Commit