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> >
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 {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