Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
pure_to_radix.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cstdint>
5#include <vector>
6
11
12namespace bb::avm2::simulation {
13
15 uint32_t num_limbs,
16 uint32_t radix)
17{
18 BB_BENCH_NAME("PureToRadix::to_le_radix");
19
20 uint256_t value_integer = static_cast<uint256_t>(value);
21 std::vector<uint8_t> limbs;
22 limbs.reserve(num_limbs);
23
24 for (uint32_t i = 0; i < num_limbs; i++) {
25 auto [quotient, remainder] = value_integer.divmod(static_cast<uint64_t>(radix));
26 limbs.push_back(static_cast<uint8_t>(remainder));
27 value_integer = quotient;
28 }
29
30 return { limbs, value_integer != 0 };
31}
32
33std::pair<std::vector<bool>, /* truncated */ bool> PureToRadix::to_le_bits(const FF& value, uint32_t num_limbs)
34{
35 BB_BENCH_NAME("PureToRadix::to_le_bits");
36
37 const auto [limbs, truncated] = to_le_radix(value, num_limbs, 2);
38 std::vector<bool> bits(limbs.size());
39
40 std::transform(limbs.begin(), limbs.end(), bits.begin(), [](uint8_t val) {
41 return val != 0; // Convert nonzero values to `true`, zero to `false`
42 });
43
44 return { bits, truncated };
45}
46
48 const FF& value,
49 uint32_t radix,
50 uint32_t num_limbs,
51 bool is_output_bits,
53{
54 BB_BENCH_NAME("PureToRadix::to_be_radix");
55
56 uint64_t write_addr_upper_bound = static_cast<uint64_t>(dst_addr) + num_limbs;
57 bool dst_out_of_range = write_addr_upper_bound > AVM_MEMORY_SIZE;
58 // Error handling - check that the radix value is within the valid range
59 // The valid range is [2, 256]. Therefore, the radix is invalid if (2 > radix) or (radix > 256)
60 // We need to perform both checks explicitly since that is what the circuit would do
61 bool radix_is_lt_2 = radix < 2;
62 bool radix_is_gt_256 = radix > 256;
63 // Error handling - check that if is_output_bits is true, the radix has to be 2
64 bool invalid_bitwise_radix = is_output_bits && (radix != 2);
65 // Error handling - if num_limbs is zero, value needs to be zero
66 bool invalid_num_limbs = (num_limbs == 0) && !value.is_zero();
67
68 if (dst_out_of_range || radix_is_lt_2 || radix_is_gt_256 || invalid_bitwise_radix || invalid_num_limbs) {
69 throw ToRadixException("Invalid parameters for ToRadix");
70 }
71
72 if (is_output_bits) {
73 auto [limbs, truncated] = to_le_bits(value, num_limbs);
74 if (truncated) {
75 throw ToRadixException("Truncation error");
76 }
77 std::reverse(limbs.begin(), limbs.end());
78 for (uint32_t i = 0; i < num_limbs; i++) {
79 memory.set(dst_addr + i, MemoryValue::from<uint1_t>(static_cast<uint1_t>(limbs[i])));
80 }
81 } else {
82 auto [limbs, truncated] = to_le_radix(value, num_limbs, radix);
83 if (truncated) {
84 throw ToRadixException("Truncation error");
85 }
86 std::ranges::reverse(limbs);
87 for (uint32_t i = 0; i < num_limbs; i++) {
88 memory.set(dst_addr + i, MemoryValue::from<uint8_t>(limbs[i]));
89 }
90 }
91}
92
93} // namespace bb::avm2::simulation
#define AVM_MEMORY_SIZE
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:225
void to_be_radix(MemoryInterface &memory, const FF &value, uint32_t radix, uint32_t num_limbs, bool is_output_bits, MemoryAddress dst_addr) override
std::pair< std::vector< bool >, bool > to_le_bits(const FF &value, uint32_t num_limbs) override
std::pair< std::vector< uint8_t >, bool > to_le_radix(const FF &value, uint32_t num_limbs, uint32_t radix) override
A 1-bit unsigned integer type.
Definition uint1.hpp:15
constexpr std::pair< uint256_t, uint256_t > divmod(const uint256_t &b) const
uint32_t dst_addr
AVM range check gadget for witness generation.
AvmFlavorSettings::FF FF
Definition field.hpp:10
uint32_t MemoryAddress
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
BB_INLINE constexpr bool is_zero() const noexcept