Crypto++  8.2
Free C++ class library of cryptographic schemes
elgamal.h
Go to the documentation of this file.
1 // elgamal.h - originally 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 /// \brief ElGamal key agreement and encryption schemes base class
20 /// \since Crypto++ 1.0
24 {
25 public:
26  virtual ~ElGamalBase() {}
27 
28  void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
29  {
30  CRYPTOPP_UNUSED(groupParams), CRYPTOPP_UNUSED(ephemeralPublicKey), CRYPTOPP_UNUSED(derivationParams);
31  agreedElement.Encode(derivedKey, derivedLength);
32  }
33 
34  size_t GetSymmetricKeyLength(size_t plainTextLength) const
35  {
36  CRYPTOPP_UNUSED(plainTextLength);
37  return GetGroupParameters().GetModulus().ByteCount();
38  }
39 
40  size_t GetSymmetricCiphertextLength(size_t plainTextLength) const
41  {
42  unsigned int len = GetGroupParameters().GetModulus().ByteCount();
43  if (plainTextLength <= GetMaxSymmetricPlaintextLength(len))
44  return len;
45  else
46  return 0;
47  }
48 
49  size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const
50  {
51  unsigned int len = GetGroupParameters().GetModulus().ByteCount();
52  if (cipherTextLength == len)
53  return STDMIN(255U, len-3);
54  else
55  return 0;
56  }
57 
58  void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, size_t plainTextLength, byte *cipherText, const NameValuePairs &parameters) const
59  {
60  CRYPTOPP_UNUSED(parameters);
61  const Integer &p = GetGroupParameters().GetModulus();
62  unsigned int modulusLen = p.ByteCount();
63 
64  SecByteBlock block(modulusLen-1);
65  rng.GenerateBlock(block, modulusLen-2-plainTextLength);
66  memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength);
67  block[modulusLen-2] = (byte)plainTextLength;
68 
69  a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen);
70  }
71 
72  DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, size_t cipherTextLength, byte *plainText, const NameValuePairs &parameters) const
73  {
74  CRYPTOPP_UNUSED(parameters);
75  const Integer &p = GetGroupParameters().GetModulus();
76  unsigned int modulusLen = p.ByteCount();
77 
78  if (cipherTextLength != modulusLen)
79  return DecodingResult();
80 
81  Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p);
82 
83  m.Encode(plainText, 1);
84  unsigned int plainTextLength = plainText[0];
85  if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen))
86  return DecodingResult();
87  m >>= 8;
88  m.Encode(plainText, plainTextLength);
89  return DecodingResult(plainTextLength);
90  }
91 
92  virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0;
93 };
94 
95 /// \brief ElGamal key agreement and encryption schemes default implementation
96 /// \since Crypto++ 1.0
97 template <class BASE, class SCHEME_OPTIONS, class KEY>
98 class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase
99 {
100 public:
101  virtual ~ElGamalObjectImpl() {}
102 
103  size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());}
104  size_t FixedCiphertextLength() const {return this->CiphertextLength(0);}
105 
106  const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();}
107 
108  DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const
109  {return Decrypt(rng, cipherText, FixedCiphertextLength(), plainText);}
110 
111 protected:
112  const DL_KeyAgreementAlgorithm<Integer> & GetKeyAgreementAlgorithm() const {return *this;}
113  const DL_KeyDerivationAlgorithm<Integer> & GetKeyDerivationAlgorithm() const {return *this;}
114  const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;}
115 };
116 
117 /// \brief ElGamal key agreement and encryption schemes keys
118 /// \details The ElGamalKeys class used DL_PrivateKey_GFP_OldFormat and DL_PublicKey_GFP_OldFormat
119 /// for the PrivateKey and PublicKey typedef from about Crypto++ 1.0 through Crypto++ 5.6.5.
120 /// At Crypto++ 6.0 the serialization format was cutover to standard PKCS8 and X509 encodings.
121 /// \sa <A HREF="https://github.com/weidai11/cryptopp/commit/a5a684d92986e8e2">Commit a5a684d92986e8e2</A>
123 {
127 };
128 
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
140  /// implements PK_Decryptor interface
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:2078
Utility functions for the Crypto++ library.
GF(p) group parameters.
Definition: gfpcrypt.h:156
ElGamal key agreement and encryption schemes default implementation.
Definition: elgamal.h:98
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:311
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:135
Abstract base classes that provide a uniform interface to this library.
GF(p) group parameters that default to safe primes.
Definition: gfpcrypt.h:180
Interface for key derivation algorithms used in DL cryptosystems.
Definition: pubkey.h:1448
Interface for random number generators.
Definition: cryptlib.h:1383
SecBlock<byte> typedef.
Definition: secblock.h:1058
ElGamal key agreement and encryption schemes keys.
Definition: elgamal.h:122
Discrete Log (DL) crypto scheme options.
Definition: pubkey.h:1881
ElGamal encryption scheme with non-standard padding.
Definition: elgamal.h:131
unsigned int ByteCount() const
Determines the number of bytes required to represent the Integer.
Definition: integer.cpp:3336
Returns a decoding results.
Definition: cryptlib.h:255
Multiple precision integer with arithmetic operations.
Definition: integer.h:49
Discrete Log (DL) base object implementation.
Definition: pubkey.h:1893
Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
Classes for the DSA signature algorithm.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:567
Discrete Log (DL) public key in GF(p) groups.
Definition: gfpcrypt.h:460
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3410
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:496
Multiple precision integer with arithmetic operations.
ElGamal key agreement and encryption schemes base class.
Definition: elgamal.h:21
Crypto++ library namespace.
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition: pubkey.h:1459
PK_FinalTemplate< ElGamalObjectImpl< DL_DecryptorBase< Integer >, SchemeOptions, SchemeOptions::PrivateKey > > Decryptor
implements PK_Decryptor interface
Definition: elgamal.h:141
Interface for retrieving values given their names.
Definition: cryptlib.h:293
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:2134