1 // lubyrack.h - originally written and placed in the public domain by Wei Dai 2 3 /// \file lubyrack.h 4 /// \brief Classes for the Luby-Rackoff block cipher 5 6 #ifndef CRYPTOPP_LUBYRACK_H 7 #define CRYPTOPP_LUBYRACK_H 8 9 #include "simple.h" 10 #include "secblock.h" 11 12 NAMESPACE_BEGIN(CryptoPP) 13 14 /// \brief Luby-Rackoff block cipher information 15 template <class T> 16 struct LR_Info : public VariableKeyLength<16, 0, 2*(INT_MAX/2), 2>, public FixedBlockSize<2*T::DIGESTSIZE> 17 { 18 static std::string StaticAlgorithmName() {return std::string("LR/")+T::StaticAlgorithmName();} 19 }; 20 21 /// \brief Luby-Rackoff block cipher 22 template <class T> 23 class LR : public LR_Info<T>, public BlockCipherDocumentation 24 { 25 class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<LR_Info<T> > 26 { 27 public: 28 // VC60 workaround: have to define these functions within class definition 29 void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) 30 { 31 this->AssertValidKeyLength(length); 32 33 L = length/2; 34 buffer.New(2*S); 35 digest.New(S); 36 key.Assign(userKey, 2*L); 37 } 38 39 protected: 40 CRYPTOPP_CONSTANT(S=T::DIGESTSIZE); 41 unsigned int L; // key length / 2 42 SecByteBlock key; 43 44 mutable T hm; 45 mutable SecByteBlock buffer, digest; 46 }; 47 48 class CRYPTOPP_NO_VTABLE Enc : public Base 49 { 50 public: 51 52 #define KL this->key 53 #define KR this->key+this->L 54 #define BL this->buffer 55 #define BR this->buffer+this->S 56 #define IL inBlock 57 #define IR inBlock+this->S 58 #define OL outBlock 59 #define OR outBlock+this->S 60 61 void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 62 { 63 this->hm.Update(KL, this->L); 64 this->hm.Update(IL, this->S); 65 this->hm.Final(BR); 66 xorbuf(BR, IR, this->S); 67 68 this->hm.Update(KR, this->L); 69 this->hm.Update(BR, this->S); 70 this->hm.Final(BL); 71 xorbuf(BL, IL, this->S); 72 73 this->hm.Update(KL, this->L); 74 this->hm.Update(BL, this->S); 75 this->hm.Final(this->digest); 76 xorbuf(BR, this->digest, this->S); 77 78 this->hm.Update(KR, this->L); 79 this->hm.Update(OR, this->S); 80 this->hm.Final(this->digest); 81 xorbuf(BL, this->digest, this->S); 82 83 if (xorBlock) 84 xorbuf(outBlock, xorBlock, this->buffer, 2*this->S); 85 else 86 memcpy_s(outBlock, 2*this->S, this->buffer, 2*this->S); 87 } 88 }; 89 90 class CRYPTOPP_NO_VTABLE Dec : public Base 91 { 92 public: 93 void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 94 { 95 this->hm.Update(KR, this->L); 96 this->hm.Update(IR, this->S); 97 this->hm.Final(BL); 98 xorbuf(BL, IL, this->S); 99 100 this->hm.Update(KL, this->L); 101 this->hm.Update(BL, this->S); 102 this->hm.Final(BR); 103 xorbuf(BR, IR, this->S); 104 105 this->hm.Update(KR, this->L); 106 this->hm.Update(BR, this->S); 107 this->hm.Final(this->digest); 108 xorbuf(BL, this->digest, this->S); 109 110 this->hm.Update(KL, this->L); 111 this->hm.Update(OL, this->S); 112 this->hm.Final(this->digest); 113 xorbuf(BR, this->digest, this->S); 114 115 if (xorBlock) 116 xorbuf(outBlock, xorBlock, this->buffer, 2*this->S); 117 else 118 memcpy(outBlock, this->buffer, 2*this->S); 119 } 120 #undef KL 121 #undef KR 122 #undef BL 123 #undef BR 124 #undef IL 125 #undef IR 126 #undef OL 127 #undef OR 128 }; 129 130 public: 131 typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; 132 typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; 133 }; 134 135 NAMESPACE_END 136 137 #endif 138