Security Scol plugin
elgamal.h
Go to the documentation of this file.
1// elgamal.h - originally written and placed in the public domain by Wei Dai
2
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 "misc.h"
15#include "oids.h"
16#include "dsa.h"
17#include "asn.h"
18
19NAMESPACE_BEGIN(CryptoPP)
20
21
23class CRYPTOPP_NO_VTABLE ElGamalBase :
27{
28public:
29 virtual ~ElGamalBase() {}
30
31 void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
32 {
33 CRYPTOPP_UNUSED(groupParams); CRYPTOPP_UNUSED(ephemeralPublicKey);
34 CRYPTOPP_UNUSED(derivationParams);
35 agreedElement.Encode(derivedKey, derivedLength);
36 }
37
38 size_t GetSymmetricKeyLength(size_t plainTextLength) const
39 {
40 CRYPTOPP_UNUSED(plainTextLength);
41 return GetGroupParameters().GetModulus().ByteCount();
42 }
43
44 size_t GetSymmetricCiphertextLength(size_t plainTextLength) const
45 {
46 unsigned int len = GetGroupParameters().GetModulus().ByteCount();
47 if (plainTextLength <= GetMaxSymmetricPlaintextLength(len))
48 return len;
49 else
50 return 0;
51 }
52
53 size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const
54 {
55 unsigned int len = GetGroupParameters().GetModulus().ByteCount();
56 CRYPTOPP_ASSERT(len >= 3);
57
58 if (cipherTextLength == len)
59 return STDMIN(255U, len-3);
60 else
61 return 0;
62 }
63
64 void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, size_t plainTextLength, byte *cipherText, const NameValuePairs &parameters) const
65 {
66 CRYPTOPP_UNUSED(parameters);
67 const Integer &p = GetGroupParameters().GetModulus();
68 unsigned int modulusLen = p.ByteCount();
69
70 SecByteBlock block(modulusLen-1);
71 rng.GenerateBlock(block, modulusLen-2-plainTextLength);
72 memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength);
73 block[modulusLen-2] = (byte)plainTextLength;
74
75 a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen);
76 }
77
78 DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, size_t cipherTextLength, byte *plainText, const NameValuePairs &parameters) const
79 {
80 CRYPTOPP_UNUSED(parameters);
81 const Integer &p = GetGroupParameters().GetModulus();
82 unsigned int modulusLen = p.ByteCount();
83
84 if (cipherTextLength != modulusLen)
85 return DecodingResult();
86
87 Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p);
88
89 m.Encode(plainText, 1);
90 unsigned int plainTextLength = plainText[0];
91 if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen))
92 return DecodingResult();
93 m >>= 8;
94 m.Encode(plainText, plainTextLength);
95 return DecodingResult(plainTextLength);
96 }
97
98 virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0;
99};
100
106template <class BASE, class SCHEME_OPTIONS, class KEY>
108 public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>,
109 public ElGamalBase
110{
111public:
112 virtual ~ElGamalObjectImpl() {}
113
114 size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());}
115 size_t FixedCiphertextLength() const {return this->CiphertextLength(0);}
116
117 const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();}
118
119 DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const
120 {return Decrypt(rng, cipherText, FixedCiphertextLength(), plainText);}
121
122protected:
123 const DL_KeyAgreementAlgorithm<Integer> & GetKeyAgreementAlgorithm() const {return *this;}
124 const DL_KeyDerivationAlgorithm<Integer> & GetKeyDerivationAlgorithm() const {return *this;}
125 const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;}
126};
127
139template <class BASE>
140struct DL_PublicKey_ElGamal : public BASE
141{
142 virtual ~DL_PublicKey_ElGamal() {}
143
154 virtual OID GetAlgorithmID() const {
155 return ASN1::elGamal();
156 }
157};
158
170template <class BASE>
171struct DL_PrivateKey_ElGamal : public BASE
172{
173 virtual ~DL_PrivateKey_ElGamal() {}
174
185 virtual OID GetAlgorithmID() const {
186 return ASN1::elGamal();
187 }
188
206 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
207 {
208 // Validate() formerly used DL_PrivateKey_GFP implementation through
209 // inheritance. However, it would reject keys from other libraries
210 // like BouncyCastle. The failure was x < q. According to ElGamal's
211 // paper and the HAC, the private key is selected in over [1,p-1],
212 // Later Tsiounis and Yung showed the lower limit as [1,q-1] in
213 // "On the Security of EIGamal Based Encryption". As such, Crypto++
214 // will generate a key in the range [1,q-1], but accept a key
215 // in [1,p-1]. Thanks to JPM for finding the reference. Also see
216 // https://github.com/weidai11/cryptopp/commit/a5a684d92986.
217
218 CRYPTOPP_ASSERT(this->GetAbstractGroupParameters().Validate(rng, level));
219 bool pass = this->GetAbstractGroupParameters().Validate(rng, level);
220
221 const Integer &p = this->GetGroupParameters().GetModulus();
222 const Integer &q = this->GetAbstractGroupParameters().GetSubgroupOrder();
223 const Integer &x = this->GetPrivateExponent();
224
225 // Changed to x < p-1 based on ElGamal's paper and the HAC.
226 CRYPTOPP_ASSERT(x.IsPositive());
227 CRYPTOPP_ASSERT(x < p-1);
228 pass = pass && x.IsPositive() && x < p-1;
229
230 if (level >= 1)
231 {
232 // Minimum security level due to Tsiounis and Yung.
233 CRYPTOPP_ASSERT(Integer::Gcd(x, q) == Integer::One());
234 pass = pass && Integer::Gcd(x, q) == Integer::One();
235 }
236 return pass;
237 }
238};
239
270
284{
286 typedef SchemeOptions::PrivateKey PrivateKey;
287 typedef SchemeOptions::PublicKey PublicKey;
288
293 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";}
294
296 typedef SchemeOptions::GroupParameters GroupParameters;
301};
302
305
306NAMESPACE_END
307
308#endif
Classes and functions for working with ANS.1 objects.
GF(p) group parameters.
Definition gfpcrypt.h:225
Interface for Discrete Log (DL) group parameters.
Definition pubkey.h:782
Diffie-Hellman key agreement algorithm.
Definition pubkey.h:2142
Interface for DL key agreement algorithms.
Definition pubkey.h:1477
Interface for key derivation algorithms used in DL cryptosystems.
Definition pubkey.h:1493
Discrete Log (DL) base object implementation.
Definition pubkey.h:1957
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition pubkey.h:1505
ElGamal key agreement and encryption schemes base class.
Definition elgamal.h:27
ElGamal key agreement and encryption schemes default implementation.
Definition elgamal.h:110
Multiple precision integer with arithmetic operations.
Definition integer.h:50
static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n)
Calculate greatest common divisor.
Definition integer.cpp:4468
static const Integer &CRYPTOPP_API One()
Integer representing 1.
Definition integer.cpp:4920
unsigned int ByteCount() const
Determines the number of bytes required to represent the Integer.
Definition integer.cpp:3355
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition integer.cpp:3427
Interface for retrieving values given their names.
Definition cryptlib.h:322
Object Identifier.
Definition asn.h:265
Template implementing constructors for public key algorithm classes.
Definition pubkey.h:2198
Interface for private keys.
Definition cryptlib.h:2541
Interface for public keys.
Definition cryptlib.h:2536
Interface for random number generators.
Definition cryptlib.h:1435
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition cryptlib.cpp:311
unsigned char byte
8-bit unsigned datatype
Definition config_int.h:56
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:655
ASN.1 object identifiers for algorithms and schemes.
This file contains helper classes/functions for implementing public key algorithms.
Discrete Log (DL) crypto scheme options.
Definition pubkey.h:1945
ElGamal Private Key adapter.
Definition elgamal.h:172
virtual OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition elgamal.h:185
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check the key for errors.
Definition elgamal.h:206
ElGamal Public Key adapter.
Definition elgamal.h:141
virtual OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition elgamal.h:154
Returns a decoding results.
Definition cryptlib.h:278
ElGamal encryption scheme with non-standard padding.
Definition elgamal.h:284
PK_FinalTemplate< ElGamalObjectImpl< DL_EncryptorBase< Integer >, SchemeOptions, SchemeOptions::PublicKey > > Encryptor
Implements PK_Encryptor interface.
Definition elgamal.h:298
CRYPTOPP_STATIC_CONSTEXPR const char * StaticAlgorithmName()
The algorithm name.
Definition elgamal.h:293
PK_FinalTemplate< ElGamalObjectImpl< DL_DecryptorBase< Integer >, SchemeOptions, SchemeOptions::PrivateKey > > Decryptor
Implements PK_Encryptor interface.
Definition elgamal.h:300
SchemeOptions::GroupParameters GroupParameters
Implements DL_GroupParameters interface.
Definition elgamal.h:296
ElGamal key agreement and encryption schemes keys.
Definition elgamal.h:262
DL_PrivateKey_ElGamal< DL_CryptoKeys_ElGamal::PrivateKey > PrivateKey
Implements DL_PrivateKey interface.
Definition elgamal.h:266
DL_CryptoKeys_ElGamal::GroupParameters GroupParameters
Implements DL_GroupParameters interface.
Definition elgamal.h:264
DL_PublicKey_ElGamal< DL_CryptoKeys_ElGamal::PublicKey > PublicKey
Implements DL_PublicKey interface.
Definition elgamal.h:268
Converts an enumeration to a type suitable for use as a template parameter.
Definition cryptlib.h:136