Crypto++ 8.0 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
14 using CryptoPP::rotlConstant;
15 using CryptoPP::rotrConstant;
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
misc.h
Utility functions for the Crypto++ library.
HasSSSE3
bool HasSSSE3()
Determines SSSE3 availability.
Definition: cpu.h:131
config.h
Library configuration file.
simeck.h
Classes for the SIMECK block cipher.
rotlConstant
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1467
BlockTransformation::AdvancedProcessBlocks
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
pch.h
Precompiled header file.
cpu.h
Functions for CPU features and intrinsics.
FixedRounds< 32 >::ROUNDS
static const int ROUNDS
The number of rounds for the algorithm provided as a constant.
Definition: seckey.h:56
rotrConstant
T rotrConstant(T x)
Performs a right rotate.
Definition: misc.h:1493
GetBlock
Access a block of memory.
Definition: misc.h:2422
PutBlock
Access a block of memory.
Definition: misc.h:2463
CryptoPP
Crypto++ library namespace.
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:293