1 // Copyright (c) 2015-2022 Clearmatics Technologies Ltd
3 // SPDX-License-Identifier: LGPL-3.0+
5 #ifndef __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__
6 #define __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__
8 #include "libzeth/core/field_element_utils.hpp"
9 #include "libzeth/serialization/stream_utils.hpp"
17 // Wrapper around == FieldT::one() which can be used by the code below when the
18 // field type is not in scope.
19 template<typename FieldT> static bool coordinate_equals_zero(const FieldT &f)
21 return f == FieldT::zero();
24 // Wrapper around == FieldT::one() which can be used by the code below when the
25 // field type is not in scope.
26 template<typename FieldT> static bool coordinate_equals_one(const FieldT &f)
28 return f == FieldT::one();
31 } // namespace internal
33 template<typename GroupT>
34 void group_element_write_json(const GroupT &point, std::ostream &out_s)
36 GroupT affine_p = point;
37 affine_p.to_affine_coordinates();
39 field_element_write_json(affine_p.X, out_s);
41 field_element_write_json(affine_p.Y, out_s);
45 template<typename GroupT>
46 void group_element_read_json(GroupT &point, std::istream &in_s)
52 throw std::runtime_error(
53 "expected opening bracket reading group element");
55 field_element_read_json(point.X, in_s);
59 throw std::runtime_error("expected comma reading group element");
62 field_element_read_json(point.Y, in_s);
65 throw std::runtime_error(
66 "expected closing bracket reading group element");
69 if (internal::coordinate_equals_zero(point.X) &&
70 internal::coordinate_equals_one(point.Y)) {
71 point.Z = point.Z.zero();
73 point.Z = point.Z.one();
77 template<typename GroupT> std::string group_element_to_json(const GroupT &point)
80 group_element_write_json(point, ss);
84 template<typename GroupT>
85 GroupT group_element_from_json(const std::string &json)
87 std::stringstream ss(json);
89 group_element_read_json(result, ss);
93 template<typename GroupT>
94 void group_element_write_bytes(const GroupT &point, std::ostream &out_s)
96 typename std::decay<GroupT>::type affine_p = point;
97 affine_p.to_affine_coordinates();
98 field_element_write_bytes(affine_p.X, out_s);
99 field_element_write_bytes(affine_p.Y, out_s);
102 template<typename GroupT>
103 void group_element_read_bytes(GroupT &point, std::istream &in_s)
105 field_element_read_bytes(point.X, in_s);
106 field_element_read_bytes(point.Y, in_s);
107 if (internal::coordinate_equals_zero(point.X) &&
108 internal::coordinate_equals_one(point.Y)) {
109 point.Z = point.Z.zero();
111 point.Z = point.Z.one();
115 template<typename GroupCollectionT>
116 void group_elements_write_bytes(
117 const GroupCollectionT &points, std::ostream &out_s)
119 collection_write_bytes<GroupCollectionT, group_element_write_bytes>(
123 template<typename GroupCollectionT>
124 void group_elements_read_bytes(GroupCollectionT &points, std::istream &in_s)
126 collection_read_bytes<GroupCollectionT, group_element_read_bytes>(
130 } // namespace libzeth
132 #endif // __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__