Skip to content

Commit 11bffcd

Browse files
kashbrtiludamad
authored andcommitted
chore: databus internal audit - small cleanups and tests coverage (#16703)
a small PR doing the following as a part of the `databus` audit - added tests to check the handling of constant or unnormalized indexes - removed some ugliness with dangling witnesses and replaced them with `set_variable` - some minor cleanups
1 parent 96bac97 commit 11bffcd

File tree

3 files changed

+114
-24
lines changed

3 files changed

+114
-24
lines changed

barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.cpp

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,13 @@ void process_ROM_operations(Builder& builder,
118118
// For a ROM table, constant read should be optimized out:
119119
// The rom_table won't work with a constant read because the table may not be initialized
120120
ASSERT(op.index.q_l != 0);
121-
// We create a new witness w to avoid issues with non-valid witness assignements:
122-
// if witness are not assigned, then w will be zero and table[w] will work
123-
fr w_value = 0;
124-
if (has_valid_witness_assignments) {
125-
// If witness are assigned, we use the correct value for w
126-
w_value = index.get_value();
121+
122+
// In case of invalid witness assignment, we set the value of index value to zero to not hit out of bound in
123+
// ROM table
124+
if (!has_valid_witness_assignments) {
125+
builder.set_variable(index.witness_index, 0);
127126
}
128-
field_ct w = field_ct::from_witness(&builder, w_value);
129-
value.assert_equal(table[w]);
130-
w.assert_equal(index);
127+
value.assert_equal(table[index]);
131128
}
132129
}
133130

@@ -144,12 +141,11 @@ void process_RAM_operations(Builder& builder,
144141
for (auto& op : constraint.trace) {
145142
field_ct value = poly_to_field_ct(op.value, builder);
146143
field_ct index = poly_to_field_ct(op.index, builder);
147-
148-
// We create a new witness w to avoid issues with non-valid witness assignements.
149-
// If witness are not assigned, then index will be zero and table[index] won't hit bounds check.
150-
fr index_value = has_valid_witness_assignments ? index.get_value() : 0;
151-
// Create new witness and ensure equal to index.
152-
field_ct::from_witness(&builder, index_value).assert_equal(index);
144+
// In case of invalid witness assignment, we set the value of index value to zero to not hit out of bound in
145+
// RAM table
146+
if (!has_valid_witness_assignments) {
147+
builder.set_variable(index.witness_index, 0);
148+
}
153149

154150
if (op.access_type == 0) {
155151
value.assert_equal(table.read(index));
@@ -179,14 +175,12 @@ void process_call_data_operations(Builder& builder,
179175
BB_ASSERT_EQ(op.access_type, 0);
180176
field_ct value = poly_to_field_ct(op.value, builder);
181177
field_ct index = poly_to_field_ct(op.index, builder);
182-
fr w_value = 0;
183-
if (has_valid_witness_assignments) {
184-
// If witness are assigned, we use the correct value for w
185-
w_value = index.get_value();
178+
// In case of invalid witness assignment, we set the value of index value to zero to not hit out of bound in
179+
// calldata-array
180+
if (!has_valid_witness_assignments) {
181+
builder.set_variable(index.witness_index, 0);
186182
}
187-
field_ct w = field_ct::from_witness(&builder, w_value);
188-
value.assert_equal(calldata_array[w]);
189-
w.assert_equal(index);
183+
value.assert_equal(calldata_array[index]);
190184
}
191185
};
192186

barretenberg/cpp/src/barretenberg/stdlib/primitives/databus/databus.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ field_t<Builder> databus<Builder>::bus_vector::operator[](const field_pt& index)
5353
if (index.is_constant()) {
5454
index_witness_idx = context->put_constant_variable(index.get_value());
5555
} else {
56-
index_witness_idx = index.normalize().get_witness_index();
56+
index_witness_idx = index.get_normalized_witness_index();
5757
}
5858

5959
// Read from the bus vector at the specified index. Creates a single read gate

barretenberg/cpp/src/barretenberg/stdlib/primitives/databus/databus.test.cpp

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,102 @@ TEST(Databus, CallDataAndReturnData)
7878
EXPECT_TRUE(CircuitChecker::check(builder));
7979
}
8080

81+
/**
82+
* @brief An expository test demonstrating the functionality of the databus in a small use case when the entries are
83+
* constant witnesses
84+
*/
85+
TEST(Databus, ConstantEntryAccess)
86+
{
87+
88+
Builder builder;
89+
databus_ct databus;
90+
fr value_0 = 13;
91+
fr value_1 = 12;
92+
auto constant_0 = witness_ct::create_constant_witness(&builder, value_0);
93+
auto constant_1 = witness_ct::create_constant_witness(&builder, value_1);
94+
databus.return_data.set_values({ constant_0, constant_1 });
95+
field_ct idx_0(witness_ct(&builder, 0));
96+
field_ct idx_1(witness_ct(&builder, 1));
97+
98+
field_ct read_result_0 = databus.return_data[idx_0];
99+
field_ct read_result_1 = databus.return_data[idx_1];
100+
101+
EXPECT_EQ(value_0, read_result_0.get_value());
102+
EXPECT_EQ(value_1, read_result_1.get_value());
103+
EXPECT_TRUE(CircuitChecker::check(builder));
104+
}
105+
106+
/**
107+
* @brief An expository test demonstrating the functionality of the databus in a small use case when the entries of the
108+
* bus_vector are not normalized
109+
*/
110+
TEST(Databus, UnnormalizedEntryAccess)
111+
{
112+
113+
Builder builder;
114+
databus_ct databus;
115+
std::array<fr, 3> raw_calldata_entries = { 3, 2, 1 };
116+
std::array<fr, 3> raw_returndata_entries = { 3, 2, 1 };
117+
std::vector<field_ct> calldata_entries;
118+
for (fr entry : raw_calldata_entries) {
119+
calldata_entries.emplace_back(witness_ct(&builder, entry));
120+
field_ct entry_witness = witness_ct(&builder, entry);
121+
}
122+
std::vector<field_ct> returndata_entries;
123+
for (fr entry : raw_returndata_entries) {
124+
field_ct entry_witness = witness_ct(&builder, entry);
125+
// add the value to itself to make it unnormalized (the multiplicative constant will be 2)
126+
returndata_entries.emplace_back(entry_witness + entry_witness);
127+
}
128+
databus.calldata.set_values(calldata_entries);
129+
databus.return_data.set_values(returndata_entries);
130+
field_ct idx_0 = witness_ct(&builder, 0);
131+
field_ct idx_1 = witness_ct(&builder, 1);
132+
field_ct idx_2 = witness_ct(&builder, 2);
133+
databus.return_data[idx_0].assert_equal(databus.calldata[idx_0] + databus.calldata[idx_0]);
134+
databus.return_data[idx_1].assert_equal(databus.calldata[idx_1] + databus.calldata[idx_1]);
135+
databus.return_data[idx_2].assert_equal(databus.calldata[idx_2] + databus.calldata[idx_2]);
136+
EXPECT_TRUE(CircuitChecker::check(builder));
137+
}
138+
139+
/**
140+
* @brief An expository test demonstrating the functionality of the databus in a small use case where the indices are
141+
* constant and/or unnormalized
142+
*/
143+
TEST(Databus, ConstantAndUnnormalizedIndices)
144+
{
145+
Builder builder;
146+
databus_ct databus;
147+
std::array<fr, 3> raw_calldata_values = { 54, 32, 30 };
148+
std::array<fr, 3> raw_returndata_values = { 54, 32, 116 };
149+
// Populate the calldata in the databus
150+
std::vector<field_ct> calldata_values;
151+
for (auto& value : raw_calldata_values) {
152+
calldata_values.emplace_back(witness_ct(&builder, value));
153+
}
154+
databus.calldata.set_values(calldata_values);
155+
156+
// Populate the return data in the databus
157+
std::vector<field_ct> returndata_values;
158+
for (auto& value : raw_returndata_values) {
159+
returndata_values.emplace_back(witness_ct(&builder, value));
160+
}
161+
databus.return_data.set_values(returndata_values);
162+
163+
// constant first index
164+
field_ct idx_0(witness_ct::create_constant_witness(&builder, 0));
165+
field_ct idx_1(witness_ct(&builder, 1));
166+
// un-normalized index (with multiplicative constant 2)
167+
field_ct idx_2 = idx_1 + idx_1;
168+
field_ct sum = databus.calldata[idx_0] + databus.calldata[idx_1] + databus.calldata[idx_2];
169+
170+
databus.return_data[idx_0].assert_equal(databus.calldata[idx_0]);
171+
databus.return_data[idx_1].assert_equal(databus.calldata[idx_1]);
172+
databus.return_data[idx_2].assert_equal(sum);
173+
174+
EXPECT_TRUE(CircuitChecker::check(builder));
175+
}
176+
81177
/**
82178
* @brief A failure test demonstrating that trying to prove (via a databus read) that an erroneous value is present in
83179
* the databus will result in an invalid witness.
@@ -179,4 +275,4 @@ TEST(Databus, DuplicateRead)
179275
databus.return_data[idx_1];
180276

181277
EXPECT_TRUE(CircuitChecker::check(builder));
182-
}
278+
}

0 commit comments

Comments
 (0)