Line | Count | Source (jump to first uncovered line) |
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 | 137k | { |
27 | 137k | const T temp = left; |
28 | 137k | left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key; |
29 | 137k | right = temp; |
30 | 137k | } simeck.cpp:void (anonymous namespace)::SIMECK_Encryption<unsigned short>(unsigned short, unsigned short&, unsigned short&) Line | Count | Source | 26 | 352 | { | 27 | 352 | const T temp = left; | 28 | 352 | left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key; | 29 | 352 | right = temp; | 30 | 352 | } |
simeck.cpp:void (anonymous namespace)::SIMECK_Encryption<unsigned int>(unsigned int, unsigned int&, unsigned int&) Line | Count | Source | 26 | 137k | { | 27 | 137k | const T temp = left; | 28 | 137k | left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key; | 29 | 137k | right = temp; | 30 | 137k | } |
|
31 | | |
32 | | ANONYMOUS_NAMESPACE_END |
33 | | |
34 | | NAMESPACE_BEGIN(CryptoPP) |
35 | | |
36 | | std::string SIMECK32::Base::AlgorithmProvider() const |
37 | 0 | { |
38 | 0 | return "C++"; |
39 | 0 | } |
40 | | |
41 | | void SIMECK32::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) |
42 | 3 | { |
43 | 3 | CRYPTOPP_UNUSED(params); |
44 | 3 | CRYPTOPP_UNUSED(keyLength); |
45 | | |
46 | 3 | GetBlock<word16, BigEndian> kblock(userKey); |
47 | 3 | kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]); |
48 | | |
49 | 3 | word16 constant = 0xFFFC; |
50 | 3 | word32 sequence = 0x9A42BB1F; |
51 | 99 | for (unsigned int i = 0; i < ROUNDS; ++i) |
52 | 96 | { |
53 | 96 | m_rk[i] = m_t[0]; |
54 | | |
55 | 96 | constant &= 0xFFFC; |
56 | 96 | constant |= sequence & 1; |
57 | 96 | sequence >>= 1; |
58 | | |
59 | 96 | SIMECK_Encryption(static_cast<word16>(constant), m_t[1], m_t[0]); |
60 | | |
61 | | // rotate the LFSR of m_t |
62 | 96 | m_t[4] = m_t[1]; |
63 | 96 | m_t[1] = m_t[2]; |
64 | 96 | m_t[2] = m_t[3]; |
65 | 96 | m_t[3] = m_t[4]; |
66 | 96 | } |
67 | 3 | } |
68 | | |
69 | | void SIMECK32::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
70 | 0 | { |
71 | | // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. |
72 | 0 | GetBlock<word16, BigEndian> iblock(inBlock); |
73 | 0 | iblock(m_t[1])(m_t[0]); |
74 | |
|
75 | 0 | for (int idx = 0; idx < ROUNDS; ++idx) |
76 | 0 | SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]); |
77 | |
|
78 | 0 | PutBlock<word16, BigEndian> oblock(xorBlock, outBlock); |
79 | 0 | oblock(m_t[1])(m_t[0]); |
80 | 0 | } |
81 | | |
82 | | void SIMECK32::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
83 | 8 | { |
84 | | // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. |
85 | 8 | GetBlock<word16, BigEndian> iblock(inBlock); |
86 | 8 | iblock(m_t[0])(m_t[1]); |
87 | | |
88 | 264 | for (int idx = ROUNDS - 1; idx >= 0; --idx) |
89 | 256 | SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]); |
90 | | |
91 | 8 | PutBlock<word16, BigEndian> oblock(xorBlock, outBlock); |
92 | 8 | oblock(m_t[0])(m_t[1]); |
93 | 8 | } |
94 | | |
95 | | std::string SIMECK64::Base::AlgorithmProvider() const |
96 | 0 | { |
97 | 0 | return "C++"; |
98 | 0 | } |
99 | | |
100 | | void SIMECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) |
101 | 3 | { |
102 | 3 | CRYPTOPP_UNUSED(params); |
103 | 3 | CRYPTOPP_UNUSED(keyLength); |
104 | | |
105 | 3 | GetBlock<word32, BigEndian> kblock(userKey); |
106 | 3 | kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]); |
107 | | |
108 | 3 | word64 constant = W64LIT(0xFFFFFFFC); |
109 | 3 | word64 sequence = W64LIT(0x938BCA3083F); |
110 | 135 | for (unsigned int i = 0; i < ROUNDS; ++i) |
111 | 132 | { |
112 | 132 | m_rk[i] = m_t[0]; |
113 | | |
114 | 132 | constant &= W64LIT(0xFFFFFFFC); |
115 | 132 | constant |= sequence & 1; |
116 | 132 | sequence >>= 1; |
117 | | |
118 | 132 | SIMECK_Encryption(static_cast<word32>(constant), m_t[1], m_t[0]); |
119 | | |
120 | | // rotate the LFSR of m_t |
121 | 132 | m_t[4] = m_t[1]; |
122 | 132 | m_t[1] = m_t[2]; |
123 | 132 | m_t[2] = m_t[3]; |
124 | 132 | m_t[3] = m_t[4]; |
125 | 132 | } |
126 | 3 | } |
127 | | |
128 | | void SIMECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
129 | 3.11k | { |
130 | | // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. |
131 | 3.11k | GetBlock<word32, BigEndian> iblock(inBlock); |
132 | 3.11k | iblock(m_t[1])(m_t[0]); |
133 | | |
134 | 139k | for (int idx = 0; idx < ROUNDS; ++idx) |
135 | 136k | SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]); |
136 | | |
137 | 3.11k | PutBlock<word32, BigEndian> oblock(xorBlock, outBlock); |
138 | 3.11k | oblock(m_t[1])(m_t[0]); |
139 | 3.11k | } |
140 | | |
141 | | void SIMECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
142 | 0 | { |
143 | | // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. |
144 | 0 | GetBlock<word32, BigEndian> iblock(inBlock); |
145 | 0 | iblock(m_t[0])(m_t[1]); |
146 | |
|
147 | 0 | for (int idx = ROUNDS - 1; idx >= 0; --idx) |
148 | 0 | SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]); |
149 | |
|
150 | 0 | PutBlock<word32, BigEndian> oblock(xorBlock, outBlock); |
151 | 0 | oblock(m_t[0])(m_t[1]); |
152 | 0 | } |
153 | | |
154 | | NAMESPACE_END |