Crypto++ 8.2
Free C&
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
12ANONYMOUS_NAMESPACE_BEGIN
13
14using CryptoPP::rotlConstant;
15using 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.
24template <class T>
25inline 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
32ANONYMOUS_NAMESPACE_END
33
34NAMESPACE_BEGIN(CryptoPP)
35
36#if CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS
37# if (CRYPTOPP_SSSE3_AVAILABLE)
38extern 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
41extern 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
46std::string SIMECK32::Base::AlgorithmProvider() const
47{
48 return "C++";
49}
50
51void 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
79void 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
92void 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
105std::string SIMECK64::Base::AlgorithmProvider() const
106{
107#if (CRYPTOPP_SSSE3_AVAILABLE)
108 if (HasSSSE3())
109 return "SSSE3";
110#endif
111 return "C++";
112}
113
114void 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
142void 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
155void 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
169size_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
181size_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
194NAMESPACE_END
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
static const int ROUNDS
The number of rounds for the algorithm provided as a constant.
Definition: seckey.h:56
Access a block of memory.
Definition: misc.h:2455
Interface for retrieving values given their names.
Definition: cryptlib.h:294
Access a block of memory.
Definition: misc.h:2496
Library configuration file.
Functions for CPU features and intrinsics.
bool HasSSSE3()
Determines SSSE3 availability.
Definition: cpu.h:131
Utility functions for the Crypto++ library.
Crypto++ library namespace.
Precompiled header file.
Classes for the SIMECK block cipher.