Crypto++  5.6.5
Free C++ class library of cryptographic schemes
elgamal.h
Go to the documentation of this file.
1 // elgamal.h - written and placed in the public domain by Wei Dai
2 
3 //! \file elgamal.h
4 //! \brief Classes and functions for ElGamal key agreement and encryption schemes
5 
6 #ifndef CRYPTOPP_ELGAMAL_H
7 #define CRYPTOPP_ELGAMAL_H
8 
9 #include "cryptlib.h"
10 #include "modexppc.h"
11 #include "integer.h"
12 #include "gfpcrypt.h"
13 #include "pubkey.h"
14 #include "dsa.h"
15 #include "misc.h"
16 
17 NAMESPACE_BEGIN(CryptoPP)
18 
19 //! \class ElGamalBase
20 //! \brief ElGamal key agreement and encryption schemes base class
21 //! \since Crypto++ 1.0
23  public DL_KeyDerivationAlgorithm<Integer>,
25 {
26 public:
27  virtual ~ElGamalBase() {}
28 
29  void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
30  {
31  CRYPTOPP_UNUSED(groupParams), CRYPTOPP_UNUSED(ephemeralPublicKey), CRYPTOPP_UNUSED(derivationParams);
32  agreedElement.Encode(derivedKey, derivedLength);
33  }
34 
35  size_t GetSymmetricKeyLength(size_t plainTextLength) const
36  {
37  CRYPTOPP_UNUSED(plainTextLength);
38  return GetGroupParameters().GetModulus().ByteCount();
39  }
40 
41  size_t GetSymmetricCiphertextLength(size_t plainTextLength) const
42  {
43  unsigned int len = GetGroupParameters().GetModulus().ByteCount();
44  if (plainTextLength <= GetMaxSymmetricPlaintextLength(len))
45  return len;
46  else
47  return 0;
48  }
49 
50  size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const
51  {
52  unsigned int len = GetGroupParameters().GetModulus().ByteCount();
53  if (cipherTextLength == len)
54  return STDMIN(255U, len-3);
55  else
56  return 0;
57  }
58 
59  void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, size_t plainTextLength, byte *cipherText, const NameValuePairs &parameters) const
60  {
61  CRYPTOPP_UNUSED(parameters);
62  const Integer &p = GetGroupParameters().GetModulus();
63  unsigned int modulusLen = p.ByteCount();
64 
65  SecByteBlock block(modulusLen-1);
66  rng.GenerateBlock(block, modulusLen-2-plainTextLength);
67  memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength);
68  block[modulusLen-2] = (byte)plainTextLength;
69 
70  a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen);
71  }
72 
73  DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, size_t cipherTextLength, byte *plainText, const NameValuePairs &parameters) const
74  {
75  CRYPTOPP_UNUSED(parameters);
76  const Integer &p = GetGroupParameters().GetModulus();
77  unsigned int modulusLen = p.ByteCount();
78 
79  if (cipherTextLength != modulusLen)
80  return DecodingResult();
81 
82  Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p);
83 
84  m.Encode(plainText, 1);
85  unsigned int plainTextLength = plainText[0];
86  if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen))
87  return DecodingResult();
88  m >>= 8;
89  m.Encode(plainText, plainTextLength);
90  return DecodingResult(plainTextLength);
91  }
92 
93  virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0;
94 };
95 
96 //! \class ElGamalObjectImpl
97 //! \brief ElGamal key agreement and encryption schemes default implementation
98 //! \since Crypto++ 1.0
99 template <class BASE, class SCHEME_OPTIONS, class KEY>
100 class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase
101 {
102 public:
103  virtual ~ElGamalObjectImpl() {}
104 
105  size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());}
106  size_t FixedCiphertextLength() const {return this->CiphertextLength(0);}
107 
108  const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();}
109 
110  DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const
111  {return Decrypt(rng, cipherText, FixedCiphertextLength(), plainText);}
112 
113 protected:
114  const DL_KeyAgreementAlgorithm<Integer> & GetKeyAgreementAlgorithm() const {return *this;}
115  const DL_KeyDerivationAlgorithm<Integer> & GetKeyDerivationAlgorithm() const {return *this;}
116  const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;}
117 };
118 
119 //! \class ElGamalKeys
120 //! \brief ElGamal key agreement and encryption schemes keys
122 {
126 };
127 
128 //! \class ElGamal
129 //! \brief ElGamal encryption scheme with non-standard padding
130 //! \since Crypto++ 1.0
131 struct ElGamal
132 {
134 
135  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";}
136 
137  typedef SchemeOptions::GroupParameters GroupParameters;
138  //! implements PK_Encryptor interface
139  typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor;
140  //! implements PK_Decryptor interface
141  typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor;
142 };
143 
146 
147 NAMESPACE_END
148 
149 #endif
PK_FinalTemplate< ElGamalObjectImpl< DL_EncryptorBase< Integer >, SchemeOptions, SchemeOptions::PublicKey > > Encryptor
implements PK_Encryptor interface
Definition: elgamal.h:139
Diffie-Hellman key agreement algorithm.
Definition: pubkey.h:1898
Utility functions for the Crypto++ library.
GF(p) group parameters.
Definition: gfpcrypt.h:157
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3369
ElGamal key agreement and encryption schemes default implementation.
Definition: elgamal.h:100
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:326
This file contains helper classes/functions for implementing public key algorithms.
Converts an enumeration to a type suitable for use as a template parameter.
Definition: cryptlib.h:116
Abstract base classes that provide a uniform interface to this library.
Interface for key derivation algorithms used in DL cryptosystems.
Definition: pubkey.h:1285
Interface for random number generators.
Definition: cryptlib.h:1188
SecBlock typedef.
Definition: secblock.h:731
ElGamal key agreement and encryption schemes keys.
Definition: elgamal.h:121
Discrete Log (DL) crypto scheme options.
Definition: pubkey.h:1701
ElGamal encryption scheme with non-standard padding.
Definition: elgamal.h:131
Returns a decoding results.
Definition: cryptlib.h:238
Discrete Log (DL) public key in GF(p) groups.
Definition: gfpcrypt.h:382
Multiple precision integer with arithmetic operations.
Definition: integer.h:43
Discrete Log (DL) base object implementation.
Definition: pubkey.h:1713
Classes for the DSA signature algorithm.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:477
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:427
Multiple precision integer with arithmetic operations.
ElGamal key agreement and encryption schemes base class.
Definition: elgamal.h:22
Crypto++ library namespace.
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition: pubkey.h:1296
PK_FinalTemplate< ElGamalObjectImpl< DL_DecryptorBase< Integer >, SchemeOptions, SchemeOptions::PrivateKey > > Decryptor
implements PK_Decryptor interface
Definition: elgamal.h:141
unsigned int ByteCount() const
Determines the number of bytes required to represent the Integer.
Definition: integer.cpp:3296
Interface for retrieving values given their names.
Definition: cryptlib.h:279
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:1954