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