Crypto++  5.6.3
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 
20  public DL_KeyDerivationAlgorithm<Integer>,
22 {
23 public:
24  void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
25  {
26  CRYPTOPP_UNUSED(groupParams), CRYPTOPP_UNUSED(ephemeralPublicKey), CRYPTOPP_UNUSED(derivationParams);
27  agreedElement.Encode(derivedKey, derivedLength);
28  }
29 
30  size_t GetSymmetricKeyLength(size_t plainTextLength) const
31  {
32  CRYPTOPP_UNUSED(plainTextLength);
33  return GetGroupParameters().GetModulus().ByteCount();
34  }
35 
36  size_t GetSymmetricCiphertextLength(size_t plainTextLength) const
37  {
38  unsigned int len = GetGroupParameters().GetModulus().ByteCount();
39  if (plainTextLength <= GetMaxSymmetricPlaintextLength(len))
40  return len;
41  else
42  return 0;
43  }
44 
45  size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const
46  {
47  unsigned int len = GetGroupParameters().GetModulus().ByteCount();
48  if (cipherTextLength == len)
49  return STDMIN(255U, len-3);
50  else
51  return 0;
52  }
53 
54  void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, size_t plainTextLength, byte *cipherText, const NameValuePairs &parameters) const
55  {
56  CRYPTOPP_UNUSED(parameters);
57  const Integer &p = GetGroupParameters().GetModulus();
58  unsigned int modulusLen = p.ByteCount();
59 
60  SecByteBlock block(modulusLen-1);
61  rng.GenerateBlock(block, modulusLen-2-plainTextLength);
62  memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength);
63  block[modulusLen-2] = (byte)plainTextLength;
64 
65  a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen);
66  }
67 
68  DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, size_t cipherTextLength, byte *plainText, const NameValuePairs &parameters) const
69  {
70  CRYPTOPP_UNUSED(parameters);
71  const Integer &p = GetGroupParameters().GetModulus();
72  unsigned int modulusLen = p.ByteCount();
73 
74  if (cipherTextLength != modulusLen)
75  return DecodingResult();
76 
77  Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p);
78 
79  m.Encode(plainText, 1);
80  unsigned int plainTextLength = plainText[0];
81  if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen))
82  return DecodingResult();
83  m >>= 8;
84  m.Encode(plainText, plainTextLength);
85  return DecodingResult(plainTextLength);
86  }
87 
88  virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0;
89 
90 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
91  virtual ~ElGamalBase() {}
92 #endif
93 };
94 
95 template <class BASE, class SCHEME_OPTIONS, class KEY>
96 class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase
97 {
98 public:
99  size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());}
100  size_t FixedCiphertextLength() const {return this->CiphertextLength(0);}
101 
102  const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();}
103 
104  DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const
105  {return Decrypt(rng, cipherText, FixedCiphertextLength(), plainText);}
106 
107 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
108  virtual ~ElGamalObjectImpl() {}
109 #endif
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 
118 {
122 };
123 
124 //! \class ElGamal
125 //! \brief ElGamal encryption scheme with non-standard padding
126 struct ElGamal
127 {
129 
130  static const char * StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";}
131 
132  typedef SchemeOptions::GroupParameters GroupParameters;
133  //! implements PK_Encryptor interface
134  typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor;
135  //! implements PK_Decryptor interface
136  typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor;
137 };
138 
141 
142 NAMESPACE_END
143 
144 #endif
PK_FinalTemplate< ElGamalObjectImpl< DL_EncryptorBase< Integer >, SchemeOptions, SchemeOptions::PublicKey > > Encryptor
implements PK_Encryptor interface
Definition: elgamal.h:134
Utility functions for the Crypto++ library.
GF(p) group parameters.
Definition: gfpcrypt.h:144
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3338
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:330
This file contains helper classes/functions for implementing public key algorithms.
Converts a typename to an enumerated value.
Definition: cryptlib.h:115
Abstract base classes that provide a uniform interface to this library.
GF(p) group parameters that default to same primes.
Definition: gfpcrypt.h:170
Interface for key derivation algorithms used in DL cryptosystems.
Definition: pubkey.h:1335
Interface for random number generators.
Definition: cryptlib.h:1186
SecBlock typedef.
Definition: secblock.h:728
Discrete Log (DL) crypto scheme options.
Definition: pubkey.h:1769
ElGamal encryption scheme with non-standard padding.
Definition: elgamal.h:126
Returns a decoding results.
Definition: cryptlib.h:236
provided for backwards compatibility, this class uses the old non-standard Crypto++ key format ...
Definition: gfpcrypt.h:322
Multiple precision integer with arithmetic operations.
Definition: integer.h:31
Discrete Log (DL) base object implementation.
Definition: pubkey.h:1781
Implementation of schemes based on 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:467
provided for backwards compatibility, this class uses the old non-standard Crypto++ key format ...
Definition: gfpcrypt.h:365
Crypto++ library namespace.
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition: pubkey.h:1348
PK_FinalTemplate< ElGamalObjectImpl< DL_DecryptorBase< Integer >, SchemeOptions, SchemeOptions::PrivateKey > > Decryptor
implements PK_Decryptor interface
Definition: elgamal.h:136
unsigned int ByteCount() const
Determines the number of bytes required to represent the Integer.
Definition: integer.cpp:3268
Interface for retrieving values given their names.
Definition: cryptlib.h:277
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:2030