Crypto++  8.2
Free C++ class library of cryptographic schemes
simeck.cpp
1 // simeck.cpp - written and placed in the public domain by Gangqiang Yang and Jeffrey Walton.
2 // Based on "The Simeck Family of Lightweight Block Ciphers" by Gangqiang Yang,
3 // Bo Zhu, Valentin Suder, Mark D. Aagaard, and Guang Gong
4 
5 #include "pch.h"
6 #include "config.h"
7 
8 #include "simeck.h"
9 #include "misc.h"
10 #include "cpu.h"
11 
12 ANONYMOUS_NAMESPACE_BEGIN
13 
16 
17 /// \brief SIMECK encryption round
18 /// \tparam T word type
19 /// \param key the key for the round or iteration
20 /// \param left the first value
21 /// \param right the second value
22 /// \details SIMECK_Encryption serves as the key schedule, encryption and
23 /// decryption functions.
24 template <class T>
25 inline void SIMECK_Encryption(const T key, T& left, T& right)
26 {
27  const T temp = left;
28  left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key;
29  right = temp;
30 }
31 
32 ANONYMOUS_NAMESPACE_END
33 
34 NAMESPACE_BEGIN(CryptoPP)
35 
36 #if CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS
37 # if (CRYPTOPP_SSSE3_AVAILABLE)
38 extern size_t SIMECK64_Enc_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds,
39  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
40 
41 extern size_t SIMECK64_Dec_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds,
42  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
43 # endif // CRYPTOPP_SSSE3_AVAILABLE
44 #endif // CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS
45 
46 std::string SIMECK32::Base::AlgorithmProvider() const
47 {
48  return "C++";
49 }
50 
51 void SIMECK32::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
52 {
53  CRYPTOPP_UNUSED(params);
54  CRYPTOPP_UNUSED(keyLength);
55 
56  GetBlock<word16, BigEndian> kblock(userKey);
57  kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]);
58 
59  word16 constant = 0xFFFC;
60  word32 sequence = 0x9A42BB1F;
61  for (unsigned int i = 0; i < ROUNDS; ++i)
62  {
63  m_rk[i] = m_t[0];
64 
65  constant &= 0xFFFC;
66  constant |= sequence & 1;
67  sequence >>= 1;
68 
69  SIMECK_Encryption(static_cast<word16>(constant), m_t[1], m_t[0]);
70 
71  // rotate the LFSR of m_t
72  m_t[4] = m_t[1];
73  m_t[1] = m_t[2];
74  m_t[2] = m_t[3];
75  m_t[3] = m_t[4];
76  }
77 }
78 
79 void SIMECK32::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
80 {
81  // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
82  GetBlock<word16, BigEndian> iblock(inBlock);
83  iblock(m_t[1])(m_t[0]);
84 
85  for (int idx = 0; idx < ROUNDS; ++idx)
86  SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
87 
88  PutBlock<word16, BigEndian> oblock(xorBlock, outBlock);
89  oblock(m_t[1])(m_t[0]);
90 }
91 
92 void SIMECK32::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
93 {
94  // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
95  GetBlock<word16, BigEndian> iblock(inBlock);
96  iblock(m_t[0])(m_t[1]);
97 
98  for (int idx = ROUNDS - 1; idx >= 0; --idx)
99  SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
100 
101  PutBlock<word16, BigEndian> oblock(xorBlock, outBlock);
102  oblock(m_t[0])(m_t[1]);
103 }
104 
105 std::string SIMECK64::Base::AlgorithmProvider() const
106 {
107 #if (CRYPTOPP_SSSE3_AVAILABLE)
108  if (HasSSSE3())
109  return "SSSE3";
110 #endif
111  return "C++";
112 }
113 
114 void SIMECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
115 {
116  CRYPTOPP_UNUSED(params);
117  CRYPTOPP_UNUSED(keyLength);
118 
119  GetBlock<word32, BigEndian> kblock(userKey);
120  kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]);
121 
122  word64 constant = W64LIT(0xFFFFFFFC);
123  word64 sequence = W64LIT(0x938BCA3083F);
124  for (unsigned int i = 0; i < ROUNDS; ++i)
125  {
126  m_rk[i] = m_t[0];
127 
128  constant &= W64LIT(0xFFFFFFFC);
129  constant |= sequence & 1;
130  sequence >>= 1;
131 
132  SIMECK_Encryption(static_cast<word32>(constant), m_t[1], m_t[0]);
133 
134  // rotate the LFSR of m_t
135  m_t[4] = m_t[1];
136  m_t[1] = m_t[2];
137  m_t[2] = m_t[3];
138  m_t[3] = m_t[4];
139  }
140 }
141 
142 void SIMECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
143 {
144  // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
145  GetBlock<word32, BigEndian> iblock(inBlock);
146  iblock(m_t[1])(m_t[0]);
147 
148  for (int idx = 0; idx < ROUNDS; ++idx)
149  SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
150 
151  PutBlock<word32, BigEndian> oblock(xorBlock, outBlock);
152  oblock(m_t[1])(m_t[0]);
153 }
154 
155 void SIMECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
156 {
157  // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
158  GetBlock<word32, BigEndian> iblock(inBlock);
159  iblock(m_t[0])(m_t[1]);
160 
161  for (int idx = ROUNDS - 1; idx >= 0; --idx)
162  SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
163 
164  PutBlock<word32, BigEndian> oblock(xorBlock, outBlock);
165  oblock(m_t[0])(m_t[1]);
166 }
167 
168 #if CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS
169 size_t SIMECK64::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
170  byte *outBlocks, size_t length, word32 flags) const
171 {
172 # if (CRYPTOPP_SSSE3_AVAILABLE)
173  if (HasSSSE3()) {
174  return SIMECK64_Enc_AdvancedProcessBlocks_SSSE3(m_rk, ROUNDS,
175  inBlocks, xorBlocks, outBlocks, length, flags);
176  }
177 # endif // CRYPTOPP_SSSE3_AVAILABLE
178  return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
179 }
180 
181 size_t SIMECK64::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
182  byte *outBlocks, size_t length, word32 flags) const
183 {
184 # if (CRYPTOPP_SSSE3_AVAILABLE)
185  if (HasSSSE3()) {
186  return SIMECK64_Dec_AdvancedProcessBlocks_SSSE3(m_rk, ROUNDS,
187  inBlocks, xorBlocks, outBlocks, length, flags);
188  }
189 # endif // CRYPTOPP_SSSE3_AVAILABLE
190  return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
191 }
192 #endif // CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS
193 
194 NAMESPACE_END
Utility functions for the Crypto++ library.
bool HasSSSE3()
Determines SSSE3 availability.
Definition: cpu.h:131
Library configuration file.
Classes for the SIMECK block cipher.
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1499
virtual size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
Encrypt and xor multiple blocks using additional flags.
Definition: cryptlib.cpp:141
Precompiled header file.
Functions for CPU features and intrinsics.
static const int ROUNDS
The number of rounds for the algorithm provided as a constant.
Definition: seckey.h:56
T rotrConstant(T x)
Performs a right rotate.
Definition: misc.h:1525
Access a block of memory.
Definition: misc.h:2454
Access a block of memory.
Definition: misc.h:2495
Crypto++ library namespace.
Interface for retrieving values given their names.
Definition: cryptlib.h:293