Line | Count | Source (jump to first uncovered line) |
1 | | // speck.h - written and placed in the public domain by Jeffrey Walton |
2 | | |
3 | | /// \file speck.h |
4 | | /// \brief Classes for the Speck block cipher |
5 | | /// \details Speck is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith, |
6 | | /// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers. |
7 | | /// \sa <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SPECK Families of |
8 | | /// Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/"> |
9 | | /// The Simon and Speck GitHub</A> and <A HREF="https://www.cryptopp.com/wiki/SPECK"> |
10 | | /// SPECK</A> on the Crypto++ wiki. |
11 | | /// \since Crypto++ 6.0 |
12 | | |
13 | | #ifndef CRYPTOPP_SPECK_H |
14 | | #define CRYPTOPP_SPECK_H |
15 | | |
16 | | #include "config.h" |
17 | | #include "seckey.h" |
18 | | #include "secblock.h" |
19 | | |
20 | | #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || \ |
21 | | CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8 || \ |
22 | | CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 |
23 | | # ifndef CRYPTOPP_DISABLE_SPECK_SIMD |
24 | | # define CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS 1 |
25 | | # endif |
26 | | #endif |
27 | | |
28 | | // Yet another SunStudio/SunCC workaround. Failed self tests |
29 | | // in SSE code paths on i386 for SunStudio 12.3 and below. |
30 | | #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120) |
31 | | # undef CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS |
32 | | #endif |
33 | | |
34 | | NAMESPACE_BEGIN(CryptoPP) |
35 | | |
36 | | /// \brief SPECK block cipher information |
37 | | /// \tparam L block size of the cipher, in bytes |
38 | | /// \tparam D default key length, in bytes |
39 | | /// \tparam N minimum key length, in bytes |
40 | | /// \tparam M maximum key length, in bytes |
41 | | /// \since Crypto++ 6.0 |
42 | | template <unsigned int L, unsigned int D, unsigned int N, unsigned int M> |
43 | | struct SPECK_Info : public FixedBlockSize<L>, VariableKeyLength<D, N, M> |
44 | | { |
45 | | /// \brief The algorithm name |
46 | | /// \return the algorithm name |
47 | | /// \details StaticAlgorithmName returns the algorithm's name as a static |
48 | | /// member function. |
49 | | static const std::string StaticAlgorithmName() |
50 | 20 | { |
51 | | // Format is Cipher-Blocksize(Keylength) |
52 | 20 | return "SPECK-" + IntToString(L*8); |
53 | 20 | } CryptoPP::SPECK_Info<8u, 12u, 12u, 16u>::StaticAlgorithmName() Line | Count | Source | 50 | 9 | { | 51 | | // Format is Cipher-Blocksize(Keylength) | 52 | 9 | return "SPECK-" + IntToString(L*8); | 53 | 9 | } |
CryptoPP::SPECK_Info<16u, 16u, 16u, 32u>::StaticAlgorithmName() Line | Count | Source | 50 | 11 | { | 51 | | // Format is Cipher-Blocksize(Keylength) | 52 | 11 | return "SPECK-" + IntToString(L*8); | 53 | 11 | } |
|
54 | | }; |
55 | | |
56 | | /// \brief SPECK block cipher base class |
57 | | /// \tparam W the word type |
58 | | /// \details User code should use SPECK64 or SPECK128 |
59 | | /// \sa SPECK64, SPECK128, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a> |
60 | | /// \since Crypto++ 6.0 |
61 | | template <class W> |
62 | | struct SPECK_Base |
63 | | { |
64 | 109 | virtual ~SPECK_Base() {} CryptoPP::SPECK_Base<unsigned int>::~SPECK_Base() Line | Count | Source | 64 | 80 | virtual ~SPECK_Base() {} |
CryptoPP::SPECK_Base<unsigned long>::~SPECK_Base() Line | Count | Source | 64 | 29 | virtual ~SPECK_Base() {} |
|
65 | 109 | SPECK_Base() : m_kwords(0), m_rounds(0) {} CryptoPP::SPECK_Base<unsigned int>::SPECK_Base() Line | Count | Source | 65 | 80 | SPECK_Base() : m_kwords(0), m_rounds(0) {} |
CryptoPP::SPECK_Base<unsigned long>::SPECK_Base() Line | Count | Source | 65 | 29 | SPECK_Base() : m_kwords(0), m_rounds(0) {} |
|
66 | | |
67 | | typedef SecBlock<W, AllocatorWithCleanup<W, true> > AlignedSecBlock; |
68 | | mutable AlignedSecBlock m_wspace; // workspace |
69 | | AlignedSecBlock m_rkeys; // round keys |
70 | | unsigned int m_kwords; // number of key words |
71 | | unsigned int m_rounds; // number of rounds |
72 | | }; |
73 | | |
74 | | /// \brief SPECK 64-bit block cipher |
75 | | /// \details Speck is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith, |
76 | | /// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers. |
77 | | /// \details SPECK64 provides 64-bit block size. The valid key sizes are 96-bit and 128-bit. |
78 | | /// \sa SPECK64, SPECK128, <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SPECK |
79 | | /// Families of Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/"> |
80 | | /// The Simon and Speck GitHub</A>, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a> on the |
81 | | /// Crypto++ wiki |
82 | | /// \since Crypto++ 6.0 |
83 | | class CRYPTOPP_NO_VTABLE SPECK64 : public SPECK_Info<8, 12, 12, 16>, public BlockCipherDocumentation |
84 | | { |
85 | | public: |
86 | | /// \brief SPECK64 block cipher base implementation |
87 | | /// \details Provides implementation common to encryption and decryption |
88 | | /// \since Crypto++ 6.0 |
89 | | class CRYPTOPP_NO_VTABLE Base : protected SPECK_Base<word32>, public BlockCipherImpl<SPECK_Info<8, 12, 12, 16> > |
90 | | { |
91 | | public: |
92 | | /// \brief The algorithm name |
93 | | /// \return the algorithm name |
94 | | /// \details AlgorithmName returns the algorithm's name as a |
95 | | /// member function. |
96 | 3 | std::string AlgorithmName() const { |
97 | 3 | return StaticAlgorithmName() + (m_kwords == 0 ? "" : |
98 | 3 | "(" + IntToString(m_kwords*sizeof(word32)*8) + ")"); |
99 | 3 | } |
100 | | |
101 | | std::string AlgorithmProvider() const; |
102 | | |
103 | | /// \brief Provides input and output data alignment for optimal performance. |
104 | | /// \return the input data alignment that provides optimal performance |
105 | | /// \sa GetAlignment() and OptimalBlockSize() |
106 | | unsigned int OptimalDataAlignment() const; |
107 | | |
108 | | protected: |
109 | | void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); |
110 | | }; |
111 | | |
112 | | /// \brief SPECK64 encryption transformation |
113 | | /// \details Enc provides the encryption transformation. |
114 | | /// All key sizes are supported. |
115 | | /// \since Crypto++ 6.0 |
116 | | class CRYPTOPP_NO_VTABLE Enc : public Base |
117 | | { |
118 | | public: |
119 | | void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
120 | | }; |
121 | | |
122 | | /// \brief SPECK64 decryption transformation |
123 | | /// \details Dec provides the decryption transformation. |
124 | | /// All key sizes are supported. |
125 | | /// \since Crypto++ 6.0 |
126 | | class CRYPTOPP_NO_VTABLE Dec : public Base |
127 | | { |
128 | | public: |
129 | | void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
130 | | }; |
131 | | |
132 | | typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; |
133 | | typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; |
134 | | }; |
135 | | |
136 | | /// \brief SPECK 128-bit block cipher |
137 | | /// \details Speck is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith, |
138 | | /// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers. |
139 | | /// \details SPECK128 provides 128-bit block size. The valid key sizes are 128-bit, 192-bit and 256-bit. |
140 | | /// \sa SPECK64, SPECK128, <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SPECK |
141 | | /// Families of Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/"> |
142 | | /// The Simon and Speck GitHub</A>, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a> on the |
143 | | /// Crypto++ wiki |
144 | | /// \since Crypto++ 6.0 |
145 | | class CRYPTOPP_NO_VTABLE SPECK128 : public SPECK_Info<16, 16, 16, 32>, public BlockCipherDocumentation |
146 | | { |
147 | | public: |
148 | | /// \brief SPECK128 block cipher base implementation |
149 | | /// \details Provides implementation common to encryption and decryption |
150 | | /// \since Crypto++ 6.0 |
151 | | class CRYPTOPP_NO_VTABLE Base : protected SPECK_Base<word64>, public BlockCipherImpl<SPECK_Info<16, 16, 16, 32> > |
152 | | { |
153 | | public: |
154 | | /// \brief The algorithm name |
155 | | /// \return the algorithm name |
156 | | /// \details AlgorithmName returns the algorithm's name as a |
157 | | /// member function. |
158 | 5 | std::string AlgorithmName() const { |
159 | 5 | return StaticAlgorithmName() + (m_kwords == 0 ? "" : |
160 | 5 | "(" + IntToString(m_kwords*sizeof(word64)*8) + ")"); |
161 | 5 | } |
162 | | |
163 | | std::string AlgorithmProvider() const; |
164 | | |
165 | | /// \brief Provides input and output data alignment for optimal performance. |
166 | | /// \return the input data alignment that provides optimal performance |
167 | | /// \sa GetAlignment() and OptimalBlockSize() |
168 | | unsigned int OptimalDataAlignment() const; |
169 | | |
170 | | protected: |
171 | | void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); |
172 | | }; |
173 | | |
174 | | /// \brief SPECK128 encryption transformation |
175 | | /// \details Enc provides the encryption transformation. |
176 | | /// All key sizes are supported. |
177 | | /// \since Crypto++ 6.0 |
178 | | class CRYPTOPP_NO_VTABLE Enc : public Base |
179 | | { |
180 | | public: |
181 | | void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
182 | | #if CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS |
183 | | size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; |
184 | | #endif |
185 | | }; |
186 | | |
187 | | /// \brief SPECK128 decryption transformation |
188 | | /// \details Dec provides the decryption transformation. |
189 | | /// All key sizes are supported. |
190 | | /// \since Crypto++ 6.0 |
191 | | class CRYPTOPP_NO_VTABLE Dec : public Base |
192 | | { |
193 | | public: |
194 | | void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
195 | | #if CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS |
196 | | size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; |
197 | | #endif |
198 | | }; |
199 | | |
200 | | typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; |
201 | | typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; |
202 | | }; |
203 | | |
204 | | NAMESPACE_END |
205 | | |
206 | | #endif // CRYPTOPP_SPECK_H |