Crypto++
elgamal.h
1 #ifndef CRYPTOPP_ELGAMAL_H
2 #define CRYPTOPP_ELGAMAL_H
3 
4 #include "modexppc.h"
5 #include "dsa.h"
6 
7 NAMESPACE_BEGIN(CryptoPP)
8 
10  public DL_KeyDerivationAlgorithm<Integer>,
12 {
13 public:
14  void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
15  {
16  agreedElement.Encode(derivedKey, derivedLength);
17  }
18 
19  size_t GetSymmetricKeyLength(size_t plainTextLength) const
20  {
21  return GetGroupParameters().GetModulus().ByteCount();
22  }
23 
24  size_t GetSymmetricCiphertextLength(size_t plainTextLength) const
25  {
26  unsigned int len = GetGroupParameters().GetModulus().ByteCount();
27  if (plainTextLength <= GetMaxSymmetricPlaintextLength(len))
28  return len;
29  else
30  return 0;
31  }
32 
33  size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const
34  {
35  unsigned int len = GetGroupParameters().GetModulus().ByteCount();
36  if (cipherTextLength == len)
37  return STDMIN(255U, len-3);
38  else
39  return 0;
40  }
41 
42  void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, size_t plainTextLength, byte *cipherText, const NameValuePairs &parameters) const
43  {
44  const Integer &p = GetGroupParameters().GetModulus();
45  unsigned int modulusLen = p.ByteCount();
46 
47  SecByteBlock block(modulusLen-1);
48  rng.GenerateBlock(block, modulusLen-2-plainTextLength);
49  memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength);
50  block[modulusLen-2] = (byte)plainTextLength;
51 
52  a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen);
53  }
54 
55  DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, size_t cipherTextLength, byte *plainText, const NameValuePairs &parameters) const
56  {
57  const Integer &p = GetGroupParameters().GetModulus();
58  unsigned int modulusLen = p.ByteCount();
59 
60  if (cipherTextLength != modulusLen)
61  return DecodingResult();
62 
63  Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p);
64 
65  m.Encode(plainText, 1);
66  unsigned int plainTextLength = plainText[0];
67  if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen))
68  return DecodingResult();
69  m >>= 8;
70  m.Encode(plainText, plainTextLength);
71  return DecodingResult(plainTextLength);
72  }
73 
74  virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0;
75 };
76 
77 template <class BASE, class SCHEME_OPTIONS, class KEY>
78 class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase
79 {
80 public:
81  size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());}
82  size_t FixedCiphertextLength() const {return this->CiphertextLength(0);}
83 
84  const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();}
85 
86  DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const
87  {return Decrypt(rng, cipherText, FixedCiphertextLength(), plainText);}
88 
89 protected:
90  const DL_KeyAgreementAlgorithm<Integer> & GetKeyAgreementAlgorithm() const {return *this;}
91  const DL_KeyDerivationAlgorithm<Integer> & GetKeyDerivationAlgorithm() const {return *this;}
92  const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;}
93 };
94 
96 {
100 };
101 
102 //! ElGamal encryption scheme with non-standard padding
103 struct ElGamal
104 {
106 
107  static const char * StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";}
108 
109  typedef SchemeOptions::GroupParameters GroupParameters;
110  //! implements PK_Encryptor interface
111  typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor;
112  //! implements PK_Decryptor interface
113  typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor;
114 };
115 
118 
119 NAMESPACE_END
120 
121 #endif
PK_FinalTemplate< ElGamalObjectImpl< DL_EncryptorBase< Integer >, SchemeOptions, SchemeOptions::PublicKey > > Encryptor
implements PK_Encryptor interface
Definition: elgamal.h:111
DH key agreement algorithm.
Definition: pubkey.h:1434
GF(p) group parameters.
Definition: gfpcrypt.h:119
GF(p) group parameters that default to same primes.
Definition: gfpcrypt.h:141
interface for key derivation algorithms used in DL cryptosystems
Definition: pubkey.h:926
interface for random number generators
Definition: cryptlib.h:668
ElGamal encryption scheme with non-standard padding.
Definition: elgamal.h:103
used to return decoding results
Definition: cryptlib.h:197
provided for backwards compatibility, this class uses the old non-standard Crypto++ key format ...
Definition: gfpcrypt.h:265
multiple precision integer and basic arithmetics
Definition: integer.h:26
virtual void GenerateBlock(byte *output, size_t size)
generate random array of bytes
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const
encode in big-endian format
provided for backwards compatibility, this class uses the old non-standard Crypto++ key format ...
Definition: gfpcrypt.h:304
interface for symmetric encryption algorithms used in DL cryptosystems
Definition: pubkey.h:934
PK_FinalTemplate< ElGamalObjectImpl< DL_DecryptorBase< Integer >, SchemeOptions, SchemeOptions::PrivateKey > > Decryptor
implements PK_Decryptor interface
Definition: elgamal.h:113
unsigned int ByteCount() const
number of significant bytes = ceiling(BitCount()/8)
interface for retrieving values given their names
Definition: cryptlib.h:224
A template implementing constructors for public key algorithm classes.
Definition: pubkey.h:1488