Line | Count | Source (jump to first uncovered line) |
1 | | // kalyna.h - written and placed in the public domain by Jeffrey Walton |
2 | | // Based on public domain code by Keru Kuro. |
3 | | |
4 | | /// \file kalyna.h |
5 | | /// \brief Classes for the Kalyna block cipher |
6 | | /// \details The Crypto++ implementation relied upon three sources. First was Oliynykov, Gorbenko, Kazymyrov, |
7 | | /// Ruzhentsev, Kuznetsov, Gorbenko, Dyrda, Dolgov, Pushkaryov, Mordvinov and Kaidalov's "A New Encryption |
8 | | /// Standard of Ukraine: The Kalyna Block Cipher" (http://eprint.iacr.org/2015/650.pdf). Second was Roman |
9 | | /// Oliynykov and Oleksandr Kazymyrov's GitHub with the reference implementation |
10 | | /// (http://github.com/Roman-Oliynykov/Kalyna-reference). The third resource was Keru Kuro's implementation |
11 | | /// of Kalyna in CppCrypto (http://sourceforge.net/projects/cppcrypto/). Kuro has an outstanding |
12 | | /// implementation that performed better than the reference implementation and our initial attempts. |
13 | | |
14 | | #ifndef CRYPTOPP_KALYNA_H |
15 | | #define CRYPTOPP_KALYNA_H |
16 | | |
17 | | #include "config.h" |
18 | | #include "seckey.h" |
19 | | #include "secblock.h" |
20 | | |
21 | | NAMESPACE_BEGIN(CryptoPP) |
22 | | |
23 | | /// \brief Kalyna-128 block cipher information |
24 | | /// \since Crypto++ 6.0 |
25 | | struct CRYPTOPP_NO_VTABLE Kalyna128_Info : public FixedBlockSize<16>, VariableKeyLength<16, 16, 32> |
26 | | { |
27 | | static const char* StaticAlgorithmName() |
28 | 2 | { |
29 | | // Format is Cipher-Blocksize(Keylength) |
30 | 2 | return "Kalyna-128"; |
31 | 2 | } |
32 | | }; |
33 | | |
34 | | /// \brief Kalyna-256 block cipher information |
35 | | /// \since Crypto++ 6.0 |
36 | | struct CRYPTOPP_NO_VTABLE Kalyna256_Info : public FixedBlockSize<32>, VariableKeyLength<32, 32, 64> |
37 | | { |
38 | | static const char* StaticAlgorithmName() |
39 | 0 | { |
40 | | // Format is Cipher-Blocksize(Keylength) |
41 | 0 | return "Kalyna-256"; |
42 | 0 | } |
43 | | }; |
44 | | |
45 | | /// \brief Kalyna-512 block cipher information |
46 | | /// \since Crypto++ 6.0 |
47 | | struct CRYPTOPP_NO_VTABLE Kalyna512_Info : public FixedBlockSize<64>, FixedKeyLength<64> |
48 | | { |
49 | | static const char* StaticAlgorithmName() |
50 | 1 | { |
51 | | // Format is Cipher-Blocksize(Keylength) |
52 | 1 | return "Kalyna-512"; |
53 | 1 | } |
54 | | }; |
55 | | |
56 | | /// \brief Kalyna block cipher base class |
57 | | /// \since Crypto++ 6.0 |
58 | | class CRYPTOPP_NO_VTABLE Kalyna_Base |
59 | | { |
60 | | public: |
61 | 19 | virtual ~Kalyna_Base() {} |
62 | | |
63 | | protected: |
64 | | typedef SecBlock<word64, AllocatorWithCleanup<word64, true> > AlignedSecBlock64; |
65 | | mutable AlignedSecBlock64 m_wspace; // work space |
66 | | AlignedSecBlock64 m_mkey; // master key |
67 | | AlignedSecBlock64 m_rkeys; // round keys |
68 | | unsigned int m_kl, m_nb, m_nk; // number 64-bit blocks and keys |
69 | | }; |
70 | | |
71 | | /// \brief Kalyna 128-bit block cipher |
72 | | /// \details Kalyna128 provides 128-bit block size. The valid key sizes are 128-bit and 256-bit. |
73 | | /// \since Crypto++ 6.0 |
74 | | class Kalyna128 : public Kalyna128_Info, public BlockCipherDocumentation |
75 | | { |
76 | | public: |
77 | | class CRYPTOPP_NO_VTABLE Base : public Kalyna_Base, public BlockCipherImpl<Kalyna128_Info> |
78 | | { |
79 | | public: |
80 | | /// \brief Provides the name of this algorithm |
81 | | /// \return the standard algorithm name |
82 | | /// \details If the object is unkeyed, then the generic name "Kalyna" is returned |
83 | | /// to the caller. If the algorithm is keyed, then a two or three part name is |
84 | | /// returned to the caller. The name follows DSTU 7624:2014, where block size is |
85 | | /// provided first and then key length. The library uses a dash to identify block size |
86 | | /// and parenthesis to identify key length. For example, Kalyna-128(256) is Kalyna |
87 | | /// with a 128-bit block size and a 256-bit key length. If a mode is associated |
88 | | /// with the object, then it follows as expected. For example, Kalyna-128(256)/ECB. |
89 | | /// DSTU is a little more complex with more parameters, dashes, underscores, but the |
90 | | /// library does not use the delimiters or full convention. |
91 | 0 | std::string AlgorithmName() const { |
92 | 0 | return std::string("Kalyna-128") + "(" + IntToString(m_kl*8) + ")"; |
93 | 0 | } |
94 | | |
95 | | /// \brief Provides input and output data alignment for optimal performance. |
96 | | /// \return the input data alignment that provides optimal performance |
97 | | /// \sa GetAlignment() and OptimalBlockSize() |
98 | 0 | unsigned int OptimalDataAlignment() const { |
99 | 0 | return GetAlignmentOf<word64>(); |
100 | 0 | } |
101 | | |
102 | | protected: |
103 | | void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); |
104 | | void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
105 | | |
106 | | protected: |
107 | | void SetKey_22(const word64 key[2]); |
108 | | void SetKey_24(const word64 key[4]); |
109 | | void ProcessBlock_22(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
110 | | void ProcessBlock_24(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
111 | | }; |
112 | | |
113 | | typedef BlockCipherFinal<ENCRYPTION, Base> Encryption; |
114 | | typedef BlockCipherFinal<DECRYPTION, Base> Decryption; |
115 | | }; |
116 | | |
117 | | /// \brief Kalyna 256-bit block cipher |
118 | | /// \details Kalyna256 provides 256-bit block size. The valid key sizes are 256-bit and 512-bit. |
119 | | /// \since Crypto++ 6.0 |
120 | | class Kalyna256 : public Kalyna256_Info, public BlockCipherDocumentation |
121 | | { |
122 | | public: |
123 | | class CRYPTOPP_NO_VTABLE Base : public Kalyna_Base, public BlockCipherImpl<Kalyna256_Info> |
124 | | { |
125 | | public: |
126 | | /// \brief Provides the name of this algorithm |
127 | | /// \return the standard algorithm name |
128 | | /// \details If the object is unkeyed, then the generic name "Kalyna" is returned |
129 | | /// to the caller. If the algorithm is keyed, then a two or three part name is |
130 | | /// returned to the caller. The name follows DSTU 7624:2014, where block size is |
131 | | /// provided first and then key length. The library uses a dash to identify block size |
132 | | /// and parenthesis to identify key length. For example, Kalyna-128(256) is Kalyna |
133 | | /// with a 128-bit block size and a 256-bit key length. If a mode is associated |
134 | | /// with the object, then it follows as expected. For example, Kalyna-128(256)/ECB. |
135 | | /// DSTU is a little more complex with more parameters, dashes, underscores, but the |
136 | | /// library does not use the delimiters or full convention. |
137 | 0 | std::string AlgorithmName() const { |
138 | 0 | return std::string("Kalyna-256") + "(" + IntToString(m_kl*8) + ")"; |
139 | 0 | } |
140 | | |
141 | | /// \brief Provides input and output data alignment for optimal performance. |
142 | | /// \return the input data alignment that provides optimal performance |
143 | | /// \sa GetAlignment() and OptimalBlockSize() |
144 | 0 | unsigned int OptimalDataAlignment() const { |
145 | 0 | return GetAlignmentOf<word64>(); |
146 | 0 | } |
147 | | |
148 | | protected: |
149 | | void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); |
150 | | void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
151 | | |
152 | | protected: |
153 | | void SetKey_44(const word64 key[4]); |
154 | | void SetKey_48(const word64 key[8]); |
155 | | void ProcessBlock_44(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
156 | | void ProcessBlock_48(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
157 | | }; |
158 | | |
159 | | typedef BlockCipherFinal<ENCRYPTION, Base> Encryption; |
160 | | typedef BlockCipherFinal<DECRYPTION, Base> Decryption; |
161 | | }; |
162 | | |
163 | | /// \brief Kalyna 512-bit block cipher |
164 | | /// \details Kalyna512 provides 512-bit block size. The valid key size is 512-bit. |
165 | | /// \since Crypto++ 6.0 |
166 | | class Kalyna512 : public Kalyna512_Info, public BlockCipherDocumentation |
167 | | { |
168 | | public: |
169 | | class CRYPTOPP_NO_VTABLE Base : public Kalyna_Base, public BlockCipherImpl<Kalyna512_Info> |
170 | | { |
171 | | public: |
172 | | /// \brief Provides the name of this algorithm |
173 | | /// \return the standard algorithm name |
174 | | /// \details If the object is unkeyed, then the generic name "Kalyna" is returned |
175 | | /// to the caller. If the algorithm is keyed, then a two or three part name is |
176 | | /// returned to the caller. The name follows DSTU 7624:2014, where block size is |
177 | | /// provided first and then key length. The library uses a dash to identify block size |
178 | | /// and parenthesis to identify key length. For example, Kalyna-128(256) is Kalyna |
179 | | /// with a 128-bit block size and a 256-bit key length. If a mode is associated |
180 | | /// with the object, then it follows as expected. For example, Kalyna-128(256)/ECB. |
181 | | /// DSTU is a little more complex with more parameters, dashes, underscores, but the |
182 | | /// library does not use the delimiters or full convention. |
183 | 0 | std::string AlgorithmName() const { |
184 | 0 | return std::string("Kalyna-512") + "(" + IntToString(m_kl*8) + ")"; |
185 | 0 | } |
186 | | |
187 | | /// \brief Provides input and output data alignment for optimal performance. |
188 | | /// \return the input data alignment that provides optimal performance |
189 | | /// \sa GetAlignment() and OptimalBlockSize() |
190 | 0 | unsigned int OptimalDataAlignment() const { |
191 | 0 | return GetAlignmentOf<word64>(); |
192 | 0 | } |
193 | | |
194 | | protected: |
195 | | void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); |
196 | | void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
197 | | |
198 | | protected: |
199 | | void SetKey_88(const word64 key[8]); |
200 | | void ProcessBlock_88(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; |
201 | | }; |
202 | | |
203 | | typedef BlockCipherFinal<ENCRYPTION, Base> Encryption; |
204 | | typedef BlockCipherFinal<DECRYPTION, Base> Decryption; |
205 | | }; |
206 | | |
207 | | typedef Kalyna128::Encryption Kalyna128Encryption; |
208 | | typedef Kalyna128::Decryption Kalyna128Decryption; |
209 | | |
210 | | typedef Kalyna256::Encryption Kalyna256Encryption; |
211 | | typedef Kalyna256::Decryption Kalyna256Decryption; |
212 | | |
213 | | typedef Kalyna512::Encryption Kalyna512Encryption; |
214 | | typedef Kalyna512::Decryption Kalyna512Decryption; |
215 | | |
216 | | NAMESPACE_END |
217 | | |
218 | | #endif // CRYPTOPP_KALYNA_H |