Skip to content

Commit

Permalink
feat: Origin tags implemented in biggroup (#10002)
Browse files Browse the repository at this point in the history
This PR extends the origin tag mechanism in stdlib to the biggroup class
  • Loading branch information
Rumata888 authored Nov 25, 2024
1 parent a415f65 commit c8696b1
Show file tree
Hide file tree
Showing 10 changed files with 502 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,12 @@ bigfield<Builder, T> bigfield<Builder, T>::sqradd(const std::vector<bigfield>& t

const auto [quotient_1024, remainder_1024] = (left * right + add_right).divmod(modulus);
remainder = bigfield(ctx, uint256_t(remainder_1024.lo.lo));
// Merge tags
OriginTag new_tag = get_origin_tag();
for (auto& element : to_add) {
new_tag = OriginTag(new_tag, element.get_origin_tag());
}
remainder.set_origin_tag(new_tag);
return remainder;
} else {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "../bigfield/bigfield.hpp"
#include "../circuit_builders/circuit_builders_fwd.hpp"
#include "../field/field.hpp"
#include "barretenberg/transcript/origin_tag.hpp"

namespace bb::stdlib {

Expand Down Expand Up @@ -120,6 +121,14 @@ template <class Builder> class goblin_field {

// done in the translator circuit
void assert_is_in_field(){};

OriginTag get_origin_tag() const { return OriginTag(limbs[0].get_origin_tag(), limbs[1].get_origin_tag()); }

void set_origin_tag(const OriginTag& tag)
{
limbs[0].set_origin_tag(tag);
limbs[1].set_origin_tag(tag);
}
};
template <typename C> inline std::ostream& operator<<(std::ostream& os, goblin_field<C> const& v)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,18 @@ template <class Builder, class Fq, class Fr, class NativeGroup> class element {
void set_point_at_infinity(const bool_ct& is_infinity) { _is_infinity = is_infinity; }
element get_standard_form() const;

void set_origin_tag(OriginTag tag) const
{
x.set_origin_tag(tag);
y.set_origin_tag(tag);
_is_infinity.set_origin_tag(tag);
}

OriginTag get_origin_tag() const
{
return OriginTag(x.get_origin_tag(), y.get_origin_tag(), _is_infinity.get_origin_tag());
}

Fq x;
Fq y;

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
**/
#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp"
#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp"
#include "barretenberg/transcript/origin_tag.hpp"
namespace bb::stdlib::element_default {

/**
Expand Down Expand Up @@ -267,6 +268,10 @@ element<C, Fq, Fr, G> element<C, Fq, Fr, G>::bn254_endo_batch_mul(const std::vec
Fr scalar_k1 = Fr::from_witness(ctx, k1.to_montgomery_form());
Fr scalar_k2 = Fr::from_witness(ctx, k2.to_montgomery_form());

// Propagate tags
scalar_k1.set_origin_tag(scalar.get_origin_tag());
scalar_k2.set_origin_tag(scalar.get_origin_tag());

// Add copy constraint that validates k1 = scalar_k1 - scalar_k2 * \lambda
scalar.assert_equal(scalar_k1 - scalar_k2 * lambda);
scalars.push_back(scalar_k1);
Expand All @@ -288,6 +293,15 @@ element<C, Fq, Fr, G> element<C, Fq, Fr, G>::bn254_endo_batch_mul(const std::vec
std::copy(endo_points.begin(), endo_points.end(), std::back_inserter(points));
std::copy(endo_scalars.begin(), endo_scalars.end(), std::back_inserter(scalars));

// Compute the tag of the result
OriginTag union_tag{};
for (size_t i = 0; i < points.size(); i++) {
union_tag = OriginTag(union_tag, OriginTag(points[i].get_origin_tag(), scalars[i].get_origin_tag()));

// Remove tags so they don't interfere during computation
points[i].set_origin_tag(OriginTag());
scalars[i].set_origin_tag(OriginTag());
}
ASSERT(big_scalars.size() == num_big_points);
ASSERT(small_scalars.size() == num_small_points);

Expand Down Expand Up @@ -422,6 +436,7 @@ element<C, Fq, Fr, G> element<C, Fq, Fr, G>::bn254_endo_batch_mul(const std::vec
// Remove the offset generator point!
accumulator = accumulator - offset_generators.second;

accumulator.set_origin_tag(union_tag);
// Return our scalar mul output
return accumulator;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "barretenberg/ecc/curves/bn254/g1.hpp"
#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp"
#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp"
#include "barretenberg/transcript/origin_tag.hpp"

namespace bb::stdlib::element_goblin {

Expand Down Expand Up @@ -116,6 +117,7 @@ template <class Builder, class Fq, class Fr, class NativeGroup> class goblin_ele
{
return batch_mul({ *this, other }, { Fr(1), Fr(1) });
}

goblin_element operator-(const goblin_element& other) const
{
auto builder = get_context(other);
Expand Down Expand Up @@ -165,6 +167,9 @@ template <class Builder, class Fq, class Fr, class NativeGroup> class goblin_ele
y_lo.assert_equal(y.limbs[0]);
y_hi.assert_equal(y.limbs[1]);
}

// Set the tag of the result to the union of the tags of inputs
result.set_origin_tag(OriginTag(get_origin_tag(), other.get_origin_tag()));
return result;
}

Expand Down Expand Up @@ -278,6 +283,18 @@ template <class Builder, class Fq, class Fr, class NativeGroup> class goblin_ele
return result;
}

OriginTag get_origin_tag() const
{
return OriginTag(x.get_origin_tag(), y.get_origin_tag(), _is_infinity.get_origin_tag());
}

void set_origin_tag(const OriginTag& tag)
{
x.set_origin_tag(tag);
y.set_origin_tag(tag);
_is_infinity.set_origin_tag(tag);
}

Fq x;
Fq y;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "barretenberg/stdlib/primitives/biggroup/biggroup_goblin.hpp"
#include "barretenberg/transcript/origin_tag.hpp"
namespace bb::stdlib::element_goblin {

/**
Expand Down Expand Up @@ -39,10 +40,15 @@ goblin_element<C, Fq, Fr, G> goblin_element<C, Fq, Fr, G>::batch_mul(const std::

// Loop over all points and scalars
size_t num_points = points.size();

OriginTag tag_union{};
for (size_t i = 0; i < num_points; ++i) {
auto& point = points[i];
auto& scalar = scalars[i];

// Merge tags

tag_union = OriginTag(tag_union, OriginTag(point.get_origin_tag(), scalar.get_origin_tag()));
// Populate the goblin-style ecc op gates for the given mul inputs
ecc_op_tuple op_tuple;
bool scalar_is_constant_equal_one = scalar.get_witness_index() == IS_CONSTANT && scalar.get_value() == 1;
Expand Down Expand Up @@ -97,6 +103,9 @@ goblin_element<C, Fq, Fr, G> goblin_element<C, Fq, Fr, G>::batch_mul(const std::
auto op2_is_infinity = (x_lo.add_two(x_hi, y_lo) + y_hi).is_zero();
result.set_point_at_infinity(op2_is_infinity);

// Set the tag of the result
result.set_origin_tag(tag_union);

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../bit_array/bit_array.hpp"
#include "../circuit_builders/circuit_builders.hpp"
#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp"
#include "barretenberg/transcript/origin_tag.hpp"

namespace bb::stdlib::element_default {

Expand Down Expand Up @@ -116,6 +117,8 @@ element<C, Fq, Fr, G> element<C, Fq, Fr, G>::operator+(const element& other) con
bool_ct result_is_infinity = infinity_predicate && (!lhs_infinity && !rhs_infinity);
result_is_infinity = result_is_infinity || (lhs_infinity && rhs_infinity);
result.set_point_at_infinity(result_is_infinity);

result.set_origin_tag(OriginTag(get_origin_tag(), other.get_origin_tag()));
return result;
}

Expand Down Expand Up @@ -186,6 +189,7 @@ element<C, Fq, Fr, G> element<C, Fq, Fr, G>::operator-(const element& other) con
bool_ct result_is_infinity = infinity_predicate && (!lhs_infinity && !rhs_infinity);
result_is_infinity = result_is_infinity || (lhs_infinity && rhs_infinity);
result.set_point_at_infinity(result_is_infinity);
result.set_origin_tag(OriginTag(get_origin_tag(), other.get_origin_tag()));
return result;
}

Expand Down Expand Up @@ -749,6 +753,25 @@ element<C, Fq, Fr, G> element<C, Fq, Fr, G>::batch_mul(const std::vector<element
const bool with_edgecases)
{
auto [points, scalars] = handle_points_at_infinity(_points, _scalars);
OriginTag tag{};
const auto empty_tag = OriginTag();

// handle_points_at_infinity_method can remove some constant points, which messes with this code under
// CircuitSimulator
for (size_t i = 0; i < _points.size(); i++) {
tag = OriginTag(tag, OriginTag(_points[i].get_origin_tag(), _scalars[i].get_origin_tag()));
}
for (size_t i = 0; i < scalars.size(); i++) {
// If batch_mul actually performs batch multiplication on the points and scalars, subprocedures can do
// operations like addition or subtraction of points, which can trigger OriginTag security mechanisms even
// though the final result satisfies the security logic
// For example result = submitted_in_round_0 *challenge_from_round_0 +submitted_in_round_1 *
// challenge_in_round_1 will trigger it, because the addition of submitted_in_round_0 to submitted_in_round_1 is
// dangerous by itself. To avoid this, we remove the tags, merge them separately and set the result
// appropriately
points[i].set_origin_tag(empty_tag);
scalars[i].set_origin_tag(empty_tag);
}

if constexpr (IsSimulator<C>) {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/663)
Expand All @@ -760,7 +783,9 @@ element<C, Fq, Fr, G> element<C, Fq, Fr, G>::batch_mul(const std::vector<element
result += (element_t(points[i].get_value()) * scalars[i].get_value());
}
result = result.normalize();
return from_witness(context, result);
auto nonnative_result = from_witness(context, result);
nonnative_result.set_origin_tag(tag);
return nonnative_result;
} else {
// Perform goblinized batched mul if available; supported only for BN254
if (with_edgecases) {
Expand Down Expand Up @@ -807,6 +832,7 @@ element<C, Fq, Fr, G> element<C, Fq, Fr, G>::batch_mul(const std::vector<element
}
accumulator = accumulator - offset_generators.second;

accumulator.set_origin_tag(tag);
return accumulator;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,12 @@ std::vector<field_t<C>> element<C, Fq, Fr, G>::compute_wnaf(const Fr& scalar)
reconstructed.assert_is_in_field();
reconstructed.assert_equal(scalar);
}

// Set tags of wnaf_entries to the original scalar tag
const auto original_tag = scalar.get_origin_tag();
for (auto& entry : wnaf_entries) {
entry.set_origin_tag(original_tag);
}
return wnaf_entries;
}

Expand Down Expand Up @@ -581,6 +587,11 @@ std::vector<bool_t<C>> element<C, Fq, Fr, G>::compute_naf(const Fr& scalar, cons
Fr accumulator = reconstructed_positive - reconstructed_negative;
accumulator.assert_equal(scalar);
}
// Propagate tags to naf
const auto original_tag = scalar.get_origin_tag();
for (auto& naf_entry : naf_entries) {
naf_entry.set_origin_tag(original_tag);
}
return naf_entries;
}
} // namespace bb::stdlib::element_default
10 changes: 7 additions & 3 deletions barretenberg/cpp/src/barretenberg/transcript/origin_tag.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,20 @@ struct OriginTag {
OriginTag(OriginTag&& other) = default;
OriginTag& operator=(const OriginTag& other) = default;
OriginTag& operator=(OriginTag&& other) = default;
~OriginTag() = default;

OriginTag(size_t, size_t, bool is_submitted [[maybe_unused]] = true) {}
OriginTag(size_t parent_index [[maybe_unused]],
size_t child_index [[maybe_unused]],
bool is_submitted [[maybe_unused]] = true)
{}

OriginTag(const OriginTag&, const OriginTag&) {}
template <class... T> OriginTag(const OriginTag&, const T&...) {}
bool operator==(const OriginTag& other) const;
void poison() {}
void unpoison() {}
bool is_poisoned() const { return false; }
bool is_empty() const { return true; };
static bool is_poisoned() { return false; }
static bool is_empty() { return true; };
};
inline std::ostream& operator<<(std::ostream& os, OriginTag const&)
{
Expand Down

0 comments on commit c8696b1

Please sign in to comment.