Kalyna

Kalyna is a Ukrainian block cipher designed by Roman Oliynykov, Ivan Gorbenko, Oleksandr Kazymyrov, Victor Ruzhentsev, Oleksandr Kuznetsov, Yurii Gorbenko, Oleksandr Dyrda, Viktor Dolgov, Andrii Pushkaryov, Ruslan Mordvinov, Dmytro Kaidalov that features a modern design comparable to AES. The keys and block sizes range from 128-bits to 512-bits, and the cipher performs above average on modern 64-bit hardware. The paper which introduces the cipher can be found at A New Encryption Standard of Ukraine: The Kalyna Block Cipher.

Crypto++ added the block cipher at Commit a5c67cfdd6ad (the big-endian port occurred at Commit 1d7dfc69274d). Kalyna is the library's first attempt to support variable size block ciphers, so things may change after this writing. Generally speaking Kalyna is a lot like a fixed size block cipher. However, key lengths and block sizes are coupled or paired, so you have to be mindful if you want sizes other than the defaults.

As of this writing there are several open tasks for large block ciphers. The last prominent issue is, what to do with GCM mode. NIST only approves AES for GCM, so larger polynomials are missing for block sizes of 256-bit, 512-bit and 1024-bit. We believe we have the correct polynomials, but we need to modify GCM. Also Issue 423, Polynomials for CMAC and GCM mode.

Note: if your project is using encryption alone to secure your data, encryption alone is usually not enough. Please take a moment to read Authenticated Encryption and understand why you should prefer to use CCM, GCM, or EAX over other modes, such as CBC or CTR.

Algorithm Name

If you call StaticAlgorithmName then the function will return the generic "Kalyna". StaticAlgorithmName always returns the base name and keying does not affect it. If you call AlgorithmName on an object that has not been keyed then you will get the same result.

Once you key the cipher you will receive a result similar to the following program. The name follows DSTU 7624:2014, where block size is provided first and then key length. The library uses a dash to identify block size and parenthesis to identify key length. For example, Kalyna-128(256) is Kalyna with a 128-bit block size and a 256-bit key length. If a mode is associated with the object, then it follows as expected. For example, Kalyna-256(512)/ECB denotes Kalyna with a 256-bit block and 512-bit key operated in ECB mode.

Modes of Operation

Kalyna is considered a "wide block" block cipher because it uses block sizes greater than 128-bits. There are pain points when using wide block ciphers, like incomplete support for some modes of operation. The problem is largely due to missing specifications for the wider block sizes, which means we don't know how to implement an algorithm in a standard way. A side effect is, no specifications lead to missing test vectors.

Another example of a missing specification is counter mode operations. The mode could be as simple as using a larger counter, or it could use a zero-extended 128-bit counter. Sometimes the result of counter mode operation is reduced by a primitive polynomial, so it can also suffer missing polynomials detailed in CMAC and GCM.

Yet another example is CCM, EAX and GCM are authenticated encryption modes of operation. The modes produce an authentication tag and the tag has traditionally been the size of the block. In the case of AES, Camellia that's 128-bits and it is sufficient to authenticate the data. In the case of wide blocks we don't know if tags should be extended accordingly. As we understand the latest revision to OCB mode, the tags are not extended.

At this point in time we believe the status of wide block modes of operation are:

In a few places we said, "probably works, we had Kalyna test vectors". There is a danger we cannot make the leap because Kalyna uses operations specified in DSTU, which is a Ukranian national standard. The standard may be different than what ISO/IEC, NESSIE, NIST or the IETF eventually produce.

BlockSize

Variable block sizes introduced the need for DEFAULT_BLOCKSIZE. DEFAULT_BLOCKSIZE is to VariableBlockSize as DEFAULT_KEYLENGTH is to VariableKeyLength. It provides a sane default in a generic way. For Kalyna, DEFAULT_BLOCKSIZE is 16 bytes or 128-bits; and its paired or couple to a DEFAULT_KEYLENGTH of 16 bytes or 128-bits. If you do nothing special, the the default cipher is Kalyna-128(128).

When inheriting from VariableBlockSize, there is also a MIN_BLOCKSIZE and MAX_BLOCKSIZE just like with VariableKeyLength. For Kalyna, the range is 16-bytes to 64-bytes.

Sample Programs

There are four sample programs. The first shows Kalyna key and block sizes. The second and third use filters in a pipeline). Pipelining is a high level abstraction and it handles buffering input, buffering output and padding for you.

If you are benchmarking then you may want to visit Benchmarks | Sample Program . It shows you how to use StreamTransformation::ProcessString method to process blocks at a time. Calling a cipher's ProcessString or ProcessBlock eventually call a cipher's ProcessAndXorBlock or AdvancedProcessBlocks, and they are the lowest level API you can use.

Key and Block sizes

There are three sample programs. The first shows Kalyna key and block sizes. The second and third use filters in a pipeline). The key is declared on the stack using a SecByteBlock to ensure the sensitive material is zeroized. Similar could be used for both plain text and recovered text.

If you are benchmarking then you may want to visit Benchmarks | Sample Program . It shows you how to use StreamTransformation and its ProcessString method to process multiple blocks at a time. ProcessString eventually calls BlockTransformation and ProcessBlock. Calling a cipher's ProcessString or ProcessBlock is the lowest level API you can use.

Below is the first program. It prints key and block size for the cipher.

128-bit key, 128-bit block

The second program uses Kalyna like a fixed size block cipher and things "just work" with the default values from DEFAULT_KEYLENGTH and DEFAULT_BLOCKSIZE. The default values are a 128-bit key and a 128-bit block size. It also uses a StreamTransformationFilter to handle buffering and padding.

The second program uses the Kaylna-128(128)/CBC/NoPadding test vector provided by DSTU 7624:2014. The test vectors can be found at TestVectors/kalyna.txt. Roman Oliynykov was kind enough to translate the relevant section from the DSTU document and send the pages to us for use in the library.

512-bit key, 256-bit block

The third program uses Kalyna-256 with a 512-bit key in CBC mode. The test vectors can be found at TestVectors/kalyna.txt.

The third example is the interesting case because it demonstrates how to change the block size. To change the block size, you have to use an AlgorithmParameters object and provide parameters for BlockSize() and IV(). The reason why is discussed at SetKeyWithBlockSizeAndIV.

Authenticated Encryption

This section discusses the use of Authenticated Encryption modes of operation like CCM, EAX and GCM. Using the modes is usually slightly different from the more traditional modes like ECB and CBC. However, the wider block sizes and polynomials are adding twists so there are some rough edges.

GCM Mode

Earlier we said we were not sure what to do with GCM because the mode uses polynomials during multiplication, and NIST only specifies a 16-byte block size to be used with AES. The Kalyna team was kind enough to provide polynomials for all the block sizes, and they are listed below. They appear to be the same polynomials from Table of Low-Weight Binary Irreducible Polynomials.

128-bit block: x127 + x7 + x2 + x + 1

256-bit block: x256 + x10 + x5 + x + 1

512-bit block: x512 + x8 + x5 + x2 + 1

Support for the larger block sizes and polynomials has not been added yet. Attempting to operate Kalyna-512(512) in GCM mode results in an exception.

EAX Mode

EAX mode is similar to GCM mode. EAX relies upon CMAC, and CMAC requires the use of a polynomial during GF multiplication. EAX mode is somewhat unique because it already had support for 256-bit block size. Commit e226523b05b5d6ab and commit 7697857481f51c51 added support for the 512-bit block size.

Below is an example of using EAX mode with Kalyna. The parameters, like key and iv, were taken from Kalyna-512(512) in CBC mode. The problem is, we are not sure if CMAC mode was correctly modified, or if the result below is expected because we don't have a test vector.

SetKeyWithBlockSizeAndIV

We could add an additional class method to SimpleKeyingInterface like SetKeyWithBlockSizeAndIV to handle an different blocksizes. For example, we could do the following, which is similar to SetKeyWithIV.

The problem is, the method does not make sense for SimpleKeyingInterface. The method would be added to all classes which inherit from the interface, including block ciphers, hashes and message authentication codes. Nearly all block ciphers, hashes and authentication codes do not have a notion of a variable block size.

Maybe the method would make better sense in a new class, like VariableBlockSizeImpl. Or maybe the recently added VariableBlockCipher interface and VariableBlockCipherImpl class.

Downloads

Kalyna-Test-Vectors.zip - Kalyna test vectors for CBC and CTR mode from DSTU 7624:2014. The Kalyna team extracted the test vectors from the DSTU document. The ZIP also includes the email with the translations.