Convert Kalyna from variable block size (GH #535)

pull/546/head
Jeffrey Walton 2018-01-18 20:26:10 -05:00
parent 1eca4fd940
commit 58b6999274
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
9 changed files with 247 additions and 322 deletions

View File

@ -1,69 +1,61 @@
AlgorithmType: SymmetricCipher AlgorithmType: SymmetricCipher
Name: Kalyna/ECB Name: Kalyna-128/ECB
Source: Kalyna reference implementation Source: Kalyna reference implementation
Comment: Kalyna 128-bit key, 128-bit block Comment: Kalyna 128-bit key, 128-bit block
Key: 000102030405060708090A0B0C0D0E0F Key: 000102030405060708090A0B0C0D0E0F
BlockSize: 16
Plaintext: 101112131415161718191A1B1C1D1E1F Plaintext: 101112131415161718191A1B1C1D1E1F
Ciphertext: 81BF1C7D779BAC20E1C9EA39B4D2AD06 Ciphertext: 81BF1C7D779BAC20E1C9EA39B4D2AD06
Test: Encrypt Test: Encrypt
Name: Kalyna/ECB Name: Kalyna-128/ECB
Source: Kalyna reference implementation Source: Kalyna reference implementation
Comment: Kalyna 256-bit key, 128-bit block Comment: Kalyna 256-bit key, 128-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
BlockSize: 16
Plaintext: 202122232425262728292A2B2C2D2E2F Plaintext: 202122232425262728292A2B2C2D2E2F
Ciphertext: 58EC3E091000158A1148F7166F334F14 Ciphertext: 58EC3E091000158A1148F7166F334F14
Test: Encrypt Test: Encrypt
Name: Kalyna/ECB Name: Kalyna-256/ECB
Source: Kalyna reference implementation Source: Kalyna reference implementation
Comment: Kalyna 256-bit key, 256-bit block Comment: Kalyna 256-bit key, 256-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
BlockSize: 32
Plaintext: 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F Plaintext: 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
Ciphertext: F66E3D570EC92135AEDAE323DCBD2A8CA03963EC206A0D5A88385C24617FD92C Ciphertext: F66E3D570EC92135AEDAE323DCBD2A8CA03963EC206A0D5A88385C24617FD92C
Test: Encrypt Test: Encrypt
Name: Kalyna/ECB Name: Kalyna-256/ECB
Source: Kalyna reference implementation Source: Kalyna reference implementation
Comment: Kalyna 512-bit key, 256-bit block Comment: Kalyna 512-bit key, 256-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
BlockSize: 32
Plaintext: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F Plaintext: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Ciphertext: 606990E9E6B7B67A4BD6D893D72268B78E02C83C3CD7E102FD2E74A8FDFE5DD9 Ciphertext: 606990E9E6B7B67A4BD6D893D72268B78E02C83C3CD7E102FD2E74A8FDFE5DD9
Test: Encrypt Test: Encrypt
Name: Kalyna/ECB Name: Kalyna-512/ECB
Source: Kalyna reference implementation Source: Kalyna reference implementation
Comment: Kalyna 512-bit key, 512-bit block Comment: Kalyna 512-bit key, 512-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
BlockSize: 64
Plaintext: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F Plaintext: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F
Ciphertext: 4A26E31B811C356AA61DD6CA0596231A67BA8354AA47F3A13E1DEEC320EB56B895D0F417175BAB662FD6F134BB15C86CCB906A26856EFEB7C5BC6472940DD9D9 Ciphertext: 4A26E31B811C356AA61DD6CA0596231A67BA8354AA47F3A13E1DEEC320EB56B895D0F417175BAB662FD6F134BB15C86CCB906A26856EFEB7C5BC6472940DD9D9
Test: Encrypt Test: Encrypt
Name: Kalyna/CBC Name: Kalyna-128/CBC
Source: DSTU 7624:2014, Section B.6.1 (p.148) Source: DSTU 7624:2014, Section B.6.1 (p.148)
Comment: Kalyna 128-bit key, 128-bit block Comment: Kalyna 128-bit key, 128-bit block
Key: 000102030405060708090A0B0C0D0E0F Key: 000102030405060708090A0B0C0D0E0F
IV: 101112131415161718191A1B1C1D1E1F IV: 101112131415161718191A1B1C1D1E1F
BlockSize: 16
Plaintext: 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F Plaintext: 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
Ciphertext: A73625D7BE994E85469A9FAABCEDAAB6DBC5F65DD77BB35E06BD7D1D8EAFC8624D6CB31CE189C82B8979F2936DE9BF14 Ciphertext: A73625D7BE994E85469A9FAABCEDAAB6DBC5F65DD77BB35E06BD7D1D8EAFC8624D6CB31CE189C82B8979F2936DE9BF14
Test: Encrypt Test: Encrypt
Name: Kalyna/CBC Name: Kalyna-128/CBC
Source: DSTU 7624:2014, Section B.6.3 (p.149) Source: DSTU 7624:2014, Section B.6.3 (p.149)
Comment: Kalyna 256-bit key, 128-bit block, OneAndZeros padding Comment: Kalyna 256-bit key, 128-bit block, OneAndZeros padding
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
IV: 202122232425262728292A2B2C2D2E2F IV: 202122232425262728292A2B2C2D2E2F
BlockSize: 16
BlockPaddingScheme: 3 # OneAndZeroPadding BlockPaddingScheme: 3 # OneAndZeroPadding
Plaintext: 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D Plaintext: 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D
Ciphertext: 13EA15843AD14C50BC03ECEF1F43E398E4217752D3EB046AC393DACC5CA1D6FA0EB9FCEB229362B4F1565527EE3D8433 Ciphertext: 13EA15843AD14C50BC03ECEF1F43E398E4217752D3EB046AC393DACC5CA1D6FA0EB9FCEB229362B4F1565527EE3D8433
Test: Encrypt Test: Encrypt
Name: Kalyna/CBC Name: Kalyna-256/CBC
Source: DSTU 7624:2014, Section B.6.5 (p.150) Source: DSTU 7624:2014, Section B.6.5 (p.150)
Comment: Kalyna 256-bit key, 256-bit block Comment: Kalyna 256-bit key, 256-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
IV: 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F IV: 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
BlockSize: 32
Plaintext: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F \ Plaintext: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F \
606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F \ 606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F \
808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F 808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
@ -71,13 +63,12 @@ Ciphertext: 9CDFDAA75929E7C2A5CFC1BF16B42C5AE3886D0258E8C577DC01DAF62D185FB9 \
99B9867736B87110F5F1BC7481912C593F48FF79E2AFDFAB9F704A277EC3E557 \ 99B9867736B87110F5F1BC7481912C593F48FF79E2AFDFAB9F704A277EC3E557 \
B1B0A9F223DAE6ED5AF591C4F2D6FB22E48334F5E9B96B1A2EA5200F30A406CE B1B0A9F223DAE6ED5AF591C4F2D6FB22E48334F5E9B96B1A2EA5200F30A406CE
Test: Encrypt Test: Encrypt
Name: Kalyna/CBC Name: Kalyna-256/CBC
Source: DSTU 7624:2014, Section B.6.7 (p.151) Source: DSTU 7624:2014, Section B.6.7 (p.151)
Comment: Kalyna 512-bit key, 256-bit block Comment: Kalyna 512-bit key, 256-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F \ Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F \
202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
IV: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F IV: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
BlockSize: 32
Plaintext: 606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F \ Plaintext: 606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F \
808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F \ 808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F \
A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF
@ -85,14 +76,13 @@ Ciphertext: B8A2474578C2FEBF3F94703587BD5FDC3F4A4D2F43575B6144A1E1031FB3D145 \
2B7FD52F5E3411461DAC506869FF8D2FAEF4FEE60379AE00B33AA3EAF911645A \ 2B7FD52F5E3411461DAC506869FF8D2FAEF4FEE60379AE00B33AA3EAF911645A \
F8091CD8A45D141D1FB150E5A01C1F26FF3DBD26AC4225EC7577B2CE57A5B0FF F8091CD8A45D141D1FB150E5A01C1F26FF3DBD26AC4225EC7577B2CE57A5B0FF
Test: Encrypt Test: Encrypt
Name: Kalyna/CBC Name: Kalyna-512/CBC
Source: DSTU 7624:2014, Section B.6.9 (p.152) Source: DSTU 7624:2014, Section B.6.9 (p.152)
Comment: Kalyna 512-bit key, 512-bit block Comment: Kalyna 512-bit key, 512-bit block
Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F \ Key: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F \
202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
IV: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F \ IV: 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F \
606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F 606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F
BlockSize: 64
Plaintext: 808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F \ Plaintext: 808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F \
A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF \ A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF \
C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF \ C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF \

View File

@ -416,7 +416,7 @@ NAMESPACE_BEGIN(CryptoPP)
// *********************** UncheckedSetKey specializations *********************** // // *********************** 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 *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; word64 *t2 = m_wspace+6, *k = m_wspace+8, *kswapped = m_wspace+10;
@ -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 *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; word64 *k = m_wspace+8, *ka = m_wspace+12, *ko = m_wspace+14;
@ -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 *ks = m_wspace+0, *ksc = m_wspace+4, *t1 = m_wspace+8;
word64 *t2 = m_wspace+12, *k = m_wspace+16; word64 *t2 = m_wspace+12, *k = m_wspace+16;
@ -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 *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; word64 *k = m_wspace+16, *ka = m_wspace+24, *ko = m_wspace+28;
@ -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 *ks = m_wspace+0, *ksc = m_wspace+8, *t1 = m_wspace+16;
word64 *t2 = m_wspace+24, *k = m_wspace+32; word64 *t2 = m_wspace+24, *k = m_wspace+32;
@ -932,7 +932,7 @@ void Kalyna::Base::SetKey_88(const word64 key[8])
// *********************** ProcessAndXorBlock specializations *********************** // // *********************** 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; word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4;
@ -978,7 +978,7 @@ void Kalyna::Base::ProcessBlock_22(const word64 inBlock[2], const word64 xorBloc
oblk(t1[0])(t1[1]); 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; word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4;
@ -1032,7 +1032,7 @@ void Kalyna::Base::ProcessBlock_24(const word64 inBlock[2], const word64 xorBloc
oblk(t1[0])(t1[1]); 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; word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8;
@ -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]); 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; word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8;
@ -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]); 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; word64 *t1 = m_wspace+0, *t2 = m_wspace+8, *msg = m_wspace+16;
@ -1212,32 +1212,16 @@ void Kalyna::Base::ProcessBlock_88(const word64 inBlock[8], const word64 xorBloc
// *********************** Library routines *********************** // // *********************** 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) switch (keylen)
{ {
case 16: // 128 case 16: // 128
m_kl = 16; 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_mkey.New(2);
m_rkeys.New(11*2); m_rkeys.New(11*2);
m_wspace.New(2*6); m_wspace.New(2*6);
@ -1245,7 +1229,8 @@ void Kalyna::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const N
GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 2, key, 16); GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 2, key, 16);
SetKey_22(m_mkey.begin()); SetKey_22(m_mkey.begin());
break; break;
case (2 << 8) | 4: // 256 key, 128 block case 32: // 256
m_kl = 32;
m_mkey.New(4); m_mkey.New(4);
m_rkeys.New(15*2); m_rkeys.New(15*2);
m_wspace.New(6*2+4); m_wspace.New(6*2+4);
@ -1253,36 +1238,12 @@ void Kalyna::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const N
GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32); GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32);
SetKey_24(m_mkey.begin()); SetKey_24(m_mkey.begin());
break; break;
case (4 << 8) | 4: // 256 key, 256 block
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
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: default:
CRYPTOPP_ASSERT(0); CRYPTOPP_ASSERT(0);
} }
} }
void Kalyna::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const void Kalyna128::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{ {
// Timing attack countermeasure. see comments in Rijndael for more details // Timing attack countermeasure. see comments in Rijndael for more details
const int cacheLineSize = GetCacheLineSize(); const int cacheLineSize = GetCacheLineSize();
@ -1304,6 +1265,56 @@ void Kalyna::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock,
ProcessBlock_24(reinterpret_cast<const word64*>(inBlock), ProcessBlock_24(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock)); reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
break; 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 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;
default:
CRYPTOPP_ASSERT(0);
}
}
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();
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 (4 << 8) | 4: case (4 << 8) | 4:
ProcessBlock_44(reinterpret_cast<const word64*>(inBlock), ProcessBlock_44(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock)); reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
@ -1312,13 +1323,50 @@ void Kalyna::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock,
ProcessBlock_48(reinterpret_cast<const word64*>(inBlock), ProcessBlock_48(reinterpret_cast<const word64*>(inBlock),
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock)); reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
break; break;
case (8 << 8) | 8: default:
ProcessBlock_88(reinterpret_cast<const word64*>(inBlock), CRYPTOPP_ASSERT(0);
reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock)); }
}
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; break;
default: default:
CRYPTOPP_ASSERT(0); 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 NAMESPACE_END

195
kalyna.h
View File

@ -20,81 +20,59 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
/// \class Kalyna_Info /// \class Kalyna128_Info
/// \brief Kalyna block cipher information /// \brief Kalyna-128 block cipher information
/// \details Kalyna key sizes and block sizes do not fit well into the library. Rather
/// than using VariableKeyLength (which is wrong) or using a GeometricKeyLength
/// (a new class), we just unroll it here. Note that the step size, Q, is still
/// wrong for this implementation.
/// \since Crypto++ 6.0 /// \since Crypto++ 6.0
struct Kalyna_Info : public VariableBlockSize<16, 16, 64> struct Kalyna128_Info : public FixedBlockSize<16>, VariableKeyLength<16, 16, 32>
{ {
CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Kalyna";} static const char* StaticAlgorithmName()
/// \brief The minimum key length used by the algorithm provided as a constant
/// \details MIN_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(MIN_KEYLENGTH=16)
/// \brief The maximum key length used by the algorithm provided as a constant
/// \details MIN_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(MAX_KEYLENGTH=64)
/// \brief The default key length used by the algorithm provided as a constant
/// \details MIN_KEYLENGTH is provided in bytes, not bits
CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=16)
/// \brief The default IV requirements for the algorithm provided as a constant
/// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
/// in cryptlib.h for allowed values.
CRYPTOPP_CONSTANT(IV_REQUIREMENT=SimpleKeyingInterface::UNIQUE_IV)
/// \brief The default initialization vector length for the algorithm provided as a constant
/// \details IV_LENGTH is provided in bytes, not bits. Kalyna has two different block sizes for
/// each key length. This function returns the default block size for the defult key length.
CRYPTOPP_CONSTANT(IV_LENGTH=16)
/// \brief Provides a valid key length for the algorithm provided by a static function.
/// \param keylength the size of the key, in bytes
/// \details The key length depends on the block size. For each block size, 128, 256 and 512,
/// the key length can be either the block size or twice the block size. That means the
/// valid key lengths are 126, 256, 512 and 1024. Additionally, it means a key length of,
/// say, 32 could be used with either 128-block size or 256-block size.
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
{ {
return (keylength >= 64) ? 64 : // Format is Cipher-Blocksize(Keylength)
(keylength >= 32) ? 32 : 16; return "Kalyna-128";
} }
};
/// \brief Validates the blocksize for Kalyna. /// \class Kalyna256_Info
/// \param blocksize the candidate blocksize /// \brief Kalyna-256 block cipher information
/// \param alg an Algorithm object used if the blocksize is invalid /// \since Crypto++ 6.0
/// \throws InvalidBlockSize if the blocksize is invalid struct Kalyna256_Info : public FixedBlockSize<32>, VariableKeyLength<32, 32, 64>
/// \details ThrowIfInvalidBlockSize() validates the blocksize and throws if invalid. {
inline void ThrowIfInvalidBlockSize(int blocksize, const Algorithm *alg) static const char* StaticAlgorithmName()
{ {
if ( blocksize != 16 && blocksize != 32 && blocksize != 64) // Format is Cipher-Blocksize(Keylength)
throw InvalidBlockSize(alg ? alg->AlgorithmName() : std::string("VariableBlockSize"), blocksize); return "Kalyna-256";
} }
};
/// \brief Validates the blocksize for Kalyna. /// \class Kalyna512_Info
/// \param keylength the key length of the cipher /// \brief Kalyna-512 block cipher information
/// \param blocksize the candidate blocksize /// \since Crypto++ 6.0
/// \param alg an Algorithm object used if the blocksize is invalid struct Kalyna512_Info : public FixedBlockSize<64>, FixedKeyLength<64>
/// \throws InvalidBlockSize if the blocksize is invalid {
/// \details ThrowIfInvalidBlockSize() validates the blocksize under a key and throws if invalid. static const char* StaticAlgorithmName()
inline void ThrowIfInvalidBlockSize(int keylength, int blocksize, const Algorithm *alg)
{ {
if ( ((keylength == 16) && (blocksize != 16)) || // Format is Cipher-Blocksize(Keylength)
((keylength == 32) && (blocksize != 32 && blocksize != 64)) || return "Kalyna-512";
((keylength == 64) && (blocksize != 32 && blocksize != 64)) )
{
throw InvalidBlockSize(alg ? alg->AlgorithmName() : std::string("VariableBlockSize"), blocksize);
}
} }
}; };
/// \class Kalyna /// \class Kalyna
/// \brief Kalyna block cipher /// \brief Kalyna block cipher
/// \since Crypto++ 6.0 /// \since Crypto++ 6.0
class Kalyna : public Kalyna_Info, public BlockCipherDocumentation class Kalyna_Base
{
protected:
typedef SecBlock<word64, AllocatorWithCleanup<word64, true> > AlignedSecBlock64;
mutable AlignedSecBlock64 m_wspace; // work space
AlignedSecBlock64 m_mkey; // master key
AlignedSecBlock64 m_rkeys; // round keys
unsigned int m_kl, m_nb, m_nk; // key length, number 64-bit blocks and keys
};
class Kalyna128 : public Kalyna128_Info, public BlockCipherDocumentation
{ {
public: public:
class CRYPTOPP_NO_VTABLE Base : public VariableBlockCipherImpl<Kalyna_Info> class CRYPTOPP_NO_VTABLE Base : public Kalyna_Base, public BlockCipherImpl<Kalyna128_Info>
{ {
public: public:
/// \brief Provides the name of this algorithm /// \brief Provides the name of this algorithm
@ -109,7 +87,7 @@ public:
/// DSTU is a little more complex with more parameters, dashes, underscores, but the /// DSTU is a little more complex with more parameters, dashes, underscores, but the
/// library does not use the delimiters or full convention. /// library does not use the delimiters or full convention.
std::string AlgorithmName() const { std::string AlgorithmName() const {
return m_blocksize ? "Kalyna-" + IntToString(m_blocksize*8) + "(" + IntToString(m_kl*8) + ")" : StaticAlgorithmName(); return std::string("Kalyna-128") + "(" + IntToString(m_kl*8) + ")";
} }
unsigned int OptimalDataAlignment() const { unsigned int OptimalDataAlignment() const {
@ -121,38 +99,93 @@ public:
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
protected: protected:
// Visual Studio and C2910: 'Kalyna::Base::SetKey_Template': cannot be explicitly specialized
//template <unsigned int NB, unsigned int NK>
// void SetKey_Template(const word64 key[NK]);
void SetKey_22(const word64 key[2]); void SetKey_22(const word64 key[2]);
void SetKey_24(const word64 key[4]); void SetKey_24(const word64 key[4]);
void SetKey_44(const word64 key[4]);
void SetKey_48(const word64 key[8]);
void SetKey_88(const word64 key[8]);
// Visual Studio and C2910: 'Kalyna::Base::ProcessBlock_Template': cannot be explicitly specialized
//template <unsigned int NB, unsigned int NK>
// void ProcessBlock_Template(const word64 inBlock[NB], const word64 outBlock[NB]) const;
void ProcessBlock_22(const word64 inBlock[2], const word64 xorBlock[2], word64 outBlock[2]) const; void ProcessBlock_22(const word64 inBlock[2], const word64 xorBlock[2], word64 outBlock[2]) const;
void ProcessBlock_24(const word64 inBlock[2], const word64 xorBlock[2] ,word64 outBlock[2]) const; void ProcessBlock_24(const word64 inBlock[2], const word64 xorBlock[2] ,word64 outBlock[2]) const;
void ProcessBlock_44(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const;
void ProcessBlock_48(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const;
void ProcessBlock_88(const word64 inBlock[8], const word64 xorBlock[8], word64 outBlock[8]) const;
private:
typedef SecBlock<word64, AllocatorWithCleanup<word64, true> > AlignedSecBlock64;
mutable AlignedSecBlock64 m_wspace; // work space
AlignedSecBlock64 m_mkey; // master key
AlignedSecBlock64 m_rkeys; // round keys
unsigned int m_kl, m_nb, m_nk; // key length, number 64-bit blocks and keys
}; };
typedef BlockCipherFinal<ENCRYPTION, Base> Encryption; typedef BlockCipherFinal<ENCRYPTION, Base> Encryption;
typedef BlockCipherFinal<DECRYPTION, Base> Decryption; typedef BlockCipherFinal<DECRYPTION, Base> Decryption;
}; };
typedef Kalyna::Encryption KalynaEncryption; class Kalyna256 : public Kalyna256_Info, public BlockCipherDocumentation
typedef Kalyna::Decryption KalynaDecryption; {
public:
class CRYPTOPP_NO_VTABLE Base : public Kalyna_Base, public BlockCipherImpl<Kalyna256_Info>
{
public:
/// \brief Provides the name of this algorithm
/// \return the standard algorithm name
/// \details If the object is unkeyed, then the generic name "Kalyna" is returned
/// to the caller. If the algorithm is keyed, then a two or three part name is
/// returned to the caller. 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-128(256)/ECB.
/// DSTU is a little more complex with more parameters, dashes, underscores, but the
/// library does not use the delimiters or full convention.
std::string AlgorithmName() const {
return std::string("Kalyna-256") + "(" + IntToString(m_kl*8) + ")";
}
unsigned int OptimalDataAlignment() const {
return GetAlignmentOf<word64>();
}
protected:
void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params);
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
protected:
void SetKey_44(const word64 key[4]);
void SetKey_48(const word64 key[8]);
void ProcessBlock_44(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const;
void ProcessBlock_48(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const;
};
typedef BlockCipherFinal<ENCRYPTION, Base> Encryption;
typedef BlockCipherFinal<DECRYPTION, Base> Decryption;
};
class Kalyna512 : Kalyna512_Info, public BlockCipherDocumentation
{
public:
class CRYPTOPP_NO_VTABLE Base : public Kalyna_Base, public BlockCipherImpl<Kalyna512_Info>
{
public:
/// \brief Provides the name of this algorithm
/// \return the standard algorithm name
/// \details If the object is unkeyed, then the generic name "Kalyna" is returned
/// to the caller. If the algorithm is keyed, then a two or three part name is
/// returned to the caller. 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-128(256)/ECB.
/// DSTU is a little more complex with more parameters, dashes, underscores, but the
/// library does not use the delimiters or full convention.
std::string AlgorithmName() const {
return std::string("Kalyna-512") + "(" + IntToString(m_kl*8) + ")";
}
unsigned int OptimalDataAlignment() const {
return GetAlignmentOf<word64>();
}
protected:
void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params);
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
protected:
void SetKey_88(const word64 key[8]);
void ProcessBlock_88(const word64 inBlock[8], const word64 xorBlock[8], word64 outBlock[8]) const;
};
typedef BlockCipherFinal<ENCRYPTION, Base> Encryption;
typedef BlockCipherFinal<DECRYPTION, Base> Decryption;
};
NAMESPACE_END NAMESPACE_END

6
nacl.h
View File

@ -229,7 +229,7 @@ int crypto_box_open_afternm(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t
/// \returns 0 on success, non-0 otherwise /// \returns 0 on success, non-0 otherwise
/// \warning This version of crypto_box() does not check for small order elements. It should not /// \warning This version of crypto_box() does not check for small order elements. It should not
/// be used in new software. /// be used in new software.
/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>, /// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>,
/// <A HREF="https://eprint.iacr.org/2017/806.pdf">May the Fourth Be With You: A Microarchitectural /// <A HREF="https://eprint.iacr.org/2017/806.pdf">May the Fourth Be With You: A Microarchitectural
/// Side Channel Attack on Several Real-World Applications of Curve25519</A>, /// Side Channel Attack on Several Real-World Applications of Curve25519</A>,
/// <A HREF="https://github.com/jedisct1/libsodium/commit/675149b9b8b66ff4">libsodium commit /// <A HREF="https://github.com/jedisct1/libsodium/commit/675149b9b8b66ff4">libsodium commit
@ -253,7 +253,7 @@ int crypto_box_unchecked(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n
/// \returns 0 on success, non-0 otherwise /// \returns 0 on success, non-0 otherwise
/// \warning This version of crypto_box_open() does not check for small order elements. It should not /// \warning This version of crypto_box_open() does not check for small order elements. It should not
/// be used in new software. /// be used in new software.
/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>, /// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>,
/// <A HREF="https://eprint.iacr.org/2017/806.pdf">May the Fourth Be With You: A Microarchitectural /// <A HREF="https://eprint.iacr.org/2017/806.pdf">May the Fourth Be With You: A Microarchitectural
/// Side Channel Attack on Several Real-World Applications of Curve25519</A>, /// Side Channel Attack on Several Real-World Applications of Curve25519</A>,
/// <A HREF="https://github.com/jedisct1/libsodium/commit/675149b9b8b66ff4">libsodium commit /// <A HREF="https://github.com/jedisct1/libsodium/commit/675149b9b8b66ff4">libsodium commit
@ -275,7 +275,7 @@ int crypto_box_open_unchecked(uint8_t *m,const uint8_t *c,uint64_t d,const uint8
/// \returns 0 on success, non-0 otherwise /// \returns 0 on success, non-0 otherwise
/// \warning This version of crypto_box_beforenm() does not check for small order elements. It should not /// \warning This version of crypto_box_beforenm() does not check for small order elements. It should not
/// be used in new software. /// be used in new software.
/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>, /// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>,
/// <A HREF="https://eprint.iacr.org/2017/806.pdf">May the Fourth Be With You: A Microarchitectural /// <A HREF="https://eprint.iacr.org/2017/806.pdf">May the Fourth Be With You: A Microarchitectural
/// Side Channel Attack on Several Real-World Applications of Curve25519</A>, /// Side Channel Attack on Several Real-World Applications of Curve25519</A>,
/// <A HREF="https://github.com/jedisct1/libsodium/commit/675149b9b8b66ff4">libsodium commit /// <A HREF="https://github.com/jedisct1/libsodium/commit/675149b9b8b66ff4">libsodium commit

View File

@ -143,9 +143,15 @@ void RegisterFactories2()
RegisterSymmetricCipherDefaultFactories<ECB_Mode<SEED> >(); RegisterSymmetricCipherDefaultFactories<ECB_Mode<SEED> >();
RegisterSymmetricCipherDefaultFactories<CTR_Mode<SEED> >(); RegisterSymmetricCipherDefaultFactories<CTR_Mode<SEED> >();
RegisterSymmetricCipherDefaultFactories<ECB_Mode<Kalyna> >(); // Test Vectors RegisterSymmetricCipherDefaultFactories<ECB_Mode<Kalyna128> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CBC_Mode<Kalyna> >(); // Test Vectors RegisterSymmetricCipherDefaultFactories<CBC_Mode<Kalyna128> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CTR_Mode<Kalyna> >(); // Benchmarks RegisterSymmetricCipherDefaultFactories<ECB_Mode<Kalyna256> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CBC_Mode<Kalyna256> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<ECB_Mode<Kalyna512> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CBC_Mode<Kalyna512> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CTR_Mode<Kalyna128> >(); // Benchmarks
RegisterSymmetricCipherDefaultFactories<CTR_Mode<Kalyna256> >(); // Benchmarks
RegisterSymmetricCipherDefaultFactories<CTR_Mode<Kalyna512> >(); // Benchmarks
RegisterSymmetricCipherDefaultFactories<ECB_Mode<Threefish256> >(); // Test Vectors RegisterSymmetricCipherDefaultFactories<ECB_Mode<Threefish256> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CBC_Mode<Threefish256> >(); // Test Vectors RegisterSymmetricCipherDefaultFactories<CBC_Mode<Threefish256> >(); // Test Vectors

152
seckey.h
View File

@ -138,123 +138,6 @@ protected:
} }
}; };
/// \class VariableBlockSize
/// \brief Inherited by algorithms with variable blocksize
/// \tparam D Default blocksize
/// \tparam N Minimum blocksize
/// \tparam M Maximum blocksize
template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX> // use INT_MAX here because enums are treated as signed ints
class VariableBlockSize
{
public:
/// \brief The default blocksize for the algorithm provided as a constant.
CRYPTOPP_CONSTANT(DEFAULT_BLOCKSIZE = D)
/// \brief The minimum blocksize for the algorithm provided as a constant.
CRYPTOPP_CONSTANT(MIN_BLOCKSIZE = N)
/// \brief The maximum blocksize for the algorithm provided as a constant.
CRYPTOPP_CONSTANT(MAX_BLOCKSIZE = M)
/// \brief The default block size for the algorithm provided by a static function.
/// \param blocksize the block size, in bytes
/// \details The default implementation returns BLOCKSIZE. blocksize is unused
/// in the default implementation.
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidBlockSize(size_t blocksize)
{
return CRYPTOPP_UNUSED(blocksize), static_cast<size_t>(DEFAULT_BLOCKSIZE);
}
/// \brief The default block size under a key provided by a static function.
/// \param keylength the size of the key, in bytes
/// \param blocksize the block size, in bytes
/// \details The default implementation returns BLOCKSIZE. blocksize is unused
/// in the default implementation.
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidBlockSize(size_t keylength, size_t blocksize)
{
return CRYPTOPP_UNUSED(keylength), CRYPTOPP_UNUSED(blocksize), static_cast<size_t>(DEFAULT_BLOCKSIZE);
}
protected:
/// \brief Validates the blocksize for an algorithm.
/// \param blocksize the candidate blocksize
/// \param alg an Algorithm object used if the blocksize is invalid
/// \throws InvalidBlockSize if the blocksize is invalid
/// \details ThrowIfInvalidBlockSize() validates the blocksize and throws if invalid.
inline void ThrowIfInvalidBlockSize(int blocksize, const Algorithm *alg)
{
if (M == INT_MAX) // Coverity and result_independent_of_operands
{
if (blocksize < MIN_BLOCKSIZE)
throw InvalidBlockSize(alg ? alg->AlgorithmName() : std::string("VariableBlockSize"), blocksize);
}
else
{
if (blocksize < MIN_BLOCKSIZE || blocksize > MAX_BLOCKSIZE)
throw InvalidBlockSize(alg ? alg->AlgorithmName() : std::string("VariableBlockSize"), blocksize);
}
}
/// \brief Validates the blocksize for an algorithm
/// \param param the candidate blocksize
/// \param alg an Algorithm object used if the blocksize is invalid
/// \returns the blocksize for the algorithm
/// \throws InvalidBlockSize if the blocksize is invalid
/// \details GetBlockSizeAndThrowIfInvalid() validates the blocksize and throws if invalid.
inline unsigned int GetBlockSizeAndThrowIfInvalid(const NameValuePairs &param, const Algorithm *alg)
{
int keylength = param.GetIntValueWithDefault("KeySize", 0);
int blocksize = param.GetIntValueWithDefault("BlockSize", DEFAULT_BLOCKSIZE);
if (keylength > 0)
ThrowIfInvalidBlockSize(keylength, blocksize, alg);
else
ThrowIfInvalidBlockSize(blocksize, alg);
return static_cast<unsigned int>(blocksize);
}
/// Provides the block size of the cipher
/// \return the block size, in bytes
/// \details The sematics of BlockSize() is return DEFAULT_BLOCKSIZE if the default blocksize
/// is in effect. If the blocksize has changed, then the value returned is the BlockSize()
/// parameter used during SetKey().
/// \details DEFAULT_BLOCKSIZE should be paired with DEFAULT_KEYLENGTH, and it is the same as
/// BLOCKSIZE in a FixedBlockSize cipher.
virtual unsigned int BlockSize() const =0;
/// Provides the minimum block size of the cipher
/// \return the minimum block size, in bytes
/// \details MinBlockSize() returns the smallest blocksize a cipher can use. The size can
/// be affected by the key length. For example, Threefish has key sizes of 256, 512 and 1024 bits,
/// and the blocksize follows the key length. If a 512-bit key is used, then the block size is 512
/// bits. Once keyed, the minimum block size of 256 is not accurate, nor is a block size of 1024 bit.
virtual unsigned int MinBlockSize() const
{ return MIN_BLOCKSIZE; }
/// Provides the maximum block size of the cipher
/// \return the maximum block size, in bytes
/// \details MaxBlockSize() returns the largest blocksize a cipher can use. The size can
/// be affected by the key length. For example, Threefish has key sizes of 256, 512 and 1024 bits,
/// and the blocksize follows the key length. If a 512-bit key is used, then the block size is 512
/// bits. Once keyed, the minimum block size of 256 is not accurate, nor is a block size of 1024 bit.
virtual unsigned int MaxBlockSize() const
{ return MAX_BLOCKSIZE; }
/// Provides the initialization vector length of the cipher
/// \return the initialization vector length, in bytes
/// \details The sematics of IVSize() is return IV_LENGTH if the default blocksize is
/// in effect. If the blocksize has changed, then the default implentation returns the value of
/// the BlockSize() parameter used during SetKey().
/// \details Derived classes may override the behavior such that a different value is returned.
/// This may happen with a cipher that requires an IV that is twice the block size.
virtual unsigned int IVSize() const =0;
/// \brief Provides the minimum size of an IV
/// \return minimal length of IVs accepted by this cipher, in bytes
virtual unsigned int MinIVLength() const
{ return MIN_BLOCKSIZE; }
/// \brief Provides the maximum size of an IV
/// \return maximal length of IVs accepted by this cipher, in bytes
virtual unsigned int MaxIVLength() const
{ return MAX_BLOCKSIZE; }
};
// ************** key length *************** // ************** key length ***************
/// \class FixedKeyLength /// \class FixedKeyLength
@ -456,41 +339,6 @@ public:
unsigned int BlockSize() const {return this->BLOCKSIZE;} unsigned int BlockSize() const {return this->BLOCKSIZE;}
}; };
/// \class VariableBlockCipherImpl
/// \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for block ciphers with varibale block sizes
/// \tparam INFO a SimpleKeyingInterface derived class
/// \tparam BASE a SimpleKeyingInterface derived class
/// \details VariableBlockCipherImpl() provides a default implementation for block ciphers with varibale block sizes using AlgorithmImpl()
/// and SimpleKeyingInterfaceImpl().
/// \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl()
template <class INFO, class BASE = BlockCipher>
class CRYPTOPP_NO_VTABLE VariableBlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > >
{
public:
VariableBlockCipherImpl() : m_blocksize(0), m_ivlength(0) {}
VariableBlockCipherImpl(unsigned int blockSize) : m_blocksize(blockSize), m_ivlength(blockSize) {}
VariableBlockCipherImpl(unsigned int blockSize, unsigned int ivLength) : m_blocksize(blockSize), m_ivlength(ivLength) {}
/// Provides the block size of the algorithm
/// \returns the block size, in bytes
unsigned int BlockSize() const {
return m_blocksize ? m_blocksize :
static_cast<unsigned int>(this->DEFAULT_BLOCKSIZE);
}
/// Provides the initialization vector length of the algorithm
/// \returns the initialization vector length, in bytes
unsigned int IVSize() const {
if (!this->IsResynchronizable())
throw NotImplemented(this->GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");
return m_ivlength ? m_ivlength :
static_cast<unsigned int>(this->IV_LENGTH);
}
protected:
unsigned int m_blocksize, m_ivlength;
};
/// \class BlockCipherFinal /// \class BlockCipherFinal
/// \brief Provides class member functions to key a block cipher /// \brief Provides class member functions to key a block cipher
/// \tparam DIR a CipherDir /// \tparam DIR a CipherDir

View File

@ -431,7 +431,7 @@ static int has_small_order(const uint8_t s[32])
{ 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
}; };
CRYPTOPP_COMPILE_ASSERT(12 == COUNTOF(blacklist)); CRYPTOPP_COMPILE_ASSERT(12 == COUNTOF(blacklist));
uint8_t c[12] = { 0 }; uint8_t c[12] = { 0 };
for (size_t j = 0; j < 32; j++) { for (size_t j = 0; j < 32; j++) {
for (size_t i = 0; i < COUNTOF(blacklist); i++) { for (size_t i = 0; i < COUNTOF(blacklist); i++) {

View File

@ -2082,7 +2082,7 @@ bool TestModeIV(SymmetricCipher &e, SymmetricCipher &d)
const int BUF_SIZE=20480U; const int BUF_SIZE=20480U;
AlignedSecByteBlock plaintext(BUF_SIZE); AlignedSecByteBlock plaintext(BUF_SIZE);
for (unsigned int i=1; i<20480; i*=2) for (unsigned int i=1; i<BUF_SIZE; i*=2)
{ {
e.GetNextIV(GlobalRNG(), iv); e.GetNextIV(GlobalRNG(), iv);
if (iv == lastIV) if (iv == lastIV)

View File

@ -135,7 +135,7 @@ bool TestCryptoBox()
rc = crypto_box_beforenm(k, small_order_p, alicesk); rc = crypto_box_beforenm(k, small_order_p, alicesk);
pass = (rc != 0) && pass; pass = (rc != 0) && pass;
// Allow small order elements // Allow small order elements
rc = crypto_box_unchecked(c, m, 163, nonce, bobpk, alicesk); rc = crypto_box_unchecked(c, m, 163, nonce, bobpk, alicesk);