Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
poseidon2_pedersen.fuzzer.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
35#include <cassert>
36#include <cstdint>
37#include <cstring>
38#include <iostream>
39#include <vector>
40
41using namespace bb;
42using Fr = fr;
45
46// Input structure constants
47static constexpr size_t SINGLE_CHUNK_SIZE = 129; // 1 byte for selection of element + 128 bytes for FieldVM data
48
55std::vector<Fr> parse_input_and_generate_elements(const uint8_t* data, size_t size)
56{
57 std::vector<Fr> elements;
58
59 // Need at least header size
60 if (size < SINGLE_CHUNK_SIZE) {
61 return elements;
62 }
63
64 // Parse header: first byte is number of elements (0-128)
65 size_t num_elements = size / SINGLE_CHUNK_SIZE;
66
67 // Create FieldVM instance for field element generation
68 FieldVM<Fr> field_vm(false, 65536); // Disable debug, max 65536 steps
69
70 // Disable heavy operations for better performance
71 field_vm.settings.enable_inv = false; // Disable inversion
72 field_vm.settings.enable_sqrt = false; // Disable square root
73 field_vm.settings.enable_batch_invert = false; // Disable batch inversion
74 field_vm.settings.enable_pow = false; // Disable power operation
75 field_vm.settings.enable_div = false; // Disable division
76 field_vm.settings.enable_div_assign = false; // Disable division assignment
77
78 // Run FieldVM with data after header (bytes 129+)
79 size_t fieldvm_data_size = size - num_elements;
80 if (fieldvm_data_size > 0) {
81 field_vm.run(data, fieldvm_data_size);
82 }
83
84 // Extract elements based on indices in header
85 elements.reserve(num_elements);
86 for (size_t i = 0; i < num_elements; ++i) {
87 uint8_t index_byte = data[fieldvm_data_size + i]; // Bytes 1-128 contain indices
88
89 size_t field_index = index_byte % 32; // Wrap around if needed
90
91 // Get element from FieldVM state
92 Fr element = field_vm.field_internal_state[field_index];
93 elements.emplace_back(element);
94 }
95
96 return elements;
97}
98
105template <typename Builder> bool test_poseidon2_circuit(const std::vector<Fr>& inputs)
106{
107 try {
110
112 std::vector<field_ct> circuit_inputs;
113 circuit_inputs.reserve(inputs.size());
114
115 // Convert native field elements to circuit witnesses
116 for (const auto& input : inputs) {
117 circuit_inputs.emplace_back(field_ct(witness_ct(&builder, input)));
118 }
119
120 // Compute hash using circuit
121 auto circuit_result = stdlib::poseidon2<Builder>::hash(builder, circuit_inputs);
122
123 // Compute hash using native implementation
124 auto native_result = native_poseidon2::hash(inputs);
125
126 // Compare results
127 if (circuit_result.get_value() != native_result) {
128 std::cerr << "Poseidon2 circuit mismatch detected!" << std::endl;
129 std::cerr << "Input length: " << inputs.size() << std::endl;
130 std::cerr << "Circuit result: " << circuit_result.get_value() << std::endl;
131 std::cerr << "Native result: " << native_result << std::endl;
132 return false;
133 }
134
135 // Verify circuit correctness
136 bool circuit_check = CircuitChecker::check(builder);
137 if (!circuit_check) {
138 std::cerr << "Poseidon2 circuit check failed!" << std::endl;
139 std::cerr << "Input length: " << inputs.size() << std::endl;
140 return false;
141 }
142
143 return true;
144
145 } catch (const std::exception& e) {
146 std::cerr << "Exception in Poseidon2 circuit test: " << e.what() << std::endl;
147 std::cerr << "Input length: " << inputs.size() << std::endl;
148 return false;
149 }
150}
157template <typename Builder> bool test_pedersen_circuit(const std::vector<Fr>& inputs)
158{
159 try {
162
164 std::vector<field_ct> circuit_inputs;
165 circuit_inputs.reserve(inputs.size());
166
167 // Convert native field elements to circuit witnesses
168 for (const auto& input : inputs) {
169 circuit_inputs.emplace_back(field_ct(witness_ct(&builder, input)));
170 }
171
172 // Compute hash using circuit
173 auto circuit_result = stdlib::pedersen_hash<Builder>::hash(circuit_inputs);
174
175 // Compute hash using native implementation
176 auto native_result = native_pedersen::hash(inputs);
177
178 // Compare results
179 if (circuit_result.get_value() != native_result) {
180 std::cerr << "Pedersen circuit mismatch detected!" << std::endl;
181 std::cerr << "Input length: " << inputs.size() << std::endl;
182 std::cerr << "Circuit result: " << circuit_result.get_value() << std::endl;
183 std::cerr << "Native result: " << native_result << std::endl;
184 return false;
185 }
186
187 // Verify circuit correctness
188 bool circuit_check = CircuitChecker::check(builder);
189 if (!circuit_check) {
190 std::cerr << "Pedersen circuit check failed!" << std::endl;
191 std::cerr << "Input length: " << inputs.size() << std::endl;
192 return false;
193 }
194
195 return true;
196
197 } catch (const std::exception& e) {
198 std::cerr << "Exception in Pedersen circuit test: " << e.what() << std::endl;
199 std::cerr << "Input length: " << inputs.size() << std::endl;
200 return false;
201 }
202}
203
210extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
211{
212 // Security check: Ensure minimum input size
213 if (Size == 0) {
214 return 0; // No input data
215 }
216 bool is_poseidon2 = Data[0] & 0x01;
217
218 // Parse input structure and generate field elements using FieldVM
219 auto field_elements = parse_input_and_generate_elements(Data + 1, Size - 1);
220
221 // Security check: Ensure we have valid elements
222 if (field_elements.empty()) {
223 return 0; // No valid field elements generated
224 }
225
226 // Test with Ultra circuit builder only
227 bool test_result = is_poseidon2 ? test_poseidon2_circuit<UltraCircuitBuilder>(field_elements)
228 : test_pedersen_circuit<UltraCircuitBuilder>(field_elements);
229
230 if (!test_result) {
231 abort(); // Circuit test failed
232 }
233
234 return 0; // Success
235}
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
Performs pedersen hashes!
Definition pedersen.hpp:30
static Fq hash(const std::vector< Fq > &inputs, GeneratorContext context={})
Given a vector of fields, generate a pedersen hash using generators from context.
Definition pedersen.cpp:78
static field_ct hash(const std::vector< field_ct > &in, GeneratorContext context={})
Definition pedersen.cpp:15
AluTraceBuilder builder
Definition alu.test.cpp:123
const std::vector< FF > data
Field arithmetic fuzzer for testing cryptographic field operations.
bn254::witness_ct witness_ct
stdlib::field_t< Builder > field_ct
pedersen_hash_base< curve::Grumpkin > pedersen_hash
Definition pedersen.hpp:47
Entry point for Barretenberg command-line interface.
field< Bn254FrParams > fr
Definition fr.hpp:174
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
Main fuzzer entry point.
bool test_poseidon2_circuit(const std::vector< Fr > &inputs)
Test Poseidon2 circuit with specified builder type.
std::vector< Fr > parse_input_and_generate_elements(const uint8_t *data, size_t size)
Parse input structure and generate field elements using FieldVM.
bool test_pedersen_circuit(const std::vector< Fr > &inputs)
Test Pedersen circuit with specified builder type.
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::array< Field, INTERNAL_STATE_SIZE > field_internal_state
Internal state array of field elements.
VMSettings settings
VM settings controlling which operations are enabled.
bool enable_inv
Enable INV operations.
bool enable_batch_invert
Enable BATCH_INVERT operations.
bool enable_div
Enable DIV operations.
bool enable_div_assign
Enable DIV_ASSIGN operations.
bool enable_sqrt
Enable SQRT operations.
bool enable_pow
Enable POW operations.