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.

Reply via email to