Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
origin_tag.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Planned, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
10#include <string>
11
12namespace bb {
13using namespace numeric;
14#ifndef AZTEC_NO_ORIGIN_TAGS
15
16namespace {
21inline int highest_set_bit_256(uint256_t value)
22{
23 if (value == 0) {
24 return -1;
25 }
26 for (int idx = 0; idx < 4; idx++) {
27 auto chunk = static_cast<uint64_t>(value >> (64 * (3 - idx)));
28 if (chunk != 0) {
29 return 255 - (idx * 64) - __builtin_clzll(chunk);
30 }
31 }
32 return -1;
33}
34} // namespace
35
51void check_round_provenance(const uint512_t& provenance_a, const uint512_t& provenance_b)
52{
53 // Lower 256 bits = submitted rounds, Upper 256 bits = challenge rounds
54 const uint256_t& submitted_a = provenance_a.lo;
55 const uint256_t& submitted_b = provenance_b.lo;
56
57 // Nothing to check if either has no submitted data or both are from the same round(s)
58 if (submitted_a == 0 || submitted_b == 0 || submitted_a == submitted_b) {
59 return;
60 }
61
62 // Ensure that values from different rounds are not mixing without max challenge round >= max submitted round
63 const int max_challenge_round = highest_set_bit_256(provenance_a.hi | provenance_b.hi);
64 const int max_submitted_round = highest_set_bit_256(submitted_a | submitted_b);
65
66 if (max_challenge_round < max_submitted_round) {
67 throw_or_abort("Round provenance check failed: max challenge round (" + std::to_string(max_challenge_round) +
68 ") < max submitted round (" + std::to_string(max_submitted_round) + ")");
69 }
70}
71
72bool OriginTag::operator==(const OriginTag& other) const
73{
74 return this->transcript_index == other.transcript_index && this->round_provenance == other.round_provenance &&
75 this->instant_death == other.instant_death;
76}
77OriginTag::OriginTag(const OriginTag& tag_a, const OriginTag& tag_b)
78{
79 // Elements with instant death should not be touched
80 if (tag_a.instant_death || tag_b.instant_death) {
81 throw_or_abort("Touched an element that should not have been touched. tag_a id: " +
82 std::to_string(tag_a.tag_id) + ", tag_b id: " + std::to_string(tag_b.tag_id));
83 }
84 // If one of the tags is a constant, just use the other tag
85 if (tag_a.transcript_index == CONSTANT) {
86 *this = tag_b;
87 return;
88 }
89 if (tag_b.transcript_index == CONSTANT) {
90 *this = tag_a;
91 return;
92 }
93
94 // A free witness element should not interact with an element that has an origin
95 if (tag_a.is_free_witness()) {
96 if (!tag_b.is_free_witness() && !tag_b.is_empty()) {
98 "A free witness element (id: " + std::to_string(tag_a.tag_id) +
99 ") should not interact with an element that has an origin (id: " + std::to_string(tag_b.tag_id) + ")");
100 } else {
101 // If both are free witnesses or one of them is empty, just use tag_a
102 *this = tag_a;
103 return;
104 }
105 }
106 if (tag_b.is_free_witness()) {
107 if (!tag_a.is_free_witness() && !tag_a.is_empty()) {
109 "A free witness element (id: " + std::to_string(tag_b.tag_id) +
110 ") should not interact with an element that has an origin (id: " + std::to_string(tag_a.tag_id) + ")");
111 } else {
112 // If both are free witnesses or one of them is empty, just use tag_b
113 *this = tag_b;
114 return;
115 }
116 }
117 // Elements from different transcripts shouldn't interact
118 if (tag_a.transcript_index != tag_b.transcript_index) {
119 throw_or_abort("Tags from different transcripts were involved in the same computation. tag_a: { id: " +
120 std::to_string(tag_a.tag_id) + ", transcript: " + std::to_string(tag_a.transcript_index) +
121 " } tag_b: { id: " + std::to_string(tag_b.tag_id) +
122 ", transcript: " + std::to_string(tag_b.transcript_index) + " }");
123 }
124 // Check that submitted values from different rounds don't mix without challenges
126
129}
130
131#else
132bool OriginTag::operator==(const OriginTag&) const
133{
134 return true;
135}
136
137#endif
138} // namespace bb
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
void check_round_provenance(const uint512_t &provenance_a, const uint512_t &provenance_b)
Detect if two elements from the same transcript are performing a suspicious interaction.
std::string to_string(bb::avm2::ValueTag tag)
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
size_t transcript_index
OriginTag()=default
uint64_t tag_id
static constexpr size_t CONSTANT
numeric::uint512_t round_provenance
bool is_empty() const
bool is_free_witness() const
bool operator==(const OriginTag &other) const
void throw_or_abort(std::string const &err)