Hey everyone,
I've already posted this one in the 6.0 implementation request thread
and pose it here for further discussion. It shows how I've solved the
issue of tweakable block ciphers so far.
My proposal is the following (can be viewed in my CryptoJPM repo).
The proposal mainly orientates at the established mechanisms used for
adding keys to transformations. All of these lines are supposed to be
placed near their counterparts, meaning the twakableblockcipher stuff
should be placed near the blockcipher stuff and the simpletweaking stuff
should be placed near the keying stuff. I've further taken care to
ensure every TweakableBlockCipher can still be used for doing standard
block cipher stuff and that the tweak can be easily changed (that's why
it's part of the process block function).
BR
JPM
*******
In Cryptlib.h:
//! keying interface for crypto algorithms that take byte strings as keys
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleTweakingInterface
{
public:
virtual ~SimpleTweakingInterface() {}
//! returns smallest valid tweak length in bytes */
virtual size_t MinTweakLength() const =0;
//! returns largest valid tweak length in bytes */
virtual size_t MaxTweakLength() const =0;
//! returns default (recommended) tweak length in bytes */
virtual size_t DefaultTweakLength() const =0;
//! returns the smallest valid tweak length in bytes that is >= min(n,
GetMaxTweakLength())
virtual size_t GetValidTweakLength(size_t n) const =0;
//! returns whether n is a valid tweak length
virtual bool IsValidTweakLength(size_t n) const
{return n == GetValidTweakLength(n);}
protected:
virtual const Algorithm & GetAlgorithm() const =0;
void ThrowIfInvalidTweakLength(size_t length);
inline void AssertValidTweakLength(size_t length) const
{assert(IsValidTweakLength(length));}
};
//! interface for one direction (encryption or decryption) of a tweakable block
cipher
/*! \note These objects usually should not be used directly. See
BlockTransformation for more details. */
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TweakableBlockCipher : public
BlockCipher, public SimpleTweakingInterface
{
public:
//! only initializes the dummy tweak
TweakableBlockCipher() {m_FakeTweak.CleanNew(DefaultTweakLength());}
//! encrypt or decrypt inBlock using Tweak of length TweakLength, xor
with xorBlock and write to outBlock
virtual void ProcessAndXorBlockWithTweak(const byte *inBlock, const
byte *xorBlock, byte *outBlock,const byte* Tweak,const size_t TweakLength)
const =0;
//! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock
virtual void ProcessAndXorBlock(const byte *inBlock, const byte
*xorBlock, byte *outBlock) const;
protected:
const Algorithm & GetAlgorithm() const {return *this;}
SecBlock<byte> m_FakeTweak;
};
In cryptlib.cpp:
void TweakableBlockCipher::ProcessAndXorBlock(const byte *inBlock, const byte
*xorBlock, byte *outBlock) const
{
ProcessAndXorBlockWithTweak(inBlock,xorBlock,outBlock,m_FakeTweak,m_FakeTweak.size());
}
In seckey.h:
// ************** tweak length ***************
//! to be inherited by keyed algorithms with fixed tweak length
template <unsigned int N>
class FixedTweakLength
{
public:
CRYPTOPP_CONSTANT(TWEAKLENGTH=N)
CRYPTOPP_CONSTANT(MIN_TWEAKLENGTH=N)
CRYPTOPP_CONSTANT(MAX_TWEAKLENGTH=N)
CRYPTOPP_CONSTANT(DEFAULT_TWEAKLENGTH=N)
static size_t CRYPTOPP_API StaticGetValidTweakLength(size_t) {return
TWEAKLENGTH;}
};
/// support query of variable tweak length, template parameters are default,
min, max, multiple (default multiple 1)
template <unsigned int D, unsigned int N, unsigned int M, unsigned int Q = 1>
class VariableTweakLength
{
// make these private to avoid Doxygen documenting them in all derived
classes
CRYPTOPP_COMPILE_ASSERT(Q > 0);
CRYPTOPP_COMPILE_ASSERT(N % Q == 0);
CRYPTOPP_COMPILE_ASSERT(M % Q == 0);
CRYPTOPP_COMPILE_ASSERT(N < M);
CRYPTOPP_COMPILE_ASSERT(D >= N);
CRYPTOPP_COMPILE_ASSERT(M >= D);
public:
CRYPTOPP_CONSTANT(MIN_TWEAKLENGTH=N)
CRYPTOPP_CONSTANT(MAX_TWEAKLENGTH=M)
CRYPTOPP_CONSTANT(DEFAULT_TWEAKLENGTH=D)
CRYPTOPP_CONSTANT(TWEAKLENGTH_MULTIPLE=Q)
static size_t CRYPTOPP_API StaticGetValidTweakLength(size_t n)
{
if (n < (size_t)MIN_TWEAKLENGTH)
return MIN_TWEAKLENGTH;
else if (n > (size_t)MAX_TWEAKLENGTH)
return (size_t)MAX_TWEAKLENGTH;
else
{
n += TWEAKLENGTH_MULTIPLE-1;
return n - n%TWEAKLENGTH_MULTIPLE;
}
}
};
//! These objects usually should not be used directly. See
CipherModeDocumentation instead.
/*! Each class derived from this one defines two types, Encryption and
Decryption,
both of which implement the TweakableBlockCipher interface. */
struct TweakableBlockCipherDocumentation
{
//! implements the TweakableBlockCipher interface
typedef TweakableBlockCipher Encryption;
//! implements the TweakableBlockCipher interface
typedef TweakableBlockCipher Decryption;
};
--
--
You received this message because you are subscribed to the "Crypto++ Users"
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at
http://www.cryptopp.com.
---
You received this message because you are subscribed to the Google Groups
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.