Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# elgamal.h

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