Skip to content

Commit

Permalink
update for sha256 for PR
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielKotov committed Sep 20, 2024
1 parent 3facaab commit 24d4529
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ inline void Graph_<FF>::remove_unnecessary_decompose_variables(bb::UltraCircuitB
}

template <typename FF>
void Graph_<FF>::remove_unnecessary_plookup_variables(bb::UltraCircuitBuilder& ultra_circuit_builder,
std::unordered_set<uint32_t>& variables_in_one_gate)
inline void Graph_<FF>::remove_unnecessary_plookup_variables(bb::UltraCircuitBuilder& ultra_circuit_builder,
std::unordered_set<uint32_t>& variables_in_one_gate)
{
auto& lookup_block = ultra_circuit_builder.blocks.lookup;
if (lookup_block.size() > 0) {
Expand Down Expand Up @@ -470,6 +470,8 @@ inline void Graph_<FF>::process_current_plookup_gate(bb::UltraCircuitBuilder& ul
std::set<bb::fr> column_2(table.column_2.begin(), table.column_2.end());
std::set<bb::fr> column_3(table.column_3.begin(), table.column_3.end());
bb::plookup::BasicTableId id = table.id;
// in some table we don't use variables from third column. So, these variables are false-case for a
// analyzer, and we have to remove them false cases for AES
if (id == bb::plookup::AES_SBOX_MAP || id == bb::plookup::AES_SPARSE_MAP) {
uint32_t real_out_idx = to_real(lookup_block.w_o()[gate_index]);
uint32_t real_right_idx = to_real(lookup_block.w_r()[gate_index]);
Expand All @@ -490,74 +492,22 @@ inline void Graph_<FF>::process_current_plookup_gate(bb::UltraCircuitBuilder& ul
}
}
}
if (id == bb::plookup::SHA256_WITNESS_SLICE_3) {
// false cases for sha256
if (id == bb::plookup::SHA256_WITNESS_SLICE_3 || id == bb::plookup::SHA256_WITNESS_SLICE_7_ROTATE_4 ||
id == bb::plookup::SHA256_WITNESS_SLICE_8_ROTATE_7 ||
id == bb::plookup::SHA256_WITNESS_SLICE_14_ROTATE_1 || id == bb::plookup::SHA256_BASE16_ROTATE2 ||
id == bb::plookup::SHA256_BASE16 || id == bb::plookup::SHA256_BASE28_ROTATE6 ||
id == bb::plookup::SHA256_BASE28_ROTATE3) {
uint32_t real_right_idx = to_real(lookup_block.w_r()[gate_index]);
uint32_t real_out_idx = to_real(lookup_block.w_o()[gate_index]);
if (variables_gate_counts[real_out_idx] != 1 || variables_gate_counts[real_right_idx] != 1) {
auto q_m = lookup_block.q_m()[gate_index];
auto q_c = lookup_block.q_c()[gate_index];
bool find_out = find_position(real_out_idx);
bool find_right = find_position(real_right_idx);
if (q_c == 0) {
if (find_out) {
variables_in_one_gate.erase(real_out_idx);
}
}
if (q_m == 0) {
if (find_right) {
variables_in_one_gate.erase(real_right_idx);
}
}
}
}
if (id == bb::plookup::SHA256_WITNESS_SLICE_7_ROTATE_4) {
uint32_t real_right_idx = to_real(lookup_block.w_r()[gate_index]);
uint32_t real_out_idx = to_real(lookup_block.w_o()[gate_index]);
if (variables_gate_counts[real_out_idx] != 1 || variables_gate_counts[real_right_idx] != 1) {
auto q_m = lookup_block.q_m()[gate_index];
auto q_c = lookup_block.q_c()[gate_index];
bool find_out = find_position(real_out_idx);
bool find_right = find_position(real_right_idx);
if (q_c == 0) {
if (find_out) {
variables_in_one_gate.erase(real_out_idx);
}
}
if (q_m == 0) {
if (find_right) {
variables_in_one_gate.erase(real_right_idx);
}
if (real_out_idx == 1504) {
info("it's selector == ", q_m);
}
}
}
if (id == bb::plookup::SHA256_WITNESS_SLICE_8_ROTATE_7) {
uint32_t real_right_idx = to_real(lookup_block.w_r()[gate_index]);
uint32_t real_out_idx = to_real(lookup_block.w_o()[gate_index]);
if (variables_gate_counts[real_out_idx] != 1 || variables_gate_counts[real_right_idx] != 1) {
auto q_m = lookup_block.q_m()[gate_index];
auto q_c = lookup_block.q_c()[gate_index];
bool find_out = find_position(real_out_idx);
bool find_right = find_position(real_right_idx);
if (q_c == 0) {
if (find_out) {
variables_in_one_gate.erase(real_out_idx);
}
}
if (q_m == 0) {
if (find_right) {
variables_in_one_gate.erase(real_right_idx);
}
}
}
}
if (id == bb::plookup::SHA256_WITNESS_SLICE_14_ROTATE_1) {
uint32_t real_right_idx = to_real(lookup_block.w_r()[gate_index]);
uint32_t real_out_idx = to_real(lookup_block.w_o()[gate_index]);
if (variables_gate_counts[real_out_idx] != 1 || variables_gate_counts[real_right_idx] != 1) {
auto q_m = lookup_block.q_m()[gate_index];
auto q_c = lookup_block.q_c()[gate_index];
bool find_out = find_position(real_out_idx);
bool find_right = find_position(real_right_idx);
if (q_c == 0) {
if (find_out) {
variables_in_one_gate.erase(real_out_idx);
Expand All @@ -568,6 +518,12 @@ inline void Graph_<FF>::process_current_plookup_gate(bb::UltraCircuitBuilder& ul
variables_in_one_gate.erase(real_right_idx);
}
}
} else {
info("gates_count: ",
variables_gate_counts[real_out_idx],
" ",
variables_gate_counts[real_right_idx]);
info("variable indices: ", real_right_idx, " ", real_out_idx);
}
}
if (column_1.size() == 1) {
Expand Down Expand Up @@ -661,16 +617,14 @@ template <typename FF> void Graph_<FF>::print_variables_gate_counts()
{
for (const auto& it : variables_gate_counts) {
info("number of gates with variables ", it.first, " == ", it.second);
info(it.second);
}
}

template <typename FF> void Graph_<FF>::print_variables_edge_counts()
{
for (const auto& it : variables_degree) {
if (it.first != 0) {
info("variable index = ", it.first);
info("number of edges for this variables = ", it.second);
info("variable index = ", it.first, "number of edges for this variable = ", it.second);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ TEST(ultra_circuit_constructor, test_sha256_55_bytes)
Graph graph = Graph(builder);
auto connected_components = graph.find_connected_components();
EXPECT_EQ(connected_components.size(), 1);
// graph.print_connected_components();
}

HEAVY_TEST(ultra_circuit_constructor, test_graph_for_sha256_NIST_vector_five)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "barretenberg/boomerang_value_detection/graph.hpp"
#include "barretenberg/circuit_checker/circuit_checker.hpp"
#include "barretenberg/common/test.hpp"
#include "barretenberg/crypto/sha256/sha256.hpp"
#include "barretenberg/stdlib/hash/sha256/sha256.hpp"
#include "barretenberg/stdlib/primitives/byte_array/byte_array.hpp"
Expand All @@ -25,6 +26,29 @@ using packed_byte_array_ct = packed_byte_array<Builder>;
using witness_ct = stdlib::witness_t<Builder>;
using field_ct = field_t<Builder>;

bool check_in_byte_array(const uint32_t& real_var_index, const packed_byte_array_ct& byte_array)
{
std::vector<field_t<Builder>> limbs = byte_array.get_limbs();
for (const auto& elem : limbs) {
if (elem.witness_index == real_var_index) {
return true;
}
}
return false;
}

bool check_in_range_lists(const uint32_t& real_var_index, const uint64_t& target_range, const Builder& builder)
{
auto range_lists = builder.range_lists;
auto target_list = range_lists[target_range];
for (const auto elem : target_list.variable_indices) {
if (elem == real_var_index) {
return true;
}
}
return false;
}

TEST(ultra_circuit_constructor, test_variables_gate_counts_for_sha256_55_bytes)
{
// 55 bytes is the largest number of bytes that can be hashed in a single block,
Expand All @@ -41,34 +65,124 @@ TEST(ultra_circuit_constructor, test_variables_gate_counts_for_sha256_55_bytes)
std::vector<uint32_t> vector_variables_in_on_gate(variables_in_on_gate.begin(), variables_in_on_gate.end());
std::sort(vector_variables_in_on_gate.begin(), vector_variables_in_on_gate.end());
for (const auto& elem : vector_variables_in_on_gate) {
info("elem == ", elem);
bool result1 = check_in_byte_array(elem, input);
bool result2 = check_in_byte_array(elem, output_bits);
bool result3 = check_in_range_lists(elem, 3, builder);
bool check = (result1 == 1) || (result2 == 1) || (result3 == 1);
EXPECT_EQ(check, true);
}
}

HEAVY_TEST(ultra_circuit_constructor, test_variable_gates_count_for_sha256_NIST_vector_five)
{
auto builder = Builder();

packed_byte_array_ct input(
&builder,
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAA");

packed_byte_array_ct output_bits = stdlib::sha256(input);
Graph graph = Graph(builder);
std::unordered_set<uint32_t> variables_in_on_gate = graph.show_variables_in_one_gate(builder);
for (const auto& elem : variables_in_on_gate) {
bool result1 = check_in_byte_array(elem, input);
bool result2 = check_in_byte_array(elem, output_bits);
bool result3 = check_in_range_lists(elem, 3, builder);
bool check = (result1 == 1) || (result2 == 1) || (result3 == 1);
if (check == false) {
info("elem == ", elem);
info(result1);
info(result2);
info(result3);
info();
}
EXPECT_EQ(check, true);
}
}

TEST(ultra_circuit_constructor, test_boomerang_value_in_sha256)
TEST(ultra_circuit_constructor, test_variable_gates_count_for_sha256_NIST_vector_one)
{
auto builder = Builder();
std::array<field_t<Builder>, 16> input;
for (size_t i = 0; i < 16; i++) {
auto variable = fr::random_element();
auto var_slice = uint256_t(variable).slice(0, 32);
field_ct elt(witness_ct(&builder, fr(var_slice)));
builder.fix_witness(elt.witness_index, elt.get_value());
input[i] = elt;
packed_byte_array_ct input(&builder, "abc");
packed_byte_array_ct output_bits = stdlib::sha256(input);

Graph graph = Graph(builder);
std::unordered_set<uint32_t> variables_in_one_gate = graph.show_variables_in_one_gate(builder);
for (const auto& elem : variables_in_one_gate) {
bool result1 = check_in_byte_array(elem, input);
bool result2 = check_in_byte_array(elem, output_bits);
bool result3 = check_in_range_lists(elem, 3, builder);
bool check = (result1 == 1) || (result2 == 1) || (result3 == 1);
EXPECT_EQ(check, true);
}
std::array<field_t<Builder>, 64> w_ext = sha256_plookup::extend_witness(input);
bool result1 = CircuitChecker::check(builder);
EXPECT_EQ(result1, true);
while (true) {
auto change_variable = fr::random_element();
auto change_var_slice = uint256_t(change_variable).slice(0, 32);
field_t change_elt(&builder, fr(change_var_slice));
uint32_t variable_index = w_ext[62].witness_index;
if (builder.variables[builder.real_variable_index[variable_index]] != fr(change_var_slice)) {
builder.variables[builder.real_variable_index[variable_index]] = fr(change_var_slice);
bool result2 = CircuitChecker::check(builder);
EXPECT_EQ(result2, true);
break;
}

TEST(ultra_circuit_constructor, test_variable_gates_count_for_sha256_NIST_vector_two)
{
auto builder = Builder();

packed_byte_array_ct input(&builder, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");

packed_byte_array_ct output_bits = stdlib::sha256(input);
Graph graph = Graph(builder);
std::unordered_set<uint32_t> variables_in_one_gate = graph.show_variables_in_one_gate(builder);
for (const auto& elem : variables_in_one_gate) {
bool result1 = check_in_byte_array(elem, input);
bool result2 = check_in_byte_array(elem, output_bits);
bool result3 = check_in_range_lists(elem, 3, builder);
bool check = (result1 == 1) || (result2 == 1) || (result3 == 1);
if (check == false) {
info("elem == ", elem);
info(result1);
info(result2);
info(result3);
info();
}
EXPECT_EQ(check, true);
}
}

TEST(ultra_circuit_constructor, test_variable_gates_count_sha256_NIST_vector_three)
{
auto builder = Builder();

// one byte, 0xbd
packed_byte_array_ct input(&builder, std::vector<uint8_t>{ 0xbd });
packed_byte_array_ct output_bits = stdlib::sha256(input);
Graph graph = Graph(builder);
std::unordered_set<uint32_t> variables_in_one_gate = graph.show_variables_in_one_gate(builder);
for (const auto& elem : variables_in_one_gate) {
bool result1 = check_in_byte_array(elem, input);
bool result2 = check_in_byte_array(elem, output_bits);
bool result3 = check_in_range_lists(elem, 3, builder);
bool check = (result1 == 1) || (result2 == 1) || (result3 == 1);
EXPECT_EQ(check, true);
}
}

TEST(ultra_circuit_constructor, test_variable_gates_count_sha256_NIST_vector_four)
{
auto builder = Builder();

// 4 bytes, 0xc98c8e55
packed_byte_array_ct input(&builder, std::vector<uint8_t>{ 0xc9, 0x8c, 0x8e, 0x55 });
packed_byte_array_ct output_bits = stdlib::sha256<Builder>(input);
Graph graph = Graph(builder);
std::unordered_set<uint32_t> variables_in_one_gate = graph.show_variables_in_one_gate(builder);
for (const auto& elem : variables_in_one_gate) {
bool result1 = check_in_byte_array(elem, input);
bool result2 = check_in_byte_array(elem, output_bits);
bool result3 = check_in_range_lists(elem, 3, builder);
bool check = (result1 == 1) || (result2 == 1) || (result3 == 1);
EXPECT_EQ(check, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ std::array<field_t<Builder>, 64> extend_witness(const std::array<field_t<Builder
} else {
w_out = witness_t<Builder>(
ctx, fr(w_out_raw.get_value().from_montgomery_form().data[0] & (uint64_t)0xffffffffULL));
constexpr fr inv_pow_two = fr(2).pow(32).invert();
field_pt w_out_raw_inv_pow_two = w_out_raw * inv_pow_two;
field_pt w_out_inv_pow_two = w_out * inv_pow_two;
field_pt divisor = (w_out_raw_inv_pow_two - w_out_inv_pow_two).normalize();
ctx->create_new_range_constraint(divisor.witness_index, 3);
}
constexpr fr inv_pow_two = fr(2).pow(32).invert();
field_pt w_out_raw_inv_pow_two = w_out_raw * inv_pow_two;
field_pt w_out_inv_pow_two = w_out * inv_pow_two;
field_pt divisor = (w_out_raw_inv_pow_two - w_out_inv_pow_two).normalize();
ctx->create_new_range_constraint(divisor.witness_index, 3);
w_sparse[i] = sparse_witness_limbs(w_out);
}

Expand Down Expand Up @@ -271,6 +271,7 @@ std::array<field_t<Builder>, 8> sha256_block(const std::array<field_t<Builder>,
auto a = map_into_maj_sparse_form(h_init[0]);
auto b = map_into_maj_sparse_form(h_init[1]);
auto c = map_into_maj_sparse_form(h_init[2]);
// auto d = sparse_value<Builder>(h_init[3]);
auto d = map_into_maj_sparse_form(h_init[3]);
auto e = map_into_choose_sparse_form(h_init[4]);
auto f = map_into_choose_sparse_form(h_init[5]);
Expand Down

0 comments on commit 24d4529

Please sign in to comment.