Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
generator_data.hpp
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#pragma once
8
14#include <array>
15#include <map>
16#include <optional>
17
18namespace bb::crypto {
48template <typename Curve> class generator_data {
49 public:
50 using Group = typename Curve::Group;
52 using GeneratorList = std::vector<AffineElement>;
54 static inline constexpr size_t DEFAULT_NUM_GENERATORS = 8;
55 static inline constexpr std::string_view DEFAULT_DOMAIN_SEPARATOR = "DEFAULT_DOMAIN_SEPARATOR";
56 inline constexpr generator_data() = default;
57
62 static constexpr std::span<const AffineElement> precomputed_generators =
63 get_precomputed_generators<Group, "DEFAULT_DOMAIN_SEPARATOR", DEFAULT_NUM_GENERATORS, 0>();
64
65 [[nodiscard]] inline GeneratorView get(const size_t num_generators,
66 const size_t generator_offset = 0,
67 const std::string_view domain_separator = DEFAULT_DOMAIN_SEPARATOR) const
68 {
69 const bool is_default_domain = domain_separator == DEFAULT_DOMAIN_SEPARATOR;
70 if (is_default_domain && (num_generators + generator_offset) < DEFAULT_NUM_GENERATORS) {
71 return GeneratorView{ precomputed_generators.data() + generator_offset, num_generators };
72 }
73
74 if (!generator_map.has_value()) {
76 }
78
79 // Case 2: we want default generators, but more than we precomputed at compile time. If we have not yet copied
80 // the default generators into the map, do so.
82 map.insert({ std::string(DEFAULT_DOMAIN_SEPARATOR),
85 }
86
87 // if the generator map does not contain our desired generators, add entry into map
88 if (!map.contains(std::string(domain_separator))) {
89 map.insert({
90 std::string(domain_separator),
91 Group::derive_generators(domain_separator, num_generators + generator_offset, 0),
92 });
93 }
94
95 GeneratorList& generators = map.at(std::string(domain_separator));
96
97 // If the current GeneratorList does not contain enough generators, extend it
98 if (num_generators + generator_offset > generators.size()) {
99 const size_t num_extra_generators = num_generators + generator_offset - generators.size();
101 Group::derive_generators(domain_separator, num_extra_generators, generators.size());
102 generators.reserve(num_generators + generator_offset);
104 }
105
106 return GeneratorView{ generators.data() + generator_offset, num_generators };
107 }
108
109 // getter method for `default_data`. Object exists as a singleton so we don't need a smart pointer.
110 // Don't call `delete` on this pointer.
112
113 private:
114 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
115 static inline constinit generator_data default_data = generator_data();
116
117 // We mark the following two params as `mutable` so that our `get` method can be marked `const`.
118 // A non-const getter creates downstream issues as all const methods that use a non-const `get`
119 // would need to be marked const.
120 // Rationale is that it's ok for `get` to be `const` because all changes are internal to the class and don't change
121 // the external functionality of `generator_data`.
122 // i.e. `generator_data.get` will return the same output regardless of the internal state of `generator_data`.
123
124 // bool that describes whether we've copied the precomputed enerators into `generator_map`. This cannot be done at
125 // compile-time because std::map is a dynamically sized object.
127
128 // We wrap the std::map in a `std::optional` so that we can construct `generator_data` at compile time.
129 // This allows us to mark `default_data` as `constinit`, which prevents static initialization ordering fiasco
131};
132
133template <typename Curve> struct GeneratorContext {
134 size_t offset = 0;
137
138 GeneratorContext() = default;
139 GeneratorContext(size_t hash_index)
140 : offset(hash_index) {};
141 GeneratorContext(size_t _offset, std::string_view _domain_separator)
142 : offset(_offset)
143 , domain_separator(_domain_separator)
144 {}
145};
146} // namespace bb::crypto
class that stores precomputed generators used for Pedersen commitments and Pedersen hashes
std::vector< AffineElement > GeneratorList
typename Curve::Group Group
typename Curve::AffineElement AffineElement
static constexpr size_t DEFAULT_NUM_GENERATORS
constexpr generator_data()=default
static constexpr std::string_view DEFAULT_DOMAIN_SEPARATOR
static generator_data * get_default_generators()
GeneratorView get(const size_t num_generators, const size_t generator_offset=0, const std::string_view domain_separator=DEFAULT_DOMAIN_SEPARATOR) const
std::span< AffineElement const > GeneratorView
static constinit generator_data default_data
static constexpr std::span< const AffineElement > precomputed_generators
We precompute and hard-code a small number of generators. For small pedersen commitments + pedersen h...
std::optional< std::map< std::string, GeneratorList > > generator_map
typename grumpkin::g1 Group
Definition grumpkin.hpp:54
typename Group::affine_element AffineElement
Definition grumpkin.hpp:56
constexpr std::span< const typename Group::affine_element > get_precomputed_generators()
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
generator_data< Curve > * generators
GeneratorContext(size_t hash_index)
GeneratorContext(size_t _offset, std::string_view _domain_separator)