Crypto++ 8.0 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
21 class CRYPTOPP_NO_VTABLE ElGamalBase : public DL_KeyAgreementAlgorithm_DH<Integer, NoCofactorMultiplication>,
22 public DL_KeyDerivationAlgorithm<Integer>,
23 public DL_SymmetricEncryptionAlgorithm
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>
122 struct ElGamalKeys
123 {
124 typedef DL_CryptoKeys_GFP::GroupParameters GroupParameters;
125 typedef DL_CryptoKeys_GFP::PrivateKey PrivateKey;
126 typedef DL_CryptoKeys_GFP::PublicKey PublicKey;
127 };
128
129 /// \brief ElGamal encryption scheme with non-standard padding
130 /// \since Crypto++ 1.0
131 struct ElGamal
132 {
133 typedef DL_CryptoSchemeOptions<ElGamal, ElGamalKeys, int, int, int> SchemeOptions;
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
144 typedef ElGamal::Encryptor ElGamalEncryptor;
145 typedef ElGamal::Decryptor ElGamalDecryptor;
146
147 NAMESPACE_END
148
149 #endif
ElGamal::Encryptor
PK_FinalTemplate< ElGamalObjectImpl< DL_EncryptorBase< Integer >, SchemeOptions, SchemeOptions::PublicKey > > Encryptor
implements PK_Encryptor interface
Definition: elgamal.h:139
DL_KeyAgreementAlgorithm_DH
Diffie-Hellman key agreement algorithm.
Definition: pubkey.h:2078
misc.h
Utility functions for the Crypto++ library.
DL_GroupParameters_GFP
GF(p) group parameters.
Definition: gfpcrypt.h:156
ElGamalObjectImpl
ElGamal key agreement and encryption schemes default implementation.
Definition: elgamal.h:98
RandomNumberGenerator::GenerateBlock
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:311
pubkey.h
This file contains helper classes/functions for implementing public key algorithms.
DL_GroupParameters< Integer >
EnumToType
Converts an enumeration to a type suitable for use as a template parameter.
Definition: cryptlib.h:135
cryptlib.h
Abstract base classes that provide a uniform interface to this library.
DL_GroupParameters_GFP_DefaultSafePrime
GF(p) group parameters that default to safe primes.
Definition: gfpcrypt.h:180
DL_KeyDerivationAlgorithm
Interface for key derivation algorithms used in DL cryptosystems.
Definition: pubkey.h:1448
RandomNumberGenerator
Interface for random number generators.
Definition: cryptlib.h:1383
SecByteBlock
SecBlock<byte> typedef.
Definition: secblock.h:1058
ElGamalKeys
ElGamal key agreement and encryption schemes keys.
Definition: elgamal.h:122
DL_CryptoSchemeOptions
Discrete Log (DL) crypto scheme options.
Definition: pubkey.h:1881
ElGamal
ElGamal encryption scheme with non-standard padding.
Definition: elgamal.h:131
Integer::ByteCount
unsigned int ByteCount() const
Determines the number of bytes required to represent the Integer.
Definition: integer.cpp:3336
DecodingResult
Returns a decoding results.
Definition: cryptlib.h:255
Integer
Multiple precision integer with arithmetic operations.
Definition: integer.h:49
DL_ObjectImplBase
Discrete Log (DL) base object implementation.
Definition: pubkey.h:1893
gfpcrypt.h
Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
dsa.h
Classes for the DSA signature algorithm.
STDMIN
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:535
DL_PublicKey_GFP
Discrete Log (DL) public key in GF(p) groups.
Definition: gfpcrypt.h:460
Integer::Encode
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3410
DL_PrivateKey_GFP
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:496
integer.h
Multiple precision integer with arithmetic operations.
ElGamalBase
ElGamal key agreement and encryption schemes base class.
Definition: elgamal.h:21
CryptoPP
Crypto++ library namespace.
DL_SymmetricEncryptionAlgorithm
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition: pubkey.h:1459
ElGamal::Decryptor
PK_FinalTemplate< ElGamalObjectImpl< DL_DecryptorBase< Integer >, SchemeOptions, SchemeOptions::PrivateKey > > Decryptor
implements PK_Decryptor interface
Definition: elgamal.h:141
DL_KeyAgreementAlgorithm< Integer >
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:293
PK_FinalTemplate
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:2134