75static_assert(
sizeof(
VMPhaseHeader) == 2,
"VMPhaseHeader must be exactly 2 bytes");
88 if (
value < Field::modulus) {
91 return value % Field::modulus;
113template <
typename Field>
137template <
typename Field>
145 size_t bytes_consumed = vm.
run(
data + data_offset, size - data_offset,
true);
148 if (bytes_consumed == 0) {
154 std::cout <<
"Internal state check failed for field type: " <<
typeid(Field).name() <<
std::endl;
162 data_offset += bytes_consumed;
164 return static_cast<int>(bytes_consumed);
182template <
typename Field>
184 const unsigned char* Data,
190 if (!current_state.empty()) {
191 import_state_with_reduction<Field>(vm, current_state);
193 int phase_result =
run_vm_phase(vm, Data, Size, header, data_offset);
194 if (phase_result > 0) {
214template <
typename Field>
216 const unsigned char* Data,
218 size_t original_data_offset,
222 if (!current_state.empty()) {
223 std::cout <<
"Importing state with " << current_state.size() <<
" elements" <<
std::endl;
224 import_state_with_reduction<Field>(vm_debug, current_state);
232 size_t bytes_consumed =
236 std::cout <<
"[Debug VM] State is still correct after execution! No discrepancy detected." <<
std::endl;
240 std::cout <<
"[Debug VM] State discrepancy detected! This is a real failure." <<
std::endl;
264 size_t data_offset = 0;
274 if (selected_steps == 0) {
277 header.
field_type =
static_cast<uint8_t
>(selected_field_type);
278 header.
steps = selected_steps;
281 int phase_result = 0;
282 switch (selected_field_type) {
284 phase_result = run_field_vm<fq>(header, Data, Size, data_offset, current_state);
288 phase_result = run_field_vm<fr>(header, Data, Size, data_offset, current_state);
292 phase_result = run_field_vm<secp256k1::fq>(header, Data, Size, data_offset, current_state);
296 phase_result = run_field_vm<secp256k1::fr>(header, Data, Size, data_offset, current_state);
300 phase_result = run_field_vm<secp256r1::fq>(header, Data, Size, data_offset, current_state);
304 phase_result = run_field_vm<secp256r1::fr>(header, Data, Size, data_offset, current_state);
309 if (phase_result < 0) {
311 std::cout <<
"Phase failed for field type: " <<
static_cast<int>(selected_field_type)
312 <<
" with steps: " <<
static_cast<int>(header.
steps) <<
std::endl;
315 std::cout <<
"Instruction stream (first 64 bytes): ";
316 size_t debug_size = std::min(Size - data_offset -
PHASE_HEADER_SIZE,
size_t(64));
317 for (
size_t i = 0; i < debug_size; i++) {
323 switch (selected_field_type) {
325 run_debug_vm<fq>(header, Data, Size, data_offset, current_state);
328 run_debug_vm<fr>(header, Data, Size, data_offset, current_state);
331 run_debug_vm<secp256k1::fq>(header, Data, Size, data_offset, current_state);
334 run_debug_vm<secp256k1::fr>(header, Data, Size, data_offset, current_state);
337 run_debug_vm<secp256r1::fq>(header, Data, Size, data_offset, current_state);
340 run_debug_vm<secp256r1::fr>(header, Data, Size, data_offset, current_state);
344 }
else if (phase_result == 0) {
const std::vector< FF > data
Field arithmetic fuzzer for testing cryptographic field operations.
FieldType
Enumeration of supported field types for the multi-field fuzzer.
@ BN254_FQ
BN254 curve base field.
@ SECP256R1_FR
Secp256r1 curve scalar field.
@ BN254_FR
BN254 curve scalar field.
@ SECP256K1_FR
Secp256k1 curve scalar field.
@ SECP256K1_FQ
Secp256k1 curve base field.
@ SECP256R1_FQ
Secp256r1 curve base field.
int run_field_vm(const VMPhaseHeader &header, const unsigned char *Data, size_t Size, size_t &data_offset, std::vector< numeric::uint256_t > ¤t_state)
Creates and runs a VM for a specific field type with state management.
int run_vm_phase(FieldVM< Field > &vm, const unsigned char *data, size_t size, const VMPhaseHeader &header, size_t &data_offset)
Runs a single VM phase with error handling and state management.
const size_t PHASE_HEADER_SIZE
void run_debug_vm(const VMPhaseHeader &header, const unsigned char *Data, size_t Size, size_t original_data_offset, const std::vector< numeric::uint256_t > ¤t_state)
Runs a debug VM to analyze failed phases.
FieldVM< Field > create_field_vm(size_t max_steps)
Creates a field VM with specified maximum steps.
numeric::uint256_t reduce_to_modulus(const numeric::uint256_t &value)
Reduces a uint256_t value to be less than the field's modulus.
constexpr size_t MAX_STEPS
Maximum number of VM steps per phase.
void import_state_with_reduction(FieldVM< Field > &vm, const std::vector< numeric::uint256_t > &state)
Imports state into a field VM with automatic modulus reduction.
constexpr size_t NUM_FIELD_TYPES
Total number of supported field types.
int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size)
Main fuzzer entry point for multi-field testing.
Entry point for Barretenberg command-line interface.
const size_t INTERNAL_STATE_SIZE
Constant defining the number of elements in the VM's internal state.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Virtual machine for field arithmetic operations.
size_t run(const unsigned char *Data, size_t Size, bool reset_steps=true)
Run the VM on input data.
std::vector< numeric::uint256_t > export_uint_state() const
Export the final uint state as a vector of uint256_t values.
std::array< numeric::uint256_t, INTERNAL_STATE_SIZE > uint_internal_state
Internal state array of uint256_t values.
void set_max_steps(size_t new_max_steps)
Set a new step limit for the VM.
std::array< Field, INTERNAL_STATE_SIZE > field_internal_state
Internal state array of field elements.
bool verify_initial_state(const std::vector< numeric::uint256_t > &state) const
Verify that the initial state is correctly loaded.
bool check_internal_state() const
Check internal state consistency between field and uint256_t representations.