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
17NAMESPACE_BEGIN(CryptoPP)
18
19/// \brief ElGamal key agreement and encryption schemes base class
20/// \since Crypto++ 1.0
24{
25public:
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
97template <class BASE, class SCHEME_OPTIONS, class KEY>
98class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase
99{
100public:
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
111protected:
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
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
147NAMESPACE_END
148
149#endif
GF(p) group parameters that default to safe primes.
Definition: gfpcrypt.h:181
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:2079
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:1894
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:497
Discrete Log (DL) public key in GF(p) groups.
Definition: gfpcrypt.h:461
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:2135
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:1882
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