Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
origin_tag.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
19#include <cstddef>
20#include <ostream>
21
22// Currently disabled, because there are violations of the tag invariant in the codebase everywhere.
23// TODO(https://github.com/AztecProtocol/barretenberg/issues/1532): Re-enable this once we resolve these issues.
24#define DISABLE_CHILD_TAG_CHECKS
25
26#define STANDARD_TESTING_TAGS /*Tags reused in tests*/ \
27 const size_t parent_id = 0; \
28 [[maybe_unused]] const auto clear_tag = OriginTag(); \
29 const auto submitted_value_origin_tag = OriginTag( \
30 parent_id, /*round_id=*/0, /*is_submitted=*/true); /*A tag describing a value submitted in the 0th round*/ \
31 const auto next_submitted_value_origin_tag = OriginTag( \
32 parent_id, /*round_id=*/1, /*is_submitted=*/true); /*A tag describing a value submitted in the 1st round*/ \
33 const auto challenge_origin_tag = OriginTag( \
34 parent_id, /*round_id=*/0, /*is_submitted=*/false); /*A tag describing a challenge derived in the 0th round*/ \
35 const auto next_challenge_tag = OriginTag( \
36 parent_id, /*round_id=*/1, /*is_submitted=*/false); /*A tag describing a challenge derived in the 1st round*/ \
37 const auto first_two_merged_tag = \
38 OriginTag(submitted_value_origin_tag, \
39 challenge_origin_tag); /*A tag describing a value constructed from values submitted by the prover in \
40 the 0th round and challenges from the same round */ \
41 const auto first_and_third_merged_tag = \
42 OriginTag(submitted_value_origin_tag, \
43 next_challenge_tag); /* A tag describing a value constructed from values submitted in the 0th round \
44 and challenges computed in the 1st round*/ \
45 const auto first_second_third_merged_tag = OriginTag( \
46 first_two_merged_tag, next_challenge_tag); /* A tag describing a value computed from values submitted in the \
47 0th round and challenges generated in the 0th and 1st round*/ \
48 const auto first_to_fourth_merged_tag = \
49 OriginTag(first_second_third_merged_tag, \
50 next_submitted_value_origin_tag); /* A tag describing a value computed from values submitted in the \
51 0th and 1st round and challenges generated in the 0th and 1st round*/ \
52 const auto instant_death_tag = []() { \
53 auto some_tag = OriginTag(); \
54 some_tag.poison(); \
55 return some_tag; \
56 }(); /* A tag that causes and abort on any arithmetic*/
57
58namespace bb {
59
60void check_child_tags(const uint256_t& tag_a, const uint256_t& tag_b);
61#ifndef AZTEC_NO_ORIGIN_TAGS
62struct OriginTag {
63
64 static constexpr size_t CONSTANT = static_cast<size_t>(-1);
65 static constexpr size_t FREE_WITNESS = static_cast<size_t>(-2);
66 // Parent tag is supposed to represent the index of a unique trancript object that generated the value. It uses
67 // a concrete index, not bits for now, since we never expect two different indices to be used in the same
68 // computation apart from equality assertion
69 // Parent tag is set to CONSTANT if the value is just a constant
70 // Parent tag is set to FREE_WITNESS if the value is a free witness (not a constant and not from the transcript)
71 size_t parent_tag = CONSTANT;
72
73 // Child tag specifies which submitted values and challenges have been used to generate this element
74 // The lower 128 bits represent using a submitted value from a corresponding round (the shift represents the
75 // round) The higher 128 bits represent using a challenge value from an corresponding round (the shift
76 // represents the round)
78
79 // Instant death is used for poisoning values we should never use in arithmetic
80 bool instant_death = false;
82 // Default Origin Tag has everything set to zero and can't cause any issues
83 OriginTag() = default;
84 OriginTag(const OriginTag& other) = default;
85 OriginTag(OriginTag&& other) = default;
86 OriginTag& operator=(const OriginTag& other) = default;
87 OriginTag& operator=(OriginTag&& other) noexcept
88 {
89
90 parent_tag = other.parent_tag;
91 child_tag = other.child_tag;
92 instant_death = other.instant_death;
93 return *this;
94 }
102 OriginTag(size_t parent_index, size_t child_index, bool is_submitted = true)
103 : parent_tag(parent_index)
104 , child_tag((static_cast<uint256_t>(1) << (child_index + (is_submitted ? 0 : 128))))
105 {
106 BB_ASSERT_LT(child_index, 128U);
107 }
108
118 OriginTag(const OriginTag& tag_a, const OriginTag& tag_b);
119
129 template <class... T>
130 OriginTag(const OriginTag& tag, const T&... rest)
132 , child_tag(tag.child_tag)
134 {
135
136 OriginTag merged_tag = *this;
137 for (const auto& next_tag : { rest... }) {
138 merged_tag = OriginTag(merged_tag, next_tag);
139 }
140 *this = merged_tag;
142 ~OriginTag() = default;
143 bool operator==(const OriginTag& other) const;
144 void poison() { instant_death = true; }
145 void unpoison() { instant_death = false; }
146 bool is_poisoned() const { return instant_death; }
147 bool is_empty() const { return !instant_death && parent_tag == CONSTANT; };
148
149#ifndef DISABLE_FREE_WITNESS_CHECK
150 bool is_free_witness() const { return parent_tag == FREE_WITNESS; }
151 void set_free_witness()
154 child_tag = 0;
155 }
156 void unset_free_witness()
157 {
160 }
161
162// The checks are disabled by disallowing to set the free witness tag, because if they are set, it's very hard to make
163// the logic of checks work
164#else
165 bool is_free_witness() const { return false; }
167 void unset_free_witness() {}
168#endif
169};
170inline std::ostream& operator<<(std::ostream& os, OriginTag const& v)
171{
172 return os << "{ p_t: " << v.parent_tag << ", ch_t: " << v.child_tag << ", instadeath: " << v.instant_death << " }";
173}
174
175#else
176
177struct OriginTag {
178 OriginTag() = default;
179 OriginTag(const OriginTag& other) = default;
180 OriginTag(OriginTag&& other) = default;
181 OriginTag& operator=(const OriginTag& other) = default;
182 OriginTag& operator=(OriginTag&& other) = default;
183 ~OriginTag() = default;
184
185 OriginTag(size_t parent_index [[maybe_unused]],
186 size_t child_index [[maybe_unused]],
187 bool is_submitted [[maybe_unused]] = true)
188 {}
189
190 OriginTag(const OriginTag&, const OriginTag&) {}
191 template <class... T> OriginTag(const OriginTag&, const T&...) {}
192 bool operator==(const OriginTag& other) const;
193 void poison() {}
194 void unpoison() {}
195 static bool is_poisoned() { return false; }
196 static bool is_empty() { return true; };
197 bool is_free_witness() const { return false; }
198 void set_free_witness() {}
199 void unset_free_witness() {}
200};
201inline std::ostream& operator<<(std::ostream& os, OriginTag const&)
202{
203 return os << "{ Origin Tag tracking is disabled in release builds }";
205#endif
206} // namespace bb
207template <typename T>
208concept usesTag = requires(T x, const bb::OriginTag& tag) { x.set_origin_tag(tag); };
#define BB_ASSERT_LT(left, right,...)
Definition assert.hpp:148
std::ostream & operator<<(std::ostream &os, uint256_t const &a)
Definition uint256.hpp:245
Entry point for Barretenberg command-line interface.
void check_child_tags(const uint256_t &tag_a, const uint256_t &tag_b)
Detect if two elements from the same transcript are performing a suspicious interaction.
std::integral_constant< size_t, I > tag
Definition tuplet.hpp:258
size_t parent_tag
void unset_free_witness()
OriginTag()=default
bool is_poisoned() const
numeric::uint256_t child_tag
~OriginTag()=default
void set_free_witness()
static constexpr size_t CONSTANT
OriginTag & operator=(const OriginTag &other)=default
static constexpr size_t FREE_WITNESS
bool is_empty() const
bool is_free_witness() const
bool operator==(const OriginTag &other) const