diff --git a/tachyon/zk/plonk/BUILD.bazel b/tachyon/zk/plonk/BUILD.bazel index c025263ee..0f24db0cd 100644 --- a/tachyon/zk/plonk/BUILD.bazel +++ b/tachyon/zk/plonk/BUILD.bazel @@ -1,4 +1,4 @@ -load("//bazel:tachyon_cc.bzl", "tachyon_cc_library") +load("//bazel:tachyon_cc.bzl", "tachyon_cc_library", "tachyon_cc_unittest") package(default_visibility = ["//visibility:public"]) @@ -20,3 +20,12 @@ tachyon_cc_library( "//tachyon/zk/plonk/permutation:permutation_argument", ], ) + +tachyon_cc_unittest( + name = "plonk_unittests", + srcs = ["constraint_system_unittest.cc"], + deps = [ + ":constraint_system", + "//tachyon/math/finite_fields/test:gf7", + ], +) diff --git a/tachyon/zk/plonk/constraint_system_unittest.cc b/tachyon/zk/plonk/constraint_system_unittest.cc new file mode 100644 index 000000000..3f02eef2f --- /dev/null +++ b/tachyon/zk/plonk/constraint_system_unittest.cc @@ -0,0 +1,191 @@ +#include "tachyon/zk/plonk/constraint_system.h" + +#include "gtest/gtest.h" + +#include "tachyon/math/finite_fields/test/gf7.h" + +namespace tachyon::zk { + +namespace { + +class ConstraintSystemTest : public testing::Test { + public: + static void SetUpTestSuite() { math::GF7::Init(); } +}; + +} // namespace + +TEST_F(ConstraintSystemTest, EnableConstant) { + ConstraintSystem constraint_system; + std::vector expected_constants; + std::vector expected_permutation_columns; + EXPECT_EQ(constraint_system.constants(), expected_constants); + EXPECT_EQ(constraint_system.permutation().columns(), + expected_permutation_columns); + + FixedColumnKey column = constraint_system.CreateFixedColumn(); + constraint_system.EnableConstant(column); + expected_constants.push_back(column); + EXPECT_EQ(constraint_system.constants(), expected_constants); + expected_permutation_columns.push_back(AnyColumnKey(column)); + EXPECT_EQ(constraint_system.permutation().columns(), + expected_permutation_columns); + + constraint_system.EnableConstant(column); + EXPECT_EQ(constraint_system.constants(), expected_constants); + EXPECT_EQ(constraint_system.permutation().columns(), + expected_permutation_columns); +} + +// TODO(chokobole): Add tests for Lookup and LookupAny. + +TEST_F(ConstraintSystemTest, QueryFixedIndex) { + ConstraintSystem constraint_system; + FixedColumnKey column = constraint_system.CreateFixedColumn(); + Rotation rotation = Rotation::Cur(); + EXPECT_EQ(constraint_system.QueryFixedIndex(column, rotation), 0); + EXPECT_EQ(constraint_system.QueryFixedIndex(column, rotation), 0); + + column = constraint_system.CreateFixedColumn(); + rotation = Rotation::Cur(); + EXPECT_EQ(constraint_system.QueryFixedIndex(column, rotation), 1); + + rotation = Rotation::Next(); + EXPECT_EQ(constraint_system.QueryFixedIndex(column, rotation), 2); +} + +TEST_F(ConstraintSystemTest, QueryAdviceIndex) { + ConstraintSystem constraint_system; + AdviceColumnKey column = constraint_system.CreateAdviceColumn(); + Rotation rotation = Rotation::Cur(); + + EXPECT_EQ(constraint_system.QueryAdviceIndex(column, rotation), 0); + EXPECT_EQ(constraint_system.QueryAdviceIndex(column, rotation), 0); + + column = constraint_system.CreateAdviceColumn(); + rotation = Rotation::Cur(); + EXPECT_EQ(constraint_system.QueryAdviceIndex(column, rotation), 1); + + rotation = Rotation::Next(); + EXPECT_EQ(constraint_system.QueryAdviceIndex(column, rotation), 2); +} + +TEST_F(ConstraintSystemTest, QueryInstanceIndex) { + ConstraintSystem constraint_system; + InstanceColumnKey column = constraint_system.CreateInstanceColumn(); + Rotation rotation = Rotation::Cur(); + EXPECT_EQ(constraint_system.QueryInstanceIndex(column, rotation), 0); + EXPECT_EQ(constraint_system.QueryInstanceIndex(column, rotation), 0); + + column = constraint_system.CreateInstanceColumn(); + rotation = Rotation::Cur(); + EXPECT_EQ(constraint_system.QueryInstanceIndex(column, rotation), 1); + + rotation = Rotation::Next(); + EXPECT_EQ(constraint_system.QueryInstanceIndex(column, rotation), 2); +} + +TEST_F(ConstraintSystemTest, Phases) { + ConstraintSystem constraint_system; + EXPECT_DEATH(constraint_system.CreateAdviceColumn(kSecondPhase), ""); + + std::vector phases = {kFirstPhase}; + EXPECT_EQ(constraint_system.ComputeMaxPhase(), kFirstPhase); + EXPECT_EQ(constraint_system.GetPhases(), phases); + + constraint_system.CreateAdviceColumn(kFirstPhase); + EXPECT_EQ(constraint_system.ComputeMaxPhase(), kFirstPhase); + EXPECT_EQ(constraint_system.GetPhases(), phases); + + constraint_system.CreateAdviceColumn(kSecondPhase); + phases.push_back(kSecondPhase); + EXPECT_EQ(constraint_system.ComputeMaxPhase(), kSecondPhase); + EXPECT_EQ(constraint_system.GetPhases(), phases); +} + +namespace { + +template +class ConstraintSystemTypedTest : public testing::Test { + public: + static void SetUpTestSuite() { math::GF7::Init(); } +}; + +} // namespace + +using ColumnKeyTypes = + testing::Types; +TYPED_TEST_SUITE(ConstraintSystemTypedTest, ColumnKeyTypes); + +TYPED_TEST(ConstraintSystemTypedTest, EnableEquality) { + using ColumnKeyTy = TypeParam; + + ConstraintSystem constraint_system; + std::vector expected_permutation_columns; + std::vector fixed_queries; + std::vector advice_queries; + std::vector num_advice_queries; + std::vector instance_queries; + EXPECT_EQ(constraint_system.permutation().columns(), + expected_permutation_columns); + + ColumnKeyTy column; + if constexpr (std::is_same_v) { + column = constraint_system.CreateFixedColumn(); + fixed_queries.push_back(FixedQueryData(Rotation::Cur(), column)); + } else if constexpr (std::is_same_v) { + column = constraint_system.CreateAdviceColumn(); + num_advice_queries.push_back(0); + EXPECT_EQ(constraint_system.num_advice_queries(), num_advice_queries); + ++num_advice_queries[column.index()]; + advice_queries.push_back(AdviceQueryData(Rotation::Cur(), column)); + } else { + column = constraint_system.CreateInstanceColumn(); + instance_queries.push_back(InstanceQueryData(Rotation::Cur(), column)); + } + constraint_system.EnableEquality(column); + expected_permutation_columns.push_back(AnyColumnKey(column)); + EXPECT_EQ(constraint_system.permutation().columns(), + expected_permutation_columns); + EXPECT_EQ(constraint_system.fixed_queries(), fixed_queries); + EXPECT_EQ(constraint_system.advice_queries(), advice_queries); + EXPECT_EQ(constraint_system.num_advice_queries(), num_advice_queries); + EXPECT_EQ(constraint_system.instance_queries(), instance_queries); + + constraint_system.EnableEquality(column); + EXPECT_EQ(constraint_system.permutation().columns(), + expected_permutation_columns); + EXPECT_EQ(constraint_system.fixed_queries(), fixed_queries); + EXPECT_EQ(constraint_system.advice_queries(), advice_queries); + EXPECT_EQ(constraint_system.num_advice_queries(), num_advice_queries); + EXPECT_EQ(constraint_system.instance_queries(), instance_queries); +} + +TYPED_TEST(ConstraintSystemTypedTest, QueryAnyIndex) { + using ColumnKeyTy = TypeParam; + + ConstraintSystem constraint_system; + std::function create_column = [&constraint_system]() { + if constexpr (std::is_same_v) { + return constraint_system.CreateFixedColumn(); + } else if constexpr (std::is_same_v) { + return constraint_system.CreateAdviceColumn(); + } else { + return constraint_system.CreateInstanceColumn(); + } + }; + + ColumnKeyTy column = create_column(); + Rotation rotation = Rotation::Cur(); + EXPECT_EQ(constraint_system.QueryAnyIndex(column, rotation), 0); + EXPECT_EQ(constraint_system.QueryAnyIndex(column, rotation), 0); + + column = create_column(); + rotation = Rotation::Cur(); + EXPECT_EQ(constraint_system.QueryAnyIndex(column, rotation), 1); + + rotation = Rotation::Next(); + EXPECT_EQ(constraint_system.QueryAnyIndex(column, rotation), 2); +} + +} // namespace tachyon::zk