Block Ciphers and variable block sizes

29 views
Skip to first unread message

Jeffrey Walton

unread,
Apr 28, 2017, 10:18:09 PM4/28/17
to Crypto++ Users
Hi Everyone,

I want to investigate variable size block ciphers, and the changes required to support them.

The immediate pain point is the class constant BLOCKSIZE, which becomes a moving target. That could be worked around with MINIMUM_BLOCKSIZE, MAXIMUM_BLOCKSIZE, and making BLOCKSIZE a sane default, similar to the way keys are described. Or, we could signal that Blocksize() must be used by making BLOCKSIZE equal to 0xffffffff.

A quick/small survey of Rijndael, Threefish and Kalyna indicate its not a straight forward VariableBlockSize<...> implemented like VariableKeyLength<...>. In the case of Threefish, the block sizes are 256, 512 and 1024; 768 is absent. In the case of Kalyna, the block size is either (1) equal to the key size; or (2) twice the key size.

I'm guessing there are more novel schemes out there. I'm also guessing we are going to need to accept a good fit because a perfect fit probably does not exist. A good fit would allow VariableBlockSize<...> with the knowledge we have some extra work to do, and Blocksize() must be used at runtime for an accurate accounting.

Does anyone have implementation experience or thoughts on it?

Jeff

Jeffrey Walton

unread,
Apr 29, 2017, 9:31:58 PM4/29/17
to Crypto++ Users

The immediate pain point is the class constant BLOCKSIZE, which becomes a moving target. That could be worked around with MINIMUM_BLOCKSIZE, MAXIMUM_BLOCKSIZE, and making BLOCKSIZE a sane default, similar to the way keys are described. Or, we could signal that Blocksize() must be used by making BLOCKSIZE equal to 0xffffffff.

This is a little trickier than I expected. A cipher in a vacuum has a few uncomfortable places like above. A cipher with a mode is where the pain lies:

    // 128-bit key, 256-bit blocksize
    AlgorithmParameters params = MakeParameters
                                                      (Name::BlockSize(), 32)
                                                      (Name::IV(), ConstByteArrayParameter(iv, 32));

    CBC_Mode<Kalyna>::Encryption enc;  // Line 1
    enc.SetKey(key, 16, params);    // Line 2

On mode construction (line 1), CBC_Mode (and other modes) size some buffers based on the block cipher's blocksize. The problem is, the key (and other parameters) have not been set (line 2), so the blocksize is mostly unknown. You can see it by tracing calls to ResizeBuffers() in modes.h (https://github.com/weidai11/cryptopp/blob/master/modes.h).

I think we can work around it by using a lazy resize strategy in the mode, but I'm concerned about how deep it could cut.

Does anyone have any thought or opinions on it?

Jeff

Jeffrey Walton

unread,
May 1, 2017, 6:05:38 PM5/1/17
to Crypto++ Users

We checked-in initial support for variable block size ciphers. It occurred at:

  * https://github.com/weidai11/cryptopp/commit/bd8edfa87b579073

And a quick follow up check-in to fix GCC compiles:

  * https://github.com/weidai11/cryptopp/commit/f8c1348667efdc0d

We don't have implementations at the moment. We are still converting Threefish and implementing Kalyna. Kalyna is the interesting one from an implementation POV because a key length can use one of two block sizes. We should have Threefish and Kalyna by the end of the week.

Jeff

Jeffrey Walton

unread,
May 2, 2017, 4:25:36 PM5/2/17
to Crypto++ Users


On Friday, April 28, 2017 at 10:18:09 PM UTC-4, Jeffrey Walton wrote:
Hi Everyone,

I want to investigate variable size block ciphers, and the changes required to support them.
...

We started tracking this at https://github.com/weidai11/cryptopp/issues/408 (better late than never).

The next changes will be for testing and benchmarks. Benchmarks call IVSize() before a cipher is keyed, so the IV size is incorrect if the block size increases after keying.

Jeff
Reply all
Reply to author
Forward
0 new messages