summaryrefslogtreecommitdiff
path: root/elgamal.h
diff options
context:
space:
mode:
authorweidai <weidai11@users.noreply.github.com>2002-10-04 17:31:41 +0000
committerweidai <weidai11@users.noreply.github.com>2002-10-04 17:31:41 +0000
commita3b6ece7ab341b5b14135baeccea7d5e4c086771 (patch)
tree8b045309c238226c32a563b1df6b9c30a2f0e0b3 /elgamal.h
downloadcryptopp-git-a3b6ece7ab341b5b14135baeccea7d5e4c086771.tar.gz
Initial revision
Diffstat (limited to 'elgamal.h')
-rw-r--r--elgamal.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/elgamal.h b/elgamal.h
new file mode 100644
index 00000000..a2f6ffb7
--- /dev/null
+++ b/elgamal.h
@@ -0,0 +1,137 @@
+#ifndef CRYPTOPP_ELGAMAL_H
+#define CRYPTOPP_ELGAMAL_H
+
+#include "modexppc.h"
+#include "dsa.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+class ElGamalBase : public DL_KeyAgreementAlgorithm_DH<Integer, NoCofactorMultiplication>,
+ public DL_KeyDerivationAlgorithm<Integer>,
+ public DL_SymmetricEncryptionAlgorithm
+{
+public:
+ void Derive(const DL_GroupParameters<Integer> &params, byte *derivedKey, unsigned int derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey) const
+ {
+ agreedElement.Encode(derivedKey, derivedLength);
+ }
+
+ unsigned int GetSymmetricKeyLength(unsigned int plainTextLength) const
+ {
+ return GetGroupParameters().GetModulus().ByteCount();
+ }
+
+ unsigned int GetSymmetricCiphertextLength(unsigned int plainTextLength) const
+ {
+ unsigned int len = GetGroupParameters().GetModulus().ByteCount();
+ if (plainTextLength <= GetMaxSymmetricPlaintextLength(len))
+ return len;
+ else
+ return 0;
+ }
+
+ unsigned int GetMaxSymmetricPlaintextLength(unsigned int cipherTextLength) const
+ {
+ unsigned int len = GetGroupParameters().GetModulus().ByteCount();
+ if (cipherTextLength == len)
+ return STDMIN(255U, len-3);
+ else
+ return 0;
+ }
+
+ void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const
+ {
+ const Integer &p = GetGroupParameters().GetModulus();
+ unsigned int modulusLen = p.ByteCount();
+
+ SecByteBlock block(modulusLen-1);
+ rng.GenerateBlock(block, modulusLen-2-plainTextLength);
+ memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength);
+ block[modulusLen-2] = plainTextLength;
+
+ a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen);
+ }
+
+ DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const
+ {
+ const Integer &p = GetGroupParameters().GetModulus();
+ unsigned int modulusLen = p.ByteCount();
+
+ if (cipherTextLength != modulusLen)
+ return DecodingResult();
+
+ Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p);
+
+ m.Encode(plainText, 1);
+ unsigned int plainTextLength = plainText[0];
+ if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen))
+ return DecodingResult();
+ m >>= 8;
+ m.Encode(plainText, plainTextLength);
+ return DecodingResult(plainTextLength);
+ }
+
+ virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0;
+};
+
+template <class BASE, class SCHEME_OPTIONS, class KEY>
+class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase
+{
+public:
+ unsigned int FixedMaxPlaintextLength() const {return MaxPlaintextLength(FixedCiphertextLength());}
+ unsigned int FixedCiphertextLength() const {return CiphertextLength(0);}
+
+ const DL_GroupParameters_GFP & GetGroupParameters() const {return GetKey().GetGroupParameters();}
+
+ DecodingResult FixedLengthDecrypt(const byte *cipherText, byte *plainText) const
+ {return Decrypt(cipherText, FixedCiphertextLength(), plainText);}
+
+protected:
+ const DL_KeyAgreementAlgorithm<Integer> & GetKeyAgreementAlgorithm() const {return *this;}
+ const DL_KeyDerivationAlgorithm<Integer> & GetKeyDerivationAlgorithm() const {return *this;}
+ const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;}
+};
+
+struct ElGamalKeys
+{
+ typedef DL_CryptoKeys_GFP::GroupParameters GroupParameters;
+ typedef DL_PrivateKey_GFP_OldFormat<DL_CryptoKeys_GFP::PrivateKey> PrivateKey;
+ typedef DL_PublicKey_GFP_OldFormat<DL_CryptoKeys_GFP::PublicKey> PublicKey;
+};
+
+//! ElGamal encryption scheme with non-standard padding
+struct ElGamal
+{
+ typedef DL_CryptoSchemeOptions<ElGamal, ElGamalKeys, int, int, int> SchemeOptions;
+
+ static const char * StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";}
+
+ class EncryptorImpl : public ElGamalObjectImpl<DL_EncryptorBase<Integer, PK_FixedLengthEncryptor>, SchemeOptions, SchemeOptions::PublicKey>, public PublicKeyCopier<SchemeOptions>
+ {
+ public:
+ void CopyKeyInto(SchemeOptions::PublicKey &key) const
+ {key = GetKey();}
+ };
+
+ class DecryptorImpl : public ElGamalObjectImpl<DL_DecryptorBase<Integer, PK_FixedLengthDecryptor>, SchemeOptions, SchemeOptions::PrivateKey>, public PrivateKeyCopier<SchemeOptions>
+ {
+ public:
+ void CopyKeyInto(SchemeOptions::PublicKey &key) const
+ {GetKey().MakePublicKey(key);}
+ void CopyKeyInto(SchemeOptions::PrivateKey &key) const
+ {key = GetKey();}
+ };
+
+ typedef SchemeOptions::GroupParameters GroupParameters;
+ //! implements PK_Encryptor interface
+ typedef PK_FinalTemplate<EncryptorImpl> Encryptor;
+ //! implements PK_Decryptor interface
+ typedef PK_FinalTemplate<DecryptorImpl> Decryptor;
+};
+
+typedef ElGamal::Encryptor ElGamalEncryptor;
+typedef ElGamal::Decryptor ElGamalDecryptor;
+
+NAMESPACE_END
+
+#endif