Skip to content

Commit d336633

Browse files
committed
new version
1 parent ba97833 commit d336633

File tree

9 files changed

+494
-291
lines changed

9 files changed

+494
-291
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
cmake_minimum_required( VERSION 3.14 )
1818

19-
project( scl VERSION 1.0.1 DESCRIPTION "Secure Computation Library" )
19+
project( scl VERSION 1.1.1 DESCRIPTION "Secure Computation Library" )
2020

2121
if(NOT CMAKE_BUILD_TYPE)
2222
set(CMAKE_BUILD_TYPE Release)
@@ -74,6 +74,7 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug")
7474
test/scl/test_hash.cc
7575
test/scl/test_prg.cc
7676

77+
test/scl/gf7.cc
7778
test/scl/math/test_mersenne61.cc
7879
test/scl/math/test_mersenne127.cc
7980
test/scl/math/test_vec.cc

RELEASE.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
1.1: Refactoring of finite field internals
2+
- Finite field operations are now defined by individual specializations of
3+
templated functions
4+
- Remove DEFINE_FINITE_FIELD macro
5+
- Move Mersenne61 and Mersenne127 definitions into ff.h
6+
17
1.0: Initial public version of SCL.
28
- Features:
39
- Math:
@@ -10,9 +16,9 @@
1016
- PRG based on AES-CTR
1117
- IUF Hash based on SHA3
1218
- Networking:
13-
- Basic support for peer-to-peer communication via TCP. Channels are designed
14-
in such a way that writing custom ones (or decorators for existing channels)
15-
is easy
19+
- Basic support for peer-to-peer communication via TCP. Channels are
20+
designed in such a way that writing custom ones (or decorators for
21+
existing channels) is easy
1622
- Peer discovery functionality to make it easier to setup working networks
1723
- Secret Sharing:
1824
- Shamir secret sharing with support for both error detection and correction

include/scl/math/ff.h

Lines changed: 149 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,58 @@
2626
#include <type_traits>
2727

2828
#include "scl/math/bases.h"
29-
#include "scl/math/fields.h"
29+
#include "scl/math/field_ops.h"
3030
#include "scl/math/ring.h"
3131
#include "scl/prg.h"
3232

3333
namespace scl {
3434
namespace details {
3535

3636
/**
37-
* @brief Elements of the finite field \f$\mathbb{F}_p\f$ for prime \f$p\f$.
37+
* @brief Elements of the finite field \f$\mathbb{F}\f$.
3838
*
39-
* <p>This class defines finite field element that behaves according to some
40-
* finite field definition as specified by the \p Field template parameter. The
41-
* \p Bits parameter is used to indicate the number of available bits of the
42-
* field, but is otherwise ignored.</p>
39+
* <p>The FF class provides the high level interface for "finite field elements"
40+
* in SCL.</p>
4341
*
44-
* <p>FF uses will call a number of static methods on \p Field, so these must be
45-
* defined in order for FF to work. The interface of these methods can be seen
46-
* in #DEFINE_FINITE_FIELD or by reading the documentation of the methods on
47-
* FF.</p>
42+
* <p>An instantiation of this template consists of two parameters: A \p Bits
43+
* parameter, indicating the number of bits that the field supports, and a \p
44+
* Field type which determines the behaviour of the field. The \p Bits parameter
45+
* is purely for documenting purposes and can be used to indicate that a
46+
* particular field instantiation supports a particular number of bits for
47+
* computing.</p>
48+
*
49+
* <p>The \p Field parameter must be a class of the following form</p>
50+
*
51+
* \code
52+
* struct SomeField {
53+
* using ValueType = ... // the internal type of a field element
54+
* constexpr static const char* kName = ... // readable name of this field
55+
* constexpr static const std::size_t kByteSize = ... // size in bytes
56+
* constexpr static const std::size_t kBitSize = ... // size in bits
57+
* };
58+
* \endcode
59+
*
60+
* <p>The <code>kBitSize</code> does not need to have any relation to the \p
61+
* Bits parameter, although it's assumed that <code>Bits <= kBitSize</code>.</p>
62+
*
63+
* <p>In order to make a field definition useful, overloads must be defined for
64+
* some or all of the functions in field_ops.h. For example, to support addition
65+
* operations on the field (that is, the operators <code>+</code> and
66+
* <code>+=</code>) we would need to define</p>
67+
*
68+
* \code
69+
* template <>
70+
* void scl::details::FieldAdd<SomeField>(SomeField::ValueType& out,
71+
* const SomeField::ValueType& in) {
72+
* // definition of addition for SomeField
73+
* }
74+
* \endcode
75+
*
76+
* <p>Refer to the documentation for methods on FF to see which specializations
77+
* are needed where.</p>
4878
*
4979
* @tparam Bits the desired bit size of the field
50-
* @tparam Field a class defining operations on field elements
51-
* @see DEFINE_FINITE_FIELD
80+
* @tparam Field the field
5281
*/
5382
template <unsigned Bits, typename Field>
5483
class FF final : details::RingBase<FF<Bits, Field>> {
@@ -92,16 +121,13 @@ class FF final : details::RingBase<FF<Bits, Field>> {
92121

93122
/**
94123
* @brief Read a field element from a buffer.
95-
*
96-
* The de-serialization of field elements are defined by a static method
97-
* <code>Field::FromBytes(ValueType&, const unsigned char*)</code>.
98-
*
99124
* @param src the buffer
100125
* @return a field element.
126+
* @see scl::details::FieldFromBytes
101127
*/
102128
static FF Read(const unsigned char* src) {
103129
FF e;
104-
Field::FromBytes(e.mValue, src);
130+
details::FieldFromBytes<Field>(e.mValue, src);
105131
return e;
106132
}
107133

@@ -118,40 +144,34 @@ class FF final : details::RingBase<FF<Bits, Field>> {
118144

119145
/**
120146
* @brief Create a field element from a string.
121-
*
122-
* De-stringification is determined by the static method
123-
* <code>Field::FromString(ValueType&, const std::string&, enum
124-
* NumberBase)</code>.
125-
*
126147
* @param str the string
127148
* @param base the base of the string
128149
* @return a finite field element.
150+
* @see scl::details::FieldFromString
129151
*/
130152
static FF FromString(const std::string& str, enum NumberBase base) {
131153
FF e;
132-
Field::FromString(e.mValue, str, base);
154+
details::FieldFromString<Field>(e.mValue, str, base);
133155
return e;
134156
};
135157

136158
/**
137159
* @brief Create a field element from a base 10 string.
138160
* @param str the string
139161
* @return a finite field element.
140-
* @see FF::FromString
141162
*/
142163
static FF FromString(const std::string& str) {
143164
return FF::FromString(str, NumberBase::DECIMAL);
144165
};
145166

146167
/**
147168
* @brief Create a new element from an int.
148-
*
149-
* The resulting field element is created according to the static method
150-
* <code>Field::FromInt(int)</code>.
151-
*
152169
* @param value the value to interpret as a field element
170+
* @see scl::details::FieldConvertIn
153171
*/
154-
explicit constexpr FF(int value) : mValue(Field::FromInt(value)){};
172+
explicit constexpr FF(int value) {
173+
details::FieldConvertIn<Field>(mValue, value);
174+
};
155175

156176
/**
157177
* @brief Create a new element equal to 0 in the field.
@@ -160,43 +180,34 @@ class FF final : details::RingBase<FF<Bits, Field>> {
160180

161181
/**
162182
* @brief Add another field element to this.
163-
*
164-
* Field element addition is defined by the static method
165-
* <code>Field::Add(ValueType&, const ValueType&)</code>.
166-
*
167183
* @param other the other element
168184
* @return this set to this + \p other.
185+
* @see scl::details::FieldAdd
169186
*/
170187
FF& operator+=(const FF& other) {
171-
Field::Add(mValue, other.mValue);
188+
details::FieldAdd<Field>(mValue, other.mValue);
172189
return *this;
173190
};
174191

175192
/**
176193
* @brief Subtract another field element to this.
177-
*
178-
* Field element subtraction is defined by the static method
179-
* <code>Field::Subtract(ValueType&, const ValueType&)</code>.
180-
*
181194
* @param other the other element
182195
* @return this set to this - \p other.
196+
* @see scl::details::FieldSubtract
183197
*/
184198
FF& operator-=(const FF& other) {
185-
Field::Subtract(mValue, other.mValue);
199+
details::FieldSubtract<Field>(mValue, other.mValue);
186200
return *this;
187201
};
188202

189203
/**
190204
* @brief Multiply another field element to this.
191-
*
192-
* Field element multiplication is defined by the static method
193-
* <code>Field::Multiply(ValueType&, const ValueType&)</code>.
194-
*
195205
* @param other the other element
196206
* @return this set to this * \p other.
207+
* @see scl::details::FieldMultiply
197208
*/
198209
FF& operator*=(const FF& other) {
199-
Field::Multiply(mValue, other.mValue);
210+
details::FieldMultiply<Field>(mValue, other.mValue);
200211
return *this;
201212
};
202213

@@ -213,14 +224,11 @@ class FF final : details::RingBase<FF<Bits, Field>> {
213224

214225
/**
215226
* @brief Negates this element.
216-
*
217-
* Field element negation is defined by
218-
* <code>Field::Negate(ValueType&)</code>.
219-
*
220227
* @return this set to -this.
228+
* @see scl::details::FieldNegate
221229
*/
222230
FF& Negate() {
223-
Field::Negate(mValue);
231+
details::FieldNegate<Field>(mValue);
224232
return *this;
225233
};
226234

@@ -232,21 +240,18 @@ class FF final : details::RingBase<FF<Bits, Field>> {
232240
FF Negated() {
233241
auto copy = mValue;
234242
FF r;
235-
Field::Negate(copy);
243+
details::FieldNegate<Field>(copy);
236244
r.mValue = copy;
237245
return r;
238246
};
239247

240248
/**
241249
* @brief Inverts this element.
242-
*
243-
* Computation of field element inverses is defined by
244-
* <code>Field::Invert(ValueType)</code>.
245-
*
246250
* @return this set to its inverse.
251+
* @see scl::details::FieldInvert
247252
*/
248253
FF& Invert() {
249-
Field::Invert(mValue);
254+
details::FieldInvert<Field>(mValue);
250255
return *this;
251256
};
252257

@@ -264,40 +269,113 @@ class FF final : details::RingBase<FF<Bits, Field>> {
264269
* @brief Checks if this element is equal to another.
265270
* @param other the other element
266271
* @return true if this is equal to \p other.
272+
* @see scl::details::FieldEqual
267273
*/
268274
bool Equal(const FF& other) const {
269-
return Field::Equal(mValue, other.mValue);
275+
return details::FieldEqual<Field>(mValue, other.mValue);
270276
};
271277

272278
/**
273279
* @brief Returns a string representation of this element.
274-
*
275-
* Stringification of an element is defined by
276-
* <code>Field::ToString(ValueType)</code>.
277-
*
278280
* @return a string representation of this field element.
281+
* @see scl::details::FieldToString
279282
*/
280-
std::string ToString() const { return Field::ToString(mValue); };
283+
std::string ToString() const {
284+
return details::FieldToString<Field>(mValue);
285+
};
281286

282287
/**
283288
* @brief Write this element to a byte buffer.
284-
*
285-
* <p>Serializes this field element. Serialization is defined by
286-
* <code>Field::ToBytes(unsigned char*, const ValueType&)</code>. In general,
287-
* it should be the case that \p dest has space for \ref ByteSize() amount of
288-
* bytes, although more may be needed depending on Field.</p>
289-
*
290-
* <p>For pre-defined fields in SCL, \p dest <i>must</i> have space for \ref
291-
* ByteSize() amount of bytes.</p>
292-
*
293289
* @param dest the buffer. Must have space for \ref ByteSize() bytes.
290+
* @see scl::details::FieldToBytes
294291
*/
295-
void Write(unsigned char* dest) const { Field::ToBytes(dest, mValue); }
292+
void Write(unsigned char* dest) const {
293+
details::FieldToBytes<Field>(dest, mValue);
294+
};
296295

297296
private:
298297
ValueType mValue;
299298
};
300299

300+
/**
301+
* @brief The field \f$\mathbb{F}_p\f$ with \f$p=2^{61}-1\f$.
302+
*/
303+
struct Mersenne61 {
304+
/**
305+
* @brief Internal type elements of this field.
306+
*/
307+
using ValueType = std::uint64_t;
308+
309+
/**
310+
* @brief The name of this field.
311+
*/
312+
constexpr static const char* kName = "Mersenne61";
313+
314+
/**
315+
* @brief The size of field elements of this field in bytes.
316+
*/
317+
constexpr static const std::size_t kByteSize = sizeof(ValueType);
318+
319+
/**
320+
* @brief The size of field elements of this field in bits.
321+
*/
322+
constexpr static const std::size_t kBitSize = 61;
323+
};
324+
325+
/**
326+
* @brief The field \f$\mathbb{F}_p\f$ with \f$p=2^{127}-1\f$.
327+
*/
328+
struct Mersenne127 {
329+
/**
330+
* @brief Internal type elements of this field.
331+
*/
332+
using ValueType = __uint128_t;
333+
334+
/**
335+
* @brief The name of this field.
336+
*/
337+
constexpr static const char* kName = "Mersenne127";
338+
339+
/**
340+
* @brief The size of field elements of this field in bytes.
341+
*/
342+
constexpr static const std::size_t kByteSize = sizeof(ValueType);
343+
344+
/**
345+
* @brief The size of field elements of this field in bits.
346+
*/
347+
constexpr static const std::size_t kBitSize = 127;
348+
};
349+
350+
#define _SCL_LE(a, b) ((a) <= (b))
351+
#define _SCL_GE(a, b) ((a) >= (b))
352+
353+
/**
354+
* @brief Select a suitable Finite Field based on a provided bitlevel.
355+
*/
356+
template <unsigned Bits>
357+
struct FieldSelector {
358+
/**
359+
* @brief The field.
360+
*/
361+
// clang-format off
362+
using Field =
363+
std::conditional_t<
364+
_SCL_GE(Bits, 1) && _SCL_LE(Bits, 61),
365+
Mersenne61,
366+
367+
std::conditional_t<
368+
_SCL_GE(Bits, 62) && _SCL_LE(Bits, 127),
369+
Mersenne127,
370+
371+
void>>;
372+
373+
// clang-format on
374+
};
375+
376+
#undef _SCL_LE
377+
#undef _SCL_GE
378+
301379
} // namespace details
302380

303381
/**

0 commit comments

Comments
 (0)