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