-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ultrahonk): Added a simple filler table to minimize the amount of entries used to make UltraHonk polynomials non-zero #531
Changes from all commits
b0fc113
26558e2
46f055e
ba926f3
d50a50e
4760c43
30fe0eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -93,30 +93,24 @@ void UltraCircuitConstructor::add_gates_to_ensure_all_polys_are_non_zero() | |
create_big_add_gate({ zero_idx, zero_idx, zero_idx, one_idx, 0, 0, 0, 1, -1 }); | ||
|
||
// Take care of all polys related to lookups (q_lookup, tables, sorted, etc) | ||
// by doing an arbitrary xor and an "and" lookup. | ||
// by doing a dummy lookup with a special table. | ||
// Note: the 4th table poly is the table index: this is not the value of the table | ||
// type enum but rather the index of the table in the list of all tables utilized | ||
// in the circuit. Therefore we naively need two different tables (indices 0, 1) | ||
// to get a non-zero value in table_4. I assume this index is arbitrary and could | ||
// start from 1 instead of 0? | ||
// in the circuit. Therefore we naively need two different basic tables (indices 0, 1) | ||
// to get a non-zero value in table_4. | ||
// The multitable operates on 2-bit values, so the maximum is 3 | ||
uint32_t left_value = 3; | ||
uint32_t right_value = 5; | ||
uint32_t right_value = 3; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you explain what this value is because the change looks arbitrary - maybe add comment as well There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The change is because the multitable only works on 2-bit values, so 5 is too big |
||
|
||
fr left_witness_value = fr{ left_value, 0, 0, 0 }.to_montgomery_form(); | ||
fr right_witness_value = fr{ right_value, 0, 0, 0 }.to_montgomery_form(); | ||
|
||
uint32_t left_witness_index = add_variable(left_witness_value); | ||
uint32_t right_witness_index = add_variable(right_witness_value); | ||
|
||
const auto and_accumulators = plookup::get_lookup_accumulators( | ||
plookup::MultiTableId::UINT32_AND, left_witness_value, right_witness_value, true); | ||
const auto xor_accumulators = plookup::get_lookup_accumulators( | ||
plookup::MultiTableId::UINT32_XOR, left_witness_value, right_witness_value, true); | ||
|
||
create_gates_from_plookup_accumulators( | ||
plookup::MultiTableId::UINT32_AND, and_accumulators, left_witness_index, right_witness_index); | ||
const auto dummy_accumulators = plookup::get_lookup_accumulators( | ||
plookup::MultiTableId::HONK_DUMMY_MULTI, left_witness_value, right_witness_value, true); | ||
create_gates_from_plookup_accumulators( | ||
plookup::MultiTableId::UINT32_XOR, xor_accumulators, left_witness_index, right_witness_index); | ||
plookup::MultiTableId::HONK_DUMMY_MULTI, dummy_accumulators, left_witness_index, right_witness_index); | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#pragma once | ||
/** | ||
* @file dummy.hpp | ||
* @author Rumata888 | ||
* @brief This file contains functions for the dummy tables that we use in UltraHonk to make table, sorted and lookup | ||
* selector polynomials non-zero. | ||
* | ||
*/ | ||
|
||
#include "types.hpp" | ||
|
||
namespace plookup { | ||
namespace dummy_tables { | ||
|
||
/** | ||
* @brief Lookup the value corresponding to a specific key | ||
* | ||
* @details We need this function for when we are constructing the circuit and want to query the table. Since we need | ||
* two basic tables to make the table polynomial have non-zero values, we instantiate two tables with the same function, | ||
* but change it slightly through templating | ||
* | ||
* @tparam id The id of the basic table used to parametrize the values for 2 fake tables | ||
* @param key The key that we are looking up | ||
* @return std::array<barretenberg::fr, 2> | ||
*/ | ||
template <uint64_t id> inline std::array<barretenberg::fr, 2> get_value_from_key(const std::array<uint64_t, 2> key) | ||
{ | ||
return { key[0] * 3 + key[1] * 4 + id * 0x1337ULL, 0ULL }; | ||
} | ||
|
||
/** | ||
* @brief Generate the whole table | ||
* | ||
* @details This function is used to generate the whole table for the table polynomial. It's templated with id, since we | ||
* generate 2 slightly different fake tables. | ||
* | ||
* @tparam table_id The id of the table this function is instantiated for | ||
* @param id Table id that is the same for all circuits | ||
* @param table_index The index for this table that is used in this circuit. 0, 1, ... | ||
* @return A table of values | ||
*/ | ||
template <uint64_t table_id> | ||
inline BasicTable generate_honk_dummy_table(const BasicTableId id, const size_t table_index) | ||
{ | ||
|
||
// We do the assertion, since this function is templated, but the general API for these functions contains the id, | ||
// too. This helps us ensure that the correct instantion is used for a particular BasicTableId | ||
ASSERT(table_id == static_cast<uint64_t>(id)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do this two have to be equal - i understand that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are using the same function in 2 places by templating it, but the API already includes the id in arguments. This is just a simple bug check to ensure that we don't use the wrong instantiation |
||
const size_t base = 1 << 1; // Probably has to be a power of 2 | ||
BasicTable table; | ||
table.id = id; | ||
table.table_index = table_index; | ||
table.size = base * base; | ||
table.use_twin_keys = true; | ||
for (uint64_t i = 0; i < base; ++i) { | ||
for (uint64_t j = 0; j < base; ++j) { | ||
table.column_1.emplace_back(i); | ||
table.column_2.emplace_back(j); | ||
table.column_3.emplace_back(i * 3 + j * 4 + static_cast<uint64_t>(id) * 0x1337ULL); | ||
} | ||
} | ||
|
||
table.get_values_from_key = &get_value_from_key<table_id>; | ||
|
||
table.column_1_step_size = base; | ||
table.column_2_step_size = base; | ||
table.column_3_step_size = base; | ||
|
||
return table; | ||
} | ||
/** | ||
* @brief Create a multitable for filling UltraHonk polynomials with non-zero values | ||
* | ||
* @details Consists of 2 Basic tables that are almost identical. Each of those basic tables should only have 4 entries, | ||
* so the overall overhead is just 8 | ||
* | ||
*/ | ||
inline MultiTable get_honk_dummy_multitable() | ||
{ | ||
const MultiTableId id = HONK_DUMMY_MULTI; | ||
const size_t number_of_elements_in_argument = 1 << 1; // Probably has to be a power of 2 | ||
const size_t number_of_lookups = 2; | ||
MultiTable table(number_of_elements_in_argument, | ||
number_of_elements_in_argument, | ||
number_of_elements_in_argument, | ||
number_of_lookups); | ||
table.id = id; | ||
table.slice_sizes.emplace_back(number_of_elements_in_argument); | ||
table.lookup_ids.emplace_back(HONK_DUMMY_BASIC1); | ||
table.get_table_values.emplace_back(&get_value_from_key<HONK_DUMMY_BASIC1>); | ||
table.slice_sizes.emplace_back(number_of_elements_in_argument); | ||
table.lookup_ids.emplace_back(HONK_DUMMY_BASIC2); | ||
table.get_table_values.emplace_back(&get_value_from_key<HONK_DUMMY_BASIC2>); | ||
return table; | ||
} | ||
} // namespace dummy_tables | ||
} // namespace plookup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was the -1 for previously?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We inserted a 1 at the end so that the polynomial would not be zero. Don't know why since we add randomness anyway