MOTION  0.01
Framework for mixed-protocol multi-party computation
block.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2019 Lennart Braun
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #pragma once
24 
25 #include <algorithm>
26 #include <array>
27 #include <boost/align/aligned_allocator.hpp>
28 #include <vector>
29 #include "config.h"
30 
31 namespace encrypto::motion {
32 
34 struct Block128 {
35  // default constructor: uninitialized
36  Block128(){};
37 
38  // XXX Copy and move constructors/assignments can be defaulted.
39  // XXX Ássignments do not check for self-assignment.
40 
41  // copy constructor
42  Block128(const Block128& other) : byte_array(other.byte_array) {}
43 
44  // move constructor
45  Block128(Block128&& other) : byte_array(std::move(other.byte_array)) {}
46 
47  // copy assignment
48  Block128& operator=(const Block128& other) {
49  byte_array = other.byte_array;
50  return *this;
51  }
52 
53  // move assignment
55  byte_array = std::move(other.byte_array);
56  return *this;
57  }
58 
59  // default destructor
60  ~Block128() = default;
61 
63  static Block128 MakeZero() {
64  Block128 result;
65  result.SetToZero();
66  return result;
67  }
68 
70  static Block128 MakeRandom() {
71  Block128 result;
72  result.SetToRandom();
73  return result;
74  }
75 
78  static Block128 MakeFromMemory(const std::byte* pointer) {
79  Block128 result;
80  result.LoadFromMemory(pointer);
81  return result;
82  }
83 
86  bool operator==(const Block128& other) const { return byte_array == other.byte_array; }
87 
90  bool operator!=(const Block128& other) const { return byte_array != other.byte_array; }
91 
94  Block128& operator^=(const Block128& __restrict__ other) {
95  auto k0 =
96  reinterpret_cast<std::byte*>(__builtin_assume_aligned(byte_array.data(), kBlockAlignment));
97  auto k1 = reinterpret_cast<const std::byte*>(
98  __builtin_assume_aligned(other.byte_array.data(), kBlockAlignment));
99  std::transform(k0, k0 + kBlockSize, k1, k0, [](auto a, auto b) { return a ^ b; });
100  return *this;
101  }
102 
105  Block128 operator^(const Block128& other) const {
106  Block128 result = *this;
107  result ^= other;
108  return result;
109  }
110 
113  Block128& operator^=(const std::byte* __restrict__ other) {
114  auto k0 =
115  reinterpret_cast<std::byte*>(__builtin_assume_aligned(byte_array.data(), kBlockAlignment));
116  std::transform(k0, k0 + kBlockSize, other, k0, [](auto a, auto b) { return a ^ b; });
117  return *this;
118  }
119 
122  Block128 operator^(const std::byte* __restrict__ other) const {
123  Block128 result = *this;
124  result ^= other;
125  return result;
126  }
127 
129  void SetToZero() {
130  auto k0 =
131  reinterpret_cast<std::byte*>(__builtin_assume_aligned(byte_array.data(), kBlockAlignment));
132  std::fill(k0, k0 + kBlockSize, std::byte(0x00));
133  }
134 
136  void SetToRandom();
137 
140  void LoadFromMemory(const std::byte* pointer) {
141  std::copy(pointer, pointer + kBlockSize, byte_array.data());
142  }
143 
145  std::string AsString() const;
146 
148  std::byte* data() { return byte_array.data(); }
149  const std::byte* data() const { return byte_array.data(); }
150 
152  static constexpr std::size_t size() { return kBlockSize; }
153 
155  static constexpr std::size_t alignment() { return kBlockAlignment; }
156 
157  // Size in bytes of Block128.
158  static constexpr std::size_t kBlockSize = 16;
159 
160  // Alignment of Block128
161  static constexpr std::size_t kBlockAlignment = 16;
162 
163  // The underlying array of bytes
164  alignas(kBlockAlignment) std::array<std::byte, 16> byte_array;
165 };
166 
169  // create an empty vector
170  Block128Vector() = default;
171 
172  // XXX Copy and move constructors/assignments can be defaulted.
173  // XXX Ássignments do not check for self-assignment.
174 
175  // copy constructor
177 
178  // move constructor
179  Block128Vector(Block128Vector&& other) : block_vector(std::move(other.block_vector)) {}
180 
181  // copy assignment
183  block_vector = other.block_vector;
184  return *this;
185  }
186  // move assignment
188  block_vector = std::move(other.block_vector);
189  return *this;
190  }
191 
192  // default destructor
193  ~Block128Vector() = default;
194 
198 
202  Block128Vector(std::size_t size, const Block128& value) : block_vector(size, value) {}
203 
207  Block128Vector(std::size_t size, const void* __restrict__ pointer) : block_vector(size) {
208  auto input = reinterpret_cast<const std::byte*>(pointer);
209  auto buffer = reinterpret_cast<std::byte*>(block_vector[0].data());
210  std::copy(input, input + 16 * size, buffer);
211  }
212 
215  Block128& at(std::size_t index) { return block_vector.at(index); };
216  const Block128& at(std::size_t index) const { return block_vector.at(index); };
217 
219  Block128* data() { return block_vector.data(); }
220 
222  const Block128* data() const { return block_vector.data(); }
223 
225  std::size_t size() const { return block_vector.size(); };
226 
228  std::size_t ByteSize() const { return block_vector.size() * Block128::size(); };
229 
233  void resize(std::size_t new_size) { block_vector.resize(new_size); }
234 
239  void resize(std::size_t new_size, const Block128& value) { block_vector.resize(new_size, value); }
240 
242  auto begin() { return block_vector.begin(); }
243 
245  auto begin() const { return block_vector.begin(); }
246 
248  auto end() { return block_vector.end(); }
249 
252  auto end() const { return block_vector.end(); }
253 
255  void SetToZero() {
256  auto start = reinterpret_cast<std::byte* __restrict__>(
257  __builtin_assume_aligned(data(), kBlockAlignment));
258  std::fill(start, start + ByteSize(), std::byte(0x00));
259  }
260 
262  void SetToRandom();
263 
268  Block128Vector& operator^=(const Block128Vector& __restrict__ other) {
269  assert(size() == other.size());
270  auto k0 = reinterpret_cast<std::byte* __restrict__>(
271  __builtin_assume_aligned(block_vector.data(), kBlockAlignment));
272  auto k1 = reinterpret_cast<const std::byte* __restrict__>(
273  __builtin_assume_aligned(other.block_vector.data(), kBlockAlignment));
274  std::transform(k0, k0 + 16 * size(), k1, k0, [](auto a, auto b) { return a ^ b; });
275  return *this;
276  }
277 
282  Block128Vector operator^(const Block128Vector& __restrict__ other) const {
283  assert(size() == other.size());
284  Block128Vector result(size());
285  auto k0 = reinterpret_cast<const std::byte* __restrict__>(
286  __builtin_assume_aligned(block_vector.data(), kBlockAlignment));
287  auto k1 = reinterpret_cast<const std::byte* __restrict__>(
288  __builtin_assume_aligned(other.block_vector.data(), kBlockAlignment));
289  auto kout = reinterpret_cast<std::byte* __restrict__>(
290  __builtin_assume_aligned(result.block_vector.data(), kBlockAlignment));
291  std::transform(k0, k0 + 16 * size(), k1, kout, [](auto a, auto b) { return a ^ b; });
292  return result;
293  }
294 
297  Block128& operator[](std::size_t index) { return block_vector[index]; };
298 
301  const Block128& operator[](std::size_t index) const { return block_vector[index]; };
302 
305  static Block128Vector MakeZero(std::size_t size) {
306  auto result = Block128Vector(size);
307  auto start = reinterpret_cast<std::byte* __restrict__>(
308  __builtin_assume_aligned(result.data(), kBlockAlignment));
309  std::fill(start, start + result.ByteSize(), std::byte(0x00));
310  return result;
311  }
312 
315  static Block128Vector MakeRandom(std::size_t size) {
316  Block128Vector result(size);
317  result.SetToRandom();
318  return result;
319  }
320 
321  static constexpr std::size_t kBlockAlignment = kAlignment;
322 
323  // underlying vector of blocks
324  std::vector<Block128, boost::alignment::aligned_allocator<Block128, kBlockAlignment>>
326 };
327 
328 } // namespace encrypto::motion
encrypto::motion::Block128Vector::resize
void resize(std::size_t new_size)
Resize the Block128Vector to contain new_size elements. New elements are left uninitialized.
Definition: block.h:233
encrypto::motion::Block128::LoadFromMemory
void LoadFromMemory(const std::byte *pointer)
Put 16 bytes starting at pointer into this Block128.
Definition: block.h:140
encrypto::motion::Block128::data
const std::byte * data() const
Definition: block.h:149
encrypto::motion::Block128Vector::Block128Vector
Block128Vector(const Block128Vector &other)
Definition: block.h:176
encrypto::motion::Block128::operator^
Block128 operator^(const Block128 &other) const
Performs XOR operation between two Block128.
Definition: block.h:105
encrypto::motion::Block128::operator^=
Block128 & operator^=(const Block128 &__restrict__ other)
Performs XOR-assign operation between two Block128.
Definition: block.h:94
encrypto::motion::Block128Vector::begin
auto begin() const
Returns a const iterator to the first element of the Block128Vector.
Definition: block.h:245
encrypto::motion::Block128Vector::MakeRandom
static Block128Vector MakeRandom(std::size_t size)
Creates a vector of size elements filled with random data.
Definition: block.h:315
encrypto::motion::Block128Vector::Block128Vector
Block128Vector(std::size_t size, const Block128 &value)
Creates initialized vector of size elements with given value.
Definition: block.h:202
encrypto::motion::Block128::operator=
Block128 & operator=(Block128 &&other)
Definition: block.h:54
encrypto::motion::Block128::~Block128
~Block128()=default
encrypto::motion::Block128Vector::kBlockAlignment
static constexpr std::size_t kBlockAlignment
Definition: block.h:321
encrypto::motion::Block128Vector::Block128Vector
Block128Vector(std::size_t size, const void *__restrict__ pointer)
Creates initialized vector of size elements read from memory.
Definition: block.h:207
encrypto::motion::Block128::MakeZero
static Block128 MakeZero()
Create a zero-initialized Block128.
Definition: block.h:63
encrypto::motion::Block128Vector::data
const Block128 * data() const
Get const pointer to the first Block128.
Definition: block.h:222
encrypto::motion::Block128Vector::Block128Vector
Block128Vector()=default
config.h
encrypto::motion::Block128::operator^
Block128 operator^(const std::byte *__restrict__ other) const
Performs XOR operation between this Block128 and a non-overlapping arbitrary range of bytes.
Definition: block.h:122
encrypto::motion::Block128::operator==
bool operator==(const Block128 &other) const
Compares two Block128 for equality.
Definition: block.h:86
encrypto::motion::Block128::kBlockAlignment
static constexpr std::size_t kBlockAlignment
Definition: block.h:161
encrypto::motion::Block128::operator!=
bool operator!=(const Block128 &other) const
Compares two Block128 for inequality.
Definition: block.h:90
encrypto::motion::Block128::operator=
Block128 & operator=(const Block128 &other)
Definition: block.h:48
encrypto::motion::Block128Vector::ByteSize
std::size_t ByteSize() const
Get size of the Block128Vector content in bytes.
Definition: block.h:228
encrypto::motion::Block128Vector::SetToRandom
void SetToRandom()
Set all Block128 in this vector to random values.
Definition: block.cpp:47
encrypto::motion::Aes128CtrRng::GetThreadInstance
static Aes128CtrRng & GetThreadInstance()
Definition: aes128_ctr_rng.h:56
encrypto::motion::Block128Vector
Vector of 128 bit / 16 B blocks.
Definition: block.h:168
block.h
encrypto::motion::Block128Vector::operator^
Block128Vector operator^(const Block128Vector &__restrict__ other) const
Perform a XOR operation between all the Block128 in this vector and the Block128 in a different one o...
Definition: block.h:282
encrypto::motion::Block128Vector::end
auto end()
Returns an iterator to the element following the last element of the Block128Vector.
Definition: block.h:248
encrypto::motion::Block128Vector::SetToZero
void SetToZero()
Set all Block128 in this vector to zero.
Definition: block.h:255
encrypto::motion::Block128::AsString
std::string AsString() const
Format this Block128 as string of hexadecimal digits.
Definition: block.cpp:37
encrypto::motion::kAlignment
constexpr std::size_t kAlignment
Definition: config.h:42
encrypto::motion::Block128Vector::MakeZero
static Block128Vector MakeZero(std::size_t size)
Creates a zero-filled vector of size elements.
Definition: block.h:305
encrypto::motion::Block128Vector::operator^=
Block128Vector & operator^=(const Block128Vector &__restrict__ other)
Perform a XOR-assign operation between all the Block128 in this vector and the Block128 in a differen...
Definition: block.h:268
encrypto::motion::Block128::byte_array
std::array< std::byte, 16 > byte_array
Definition: block.h:164
encrypto::motion::Block128::Block128
Block128(const Block128 &other)
Definition: block.h:42
encrypto::motion::Block128::SetToZero
void SetToZero()
Set this Block128 to zero.
Definition: block.h:129
encrypto::motion::Block128Vector::data
Block128 * data()
Get pointer to the first Block128.
Definition: block.h:219
encrypto::motion::Block128Vector::block_vector
std::vector< Block128, boost::alignment::aligned_allocator< Block128, kBlockAlignment > > block_vector
Definition: block.h:325
encrypto::motion
Definition: algorithm_description.cpp:35
encrypto::motion::Block128Vector::Block128Vector
Block128Vector(Block128Vector &&other)
Definition: block.h:179
encrypto::motion::Block128::operator^=
Block128 & operator^=(const std::byte *__restrict__ other)
Performs XOR-assign operation between this Block128 and a non-overlapping arbitrary range of bytes.
Definition: block.h:113
encrypto::motion::Block128Vector::operator[]
Block128 & operator[](std::size_t index)
Access Block128 at index. Undefined behaviour if index is out of bounds.
Definition: block.h:297
encrypto::motion::Block128
Block of aligned 128 bit / 16 B.
Definition: block.h:34
encrypto::motion::Block128::Block128
Block128(Block128 &&other)
Definition: block.h:45
encrypto::motion::Block128::alignment
static constexpr std::size_t alignment()
Get alignment of Block128.
Definition: block.h:155
encrypto::motion::Block128Vector::~Block128Vector
~Block128Vector()=default
encrypto::motion::Block128::Block128
Block128()
Definition: block.h:36
encrypto::motion::Block128Vector::operator[]
const Block128 & operator[](std::size_t index) const
Access Block128 at index. Undefined behaviour if index is out of bounds.
Definition: block.h:301
encrypto::motion::Block128Vector::begin
auto begin()
Returns an iterator to the first element of the Block128Vector.
Definition: block.h:242
encrypto::motion::Block128::kBlockSize
static constexpr std::size_t kBlockSize
Definition: block.h:158
encrypto::motion::Block128::size
static constexpr std::size_t size()
Get size of Block128.
Definition: block.h:152
encrypto::motion::Block128::MakeFromMemory
static Block128 MakeFromMemory(const std::byte *pointer)
Load data from memory and store it in Block128.
Definition: block.h:78
encrypto::motion::Block128Vector::operator=
Block128Vector & operator=(Block128Vector &&other)
Definition: block.h:187
encrypto::motion::Block128::SetToRandom
void SetToRandom()
Set this Block128 to a random value.
Definition: block.cpp:32
encrypto::motion::Block128Vector::at
const Block128 & at(std::size_t index) const
Definition: block.h:216
encrypto::motion::Block128::MakeRandom
static Block128 MakeRandom()
Create a random-initialized Block128.
Definition: block.h:70
encrypto::motion::Block128Vector::Block128Vector
Block128Vector(std::size_t size)
Creates uninitialized vector of size elements.
Definition: block.h:197
encrypto::motion::Block128Vector::resize
void resize(std::size_t new_size, const Block128 &value)
Resize the Block128Vector to contain new_size elements. New elements are set to value.
Definition: block.h:239
encrypto::motion::Block128Vector::operator=
Block128Vector & operator=(const Block128Vector &other)
Definition: block.h:182
encrypto::motion::Block128::data
std::byte * data()
Get a pointer to the beginning of this Block128.
Definition: block.h:148
default_rng.h
encrypto::motion::Block128Vector::end
auto end() const
Returns a const iterator to the element following the last element of the Block128Vector.
Definition: block.h:252
encrypto::motion::Block128Vector::size
std::size_t size() const
Get size of Block128Vector.
Definition: block.h:225
encrypto::motion::Block128Vector::at
Block128 & at(std::size_t index)
Access Block128 at index. Throws an exception if index is out of bounds.
Definition: block.h:215