Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Goblinize the final ecc ops in ZM #3741

Merged
merged 6 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,16 @@ template <typename Curve> class ZeroMorphVerifier_ {
concatenation_group_commitments);

// Compute commitment C_{\zeta,Z}
auto C_zeta_Z = C_zeta_x + C_Z_x * z_challenge;
Commitment C_zeta_Z;
if constexpr (Curve::is_stdlib_type) {
// Express operation as a batch_mul in order to use Goblinization if available
auto builder = rho.get_context();
std::vector<FF> scalars = { FF(builder, 1), z_challenge };
std::vector<Commitment> points = { C_zeta_x, C_Z_x };
C_zeta_Z = Commitment::batch_mul(points, scalars);
} else {
C_zeta_Z = C_zeta_x + C_Z_x * z_challenge;
}

// Receive proof commitment \pi
auto C_pi = transcript->template receive_from_prover<Commitment>("ZM:PI");
Expand All @@ -702,7 +711,17 @@ template <typename Curve> class ZeroMorphVerifier_ {
// e(C_{\zeta,Z}, [1]_2) = e(pi, [X - x]_2). This can be rearranged (e.g. see the plonk paper) as
// e(C_{\zeta,Z} - x*pi, [1]_2) * e(-pi, [X]_2) = 1, or
// e(P_0, [1]_2) * e(P_1, [X]_2) = 1
auto P0 = C_zeta_Z + C_pi * x_challenge;
Commitment P0;
if constexpr (Curve::is_stdlib_type) {
// Express operation as a batch_mul in order to use Goblinization if available
auto builder = rho.get_context();
std::vector<FF> scalars = { FF(builder, 1), x_challenge };
std::vector<Commitment> points = { C_zeta_Z, C_pi };
P0 = Commitment::batch_mul(points, scalars);
} else {
P0 = C_zeta_Z + C_pi * x_challenge;
}

auto P1 = -C_pi;

return { P0, P1 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@

#include "../bigfield/bigfield.hpp"
#include "../byte_array/byte_array.hpp"
#include "../field/field.hpp"
#include "barretenberg/ecc/curves/bn254/g1.hpp"

#include "../circuit_builders/circuit_builders_fwd.hpp"
#include "../field/field.hpp"
#include "../memory/rom_table.hpp"
#include "../memory/twin_rom_table.hpp"
#include "barretenberg/ecc/curves/bn254/g1.hpp"
#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp"
#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp"

namespace proof_system::plonk {
namespace stdlib {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/707) If using a a circuit builder with Goblin, which is
// designed to have efficient barretenberg::g1 operations, a developer might accidentally write inefficient circuits
// using biggroup functions that do not use the OpQueue. We use this concept to prevent compilation of such functions.
template <typename Builder, typename NativeGroup>
concept IsNotGoblinInefficiencyTrap = !(IsGoblinBuilder<Builder> && std::same_as<NativeGroup, barretenberg::g1>);

namespace proof_system::plonk::stdlib {

// ( ͡° ͜ʖ ͡°)
template <class Builder, class Fq, class Fr, class NativeGroup> class element {
Expand Down Expand Up @@ -154,14 +157,22 @@ template <class Builder, class Fq, class Fr, class NativeGroup> class element {
* We can chain repeated point additions together, where we only require 2 non-native field multiplications per
* point addition, instead of 3
**/
static chain_add_accumulator chain_add_start(const element& p1, const element& p2);
static chain_add_accumulator chain_add(const element& p1, const chain_add_accumulator& accumulator);
static element chain_add_end(const chain_add_accumulator& accumulator);

element montgomery_ladder(const element& other) const;
element montgomery_ladder(const chain_add_accumulator& accumulator);
element multiple_montgomery_ladder(const std::vector<chain_add_accumulator>& to_add) const;
element quadruple_and_add(const std::vector<element>& to_add) const;
static chain_add_accumulator chain_add_start(const element& p1, const element& p2)
requires(IsNotGoblinInefficiencyTrap<Builder, NativeGroup>);
static chain_add_accumulator chain_add(const element& p1, const chain_add_accumulator& accumulator)
requires(IsNotGoblinInefficiencyTrap<Builder, NativeGroup>);
static element chain_add_end(const chain_add_accumulator& accumulator)
requires(IsNotGoblinInefficiencyTrap<Builder, NativeGroup>);

element montgomery_ladder(const element& other) const
requires(IsNotGoblinInefficiencyTrap<Builder, NativeGroup>);
element montgomery_ladder(const chain_add_accumulator& accumulator)
requires(IsNotGoblinInefficiencyTrap<Builder, NativeGroup>);
element multiple_montgomery_ladder(const std::vector<chain_add_accumulator>& to_add) const
requires(IsNotGoblinInefficiencyTrap<Builder, NativeGroup>);

element quadruple_and_add(const std::vector<element>& to_add) const
requires(IsNotGoblinInefficiencyTrap<Builder, NativeGroup>);

typename NativeGroup::affine_element get_value() const
{
Expand All @@ -179,6 +190,9 @@ template <class Builder, class Fq, class Fr, class NativeGroup> class element {
static element batch_mul(const std::vector<element>& points,
const std::vector<Fr>& scalars,
const size_t max_num_bits = 0);

// TODO(https://github.com/AztecProtocol/barretenberg/issues/707) max_num_bits is unused; could implement and use
// this to optimize other operations.
static element goblin_batch_mul(const std::vector<element>& points,
const std::vector<Fr>& scalars,
const size_t max_num_bits = 0);
Expand All @@ -196,13 +210,15 @@ template <class Builder, class Fq, class Fr, class NativeGroup> class element {
// i.e. for the bn254 curve, the template param is `typename = void`
// for any other curve, there is no template param
template <typename X = NativeGroup, typename = typename std::enable_if_t<std::is_same<X, barretenberg::g1>::value>>
requires(IsNotGoblinBuilder<Builder>) // TODO(https://github.com/AztecProtocol/barretenberg/issues/707)
static element bn254_endo_batch_mul(const std::vector<element>& big_points,
const std::vector<Fr>& big_scalars,
const std::vector<element>& small_points,
const std::vector<Fr>& small_scalars,
const size_t max_num_small_bits);

template <typename X = NativeGroup, typename = typename std::enable_if_t<std::is_same<X, barretenberg::g1>::value>>
requires(IsNotGoblinBuilder<Builder>) // TODO(https://github.com/AztecProtocol/barretenberg/issues/707)
static element bn254_endo_batch_mul_with_generator(const std::vector<element>& big_points,
const std::vector<Fr>& big_scalars,
const std::vector<element>& small_points,
Expand Down Expand Up @@ -889,8 +905,7 @@ inline std::ostream& operator<<(std::ostream& os, element<C, Fq, Fr, G> const& v
{
return os << "{ " << v.x << " , " << v.y << " }";
}
} // namespace stdlib
} // namespace proof_system::plonk
} // namespace proof_system::plonk::stdlib

#include "biggroup_batch_mul.hpp"
#include "biggroup_bn254.hpp"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
#include "barretenberg/common/test.hpp"
#include <type_traits>

#include "../bigfield/bigfield.hpp"
#include "../biggroup/biggroup.hpp"
#include "../bigfield/bigfield.hpp"
#include "../bool/bool.hpp"
#include "../field/field.hpp"
#include "barretenberg/common/test.hpp"
#include "barretenberg/numeric/random/engine.hpp"
#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp"

#include "barretenberg/stdlib/primitives/curves/bn254.hpp"
#include "barretenberg/stdlib/primitives/curves/secp256k1.hpp"
#include "barretenberg/stdlib/primitives/curves/secp256r1.hpp"

#include "barretenberg/numeric/random/engine.hpp"
#include <memory>

namespace test_stdlib_biggroup {
namespace {
auto& engine = numeric::random::get_debug_engine();
Expand Down Expand Up @@ -825,12 +820,17 @@ template <typename TestType> class stdlib_biggroup : public testing::Test {

enum UseBigfield { No, Yes };
using TestTypes = testing::Types<TestType<stdlib::bn254<proof_system::StandardCircuitBuilder>, UseBigfield::No>,
TestType<stdlib::bn254<proof_system::UltraCircuitBuilder>, UseBigfield::Yes>>;
TestType<stdlib::bn254<proof_system::UltraCircuitBuilder>, UseBigfield::Yes>,
TestType<stdlib::bn254<proof_system::GoblinUltraCircuitBuilder>, UseBigfield::No>>;

TYPED_TEST_SUITE(stdlib_biggroup, TestTypes);

template <typename T>
concept HasGoblinBuilder = IsGoblinBuilder<typename T::Curve::Builder>;

TYPED_TEST(stdlib_biggroup, add)
{

TestFixture::test_add();
}
TYPED_TEST(stdlib_biggroup, sub)
Expand All @@ -843,23 +843,39 @@ TYPED_TEST(stdlib_biggroup, dbl)
}
TYPED_TEST(stdlib_biggroup, montgomery_ladder)
{
TestFixture::test_montgomery_ladder();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_montgomery_ladder();
};
}
HEAVY_TYPED_TEST(stdlib_biggroup, mul)
{
TestFixture::test_mul();
}
HEAVY_TYPED_TEST(stdlib_biggroup, twin_mul)
{
TestFixture::test_twin_mul();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_twin_mul();
};
}
HEAVY_TYPED_TEST(stdlib_biggroup, triple_mul)
{
TestFixture::test_triple_mul();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_triple_mul();
};
}
HEAVY_TYPED_TEST(stdlib_biggroup, quad_mul)
{
TestFixture::test_quad_mul();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_quad_mul();
};
}
HEAVY_TYPED_TEST(stdlib_biggroup, one)
{
Expand All @@ -872,12 +888,20 @@ HEAVY_TYPED_TEST(stdlib_biggroup, batch_mul)
HEAVY_TYPED_TEST(stdlib_biggroup, chain_add)
{

TestFixture::test_chain_add();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_chain_add();
};
}
HEAVY_TYPED_TEST(stdlib_biggroup, multiple_montgomery_ladder)
{

TestFixture::test_multiple_montgomery_ladder();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_multiple_montgomery_ladder();
};
}

HEAVY_TYPED_TEST(stdlib_biggroup, compute_naf)
Expand All @@ -897,7 +921,11 @@ HEAVY_TYPED_TEST(stdlib_biggroup, compute_naf)
HEAVY_TYPED_TEST(stdlib_biggroup, wnaf_batch_mul)
{
if constexpr (HasPlookup<typename TypeParam::Curve::Builder>) {
TestFixture::test_compute_wnaf();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_compute_wnaf();
};
} else {
GTEST_SKIP();
}
Expand All @@ -921,15 +949,23 @@ HEAVY_TYPED_TEST(stdlib_biggroup, batch_mul_short_scalars)
if constexpr (TypeParam::use_bigfield) {
GTEST_SKIP();
} else {
TestFixture::test_batch_mul_short_scalars();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_batch_mul_short_scalars();
};
}
}
HEAVY_TYPED_TEST(stdlib_biggroup, wnaf_batch_mul_128_bit)
{
if constexpr (TypeParam::use_bigfield) {
GTEST_SKIP();
} else {
TestFixture::test_wnaf_batch_mul_128_bit();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_wnaf_batch_mul_128_bit();
};
}
}
HEAVY_TYPED_TEST(stdlib_biggroup, wnaf_batch_4)
Expand All @@ -945,15 +981,23 @@ HEAVY_TYPED_TEST(stdlib_biggroup, wnaf_batch_4)
HEAVY_TYPED_TEST(stdlib_biggroup, bn254_endo_batch_mul)
{
if constexpr (TypeParam::Curve::type == proof_system::CurveType::BN254 && !TypeParam::use_bigfield) {
TestFixture::test_bn254_endo_batch_mul();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_bn254_endo_batch_mul();
};
} else {
GTEST_SKIP();
}
}
HEAVY_TYPED_TEST(stdlib_biggroup, mixed_mul_bn254_endo)
{
if constexpr (TypeParam::Curve::type == proof_system::CurveType::BN254 && !TypeParam::use_bigfield) {
TestFixture::test_mixed_mul_bn254_endo();
if constexpr (HasGoblinBuilder<TypeParam>) {
GTEST_SKIP() << "https://github.com/AztecProtocol/barretenberg/issues/707";
} else {
TestFixture::test_mixed_mul_bn254_endo();
};
} else {
GTEST_SKIP();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace stdlib {
**/
template <class C, class Fq, class Fr, class G>
template <typename, typename>
requires(IsNotGoblinBuilder<C>)
element<C, Fq, Fr, G> element<C, Fq, Fr, G>::bn254_endo_batch_mul_with_generator(
const std::vector<element>& big_points,
const std::vector<Fr>& big_scalars,
Expand Down Expand Up @@ -216,6 +217,7 @@ element<C, Fq, Fr, G> element<C, Fq, Fr, G>::bn254_endo_batch_mul_with_generator
**/
template <typename C, class Fq, class Fr, class G>
template <typename, typename>
requires(IsNotGoblinBuilder<C>)
element<C, Fq, Fr, G> element<C, Fq, Fr, G>::bn254_endo_batch_mul(const std::vector<element>& big_points,
const std::vector<Fr>& big_scalars,
const std::vector<element>& small_points,
Expand Down
Loading