Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/kalyna.h
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 &params);
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 &params);
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 &params);
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