Zeth - Zerocash on Ethereum  0.8
Reference implementation of the Zeth protocol by Clearmatics
group_element_utils.tcc
Go to the documentation of this file.
1 // Copyright (c) 2015-2022 Clearmatics Technologies Ltd
2 //
3 // SPDX-License-Identifier: LGPL-3.0+
4 
5 #ifndef __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__
6 #define __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__
7 
8 #include "libzeth/core/field_element_utils.hpp"
9 #include "libzeth/serialization/stream_utils.hpp"
10 
11 namespace libzeth
12 {
13 
14 namespace internal
15 {
16 
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)
20 {
21  return f == FieldT::zero();
22 }
23 
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)
27 {
28  return f == FieldT::one();
29 }
30 
31 } // namespace internal
32 
33 template<typename GroupT>
34 void group_element_write_json(const GroupT &point, std::ostream &out_s)
35 {
36  GroupT affine_p = point;
37  affine_p.to_affine_coordinates();
38  out_s << "[";
39  field_element_write_json(affine_p.X, out_s);
40  out_s << ",";
41  field_element_write_json(affine_p.Y, out_s);
42  out_s << "]";
43 }
44 
45 template<typename GroupT>
46 void group_element_read_json(GroupT &point, std::istream &in_s)
47 {
48  char sep;
49 
50  in_s >> sep;
51  if (sep != '[') {
52  throw std::runtime_error(
53  "expected opening bracket reading group element");
54  }
55  field_element_read_json(point.X, in_s);
56 
57  in_s >> sep;
58  if (sep != ',') {
59  throw std::runtime_error("expected comma reading group element");
60  }
61 
62  field_element_read_json(point.Y, in_s);
63  in_s >> sep;
64  if (sep != ']') {
65  throw std::runtime_error(
66  "expected closing bracket reading group element");
67  }
68 
69  if (internal::coordinate_equals_zero(point.X) &&
70  internal::coordinate_equals_one(point.Y)) {
71  point.Z = point.Z.zero();
72  } else {
73  point.Z = point.Z.one();
74  }
75 }
76 
77 template<typename GroupT> std::string group_element_to_json(const GroupT &point)
78 {
79  std::stringstream ss;
80  group_element_write_json(point, ss);
81  return ss.str();
82 }
83 
84 template<typename GroupT>
85 GroupT group_element_from_json(const std::string &json)
86 {
87  std::stringstream ss(json);
88  GroupT result;
89  group_element_read_json(result, ss);
90  return result;
91 }
92 
93 template<typename GroupT>
94 void group_element_write_bytes(const GroupT &point, std::ostream &out_s)
95 {
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);
100 }
101 
102 template<typename GroupT>
103 void group_element_read_bytes(GroupT &point, std::istream &in_s)
104 {
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();
110  } else {
111  point.Z = point.Z.one();
112  }
113 }
114 
115 template<typename GroupCollectionT>
116 void group_elements_write_bytes(
117  const GroupCollectionT &points, std::ostream &out_s)
118 {
119  collection_write_bytes<GroupCollectionT, group_element_write_bytes>(
120  points, out_s);
121 }
122 
123 template<typename GroupCollectionT>
124 void group_elements_read_bytes(GroupCollectionT &points, std::istream &in_s)
125 {
126  collection_read_bytes<GroupCollectionT, group_element_read_bytes>(
127  points, in_s);
128 }
129 
130 } // namespace libzeth
131 
132 #endif // __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__