Crypto++ 8.4 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 std::string SIMECK32::Base::AlgorithmProvider() const
37 {
38 return "C++";
39 }
40
41 void SIMECK32::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
42 {
43 CRYPTOPP_UNUSED(params);
44 CRYPTOPP_UNUSED(keyLength);
45
46 GetBlock<word16, BigEndian> kblock(userKey);
47 kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]);
48
49 word16 constant = 0xFFFC;
50 word32 sequence = 0x9A42BB1F;
51 for (unsigned int i = 0; i < ROUNDS; ++i)
52 {
53 m_rk[i] = m_t[0];
54
55 constant &= 0xFFFC;
56 constant |= sequence & 1;
57 sequence >>= 1;
58
59 SIMECK_Encryption(static_cast<word16>(constant), m_t[1], m_t[0]);
60
61 // rotate the LFSR of m_t
62 m_t[4] = m_t[1];
63 m_t[1] = m_t[2];
64 m_t[2] = m_t[3];
65 m_t[3] = m_t[4];
66 }
67 }
68
69 void SIMECK32::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
70 {
71 // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
72 GetBlock<word16, BigEndian> iblock(inBlock);
73 iblock(m_t[1])(m_t[0]);
74
75 for (int idx = 0; idx < ROUNDS; ++idx)
76 SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
77
78 PutBlock<word16, BigEndian> oblock(xorBlock, outBlock);
79 oblock(m_t[1])(m_t[0]);
80 }
81
82 void SIMECK32::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
83 {
84 // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
85 GetBlock<word16, BigEndian> iblock(inBlock);
86 iblock(m_t[0])(m_t[1]);
87
88 for (int idx = ROUNDS - 1; idx >= 0; --idx)
89 SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
90
91 PutBlock<word16, BigEndian> oblock(xorBlock, outBlock);
92 oblock(m_t[0])(m_t[1]);
93 }
94
95 std::string SIMECK64::Base::AlgorithmProvider() const
96 {
97 return "C++";
98 }
99
100 void SIMECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
101 {
102 CRYPTOPP_UNUSED(params);
103 CRYPTOPP_UNUSED(keyLength);
104
105 GetBlock<word32, BigEndian> kblock(userKey);
106 kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]);
107
108 word64 constant = W64LIT(0xFFFFFFFC);
109 word64 sequence = W64LIT(0x938BCA3083F);
110 for (unsigned int i = 0; i < ROUNDS; ++i)
111 {
112 m_rk[i] = m_t[0];
113
114 constant &= W64LIT(0xFFFFFFFC);
115 constant |= sequence & 1;
116 sequence >>= 1;
117
118 SIMECK_Encryption(static_cast<word32>(constant), m_t[1], m_t[0]);
119
120 // rotate the LFSR of m_t
121 m_t[4] = m_t[1];
122 m_t[1] = m_t[2];
123 m_t[2] = m_t[3];
124 m_t[3] = m_t[4];
125 }
126 }
127
128 void SIMECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
129 {
130 // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
131 GetBlock<word32, BigEndian> iblock(inBlock);
132 iblock(m_t[1])(m_t[0]);
133
134 for (int idx = 0; idx < ROUNDS; ++idx)
135 SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
136
137 PutBlock<word32, BigEndian> oblock(xorBlock, outBlock);
138 oblock(m_t[1])(m_t[0]);
139 }
140
141 void SIMECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
142 {
143 // Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
144 GetBlock<word32, BigEndian> iblock(inBlock);
145 iblock(m_t[0])(m_t[1]);
146
147 for (int idx = ROUNDS - 1; idx >= 0; --idx)
148 SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
149
150 PutBlock<word32, BigEndian> oblock(xorBlock, outBlock);
151 oblock(m_t[0])(m_t[1]);
152 }
153
154 NAMESPACE_END
W64LIT
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:119
word64
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
rotlConstant
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1527
pch.h
Precompiled header file.
word32
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:62
GetBlock
Access a block of memory.
Definition: misc.h:2508
FixedRounds< 32 >::ROUNDS
static const int ROUNDS
The number of rounds for the algorithm provided as a constant.
Definition: seckey.h:56
misc.h
Utility functions for the Crypto++ library.
rotrConstant
T rotrConstant(T x)
Performs a right rotate.
Definition: misc.h:1553
PutBlock
Access a block of memory.
Definition: misc.h:2549
cpu.h
Functions for CPU features and intrinsics.
simeck.h
Classes for the SIMECK block cipher.
CryptoPP
Crypto++ library namespace.
config.h
Library configuration file.
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:321
word16
unsigned short word16
16-bit unsigned datatype
Definition: config_int.h:59