Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
process_buckets.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
7#include "process_buckets.hpp"
8
9#include <array>
10
12
13// NOLINTNEXTLINE(misc-no-recursion) recursion is fine here, max recursion depth is 8 (64 bit int / 8 bits per call)
15 const size_t num_entries,
16 const uint32_t shift,
17 size_t& num_zero_entries,
18 const uint32_t total_bits,
19 const uint64_t* start_pointer) noexcept
20{
21 constexpr size_t num_bits = 8;
22 constexpr size_t num_buckets = 1UL << num_bits;
23 constexpr uint32_t mask = static_cast<uint32_t>(num_buckets) - 1U;
25
26 for (size_t i = 0; i < num_entries; ++i) {
27 bucket_counts[(keys[i] >> shift) & mask]++;
28 }
29
32 offsets[0] = 0;
33
34 for (size_t i = 0; i < num_buckets - 1; ++i) {
35 bucket_counts[i + 1] += bucket_counts[i];
36 }
37 if ((shift == 0) && (keys == start_pointer)) {
38 num_zero_entries = bucket_counts[0];
39 }
40 for (size_t i = 1; i < num_buckets + 1; ++i) {
41 offsets[i] = bucket_counts[i - 1];
42 }
43 for (size_t i = 0; i < num_buckets + 1; ++i) {
44 offsets_copy[i] = offsets[i];
45 }
46 uint64_t* start = &keys[0];
47
48 for (size_t i = 0; i < num_buckets; ++i) {
49 uint64_t* bucket_start = &keys[offsets[i]];
50 const uint64_t* bucket_end = &keys[offsets_copy[i + 1]];
51 while (bucket_start != bucket_end) {
52 for (uint64_t* it = bucket_start; it < bucket_end; ++it) {
53 const size_t value = (*it >> shift) & mask;
54 const uint64_t offset = offsets[value]++;
55 std::iter_swap(it, start + offset);
56 }
57 bucket_start = &keys[offsets[i]];
58 }
59 }
60 if (shift > 0) {
61 for (size_t i = 0; i < num_buckets; ++i) {
62 if (offsets_copy[i + 1] - offsets_copy[i] > 1) {
63 radix_sort_count_zero_entries(&keys[offsets_copy[i]],
64 offsets_copy[i + 1] - offsets_copy[i],
65 shift - 8,
66 num_zero_entries,
67 total_bits,
68 keys);
69 }
70 }
71 }
72}
73
74size_t process_buckets_count_zero_entries(uint64_t* wnaf_entries,
75 const size_t num_entries,
76 const uint32_t num_bits) noexcept
77{
78 if (num_entries == 0) {
79 return 0;
80 }
81 const uint32_t bits_per_round = 8;
82 const uint32_t base = num_bits & 7;
83 const uint32_t total_bits = (base == 0) ? num_bits : num_bits - base + 8;
84 const uint32_t shift = total_bits - bits_per_round;
85 size_t num_zero_entries = 0;
86 radix_sort_count_zero_entries(wnaf_entries, num_entries, shift, num_zero_entries, num_bits, wnaf_entries);
87
88 // inside radix_sort_count_zero_entries, if the least significant *byte* of `wnaf_entries[0] == 0`,
89 // then num_nonzero_entries = number of entries that share the same value as wnaf_entries[0].
90 // If wnaf_entries[0] != 0, we must manually set num_zero_entries = 0
91 if (num_entries > 0) {
92 if ((wnaf_entries[0] & 0xffffffff) != 0) {
93 num_zero_entries = 0;
94 }
95 }
96 return num_zero_entries;
97}
98} // namespace bb::scalar_multiplication
ssize_t offset
Definition engine.cpp:36
size_t process_buckets_count_zero_entries(uint64_t *wnaf_entries, const size_t num_entries, const uint32_t num_bits) noexcept
void radix_sort_count_zero_entries(uint64_t *keys, const size_t num_entries, const uint32_t shift, size_t &num_zero_entries, const uint32_t total_bits, const uint64_t *start_pointer) noexcept
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13