00001
00002
00003 #ifndef CRYPTOPP_LUBYRACK_H
00004 #define CRYPTOPP_LUBYRACK_H
00005
00006
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};};
00014
00015
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
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> >, public SimpledKeyed_Helper
00027 {
00028 public:
00029
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 GCC4FIX4 {S=T::DIGESTSIZE};
00042 unsigned int L;
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(outBlock, 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