barretenberg
Loading...
Searching...
No Matches
generator_data.hpp
1#pragma once
2
3#include "barretenberg/common/container.hpp"
4#include "barretenberg/ecc/curves/bn254/bn254.hpp"
5#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp"
6#include <array>
7#include <map>
8#include <optional>
9
10namespace crypto {
40template <typename Curve> class generator_data {
41 public:
42 using Group = typename Curve::Group;
43 using AffineElement = typename Curve::AffineElement;
44 using GeneratorList = std::vector<AffineElement>;
45 using GeneratorView = std::span<AffineElement const>;
46 static inline constexpr size_t DEFAULT_NUM_GENERATORS = 8;
47 static inline constexpr std::string_view DEFAULT_DOMAIN_SEPARATOR = "DEFAULT_DOMAIN_SEPARATOR";
48 inline constexpr generator_data() = default;
49
50 static inline constexpr std::array<AffineElement, DEFAULT_NUM_GENERATORS> make_precomputed_generators()
51 {
52 std::array<AffineElement, DEFAULT_NUM_GENERATORS> output;
53 std::vector<AffineElement> res = Group::derive_generators(DEFAULT_DOMAIN_SEPARATOR, DEFAULT_NUM_GENERATORS, 0);
54 std::copy(res.begin(), res.end(), output.begin());
55 return output;
56 }
57
62 static inline constexpr std::array<AffineElement, DEFAULT_NUM_GENERATORS> precomputed_generators =
63 make_precomputed_generators();
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()) {
75 generator_map = std::map<std::string, GeneratorList>();
76 }
77 std::map<std::string, GeneratorList>& map = generator_map.value();
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.
81 if (is_default_domain && !initialized_precomputed_generators) {
82 map.insert({ std::string(DEFAULT_DOMAIN_SEPARATOR),
83 GeneratorList(precomputed_generators.begin(), precomputed_generators.end()) });
84 initialized_precomputed_generators = true;
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();
100 GeneratorList extended_generators =
101 Group::derive_generators(domain_separator, num_extra_generators, generators.size());
102 generators.reserve(num_generators + generator_offset);
103 std::copy(extended_generators.begin(), extended_generators.end(), std::back_inserter(generators));
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.
111 static inline generator_data* get_default_generators() { return &default_data; }
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.
126 mutable bool initialized_precomputed_generators = false;
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
130 mutable std::optional<std::map<std::string, GeneratorList>> generator_map = {};
131};
132
133template <typename Curve> struct GeneratorContext {
134 size_t offset = 0;
135 std::string domain_separator = std::string(generator_data<Curve>::DEFAULT_DOMAIN_SEPARATOR);
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 crypto
class that stores precomputed generators used for Pedersen commitments and Pedersen hashes
Definition: generator_data.hpp:40
static constexpr std::array< AffineElement, DEFAULT_NUM_GENERATORS > precomputed_generators
Precompute a small number of generators at compile time. For small pedersen commitments + pedersen ha...
Definition: generator_data.hpp:62
Definition: aes128.cpp:9
Definition: generator_data.hpp:133