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
10
11namespace bb::avm2::simulation {
12
14 uint32_t num_limbs,
15 uint32_t radix)
16{
17 BB_BENCH_NAME("PureToRadix::to_le_radix");
18
19 uint256_t value_integer = static_cast<uint256_t>(value);
20 std::vector<uint8_t> limbs;
21 limbs.reserve(num_limbs);
22
23 for (uint32_t i = 0; i < num_limbs; i++) {
24 auto [quotient, remainder] = value_integer.divmod(static_cast<uint64_t>(radix));
25 limbs.push_back(static_cast<uint8_t>(remainder));
26 value_integer = quotient;
27 }
28
29 return { limbs, value_integer != 0 };
30}
31
32std::pair<std::vector<bool>, /* truncated */ bool> PureToRadix::to_le_bits(const FF& value, uint32_t num_limbs)
33{
34 BB_BENCH_NAME("PureToRadix::to_le_bits");
35
36 const auto [limbs, truncated] = to_le_radix(value, num_limbs, 2);
37 std::vector<bool> bits(limbs.size());
38
39 std::transform(limbs.begin(), limbs.end(), bits.begin(), [](uint8_t val) {
40 return val != 0; // Convert nonzero values to `true`, zero to `false`
41 });
42
43 return { bits, truncated };
44}
45
47 const FF& value,
48 uint32_t radix,
49 uint32_t num_limbs,
50 bool is_output_bits,
52{
53 BB_BENCH_NAME("PureToRadix::to_be_radix");
54
55 uint64_t write_addr_upper_bound = static_cast<uint64_t>(dst_addr) + num_limbs;
56 bool dst_out_of_range = write_addr_upper_bound > AVM_MEMORY_SIZE;
57 // Error handling - check that the radix value is within the valid range
58 // The valid range is [2, 256]. Therefore, the radix is invalid if (2 > radix) or (radix > 256)
59 // We need to perform both checks explicitly since that is what the circuit would do
60 bool radix_is_lt_2 = radix < 2;
61 bool radix_is_gt_256 = radix > 256;
62 // Error handling - check that if is_output_bits is true, the radix has to be 2
63 bool invalid_bitwise_radix = is_output_bits && (radix != 2);
64 // Error handling - if num_limbs is zero, value needs to be zero
65 bool invalid_num_limbs = (num_limbs == 0) && !value.is_zero();
66
67 if (dst_out_of_range || radix_is_lt_2 || radix_is_gt_256 || invalid_bitwise_radix || invalid_num_limbs) {
68 throw ToRadixException("Invalid parameters for ToRadix");
69 }
70
71 if (is_output_bits) {
72 auto [limbs, truncated] = to_le_bits(value, num_limbs);
73 if (truncated) {
74 throw ToRadixException("Truncation error");
75 }
76 std::reverse(limbs.begin(), limbs.end());
77 for (uint32_t i = 0; i < num_limbs; i++) {
78 memory.set(dst_addr + i, MemoryValue::from<uint1_t>(static_cast<uint1_t>(limbs[i])));
79 }
80 } else {
81 auto [limbs, truncated] = to_le_radix(value, num_limbs, radix);
82 if (truncated) {
83 throw ToRadixException("Truncation error");
84 }
85 std::ranges::reverse(limbs);
86 for (uint32_t i = 0; i < num_limbs; i++) {
87 memory.set(dst_addr + i, MemoryValue::from<uint8_t>(limbs[i]));
88 }
89 }
90}
91
92} // 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