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__