Crypto++ 8.7
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
12ANONYMOUS_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.
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
36std::string SIMECK32::Base::AlgorithmProvider() const
37{
38 return "C++";
39}
40
41void 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
69void 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
82void 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
95std::string SIMECK64::Base::AlgorithmProvider() const
96{
97 return "C++";
98}
99
100void 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
128void 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
141void 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
154NAMESPACE_END
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:2766
Interface for retrieving values given their names.
Definition: cryptlib.h:322
Access a block of memory.
Definition: misc.h:2807
Library configuration file.
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:119
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:62
unsigned short word16
16-bit unsigned datatype
Definition: config_int.h:59
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
Functions for CPU features and intrinsics.
Utility functions for the Crypto++ library.
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1548
T rotrConstant(T x)
Performs a right rotate.
Definition: misc.h:1574
Crypto++ library namespace.
Precompiled header file.
Classes for the SIMECK block cipher.