Crypto++
|
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 ¶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; // 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