00001
00002
00003
00004
00005
00006 #ifndef CRYPTOPP_ELGAMAL_H
00007 #define CRYPTOPP_ELGAMAL_H
00008
00009 #include "cryptlib.h"
00010 #include "modexppc.h"
00011 #include "integer.h"
00012 #include "gfpcrypt.h"
00013 #include "pubkey.h"
00014 #include "dsa.h"
00015 #include "misc.h"
00016
00017 NAMESPACE_BEGIN(CryptoPP)
00018
00019 class CRYPTOPP_NO_VTABLE ElGamalBase : public DL_KeyAgreementAlgorithm_DH<Integer, NoCofactorMultiplication>,
00020 public DL_KeyDerivationAlgorithm<Integer>,
00021 public DL_SymmetricEncryptionAlgorithm
00022 {
00023 public:
00024 void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
00025 {
00026 CRYPTOPP_UNUSED(groupParams), CRYPTOPP_UNUSED(ephemeralPublicKey), CRYPTOPP_UNUSED(derivationParams);
00027 agreedElement.Encode(derivedKey, derivedLength);
00028 }
00029
00030 size_t GetSymmetricKeyLength(size_t plainTextLength) const
00031 {
00032 CRYPTOPP_UNUSED(plainTextLength);
00033 return GetGroupParameters().GetModulus().ByteCount();
00034 }
00035
00036 size_t GetSymmetricCiphertextLength(size_t plainTextLength) const
00037 {
00038 unsigned int len = GetGroupParameters().GetModulus().ByteCount();
00039 if (plainTextLength <= GetMaxSymmetricPlaintextLength(len))
00040 return len;
00041 else
00042 return 0;
00043 }
00044
00045 size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const
00046 {
00047 unsigned int len = GetGroupParameters().GetModulus().ByteCount();
00048 if (cipherTextLength == len)
00049 return STDMIN(255U, len-3);
00050 else
00051 return 0;
00052 }
00053
00054 void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, size_t plainTextLength, byte *cipherText, const NameValuePairs ¶meters) const
00055 {
00056 CRYPTOPP_UNUSED(parameters);
00057 const Integer &p = GetGroupParameters().GetModulus();
00058 unsigned int modulusLen = p.ByteCount();
00059
00060 SecByteBlock block(modulusLen-1);
00061 rng.GenerateBlock(block, modulusLen-2-plainTextLength);
00062 memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength);
00063 block[modulusLen-2] = (byte)plainTextLength;
00064
00065 a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen);
00066 }
00067
00068 DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, size_t cipherTextLength, byte *plainText, const NameValuePairs ¶meters) const
00069 {
00070 CRYPTOPP_UNUSED(parameters);
00071 const Integer &p = GetGroupParameters().GetModulus();
00072 unsigned int modulusLen = p.ByteCount();
00073
00074 if (cipherTextLength != modulusLen)
00075 return DecodingResult();
00076
00077 Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p);
00078
00079 m.Encode(plainText, 1);
00080 unsigned int plainTextLength = plainText[0];
00081 if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen))
00082 return DecodingResult();
00083 m >>= 8;
00084 m.Encode(plainText, plainTextLength);
00085 return DecodingResult(plainTextLength);
00086 }
00087
00088 virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0;
00089
00090 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00091 virtual ~ElGamalBase() {}
00092 #endif
00093 };
00094
00095 template <class BASE, class SCHEME_OPTIONS, class KEY>
00096 class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase
00097 {
00098 public:
00099 size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());}
00100 size_t FixedCiphertextLength() const {return this->CiphertextLength(0);}
00101
00102 const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();}
00103
00104 DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const
00105 {return Decrypt(rng, cipherText, FixedCiphertextLength(), plainText);}
00106
00107 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00108 virtual ~ElGamalObjectImpl() {}
00109 #endif
00110
00111 protected:
00112 const DL_KeyAgreementAlgorithm<Integer> & GetKeyAgreementAlgorithm() const {return *this;}
00113 const DL_KeyDerivationAlgorithm<Integer> & GetKeyDerivationAlgorithm() const {return *this;}
00114 const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;}
00115 };
00116
00117 struct ElGamalKeys
00118 {
00119 typedef DL_CryptoKeys_GFP::GroupParameters GroupParameters;
00120 typedef DL_PrivateKey_GFP_OldFormat<DL_CryptoKeys_GFP::PrivateKey> PrivateKey;
00121 typedef DL_PublicKey_GFP_OldFormat<DL_CryptoKeys_GFP::PublicKey> PublicKey;
00122 };
00123
00124
00125
00126 struct ElGamal
00127 {
00128 typedef DL_CryptoSchemeOptions<ElGamal, ElGamalKeys, int, int, int> SchemeOptions;
00129
00130 static const char * StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";}
00131
00132 typedef SchemeOptions::GroupParameters GroupParameters;
00133
00134 typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor;
00135
00136 typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor;
00137 };
00138
00139 typedef ElGamal::Encryptor ElGamalEncryptor;
00140 typedef ElGamal::Decryptor ElGamalDecryptor;
00141
00142 NAMESPACE_END
00143
00144 #endif