Skip to content

Commit

Permalink
feat(math)!: use number when (de)serializing small prime filed in json
Browse files Browse the repository at this point in the history
BREAKING CHANGE: This update changes the (de)serialization of
small prime fields in JSON to use numbers instead of hex strings.
Given that the modulus of the small prime field is less than `uint32_t`,
using JSON numbers is more appropriate. Previously, these values were
(de)serialized as hex strings.
  • Loading branch information
chokobole committed Jun 17, 2024
1 parent 738a4e9 commit c67611f
Show file tree
Hide file tree
Showing 13 changed files with 31 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ TEST_F(AffinePointTest, Copyable) {

TEST_F(AffinePointTest, JsonValueConverter) {
test::AffinePoint expected_point(GF7(1), GF7(2));
std::string expected_json = R"({"x":"0x1","y":"0x2"})";
std::string expected_json = R"({"x":1,"y":2})";

test::AffinePoint p;
std::string error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ TEST_F(JacobianPointTest, Copyable) {

TEST_F(JacobianPointTest, JsonValueConverter) {
test::JacobianPoint expected_point(GF7(1), GF7(2), GF7(3));
std::string expected_json = R"({"x":"0x1","y":"0x2","z":"0x3"})";
std::string expected_json = R"({"x":1,"y":2,"z":3})";

test::JacobianPoint p;
std::string error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ TEST_F(PointXYZZTest, Copyable) {

TEST_F(PointXYZZTest, JsonValueConverter) {
test::PointXYZZ expected_point(GF7(1), GF7(2), GF7(3), GF7(4));
std::string expected_json = R"({"x":"0x1","y":"0x2","zz":"0x3","zzz":"0x4"})";
std::string expected_json = R"({"x":1,"y":2,"zz":3,"zzz":4})";

test::PointXYZZ p;
std::string error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ TEST_F(ProjectivePointTest, Copyable) {

TEST_F(ProjectivePointTest, JsonValueConverter) {
test::ProjectivePoint expected_point(GF7(1), GF7(2), GF7(3));
std::string expected_json = R"({"x":"0x1","y":"0x2","z":"0x3"})";
std::string expected_json = R"({"x":1,"y":2,"z":3})";

test::ProjectivePoint p;
std::string error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ TEST_F(CubicExtensionFieldTest, MultiplicativeGroupOperators) {

TEST_F(CubicExtensionFieldTest, JsonValueConverter) {
GF7_3 expected_point(GF7(1), GF7(2), GF7(3));
std::string expected_json = R"({"c0":"0x1","c1":"0x2","c2":"0x3"})";
std::string expected_json = R"({"c0":1,"c1":2,"c2":3})";

GF7_3 p;
std::string error;
Expand Down
26 changes: 19 additions & 7 deletions tachyon/math/finite_fields/prime_field_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ template <typename T>
class RapidJsonValueConverter<
T, std::enable_if_t<std::is_base_of_v<math::PrimeFieldBase<T>, T>>> {
public:
using value_type = typename T::value_type;
using BigInt = typename T::BigIntTy;

static bool s_allow_value_greater_than_or_equal_to_modulus;
Expand All @@ -231,21 +232,32 @@ class RapidJsonValueConverter<
static rapidjson::Value From(const T& value, Allocator& allocator) {
if constexpr (T::Config::kUseMontgomery) {
if (s_is_in_montgomery) {
return RapidJsonValueConverter<BigInt>::From(value.value(), allocator);
return RapidJsonValueConverter<value_type>::From(value.value(),
allocator);
}
}
return RapidJsonValueConverter<BigInt>::From(value.ToBigInt(), allocator);
if constexpr (T::Config::kModulusBits <= 32) {
if constexpr (T::Config::kUseMontgomery) {
return RapidJsonValueConverter<uint32_t>::From(
T::Config::FromMontgomery(value.value()), allocator);
} else {
return RapidJsonValueConverter<uint32_t>::From(value.value(),
allocator);
}
} else {
return RapidJsonValueConverter<BigInt>::From(value.ToBigInt(), allocator);
}
}

static bool To(const rapidjson::Value& json_value, std::string_view key,
T* value, std::string* error) {
BigInt v;
if (!RapidJsonValueConverter<BigInt>::To(json_value, key, &v, error))
value_type v;
if (!RapidJsonValueConverter<value_type>::To(json_value, key, &v, error))
return false;

if (s_allow_value_greater_than_or_equal_to_modulus) {
if (v >= BigInt(T::Config::kModulus)) {
v = v.Mod(BigInt(T::Config::kModulus));
if (v >= T::Config::kModulus) {
v %= T::Config::kModulus;
}
}
if constexpr (T::Config::kUseMontgomery) {
Expand All @@ -254,7 +266,7 @@ class RapidJsonValueConverter<
return true;
}
}
*value = T::FromBigInt(v);
*value = T(v);
return true;
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ TEST(CyclotomicInverseTest, FastCyclotomicInverse) {

TEST_F(QuadraticExtensionFieldTest, JsonValueConverter) {
GF7_2 expected_point(GF7(1), GF7(2));
std::string expected_json = R"({"c0":"0x1","c1":"0x2"})";
std::string expected_json = R"({"c0":1,"c1":2})";

GF7_2 p;
std::string error;
Expand Down
2 changes: 1 addition & 1 deletion tachyon/math/geometry/point2_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ TEST(Point2Test, Copyable) {

TEST(Point2Test, JsonValueConverter) {
Point2GF7 expected_point(GF7(1), GF7(2));
std::string expected_json = R"({"x":"0x1","y":"0x2"})";
std::string expected_json = R"({"x":1,"y":2})";

Point2GF7 p;
std::string error;
Expand Down
2 changes: 1 addition & 1 deletion tachyon/math/geometry/point3_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ TEST(Point3Test, Copyable) {

TEST(Point3Test, JsonValueConverter) {
Point3GF7 expected_point(GF7(1), GF7(2), GF7(3));
std::string expected_json = R"({"x":"0x1","y":"0x2","z":"0x3"})";
std::string expected_json = R"({"x":1,"y":2,"z":3})";

Point3GF7 p;
std::string error;
Expand Down
2 changes: 1 addition & 1 deletion tachyon/math/geometry/point4_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ TEST(Point4Test, Copyable) {

TEST(Point4Test, JsonValueConverter) {
Point4GF7 expected_point(GF7(1), GF7(2), GF7(3), GF7(4));
std::string expected_json = R"({"x":"0x1","y":"0x2","z":"0x3","w":"0x4"})";
std::string expected_json = R"({"x":1,"y":2,"z":3,"w":4})";

Point4GF7 p;
std::string error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ TEST_F(UnivariateDensePolynomialTest, Hash) {
TEST_F(UnivariateDensePolynomialTest, JsonValueConverter) {
Poly expected_poly(Coeffs({GF7(1), GF7(2), GF7(3), GF7(4), GF7(5)}));
std::string expected_json =
R"({"coefficients":{"coefficients":["0x1","0x2","0x3","0x4","0x5"]}})";
R"({"coefficients":{"coefficients":[1,2,3,4,5]}})";

Poly poly;
std::string error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,7 @@ TEST_F(UnivariateEvaluationsTest, Hash) {

TEST_F(UnivariateEvaluationsTest, JsonValueConverter) {
Poly expected_poly({GF7(1), GF7(2), GF7(3), GF7(4), GF7(5)});
std::string expected_json =
R"({"evaluations":["0x1","0x2","0x3","0x4","0x5"]})";
std::string expected_json = R"({"evaluations":[1,2,3,4,5]})";

Poly poly;
std::string error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ TEST_F(UnivariateSparsePolynomialTest, Hash) {
TEST_F(UnivariateSparsePolynomialTest, JsonValueConverter) {
Poly expected_poly(Coeffs({{0, GF7(1)}, {1, GF7(2)}, {4, GF7(3)}}));
std::string expected_json =
R"({"coefficients":{"terms":[{"degree":0,"coefficient":"0x1"},{"degree":1,"coefficient":"0x2"},{"degree":4,"coefficient":"0x3"}]}})";
R"({"coefficients":{"terms":[{"degree":0,"coefficient":1},{"degree":1,"coefficient":2},{"degree":4,"coefficient":3}]}})";

Poly poly;
std::string error;
Expand Down

0 comments on commit c67611f

Please sign in to comment.