kalyna.h 9.5 KB

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