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
00014 {
00015 CRYPTOPP_CONSTANT(RESULT = 2*T::DIGESTSIZE)
00016 };
00017
00018
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
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
00033 void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms)
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;
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