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 ¶meters)
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 ¶meters)
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
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
00127 typedef PK_FinalTemplate<EncryptorImpl> Encryptor;
00128
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