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