Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
bitwise.fuzzer.cpp
Go to the documentation of this file.
1#include <cstdint>
2#include <fuzzer/FuzzedDataProvider.h>
3
20
21using namespace bb::avm2::simulation;
22using namespace bb::avm2::tracegen;
23using namespace bb::avm2::constraining;
24using namespace bb::avm2::fuzzing;
25
27using bb::avm2::FF;
30
32
33// We initialize it here once so it can be shared to other threads.
34// We don't use LLVMFuzzerInitialize since (IIUC) it is not thread safe and we want to run this
35// with multiple worker threads.
36static const TestTraceContainer precomputed_trace = []() {
41 precomputed_builder.process_misc(t, 1 << 18); // Need enough for bitwise trace
42 return t;
43}();
44
45// Each worker thread gets its own trace, initialized from precomputed_trace
46thread_local static TestTraceContainer trace = precomputed_trace;
47
48extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
49{
51
52 // two uint256 + <int>op_type + <int>tag_choice
53 size_t minimum_size = 64 + (sizeof(int) * 2);
54
55 if (size < minimum_size) {
56 return 0;
57 }
58
59 // Fuzzed Data Provider helps with extracting typed data from the raw byte stream.
60 FuzzedDataProvider fuzzed_data(data, size);
61
62 MemoryValue a = read_mem_value(fuzzed_data);
63 MemoryValue b = read_mem_value(fuzzed_data);
64
65 MemoryValue c = MemoryValue::from_tag(MemoryTag::FF, 0); // Placeholder for result
66 int op_id = 0; // For execution trace bitwise_op_id
67
68 int op_type = fuzzed_data.ConsumeIntegralInRange<int>(0, 2);
69
70 // Set up gadgets and event emitters
72
73 bool bitwise_error = false;
74
75 Bitwise bitwise(bitwise_emitter);
76 // Pick and execute operation
77 try {
78 switch (op_type) {
79 case 0: {
81 c = bitwise.and_op(a, b);
82 break;
83 }
84 case 1: {
86 c = bitwise.or_op(a, b);
87 break;
88 }
89 case 2: {
91 c = bitwise.xor_op(a, b);
92 break;
93 }
94 default:
95 return 0;
96 }
97 } catch (const BitwiseException& e) {
98 // Bitwise Errors are recoverable
99 bitwise_error = true;
100 }
101
102 // info("Fuzz Input: a: ", a.to_string(), ", b: ", b.to_string(), ", op_type: ", op_type);
103 // Set execution trace columns
104 trace.set(0,
105 { {
106 { Column::execution_mem_tag_reg_0_, static_cast<uint8_t>(a.get_tag()) }, // = ia_tag
107 { Column::execution_mem_tag_reg_1_, static_cast<uint8_t>(b.get_tag()) }, // = ib_tag
108 { Column::execution_mem_tag_reg_2_, static_cast<uint8_t>(c.get_tag()) }, // = ic_tag
109 { Column::execution_register_0_, a.as_ff() }, // = ia
110 { Column::execution_register_1_, b.as_ff() }, // = ib
111 { Column::execution_register_2_, c.as_ff() }, // = ic
112 { Column::execution_sel_exec_dispatch_bitwise, 1 }, // = sel
113 { Column::execution_sel_opcode_error, bitwise_error ? 1 : 0 }, // = sel_err
114 { Column::execution_subtrace_operation_id, op_id }, // = bitwise_op_id
115
116 } });
117
119 builder.process(bitwise_emitter.dump_events(), trace);
120
121 if (getenv("AVM_DEBUG") != nullptr) {
122 info("Debugging trace:");
123 bb::avm2::InteractiveDebugger debugger(trace);
124 debugger.run();
125 }
126
127 check_relation<bitwise_rel>(trace);
128 check_all_interactions<BitwiseTraceBuilder>(trace);
129 check_interaction<ExecutionTraceBuilder, bb::avm2::lookup_execution_dispatch_to_bitwise_settings>(trace);
130
131 // Reset the bitwise portion of the trace for the next iteration, bitwise portion begins at row 1 and can maximally
132 // create 16 additional rows(for U128). Therefore we reset rows [1, 17] This could be done more optimally by only
133 // resetting get_tag_bytes(a.get_tag()) rows.
134 for (uint8_t i = 1; i < 17; i++) {
135 trace.set(i,
136 { {
137 { Column::bitwise_op_id, 0 },
138 { Column::bitwise_start, 0 },
139 { Column::bitwise_sel_get_ctr, 0 },
140 { Column::bitwise_end, 0 },
141 { Column::bitwise_acc_ia, 0 },
142 { Column::bitwise_acc_ib, 0 },
143 { Column::bitwise_acc_ic, 0 },
144 { Column::bitwise_ia_byte, 0 },
145 { Column::bitwise_ib_byte, 0 },
146 { Column::bitwise_ic_byte, 0 },
147 { Column::bitwise_tag_a, 0 },
148 { Column::bitwise_tag_b, 0 },
149 { Column::bitwise_tag_c, 0 },
150 { Column::bitwise_sel_tag_ff_err, 0 },
151 { Column::bitwise_sel_tag_mismatch_err, 0 },
152 { Column::bitwise_err, 0 },
153 { Column::bitwise_tag_a_inv, 0 },
154 { Column::bitwise_tag_ab_diff_inv, 0 },
155 { Column::bitwise_ctr, 0 },
156 { Column::bitwise_ctr_min_one_inv, 0 },
157 { Column::bitwise_sel, 0 },
158 { Column::bitwise_tag_a_inv, 0 },
159 { Column::bitwise_tag_ab_diff_inv, 0 },
160 } });
161 }
162
163 return 0;
164}
#define AVM_BITWISE_AND_OP_ID
#define AVM_BITWISE_OR_OP_ID
#define AVM_BITWISE_XOR_OP_ID
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
void run(uint32_t starting_row=0)
Definition debugger.cpp:76
static TaggedValue from_tag(ValueTag tag, FF value)
ValueTag get_tag() const
Witness-generating implementation of bitwise AND/OR/XOR operations.
Definition bitwise.hpp:13
void process(const simulation::EventEmitterInterface< simulation::AluEvent >::Container &events, TraceContainer &trace)
Process the ALU events and populate the ALU relevant columns in the trace.
Trace builder for the bitwise subtrace (AND/OR/XOR operations).
void process_misc(TraceContainer &trace, const uint32_t num_rows=PRECOMPUTED_TRACE_SIZE)
Populate miscellaneous precomputed columns: first_row selector and idx (row index).
void process_bitwise(TraceContainer &trace)
Populate the 8-bit bitwise lookup table (AND, OR, XOR).
void process_tag_parameters(TraceContainer &trace)
Populate the memory tag parameters table (byte length, max bits, max value per tag).
void set(Column col, uint32_t row, const FF &value)
#define info(...)
Definition log.hpp:93
PrecomputedTraceBuilder precomputed_builder
Definition alu.test.cpp:120
AluTraceBuilder builder
Definition alu.test.cpp:124
const std::vector< MemoryValue > data
FF a
FF b
MemoryValue read_mem_value(FuzzedDataProvider &fdp)
Read a MemoryValue from the fuzzed data provider.
AVM range check gadget for witness generation.
AvmFlavorSettings::FF FF
Definition field.hpp:10