SUNphi  1.0
Encrypter.hpp
Go to the documentation of this file.
1 #ifndef ENCRYPTER_HPP
2 #define ENCRYPTER_HPP
3 
4 /// \file Encrypter.hpp
5 ///
6 /// \brief Implements the SITMO random number generator
7 ///
8 /// Copyright (c) 2012-2016 M.A. (Thijs) van den Berg, http://sitmo.com/
9 ///
10 /// Use, modification and distribution are subject to the MIT Software License.
11 ///
12 /// The MIT License (MIT)
13 /// Permission is hereby granted, free of charge, to any person obtaining a copy
14 /// of this software and associated documentation files (the "Software"), to deal
15 /// in the Software without restriction, including without limitation the rights
16 /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 /// copies of the Software, and to permit persons to whom the Software is
18 /// furnished to do so, subject to the following conditions:
19 ///
20 /// The above copyright notice and this permission notice shall be included in
21 /// all copies or substantial portions of the Software.
22 ///
23 /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 /// THE SOFTWARE.
30 
31 #include <array>
32 #include <cstdint>
33 #include <iostream>
34 
35 #include <Serialize.hpp>
36 #include <metaprogramming/LoopUnroll.hpp>
37 
38 namespace SUNphi
39 {
40  namespace Sitmo
41  {
42  /// Type of the key
43  using Key=
44  std::array<uint64_t,5>;
45 
46  /// Encrypted word
47  using Word=
48  std::array<uint64_t,4>;
49 
50  /// Encrypts the input
51  inline Word encrypt(const Key& key, ///< Key to encrypt
52  Word x) ///< Input to encrypt
53  {
54  loopUnroll<0,5>([&x,&key](const int j)
55  {
56  loopUnroll<0,2>([j,&x,&key](const int i)
57  {
58  constexpr uint64_t mk[2][2]=
59  {{14,16},{25,33}};
60 
61  uint64_t& x0=
62  x[2*i];
63  uint64_t& x1=
64  x[(2*i+1)%4];
65  const uint64_t& rx=
66  mk[j%2][i];
67 
68  x1+=
69  key[(2*i+1+j)%5]+((i==1)?j:0);
70  x0+=
71  x1+key[(2*i+j)%5];
72  x1=
73  (x1<<rx)|(x1>>(64-rx));
74  x1^=
75  x0;
76  });
77  loopUnroll<0,3>([j,&x](const int l)
78  {
79  loopUnroll<0,2>([l,j,&x](const int i)
80  {
81  constexpr uint64_t m[2][3][2]=
82  {{{52,57},{23,40},{5,37}},
83  {{46,12},{58,22},{32,32}}};
84 
85  uint64_t& x0=
86  x[2*i];
87  uint64_t& x1=
88  x[(2*i+((l%2==0)?3:1))%4];
89  const uint64_t& rx=
90  m[j%2][l][i];
91 
92  x0+=
93  x1;
94  x1=
95  (x1<<rx)|(x1>>(64-rx));
96  x1^=
97  x0;
98  });
99  });
100  });
101 
102  // Increment entry 3
103  x[3]+=
104  5;
105 
106  return
107  x;
108  }
109 
110  /// Build a key from a word
111  inline Key buildKey(const Word& word)
112  {
113  /// Output
114  Key key;
115 
116  // Copy the first 4
117  for(int i=0;i<4;i++)
118  key[i]=
119  word[i];
120 
121  // Set the fifth
122  key[4]=
123  0x1BD11BDAA9FC1A22^key[0]^key[1]^key[2]^key[3];
124 
125  return
126  key;
127  }
128  };
129 }
130 
131 #endif
Word encrypt(const Key &key, Word x)
Encrypts the input.
Definition: Encrypter.hpp:51
Key buildKey(const Word &word)
Build a key from a word.
Definition: Encrypter.hpp:111
decltype(auto) operator+(T1 &&smet1, T2 &&smet2)
Implement smet1+smet2.
Definition: Add.hpp:87