summaryrefslogtreecommitdiffstats
path: root/CryptoPP/lubyrack.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CryptoPP/lubyrack.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/CryptoPP/lubyrack.h b/CryptoPP/lubyrack.h
new file mode 100644
index 000000000..e8fd2f748
--- /dev/null
+++ b/CryptoPP/lubyrack.h
@@ -0,0 +1,141 @@
+// lubyrack.h - written and placed in the public domain by Wei Dai
+
+#ifndef CRYPTOPP_LUBYRACK_H
+#define CRYPTOPP_LUBYRACK_H
+
+/** \file */
+
+#include "simple.h"
+#include "secblock.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+template <class T> struct DigestSizeDoubleWorkaround // VC60 workaround
+{
+ CRYPTOPP_CONSTANT(RESULT = 2*T::DIGESTSIZE)
+};
+
+//! algorithm info
+template <class T>
+struct LR_Info : public VariableKeyLength<16, 0, 2*(INT_MAX/2), 2>, public FixedBlockSize<DigestSizeDoubleWorkaround<T>::RESULT>
+{
+ static std::string StaticAlgorithmName() {return std::string("LR/")+T::StaticAlgorithmName();}
+};
+
+//! Luby-Rackoff
+template <class T>
+class LR : public LR_Info<T>, public BlockCipherDocumentation
+{
+ class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<LR_Info<T> >
+ {
+ public:
+ // VC60 workaround: have to define these functions within class definition
+ void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &params)
+ {
+ this->AssertValidKeyLength(length);
+
+ L = length/2;
+ buffer.New(2*S);
+ digest.New(S);
+ key.Assign(userKey, 2*L);
+ }
+
+ protected:
+ CRYPTOPP_CONSTANT(S=T::DIGESTSIZE)
+ unsigned int L; // key length / 2
+ SecByteBlock key;
+
+ mutable T hm;
+ mutable SecByteBlock buffer, digest;
+ };
+
+ class CRYPTOPP_NO_VTABLE Enc : public Base
+ {
+ public:
+
+#define KL this->key
+#define KR this->key+this->L
+#define BL this->buffer
+#define BR this->buffer+this->S
+#define IL inBlock
+#define IR inBlock+this->S
+#define OL outBlock
+#define OR outBlock+this->S
+
+ void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
+ {
+ this->hm.Update(KL, this->L);
+ this->hm.Update(IL, this->S);
+ this->hm.Final(BR);
+ xorbuf(BR, IR, this->S);
+
+ this->hm.Update(KR, this->L);
+ this->hm.Update(BR, this->S);
+ this->hm.Final(BL);
+ xorbuf(BL, IL, this->S);
+
+ this->hm.Update(KL, this->L);
+ this->hm.Update(BL, this->S);
+ this->hm.Final(this->digest);
+ xorbuf(BR, this->digest, this->S);
+
+ this->hm.Update(KR, this->L);
+ this->hm.Update(OR, this->S);
+ this->hm.Final(this->digest);
+ xorbuf(BL, this->digest, this->S);
+
+ if (xorBlock)
+ xorbuf(outBlock, xorBlock, this->buffer, 2*this->S);
+ else
+ memcpy_s(outBlock, 2*this->S, this->buffer, 2*this->S);
+ }
+ };
+
+ class CRYPTOPP_NO_VTABLE Dec : public Base
+ {
+ public:
+ void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
+ {
+ this->hm.Update(KR, this->L);
+ this->hm.Update(IR, this->S);
+ this->hm.Final(BL);
+ xorbuf(BL, IL, this->S);
+
+ this->hm.Update(KL, this->L);
+ this->hm.Update(BL, this->S);
+ this->hm.Final(BR);
+ xorbuf(BR, IR, this->S);
+
+ this->hm.Update(KR, this->L);
+ this->hm.Update(BR, this->S);
+ this->hm.Final(this->digest);
+ xorbuf(BL, this->digest, this->S);
+
+ this->hm.Update(KL, this->L);
+ this->hm.Update(OL, this->S);
+ this->hm.Final(this->digest);
+ xorbuf(BR, this->digest, this->S);
+
+ if (xorBlock)
+ xorbuf(outBlock, xorBlock, this->buffer, 2*this->S);
+ else
+ memcpy(outBlock, this->buffer, 2*this->S);
+ }
+#undef KL
+#undef KR
+#undef BL
+#undef BR
+#undef IL
+#undef IR
+#undef OL
+#undef OR
+ };
+
+public:
+ typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
+ typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
+};
+
+NAMESPACE_END
+
+#endif