Crypto++  8.2
Free C&
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
ElGamal encryption due to due to ElGamal safe interop.
Definition: gfpcrypt.h:197
GF(p) group parameters.
Definition: gfpcrypt.h:157
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:754
Diffie-Hellman key agreement algorithm.
Definition: pubkey.h:2086
Interface for DL key agreement algorithms.
Definition: pubkey.h:1435
Interface for key derivation algorithms used in DL cryptosystems.
Definition: pubkey.h:1449
Discrete Log (DL) base object implementation.
Definition: pubkey.h:1901
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:515
Discrete Log (DL) public key in GF(p) groups.
Definition: gfpcrypt.h:479
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition: pubkey.h:1460
ElGamal key agreement and encryption schemes base class.
Definition: elgamal.h:24
ElGamal key agreement and encryption schemes default implementation.
Definition: elgamal.h:99
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
unsigned int ByteCount() const
Determines the number of bytes required to represent the Integer.
Definition: integer.cpp:3336
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3410
Interface for retrieving values given their names.
Definition: cryptlib.h:294
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:2142
Interface for random number generators.
Definition: cryptlib.h:1384
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:311
SecBlock<byte> typedef.
Definition: secblock.h:1058
Abstract base classes that provide a uniform interface to this library.
Classes for the DSA signature algorithm.
Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
Multiple precision integer with arithmetic operations.
Utility functions for the Crypto++ library.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:567
Crypto++ library namespace.
This file contains helper classes/functions for implementing public key algorithms.
Discrete Log (DL) crypto scheme options.
Definition: pubkey.h:1889
Returns a decoding results.
Definition: cryptlib.h:256
ElGamal encryption scheme with non-standard padding.
Definition: elgamal.h:132
PK_FinalTemplate< ElGamalObjectImpl< DL_EncryptorBase< Integer >, SchemeOptions, SchemeOptions::PublicKey > > Encryptor
implements PK_Encryptor interface
Definition: elgamal.h:139
PK_FinalTemplate< ElGamalObjectImpl< DL_DecryptorBase< Integer >, SchemeOptions, SchemeOptions::PrivateKey > > Decryptor
implements PK_Decryptor interface
Definition: elgamal.h:141
ElGamal key agreement and encryption schemes keys.
Definition: elgamal.h:123
Converts an enumeration to a type suitable for use as a template parameter.
Definition: cryptlib.h:136