Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class 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 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, unsigned int derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) 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 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] = 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 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 CRYPTOPP_NO_VTABLE 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 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         class EncryptorImpl : public ElGamalObjectImpl<DL_EncryptorBase<Integer>,  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>, 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

Generated on Sun Jul 3 00:20:12 2005 for Crypto++ by  doxygen 1.4.3-20050530