- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# lubyrack.h

Go to the documentation of this file.

    00001 // lubyrack.h - written and placed in the public domain by Wei Dai
    00002
    00003 #ifndef CRYPTOPP_LUBYRACK_H
    00004 #define CRYPTOPP_LUBYRACK_H
    00005
    00006 /** \file */
    00007
    00008 #include "simple.h"
    00009 #include "secblock.h"
    00010
    00011 NAMESPACE_BEGIN(CryptoPP)
    00012
    00013 template <class T> struct DigestSizeDoubleWorkaround {enum {RESULT = 2*T::DIGESTSIZE};};        // VC60 workaround
    00014
    00015 //! algorithm info
    00016 template <class T>
    00017 struct LR_Info : public VariableKeyLength<16, 0, 2*(UINT_MAX/2), 2>, public FixedBlockSize<DigestSizeDoubleWorkaround<T>::RESULT>
    00018 {
    00019         static std::string StaticAlgorithmName() {return std::string("LR/")+T::StaticAlgorithmName();}
    00020 };
    00021
    00022 //! Luby-Rackoff
    00023 template <class T>
    00024 class LR : public LR_Info<T>, public BlockCipherDocumentation
    00025 {
    00026         class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<LR_Info<T> >
    00027         {
    00028         public:
    00029                 // VC60 workaround: have to define these functions within class definition
    00030                 void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length)
    00031                 {
    00032                         this->AssertValidKeyLength(length);
    00033
    00034                         L = length/2;
    00035                         buffer.New(2*S);
    00036                         digest.New(S);
    00037                         key.Assign(userKey, 2*L);
    00038                 }
    00039
    00040         protected:
    00041                 enum {S=T::DIGESTSIZE};
    00042                 unsigned int L; // key length / 2
    00043                 SecByteBlock key;
    00044
    00045                 mutable T hm;
    00046                 mutable SecByteBlock buffer, digest;
    00047         };
    00048
    00049         class CRYPTOPP_NO_VTABLE Enc : public Base
    00050         {
    00051         public:
    00052
    00053 #define KL this->key
    00054 #define KR this->key+this->L
    00055 #define BL this->buffer
    00056 #define BR this->buffer+this->S
    00057 #define IL inBlock
    00058 #define IR inBlock+this->S
    00059 #define OL outBlock
    00060 #define OR outBlock+this->S
    00061
    00062                 void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00063                 {
    00064                         this->hm.Update(KL, this->L);
    00065                         this->hm.Update(IL, this->S);
    00066                         this->hm.Final(BR);
    00067                         xorbuf(BR, IR, this->S);
    00068
    00069                         this->hm.Update(KR, this->L);
    00070                         this->hm.Update(BR, this->S);
    00071                         this->hm.Final(BL);
    00072                         xorbuf(BL, IL, this->S);
    00073
    00074                         this->hm.Update(KL, this->L);
    00075                         this->hm.Update(BL, this->S);
    00076                         this->hm.Final(this->digest);
    00077                         xorbuf(BR, this->digest, this->S);
    00078
    00079                         this->hm.Update(KR, this->L);
    00080                         this->hm.Update(OR, this->S);
    00081                         this->hm.Final(this->digest);
    00082                         xorbuf(BL, this->digest, this->S);
    00083
    00084                         if (xorBlock)
    00085                                 xorbuf(outBlock, xorBlock, this->buffer, 2*this->S);
    00086                         else
    00087                                 memcpy_s(outBlock, 2*this->S, this->buffer, 2*this->S);
    00088                 }
    00089         };
    00090
    00091         class CRYPTOPP_NO_VTABLE Dec : public Base
    00092         {
    00093         public:
    00094                 void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00095                 {
    00096                         this->hm.Update(KR, this->L);
    00097                         this->hm.Update(IR, this->S);
    00098                         this->hm.Final(BL);
    00099                         xorbuf(BL, IL, this->S);
    00100
    00101                         this->hm.Update(KL, this->L);
    00102                         this->hm.Update(BL, this->S);
    00103                         this->hm.Final(BR);
    00104                         xorbuf(BR, IR, this->S);
    00105
    00106                         this->hm.Update(KR, this->L);
    00107                         this->hm.Update(BR, this->S);
    00108                         this->hm.Final(this->digest);
    00109                         xorbuf(BL, this->digest, this->S);
    00110
    00111                         this->hm.Update(KL, this->L);
    00112                         this->hm.Update(OL, this->S);
    00113                         this->hm.Final(this->digest);
    00114                         xorbuf(BR, this->digest, this->S);
    00115
    00116                         if (xorBlock)
    00117                                 xorbuf(outBlock, xorBlock, this->buffer, 2*this->S);
    00118                         else
    00119                                 memcpy(outBlock, this->buffer, 2*this->S);
    00120                 }
    00121 #undef KL
    00122 #undef KR
    00123 #undef BL
    00124 #undef BR
    00125 #undef IL
    00126 #undef IR
    00127 #undef OL
    00128 #undef OR
    00129         };
    00130
    00131 public:
    00132         typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
    00133         typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
    00134 };
    00135
    00136 NAMESPACE_END
    00137
    00138 #endif