Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | 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 Wed Jul 21 19:15:23 2004 for Crypto++ by doxygen 1.3.7-20040704