1 #ifndef __LIBFF_FFI_FFI_SERIALIZATION_TCC__
2 #define __LIBFF_FFI_FFI_SERIALIZATION_TCC__
4 #include "ffi_serialization.hpp"
6 #include <libff/algebra/fields/fp.hpp>
17 // Generic big-endian field_serializer for multi-component field
19 template<typename FieldT> class field_serializer
22 static bool read_from_buffer(
23 FieldT &f, const void *buffer, size_t buffer_size)
25 constexpr size_t component_size = sizeof(f.coeffs[0]);
26 size_t i = FieldT::extension_degree() - 1;
28 if (buffer_size < component_size ||
29 !field_element_read(f.coeffs[i], buffer, component_size)) {
32 buffer = ((const char *)buffer) + component_size;
33 buffer_size -= component_size;
39 static bool write_to_buffer(
40 const FieldT &f, void *buffer, size_t buffer_size)
42 constexpr size_t component_size = sizeof(f.coeffs[0]);
43 size_t i = FieldT::extension_degree() - 1;
45 if (buffer_size < component_size ||
46 !field_element_write(f.coeffs[i], buffer, component_size)) {
49 buffer = ((char *)buffer) + component_size;
50 buffer_size -= component_size;
57 // Specialized version of field_serializer, for the base-case of base
59 template<mp_size_t n, const libff::bigint<n> &modulus>
60 class field_serializer<libff::Fp_model<n, modulus>>
63 using FieldT = libff::Fp_model<n, modulus>;
65 static bool read_from_buffer(
66 FieldT &f, const void *buffer, size_t buffer_size)
68 libff::bigint<n> bigint;
69 if (object_read_from_buffer(bigint, buffer, buffer_size) &&
70 mpn_cmp(modulus.data, bigint.data, n) > 0) {
71 f = libff::Fp_model<n, modulus>(bigint);
78 static bool write_to_buffer(
79 const FieldT &f, void *buffer, size_t buffer_size)
81 const libff::bigint<n> bigint = f.as_bigint();
82 return object_write_to_buffer(bigint, buffer, buffer_size);
86 template<typename FieldT> bool field_element_equals_zero(const FieldT &f)
88 return f == FieldT::zero();
91 template<typename FieldT> bool field_element_equals_one(const FieldT &f)
93 return f == FieldT::one();
96 } // namespace internal
99 bool object_read_from_buffer(T &object, const void *buffer, size_t buffer_size)
101 constexpr size_t object_size = sizeof(T);
102 if (buffer_size != object_size) {
106 char *dest = (char *)&object;
107 const char *src = ((const char *)buffer) + buffer_size;
108 const char *end = src - object_size;
110 *(dest++) = *(--src);
116 // Ensure there is enough data in the buffer, copy in reverse-byte
117 // order from the right of the buffer into an array of element_size.
119 bool object_write_to_buffer(const T &object, void *buffer, size_t buffer_size)
121 constexpr size_t object_size = sizeof(T);
122 if (buffer_size != object_size) {
126 char *dest = (char *)buffer;
127 const char *const end = ((const char *)&object);
128 const char *src = end + object_size;
130 *(dest++) = *(--src);
136 template<typename FieldT>
137 bool field_element_read(FieldT &f, const void *buffer, size_t buffer_size)
139 return internal::field_serializer<FieldT>::read_from_buffer(
140 f, buffer, buffer_size);
143 template<typename FieldT>
144 bool field_element_write(const FieldT &f, void *buffer, size_t buffer_size)
146 return internal::field_serializer<FieldT>::write_to_buffer(
147 f, buffer, buffer_size);
150 template<typename GroupT>
151 bool group_element_read(GroupT &g, const void *buffer, size_t buffer_size)
153 constexpr size_t coordinate_size = sizeof(g.X);
154 if (buffer_size == 2 * coordinate_size) {
155 if (field_element_read(g.X, buffer, coordinate_size)) {
156 buffer = ((const char *)buffer) + coordinate_size;
157 if (field_element_read(g.Y, buffer, coordinate_size)) {
158 if (internal::field_element_equals_zero(g.X) &&
159 internal::field_element_equals_one(g.Y)) {
165 return g.is_well_formed() && g.is_in_safe_subgroup();
173 template<typename GroupT>
174 bool group_element_write(const GroupT &g, void *buffer, size_t buffer_size)
176 constexpr size_t coordinate_size = sizeof(g.X);
177 if (buffer_size == 2 * coordinate_size) {
179 affine_p.to_affine_coordinates();
180 if (field_element_write(affine_p.X, buffer, coordinate_size)) {
181 buffer = ((char *)buffer) + coordinate_size;
182 return field_element_write(affine_p.Y, buffer, coordinate_size);
193 #endif // __LIBFF_FFI_FFI_SERIALIZATION_HPP__