Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- 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 CRYPTOPP_NO_VTABLE 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> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
    00015     {
    00016         agreedElement.Encode(derivedKey, derivedLength);
    00017     }
    00018
    00019     size_t GetSymmetricKeyLength(size_t plainTextLength) const
    00020     {
    00021         return GetGroupParameters().GetModulus().ByteCount();
    00022     }
    00023
    00024     size_t GetSymmetricCiphertextLength(size_t 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     size_t GetMaxSymmetricPlaintextLength(size_t 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, size_t plainTextLength, byte *cipherText, const NameValuePairs &parameters) 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] = (byte)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, size_t cipherTextLength, byte *plainText, const NameValuePairs &parameters) 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     size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());}
    00082     size_t FixedCiphertextLength() const {return this->CiphertextLength(0);}
    00083
    00084     const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();}
    00085
    00086     DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const
    00087         {return Decrypt(rng, 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     typedef SchemeOptions::GroupParameters GroupParameters;
    00110     //! implements PK_Encryptor interface
    00111     typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor;
    00112     //! implements PK_Decryptor interface
    00113     typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor;
    00114 };
    00115
    00116 typedef ElGamal::Encryptor ElGamalEncryptor;
    00117 typedef ElGamal::Decryptor ElGamalDecryptor;
    00118
    00119 NAMESPACE_END
    00120
    00121 #endif