Skip to content

Commit

Permalink
Convert Kalyna from variable block size (GH #535)
Browse files Browse the repository at this point in the history
  • Loading branch information
noloader committed Jan 19, 2018
1 parent 1eca4fd commit 58b6999
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 314 deletions.
30 changes: 10 additions & 20 deletions TestVectors/kalyna.txt
@@ -1,98 +1,88 @@
AlgorithmType: SymmetricCipher
Name: Kalyna/ECB
Name: Kalyna-128/ECB
Source: Kalyna reference implementation
Comment: Kalyna 128-bit key, 128-bit block
Key: 000102030405060708090A0B0C0D0E0F
BlockSize: 16
Plaintext: 101112131415161718191A1B1C1D1E1F
Ciphertext: 81BF1C7D779BAC20E1C9EA39B4D2AD06
Test: Encrypt
Name: Kalyna/ECB
Name: Kalyna-128/ECB
Source: Kalyna reference implementation
Comment: Kalyna 256-bit key, 128-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
BlockSize: 16
Plaintext: 202122232425262728292A2B2C2D2E2F
Ciphertext: 58EC3E091000158A1148F7166F334F14
Test: Encrypt
Name: Kalyna/ECB
Name: Kalyna-256/ECB
Source: Kalyna reference implementation
Comment: Kalyna 256-bit key, 256-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
BlockSize: 32
Plaintext: 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
Ciphertext: F66E3D570EC92135AEDAE323DCBD2A8CA03963EC206A0D5A88385C24617FD92C
Test: Encrypt
Name: Kalyna/ECB
Name: Kalyna-256/ECB
Source: Kalyna reference implementation
Comment: Kalyna 512-bit key, 256-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
BlockSize: 32
Plaintext: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Ciphertext: 606990E9E6B7B67A4BD6D893D72268B78E02C83C3CD7E102FD2E74A8FDFE5DD9
Test: Encrypt
Name: Kalyna/ECB
Name: Kalyna-512/ECB
Source: Kalyna reference implementation
Comment: Kalyna 512-bit key, 512-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
BlockSize: 64
Plaintext: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F
Ciphertext: 4A26E31B811C356AA61DD6CA0596231A67BA8354AA47F3A13E1DEEC320EB56B895D0F417175BAB662FD6F134BB15C86CCB906A26856EFEB7C5BC6472940DD9D9
Test: Encrypt
Name: Kalyna/CBC
Name: Kalyna-128/CBC
Source: DSTU 7624:2014, Section B.6.1 (p.148)
Comment: Kalyna 128-bit key, 128-bit block
Key: 000102030405060708090A0B0C0D0E0F
IV: 101112131415161718191A1B1C1D1E1F
BlockSize: 16
Plaintext: 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
Ciphertext: A73625D7BE994E85469A9FAABCEDAAB6DBC5F65DD77BB35E06BD7D1D8EAFC8624D6CB31CE189C82B8979F2936DE9BF14
Test: Encrypt
Name: Kalyna/CBC
Name: Kalyna-128/CBC
Source: DSTU 7624:2014, Section B.6.3 (p.149)
Comment: Kalyna 256-bit key, 128-bit block, OneAndZeros padding
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
IV: 202122232425262728292A2B2C2D2E2F
BlockSize: 16
BlockPaddingScheme: 3 # OneAndZeroPadding
Plaintext: 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D
Ciphertext: 13EA15843AD14C50BC03ECEF1F43E398E4217752D3EB046AC393DACC5CA1D6FA0EB9FCEB229362B4F1565527EE3D8433
Test: Encrypt
Name: Kalyna/CBC
Name: Kalyna-256/CBC
Source: DSTU 7624:2014, Section B.6.5 (p.150)
Comment: Kalyna 256-bit key, 256-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
IV: 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
BlockSize: 32
Plaintext: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F \
606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F \
808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
Ciphertext: 9CDFDAA75929E7C2A5CFC1BF16B42C5AE3886D0258E8C577DC01DAF62D185FB9 \
99B9867736B87110F5F1BC7481912C593F48FF79E2AFDFAB9F704A277EC3E557 \
B1B0A9F223DAE6ED5AF591C4F2D6FB22E48334F5E9B96B1A2EA5200F30A406CE
Test: Encrypt
Name: Kalyna/CBC
Name: Kalyna-256/CBC
Source: DSTU 7624:2014, Section B.6.7 (p.151)
Comment: Kalyna 512-bit key, 256-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F \
202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
IV: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
BlockSize: 32
Plaintext: 606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F \
808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F \
A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF
Ciphertext: B8A2474578C2FEBF3F94703587BD5FDC3F4A4D2F43575B6144A1E1031FB3D145 \
2B7FD52F5E3411461DAC506869FF8D2FAEF4FEE60379AE00B33AA3EAF911645A \
F8091CD8A45D141D1FB150E5A01C1F26FF3DBD26AC4225EC7577B2CE57A5B0FF
Test: Encrypt
Name: Kalyna/CBC
Name: Kalyna-512/CBC
Source: DSTU 7624:2014, Section B.6.9 (p.152)
Comment: Kalyna 512-bit key, 512-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F \
202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
IV: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F \
606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F
BlockSize: 64
Plaintext: 808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F \
A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF \
C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF \
Expand Down
156 changes: 102 additions & 54 deletions kalyna.cpp
Expand Up @@ -416,7 +416,7 @@ NAMESPACE_BEGIN(CryptoPP)

// *********************** UncheckedSetKey specializations *********************** //

void Kalyna::Base::SetKey_22(const word64 key[2])
void Kalyna128::Base::SetKey_22(const word64 key[2])
{
word64 *ks = m_wspace+0, *ksc = m_wspace+2, *t1 = m_wspace+4;
word64 *t2 = m_wspace+6, *k = m_wspace+8, *kswapped = m_wspace+10;
Expand Down Expand Up @@ -491,7 +491,7 @@ void Kalyna::Base::SetKey_22(const word64 key[2])
}
}

void Kalyna::Base::SetKey_24(const word64 key[4])
void Kalyna128::Base::SetKey_24(const word64 key[4])
{
word64 *ks = m_wspace+0, *ksc = m_wspace+2, *t1 = m_wspace+4, *t2 = m_wspace+6;
word64 *k = m_wspace+8, *ka = m_wspace+12, *ko = m_wspace+14;
Expand Down Expand Up @@ -592,7 +592,7 @@ void Kalyna::Base::SetKey_24(const word64 key[4])
}
}

void Kalyna::Base::SetKey_44(const word64 key[4])
void Kalyna256::Base::SetKey_44(const word64 key[4])
{
word64 *ks = m_wspace+0, *ksc = m_wspace+4, *t1 = m_wspace+8;
word64 *t2 = m_wspace+12, *k = m_wspace+16;
Expand Down Expand Up @@ -695,7 +695,7 @@ void Kalyna::Base::SetKey_44(const word64 key[4])
}
}

void Kalyna::Base::SetKey_48(const word64 key[8])
void Kalyna256::Base::SetKey_48(const word64 key[8])
{
word64 *ks = m_wspace+0, *ksc = m_wspace+4, *t1 = m_wspace+8, *t2 = m_wspace+12;
word64 *k = m_wspace+16, *ka = m_wspace+24, *ko = m_wspace+28;
Expand Down Expand Up @@ -817,7 +817,7 @@ void Kalyna::Base::SetKey_48(const word64 key[8])
}
}

void Kalyna::Base::SetKey_88(const word64 key[8])
void Kalyna512::Base::SetKey_88(const word64 key[8])
{
word64 *ks = m_wspace+0, *ksc = m_wspace+8, *t1 = m_wspace+16;
word64 *t2 = m_wspace+24, *k = m_wspace+32;
Expand Down Expand Up @@ -932,7 +932,7 @@ void Kalyna::Base::SetKey_88(const word64 key[8])

// *********************** ProcessAndXorBlock specializations *********************** //

void Kalyna::Base::ProcessBlock_22(const word64 inBlock[2], const word64 xorBlock[2], word64 outBlock[2]) const
void Kalyna128::Base::ProcessBlock_22(const word64 inBlock[2], const word64 xorBlock[2], word64 outBlock[2]) const
{
word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4;

Expand Down Expand Up @@ -978,7 +978,7 @@ void Kalyna::Base::ProcessBlock_22(const word64 inBlock[2], const word64 xorBloc
oblk(t1[0])(t1[1]);
}

void Kalyna::Base::ProcessBlock_24(const word64 inBlock[2], const word64 xorBlock[2], word64 outBlock[2]) const
void Kalyna128::Base::ProcessBlock_24(const word64 inBlock[2], const word64 xorBlock[2], word64 outBlock[2]) const
{
word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4;

Expand Down Expand Up @@ -1032,7 +1032,7 @@ void Kalyna::Base::ProcessBlock_24(const word64 inBlock[2], const word64 xorBloc
oblk(t1[0])(t1[1]);
}

void Kalyna::Base::ProcessBlock_44(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const
void Kalyna256::Base::ProcessBlock_44(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const
{
word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8;

Expand Down Expand Up @@ -1086,7 +1086,7 @@ void Kalyna::Base::ProcessBlock_44(const word64 inBlock[4], const word64 xorBloc
oblk(t1[0])(t1[1])(t1[2])(t1[3]);
}

void Kalyna::Base::ProcessBlock_48(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const
void Kalyna256::Base::ProcessBlock_48(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const
{
word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8;

Expand Down Expand Up @@ -1148,7 +1148,7 @@ void Kalyna::Base::ProcessBlock_48(const word64 inBlock[4], const word64 xorBloc
oblk(t1[0])(t1[1])(t1[2])(t1[3]);
}

void Kalyna::Base::ProcessBlock_88(const word64 inBlock[8], const word64 xorBlock[8], word64 outBlock[8]) const
void Kalyna512::Base::ProcessBlock_88(const word64 inBlock[8], const word64 xorBlock[8], word64 outBlock[8]) const
{
word64 *t1 = m_wspace+0, *t2 = m_wspace+8, *msg = m_wspace+16;

Expand Down Expand Up @@ -1212,77 +1212,96 @@ void Kalyna::Base::ProcessBlock_88(const word64 inBlock[8], const word64 xorBloc

// *********************** Library routines *********************** //

void Kalyna::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
void Kalyna128::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
{
CRYPTOPP_UNUSED(params);
m_nb = static_cast<unsigned int>(16U / sizeof(word64));
m_nk = static_cast<unsigned int>(keylen / sizeof(word64));

switch (keylen)
{
case 16: // 128
m_kl = 16;
m_blocksize = params.GetIntValueWithDefault(Name::BlockSize(), 16);
break;
case 32: // 256
m_kl = 32;
m_blocksize = params.GetIntValueWithDefault(Name::BlockSize(), 32);
break;
case 64: // 512
m_kl = 64;
m_blocksize = params.GetIntValueWithDefault(Name::BlockSize(), 64);
break;
default:
CRYPTOPP_ASSERT(0);
}

m_nb = static_cast<unsigned int>(m_blocksize / sizeof(word64));
m_nk = static_cast<unsigned int>(keylen / sizeof(word64));

switch ((m_nb << 8) | m_nk)
{
case (2 << 8) | 2: // 128 key, 128 block
m_mkey.New(2);
m_rkeys.New(11*2);
m_wspace.New(2*6);

GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 2, key, 16);
SetKey_22(m_mkey.begin());
break;
case (2 << 8) | 4: // 256 key, 128 block
case 32: // 256
m_kl = 32;
m_mkey.New(4);
m_rkeys.New(15*2);
m_wspace.New(6*2+4);

GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32);
SetKey_24(m_mkey.begin());
break;
case (4 << 8) | 4: // 256 key, 256 block
default:
CRYPTOPP_ASSERT(0);
}
}

void Kalyna128::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Timing attack countermeasure. see comments in Rijndael for more details
const int cacheLineSize = GetCacheLineSize();
volatile word64 _u = 0;
word64 u = _u;

const byte* p = reinterpret_cast<const byte*>(KalynaTab::S);
for (unsigned int i=0; i<256; i+=cacheLineSize)
u ^= *reinterpret_cast<const word64*>(p+i);
m_wspace[0] = u;

switch ((m_nb << 8) | m_nk)
{
case (2 << 8) | 2:
ProcessBlock_22(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
break;
case (2 << 8) | 4:
ProcessBlock_24(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
break;
default:
CRYPTOPP_ASSERT(0);
}
}

void Kalyna256::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
{
CRYPTOPP_UNUSED(params);
m_nb = static_cast<unsigned int>(32U / sizeof(word64));
m_nk = static_cast<unsigned int>(keylen / sizeof(word64));

switch (keylen)
{
case 32: // 256
m_kl = 32;
m_mkey.New(4);
m_rkeys.New(15*4);
m_wspace.New(5*4);

GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32);
SetKey_44(m_mkey.begin());
break;
case (4 << 8) | 8: // 512 key, 256 block
case 64: // 512
m_kl = 64;
m_mkey.New(8);
m_rkeys.New(19*4);
m_wspace.New(6*4+8);

GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64);
SetKey_48(m_mkey.begin());
break;
case (8 << 8) | 8: // 512 key, 512 block
m_mkey.New(8);
m_rkeys.New(19*8);
m_wspace.New(5*8);

GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64);
SetKey_88(m_mkey.begin());
break;
default:
CRYPTOPP_ASSERT(0);
}
}

void Kalyna::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
void Kalyna256::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Timing attack countermeasure. see comments in Rijndael for more details
const int cacheLineSize = GetCacheLineSize();
Expand All @@ -1296,14 +1315,6 @@ void Kalyna::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock,

switch ((m_nb << 8) | m_nk)
{
case (2 << 8) | 2:
ProcessBlock_22(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
break;
case (2 << 8) | 4:
ProcessBlock_24(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
break;
case (4 << 8) | 4:
ProcessBlock_44(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
Expand All @@ -1312,13 +1323,50 @@ void Kalyna::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock,
ProcessBlock_48(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
break;
case (8 << 8) | 8:
ProcessBlock_88(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
default:
CRYPTOPP_ASSERT(0);
}
}

void Kalyna512::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
{
CRYPTOPP_UNUSED(params);
m_nb = static_cast<unsigned int>(64U / sizeof(word64));
m_nk = static_cast<unsigned int>(keylen / sizeof(word64));

switch (keylen)
{
case 64: // 512
m_kl = 64;
m_nb = static_cast<unsigned int>(64U / sizeof(word64));
m_nk = static_cast<unsigned int>(keylen / sizeof(word64));

m_mkey.New(8);
m_rkeys.New(19*8);
m_wspace.New(5*8);

GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64);
SetKey_88(m_mkey.begin());
break;
default:
CRYPTOPP_ASSERT(0);
}
}

void Kalyna512::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Timing attack countermeasure. see comments in Rijndael for more details
const int cacheLineSize = GetCacheLineSize();
volatile word64 _u = 0;
word64 u = _u;

const byte* p = reinterpret_cast<const byte*>(KalynaTab::S);
for (unsigned int i=0; i<256; i+=cacheLineSize)
u ^= *reinterpret_cast<const word64*>(p+i);
m_wspace[0] = u;

ProcessBlock_88(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
}

NAMESPACE_END

0 comments on commit 58b6999

Please sign in to comment.