parent
93fb412215
commit
4b3560baef
|
|
@ -14,9 +14,9 @@ Currently the library contains the following algorithms:
|
|||
AES and AES candidates AES (Rijndael), RC6, MARS, Twofish, Serpent,
|
||||
CAST-256
|
||||
|
||||
ARIA, IDEA, Triple-DES (DES-EDE2 and DES-EDE3),
|
||||
other block ciphers Camellia, SEED, Kalyna, RC5, Blowfish, TEA, XTEA,
|
||||
Threefish, Skipjack, SHACAL-2
|
||||
ARIA, IDEA, Blowfish, Triple-DES (DES-EDE2 and
|
||||
other block ciphers DES-EDE3), Camellia, SEED, Kalyna, RC5, SPECK-64,
|
||||
SPECK-128, Threefish, Skipjack, SHACAL-2, TEA, XTEA
|
||||
|
||||
block cipher modes of operation ECB, CBC, CBC ciphertext stealing (CTS),
|
||||
CFB, OFB, counter mode (CTR)
|
||||
|
|
|
|||
392
speck.cpp
392
speck.cpp
|
|
@ -18,108 +18,138 @@ using CryptoPP::rotrFixed;
|
|||
using CryptoPP::rotlVariable;
|
||||
using CryptoPP::rotrVariable;
|
||||
|
||||
//! \brief Forward round transformation
|
||||
//! \tparam W word type
|
||||
template <class W>
|
||||
inline void TF83(W& x, W& y, const W& k)
|
||||
{
|
||||
x = rotrFixed(x, 8);
|
||||
x += y; x ^= k;
|
||||
y = rotlFixed(y, 3);
|
||||
y ^= x;
|
||||
x = rotrFixed(x, 8);
|
||||
x += y; x ^= k;
|
||||
y = rotlFixed(y, 3);
|
||||
y ^= x;
|
||||
}
|
||||
|
||||
//! \brief Reverse round transformation
|
||||
//! \tparam W word type
|
||||
template <class W>
|
||||
inline void TR83(W& x, W& y, const W& k)
|
||||
{
|
||||
y^=x;
|
||||
y=rotrFixed(y,3);
|
||||
x^=k;
|
||||
x-=y;
|
||||
x=rotlFixed(x,8);
|
||||
y^=x;
|
||||
y=rotrFixed(y,3);
|
||||
x^=k; x-=y;
|
||||
x=rotlFixed(x,8);
|
||||
}
|
||||
|
||||
// W is word type
|
||||
// R is number of rounds
|
||||
// p = plain text, k = key, c = cipher text
|
||||
//! \brief Forward transformation
|
||||
//! \tparam W word type
|
||||
//! \tparam R number of rounds
|
||||
//! \param c output array
|
||||
//! \param p input array
|
||||
//! \param k subkey array
|
||||
template <class W, unsigned int R>
|
||||
inline void SPECK_Encrypt(W c[2], const W p[2], const W k[R])
|
||||
{
|
||||
c[0]=p[0]; c[1]=p[1];
|
||||
c[0]=p[0]; c[1]=p[1];
|
||||
|
||||
// Don't unroll this loop. Things slow down.
|
||||
for(W i=0; static_cast<int>(i)<R; ++i)
|
||||
TF83(c[0], c[1], k[i]);
|
||||
// Don't unroll this loop. Things slow down.
|
||||
for(W i=0; static_cast<int>(i)<R; ++i)
|
||||
TF83(c[0], c[1], k[i]);
|
||||
}
|
||||
|
||||
//! \brief Reverse transformation
|
||||
//! \tparam W word type
|
||||
//! \tparam R number of rounds
|
||||
//! \param p output array
|
||||
//! \param c input array
|
||||
//! \param k subkey array
|
||||
template <class W, unsigned int R>
|
||||
inline void SPECK_Decrypt(W p[2], const W c[2], const W k[R])
|
||||
{
|
||||
p[0]=c[0]; p[1]=c[1];
|
||||
p[0]=c[0]; p[1]=c[1];
|
||||
|
||||
// Don't unroll this loop. Things slow down.
|
||||
for(W i=R-1; static_cast<int>(i)>=0; --i)
|
||||
TR83(p[0], p[1], k[i]);
|
||||
// Don't unroll this loop. Things slow down.
|
||||
for(W i=R-1; static_cast<int>(i)>=0; --i)
|
||||
TR83(p[0], p[1], k[i]);
|
||||
}
|
||||
|
||||
//! \brief Subkey generation function
|
||||
//! \details Used when the user key consists of 2 words
|
||||
//! \tparam W word type
|
||||
//! \tparam R number of rounds
|
||||
//! \param key empty subkey array
|
||||
//! \param k user key array
|
||||
template <class W, unsigned int R>
|
||||
inline void SPECK_RoundKeys_2W(W key[R], const W k[2])
|
||||
{
|
||||
CRYPTOPP_ASSERT(R==32);
|
||||
W i=0, B=k[1], A=k[0];
|
||||
CRYPTOPP_ASSERT(R==32);
|
||||
W i=0, B=k[1], A=k[0];
|
||||
|
||||
while(i<R-1)
|
||||
{
|
||||
key[i]=A; TF83(B, A, i);
|
||||
i++;
|
||||
}
|
||||
key[R-1]=A;
|
||||
while(i<R-1)
|
||||
{
|
||||
key[i]=A; TF83(B, A, i);
|
||||
i++;
|
||||
}
|
||||
key[R-1]=A;
|
||||
}
|
||||
|
||||
//! \brief Subkey generation function
|
||||
//! \details Used when the user key consists of 3 words
|
||||
//! \tparam W word type
|
||||
//! \tparam R number of rounds
|
||||
//! \param key empty subkey array
|
||||
//! \param k user key array
|
||||
template <class W, unsigned int R>
|
||||
inline void SPECK_RoundKeys_3W(W key[R], const W k[3])
|
||||
{
|
||||
CRYPTOPP_ASSERT(R==33 || R==26);
|
||||
W i=0, C=k[2], B=k[1], A=k[0];
|
||||
CRYPTOPP_ASSERT(R==33 || R==26);
|
||||
W i=0, C=k[2], B=k[1], A=k[0];
|
||||
|
||||
unsigned int blocks = R/2;
|
||||
while(blocks--)
|
||||
{
|
||||
key[i+0]=A; TF83(B, A, i+0);
|
||||
key[i+1]=A; TF83(C, A, i+1);
|
||||
i+=2;
|
||||
}
|
||||
unsigned int blocks = R/2;
|
||||
while(blocks--)
|
||||
{
|
||||
key[i+0]=A; TF83(B, A, i+0);
|
||||
key[i+1]=A; TF83(C, A, i+1);
|
||||
i+=2;
|
||||
}
|
||||
|
||||
// The constexpr residue should allow the optimizer to remove unneeded statements
|
||||
if(R%2 == 1)
|
||||
{
|
||||
key[R-1]=A;
|
||||
}
|
||||
// The constexpr residue should allow the optimizer to remove unneeded statements
|
||||
if(R%2 == 1)
|
||||
{
|
||||
key[R-1]=A;
|
||||
}
|
||||
}
|
||||
|
||||
//! \brief Subkey generation function
|
||||
//! \details Used when the user key consists of 4 words
|
||||
//! \tparam W word type
|
||||
//! \tparam R number of rounds
|
||||
//! \param key empty subkey array
|
||||
//! \param k user key array
|
||||
template <class W, unsigned int R>
|
||||
inline void SPECK_RoundKeys_4W(W key[R], const W k[4])
|
||||
{
|
||||
CRYPTOPP_ASSERT(R==34 || R==27);
|
||||
W i=0, D=k[3], C=k[2], B=k[1], A=k[0];
|
||||
CRYPTOPP_ASSERT(R==34 || R==27);
|
||||
W i=0, D=k[3], C=k[2], B=k[1], A=k[0];
|
||||
|
||||
unsigned int blocks = R/3;
|
||||
while(blocks--)
|
||||
{
|
||||
key[i+0]=A; TF83(B, A, i+0);
|
||||
key[i+1]=A; TF83(C, A, i+1);
|
||||
key[i+2]=A; TF83(D, A, i+2);
|
||||
i+=3;
|
||||
}
|
||||
unsigned int blocks = R/3;
|
||||
while(blocks--)
|
||||
{
|
||||
key[i+0]=A; TF83(B, A, i+0);
|
||||
key[i+1]=A; TF83(C, A, i+1);
|
||||
key[i+2]=A; TF83(D, A, i+2);
|
||||
i+=3;
|
||||
}
|
||||
|
||||
// The constexpr residue should allow the optimizer to remove unneeded statements
|
||||
if(R%3 == 1)
|
||||
{
|
||||
key[R-1]=A;
|
||||
}
|
||||
else if(R%3 == 2)
|
||||
{
|
||||
key[R-2]=A; TF83(B, A, W(R-2));
|
||||
key[R-1]=A;
|
||||
}
|
||||
// The constexpr residue should allow the optimizer to remove unneeded statements
|
||||
if(R%3 == 1)
|
||||
{
|
||||
key[R-1]=A;
|
||||
}
|
||||
else if(R%3 == 2)
|
||||
{
|
||||
key[R-2]=A; TF83(B, A, W(R-2));
|
||||
key[R-1]=A;
|
||||
}
|
||||
}
|
||||
|
||||
ANONYMOUS_NAMESPACE_END
|
||||
|
|
@ -128,169 +158,169 @@ NAMESPACE_BEGIN(CryptoPP)
|
|||
|
||||
void SPECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms)
|
||||
{
|
||||
CRYPTOPP_ASSERT(keyLength == 12 || keyLength == 16);
|
||||
CRYPTOPP_ASSERT(keyLength == 12 || keyLength == 16);
|
||||
|
||||
// Building the key schedule table requires {3,4} words workspace.
|
||||
// Encrypting and decrypting requires 4 words workspace.
|
||||
m_kwords = keyLength/sizeof(word32);
|
||||
m_wspace.New(STDMAX(m_kwords,4U));
|
||||
// Building the key schedule table requires {3,4} words workspace.
|
||||
// Encrypting and decrypting requires 4 words workspace.
|
||||
m_kwords = keyLength/sizeof(word32);
|
||||
m_wspace.New(STDMAX(m_kwords,4U));
|
||||
|
||||
// Avoid GetUserKey. SPECK does unusual things with key string and word ordering
|
||||
// {A,B} -> {B,A}, {A,B,C} -> {C,B,A}, etc.
|
||||
typedef GetBlock<word32, BigEndian, false> InBlock;
|
||||
InBlock iblk(userKey);
|
||||
// Avoid GetUserKey. SPECK does unusual things with key string and word ordering
|
||||
// {A,B} -> {B,A}, {A,B,C} -> {C,B,A}, etc.
|
||||
typedef GetBlock<word32, BigEndian, false> InBlock;
|
||||
InBlock iblk(userKey);
|
||||
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 3:
|
||||
m_rkey.New(26);
|
||||
iblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_3W<word32, 26>(m_rkey, m_wspace);
|
||||
break;
|
||||
case 4:
|
||||
m_rkey.New(27);
|
||||
iblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_4W<word32, 27>(m_rkey, m_wspace);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 3:
|
||||
m_rkey.New(26);
|
||||
iblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_3W<word32, 26>(m_rkey, m_wspace);
|
||||
break;
|
||||
case 4:
|
||||
m_rkey.New(27);
|
||||
iblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_4W<word32, 27>(m_rkey, m_wspace);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
}
|
||||
|
||||
void SPECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef GetBlock<word32, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
|
||||
typedef GetBlock<word32, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
|
||||
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 3:
|
||||
SPECK_Encrypt<word32, 26>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 4:
|
||||
SPECK_Encrypt<word32, 27>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 3:
|
||||
SPECK_Encrypt<word32, 26>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 4:
|
||||
SPECK_Encrypt<word32, 27>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef PutBlock<word32, BigEndian, false> OutBlock;
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
|
||||
}
|
||||
|
||||
void SPECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef GetBlock<word32, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
|
||||
typedef GetBlock<word32, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
|
||||
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 3:
|
||||
SPECK_Decrypt<word32, 26>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 4:
|
||||
SPECK_Decrypt<word32, 27>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 3:
|
||||
SPECK_Decrypt<word32, 26>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 4:
|
||||
SPECK_Decrypt<word32, 27>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef PutBlock<word32, BigEndian, false> OutBlock;
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
void SPECK128::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms)
|
||||
{
|
||||
CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32);
|
||||
CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32);
|
||||
|
||||
// Building the key schedule table requires {2,3,4} words workspace.
|
||||
// Encrypting and decrypting requires 4 words workspace.
|
||||
m_kwords = keyLength/sizeof(word64);
|
||||
m_wspace.New(STDMAX(m_kwords,4U));
|
||||
// Building the key schedule table requires {2,3,4} words workspace.
|
||||
// Encrypting and decrypting requires 4 words workspace.
|
||||
m_kwords = keyLength/sizeof(word64);
|
||||
m_wspace.New(STDMAX(m_kwords,4U));
|
||||
|
||||
// Avoid GetUserKey. SPECK does unusual things with key string and word ordering
|
||||
// {A,B} -> {B,A}, {A,B,C} -> {C,B,A}, etc.
|
||||
typedef GetBlock<word64, BigEndian, false> InBlock;
|
||||
InBlock iblk(userKey);
|
||||
// Avoid GetUserKey. SPECK does unusual things with key string and word ordering
|
||||
// {A,B} -> {B,A}, {A,B,C} -> {C,B,A}, etc.
|
||||
typedef GetBlock<word64, BigEndian, false> InBlock;
|
||||
InBlock iblk(userKey);
|
||||
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 2:
|
||||
m_rkey.New(32);
|
||||
iblk(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_2W<word64, 32>(m_rkey, m_wspace);
|
||||
break;
|
||||
case 3:
|
||||
m_rkey.New(33);
|
||||
iblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_3W<word64, 33>(m_rkey, m_wspace);
|
||||
break;
|
||||
case 4:
|
||||
m_rkey.New(34);
|
||||
iblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_4W<word64, 34>(m_rkey, m_wspace);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 2:
|
||||
m_rkey.New(32);
|
||||
iblk(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_2W<word64, 32>(m_rkey, m_wspace);
|
||||
break;
|
||||
case 3:
|
||||
m_rkey.New(33);
|
||||
iblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_3W<word64, 33>(m_rkey, m_wspace);
|
||||
break;
|
||||
case 4:
|
||||
m_rkey.New(34);
|
||||
iblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
SPECK_RoundKeys_4W<word64, 34>(m_rkey, m_wspace);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
}
|
||||
|
||||
void SPECK128::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef GetBlock<word64, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
|
||||
typedef GetBlock<word64, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
|
||||
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 2:
|
||||
SPECK_Encrypt<word64, 32>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 3:
|
||||
SPECK_Encrypt<word64, 33>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 4:
|
||||
SPECK_Encrypt<word64, 34>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 2:
|
||||
SPECK_Encrypt<word64, 32>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 3:
|
||||
SPECK_Encrypt<word64, 33>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 4:
|
||||
SPECK_Encrypt<word64, 34>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef PutBlock<word64, BigEndian, false> OutBlock;
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
|
||||
}
|
||||
|
||||
void SPECK128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef GetBlock<word64, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
|
||||
typedef GetBlock<word64, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
|
||||
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 2:
|
||||
SPECK_Decrypt<word64, 32>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 3:
|
||||
SPECK_Decrypt<word64, 33>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 4:
|
||||
SPECK_Decrypt<word64, 34>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
switch (m_kwords)
|
||||
{
|
||||
case 2:
|
||||
SPECK_Decrypt<word64, 32>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 3:
|
||||
SPECK_Decrypt<word64, 33>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
case 4:
|
||||
SPECK_Decrypt<word64, 34>(m_wspace+2, m_wspace+0, m_rkey);
|
||||
break;
|
||||
default:
|
||||
CRYPTOPP_ASSERT(0);;
|
||||
}
|
||||
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef PutBlock<word64, BigEndian, false> OutBlock;
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
|
|||
87
speck.h
87
speck.h
|
|
@ -21,6 +21,9 @@ NAMESPACE_BEGIN(CryptoPP)
|
|||
//! \class SPECK_Info
|
||||
//! \brief SPECK block cipher information
|
||||
//! \tparam BS block size of the cipher, in bytes
|
||||
//! \tparam D default key length, in bytes
|
||||
//! \tparam N minimum key length, in bytes
|
||||
//! \tparam M maximum key length, in bytes
|
||||
//! \since Crypto++ 6.0
|
||||
template <unsigned int BS, unsigned int D, unsigned int N, unsigned int M>
|
||||
struct SPECK_Info : public FixedBlockSize<BS>, VariableKeyLength<D, N, M>
|
||||
|
|
@ -35,23 +38,25 @@ struct SPECK_Info : public FixedBlockSize<BS>, VariableKeyLength<D, N, M>
|
|||
//! \class SPECK_Base
|
||||
//! \brief SPECK block cipher base class
|
||||
//! \tparam BS block size of the cipher, in bytes
|
||||
//! \details User code should use SPECK128, SPECK512, SPECK1024
|
||||
//! \sa SPECK32, SPECK48, SPECK64, SPECK96, SPECK128, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a>
|
||||
//! \details User code should use SPECK64 or SPECK128
|
||||
//! \sa SPECK64, SPECK128, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a>
|
||||
//! \since Crypto++ 6.0
|
||||
template <class W>
|
||||
struct SPECK_Base
|
||||
{
|
||||
virtual ~SPECK_Base() {}
|
||||
|
||||
typedef SecBlock<W, AllocatorWithCleanup<W, true> > AlignedSecBlock;
|
||||
mutable AlignedSecBlock m_wspace; // workspace
|
||||
AlignedSecBlock m_rkey; // round keys
|
||||
unsigned int m_kwords; // number of key words
|
||||
unsigned int m_kwords; // number of key words
|
||||
};
|
||||
|
||||
//! \class SPECK64
|
||||
//! \brief SPECK 64-bit block cipher
|
||||
//! \details SPECK64 provides 64-bit block size. The valid key sizes are 98-bit and 128-bit.
|
||||
//! \note Crypto++ provides a byte oriented implementation
|
||||
//! \sa SPECK32, SPECK64, and SPECK128, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a>
|
||||
//! \sa SPECK64, SPECK128, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a>
|
||||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE SPECK64 : public SPECK_Info<8, 12, 12, 16>, public BlockCipherDocumentation
|
||||
{
|
||||
|
|
@ -61,26 +66,34 @@ public:
|
|||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE Base : protected SPECK_Base<word32>, public BlockCipherImpl<SPECK_Info<8, 12, 12, 16> >
|
||||
{
|
||||
public:
|
||||
std::string AlgorithmName() const {
|
||||
return StaticAlgorithmName() + "(" + IntToString(m_kwords*sizeof(word32)*8) + ")";
|
||||
}
|
||||
public:
|
||||
std::string AlgorithmName() const {
|
||||
return StaticAlgorithmName() + "(" + IntToString(m_kwords*sizeof(word32)*8) + ")";
|
||||
}
|
||||
|
||||
protected:
|
||||
void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms);
|
||||
};
|
||||
|
||||
class CRYPTOPP_NO_VTABLE Enc : public Base
|
||||
{
|
||||
protected:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
//! \brief Provides implementation for encryption transformation
|
||||
//! \details Enc provides implementation for encryption transformation. All key
|
||||
//! sizes are supported.
|
||||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE Enc : public Base
|
||||
{
|
||||
protected:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
class CRYPTOPP_NO_VTABLE Dec : public Base
|
||||
{
|
||||
protected:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
//! \brief Provides implementation for encryption transformation
|
||||
//! \details Dec provides implementation for decryption transformation. All key
|
||||
//! sizes are supported.
|
||||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE Dec : public Base
|
||||
{
|
||||
protected:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
|
||||
typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
|
||||
|
|
@ -90,7 +103,7 @@ public:
|
|||
//! \brief SPECK 128-bit block cipher
|
||||
//! \details SPECK128 provides 128-bit block size. The valid key sizes are 128-bit, 192-bit and 256-bit.
|
||||
//! \note Crypto++ provides a byte oriented implementation
|
||||
//! \sa SPECK32, SPECK64, and SPECK128, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a>
|
||||
//! \sa SPECK64, SPECK128, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a>
|
||||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE SPECK128 : public SPECK_Info<16, 16, 16, 32>, public BlockCipherDocumentation
|
||||
{
|
||||
|
|
@ -100,26 +113,34 @@ public:
|
|||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE Base : protected SPECK_Base<word64>, public BlockCipherImpl<SPECK_Info<16, 16, 16, 32> >
|
||||
{
|
||||
public:
|
||||
std::string AlgorithmName() const {
|
||||
return StaticAlgorithmName() + "(" + IntToString(sizeof(word64)*8) + ")";
|
||||
}
|
||||
public:
|
||||
std::string AlgorithmName() const {
|
||||
return StaticAlgorithmName() + "(" + IntToString(sizeof(word64)*8) + ")";
|
||||
}
|
||||
|
||||
protected:
|
||||
void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms);
|
||||
};
|
||||
|
||||
class CRYPTOPP_NO_VTABLE Enc : public Base
|
||||
{
|
||||
protected:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
//! \brief Provides implementation for encryption transformation
|
||||
//! \details Enc provides implementation for encryption transformation. All key
|
||||
//! sizes are supported.
|
||||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE Enc : public Base
|
||||
{
|
||||
protected:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
class CRYPTOPP_NO_VTABLE Dec : public Base
|
||||
{
|
||||
protected:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
//! \brief Provides implementation for encryption transformation
|
||||
//! \details Dec provides implementation for decryption transformation. All key
|
||||
//! sizes are supported.
|
||||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE Dec : public Base
|
||||
{
|
||||
protected:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
|
||||
typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
|
||||
|
|
|
|||
Loading…
Reference in New Issue