1
// pubkey.h - written and placed in the public domain by Wei Dai
3
#ifndef CRYPTOPP_PUBKEY_H
4
#define CRYPTOPP_PUBKEY_H
8
This file contains helper classes/functions for implementing public key algorithms.
10
The class hierachies in this .h file tend to look like this:
24
- x1, y1, z1 are abstract interface classes defined in cryptlib.h
25
- x2, y2, z2 are implementations of the interfaces using "abstract policies", which
26
are pure virtual functions that should return interfaces to interchangeable algorithms.
27
These classes have "Base" suffixes.
28
- x3, y3, z3 hold actual algorithms and implement those virtual functions.
29
These classes have "Impl" suffixes.
31
The "TF_" prefix means an implementation using trapdoor functions on integers.
32
The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard).
42
// VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file
45
NAMESPACE_BEGIN(CryptoPP)
48
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
51
virtual ~TrapdoorFunctionBounds() {}
53
virtual Integer PreimageBound() const =0;
54
virtual Integer ImageBound() const =0;
55
virtual Integer MaxPreimage() const {return --PreimageBound();}
56
virtual Integer MaxImage() const {return --ImageBound();}
60
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
63
virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
64
virtual bool IsRandomized() const {return true;}
68
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
71
Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
72
{return ApplyFunction(x);}
73
bool IsRandomized() const {return false;}
75
virtual Integer ApplyFunction(const Integer &x) const =0;
79
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
82
virtual ~RandomizedTrapdoorFunctionInverse() {}
84
virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
85
virtual bool IsRandomized() const {return true;}
89
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
92
virtual ~TrapdoorFunctionInverse() {}
94
Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
95
{return CalculateInverse(rng, x);}
96
bool IsRandomized() const {return false;}
98
virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
101
// ********************************************************
103
//! message encoding method for public key encryption
104
class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
107
virtual ~PK_EncryptionMessageEncodingMethod() {}
109
virtual bool ParameterSupported(const char *name) const {return false;}
111
//! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
112
virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0;
114
virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs ¶meters) const =0;
116
virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs ¶meters) const =0;
119
// ********************************************************
122
template <class TFI, class MEI>
123
class CRYPTOPP_NO_VTABLE TF_Base
126
virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
128
typedef TFI TrapdoorFunctionInterface;
129
virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
131
typedef MEI MessageEncodingInterface;
132
virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
135
// ********************************************************
138
template <class BASE>
139
class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
142
size_t MaxPlaintextLength(size_t ciphertextLength) const
143
{return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
144
size_t CiphertextLength(size_t plaintextLength) const
145
{return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
147
virtual size_t FixedMaxPlaintextLength() const =0;
148
virtual size_t FixedCiphertextLength() const =0;
152
template <class INTERFACE, class BASE>
153
class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
156
bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);}
157
size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
158
size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
161
size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
162
size_t PaddedBlockBitLength() const {return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
166
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
169
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const;
173
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
176
void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const;
179
// ********************************************************
181
typedef std::pair<const byte *, size_t> HashIdentifier;
183
//! interface for message encoding method for public key signature schemes
184
class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
187
virtual ~PK_SignatureMessageEncodingMethod() {}
189
virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const
191
virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
194
bool IsProbabilistic() const
196
bool AllowNonrecoverablePart() const
197
{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
198
virtual bool RecoverablePartFirst() const
199
{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
201
// for verification, DL
202
virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const {}
205
virtual void ProcessRecoverableMessage(HashTransformation &hash,
206
const byte *recoverableMessage, size_t recoverableMessageLength,
207
const byte *presignature, size_t presignatureLength,
208
SecByteBlock &semisignature) const
210
if (RecoverablePartFirst())
211
assert(!"ProcessRecoverableMessage() not implemented");
214
virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
215
const byte *recoverableMessage, size_t recoverableMessageLength,
216
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
217
byte *representative, size_t representativeBitLength) const =0;
219
virtual bool VerifyMessageRepresentative(
220
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
221
byte *representative, size_t representativeBitLength) const =0;
223
virtual DecodingResult RecoverMessageFromRepresentative( // for TF
224
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
225
byte *representative, size_t representativeBitLength,
226
byte *recoveredMessage) const
227
{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
229
virtual DecodingResult RecoverMessageFromSemisignature( // for DL
230
HashTransformation &hash, HashIdentifier hashIdentifier,
231
const byte *presignature, size_t presignatureLength,
232
const byte *semisignature, size_t semisignatureLength,
233
byte *recoveredMessage) const
234
{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
237
struct HashIdentifierLookup
239
template <class H> struct HashIdentifierLookup2
241
static HashIdentifier CRYPTOPP_API Lookup()
243
return HashIdentifier(NULL, 0);
249
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
252
bool VerifyMessageRepresentative(
253
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
254
byte *representative, size_t representativeBitLength) const;
257
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
260
bool VerifyMessageRepresentative(
261
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
262
byte *representative, size_t representativeBitLength) const;
265
class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
268
void ComputeMessageRepresentative(RandomNumberGenerator &rng,
269
const byte *recoverableMessage, size_t recoverableMessageLength,
270
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
271
byte *representative, size_t representativeBitLength) const;
274
class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
277
void ComputeMessageRepresentative(RandomNumberGenerator &rng,
278
const byte *recoverableMessage, size_t recoverableMessageLength,
279
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
280
byte *representative, size_t representativeBitLength) const;
283
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
286
PK_MessageAccumulatorBase() : m_empty(true) {}
288
virtual HashTransformation & AccessHash() =0;
290
void Update(const byte *input, size_t length)
292
AccessHash().Update(input, length);
293
m_empty = m_empty && length == 0;
296
SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
301
template <class HASH_ALGORITHM>
302
class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
305
HashTransformation & AccessHash() {return this->m_object;}
309
template <class INTERFACE, class BASE>
310
class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTERFACE, protected BASE
313
size_t SignatureLength() const
314
{return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
315
size_t MaxRecoverableLength() const
316
{return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
317
size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
318
{return this->MaxRecoverableLength();}
320
bool IsProbabilistic() const
321
{return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
322
bool AllowNonrecoverablePart() const
323
{return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
324
bool RecoverablePartFirst() const
325
{return this->GetMessageEncodingInterface().RecoverablePartFirst();}
328
size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
329
size_t MessageRepresentativeBitLength() const {return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
330
virtual HashIdentifier GetHashIdentifier() const =0;
331
virtual size_t GetDigestSize() const =0;
335
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
338
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const;
339
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
343
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
346
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const;
347
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
348
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
351
// ********************************************************
354
template <class T1, class T2, class T3>
355
struct TF_CryptoSchemeOptions
357
typedef T1 AlgorithmInfo;
359
typedef typename Keys::PrivateKey PrivateKey;
360
typedef typename Keys::PublicKey PublicKey;
361
typedef T3 MessageEncodingMethod;
365
template <class T1, class T2, class T3, class T4>
366
struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3>
368
typedef T4 HashFunction;
372
template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
373
class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
376
typedef SCHEME_OPTIONS SchemeOptions;
377
typedef KEY_CLASS KeyClass;
379
PublicKey & AccessPublicKey() {return AccessKey();}
380
const PublicKey & GetPublicKey() const {return GetKey();}
382
PrivateKey & AccessPrivateKey() {return AccessKey();}
383
const PrivateKey & GetPrivateKey() const {return GetKey();}
385
virtual const KeyClass & GetKey() const =0;
386
virtual KeyClass & AccessKey() =0;
388
const KeyClass & GetTrapdoorFunction() const {return GetKey();}
390
PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
392
return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
394
PK_MessageAccumulator * NewVerificationAccumulator() const
396
return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
400
const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
401
{return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
402
const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
404
const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
407
// for signature scheme
408
HashIdentifier GetHashIdentifier() const
410
typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
413
size_t GetDigestSize() const
415
typedef CPP_TYPENAME SchemeOptions::HashFunction H;
416
return H::DIGESTSIZE;
421
template <class BASE, class SCHEME_OPTIONS, class KEY>
422
class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
425
TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {}
426
void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;}
428
const KEY & GetKey() const {return *m_pKey;}
429
KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");}
436
template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
437
class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS>
440
typedef KEY_CLASS KeyClass;
442
const KeyClass & GetKey() const {return m_trapdoorFunction;}
443
KeyClass & AccessKey() {return m_trapdoorFunction;}
446
KeyClass m_trapdoorFunction;
450
template <class SCHEME_OPTIONS>
451
class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
456
template <class SCHEME_OPTIONS>
457
class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
462
template <class SCHEME_OPTIONS>
463
class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
468
template <class SCHEME_OPTIONS>
469
class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
473
// ********************************************************
476
class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
479
virtual ~MaskGeneratingFunction() {}
480
virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0;
483
CRYPTOPP_DLL void CRYPTOPP_API P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart);
486
class P1363_MGF1 : public MaskGeneratingFunction
489
static const char * CRYPTOPP_API StaticAlgorithmName() {return "MGF1";}
490
void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const
492
P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0);
496
// ********************************************************
503
static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
506
P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
510
// ********************************************************
512
//! to be thrown by DecodeElement and AgreeWithStaticPrivateKey
513
class DL_BadElement : public InvalidDataFormat
516
DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
519
//! interface for DL group parameters
521
class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters
523
typedef DL_GroupParameters<T> ThisClass;
528
DL_GroupParameters() : m_validationLevel(0) {}
531
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
533
if (!GetBasePrecomputation().IsInitialized())
536
if (m_validationLevel > level)
539
bool pass = ValidateGroup(rng, level);
540
pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
542
m_validationLevel = pass ? level+1 : 0;
547
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
549
return GetValueHelper(this, name, valueType, pValue)
550
CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
551
CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
555
bool SupportsPrecomputation() const {return true;}
557
void Precompute(unsigned int precomputationStorage=16)
559
AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
562
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
564
AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
565
m_validationLevel = 0;
568
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
570
GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
574
virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
575
virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
576
virtual Element ExponentiateBase(const Integer &exponent) const
578
return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
580
virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
583
SimultaneousExponentiate(&result, base, &exponent, 1);
587
virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
588
virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
589
virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
590
virtual const Integer & GetSubgroupOrder() const =0; // order of subgroup generated by base element
591
virtual Integer GetMaxExponent() const =0;
592
virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();} // one of these two needs to be overriden
593
virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
594
virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
595
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
596
virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
597
virtual Integer ConvertElementToInteger(const Element &element) const =0;
598
virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
599
virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
600
virtual bool FastSubgroupCheckAvailable() const =0;
601
virtual bool IsIdentity(const Element &element) const =0;
602
virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
605
void ParametersChanged() {m_validationLevel = 0;}
608
mutable unsigned int m_validationLevel;
612
template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<CPP_TYPENAME GROUP_PRECOMP::Element> >
613
class DL_GroupParametersImpl : public BASE
616
typedef GROUP_PRECOMP GroupPrecomputation;
617
typedef typename GROUP_PRECOMP::Element Element;
618
typedef BASE_PRECOMP BasePrecomputation;
620
const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
621
const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return m_gpc;}
622
DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return m_gpc;}
625
GROUP_PRECOMP m_groupPrecomputation;
631
class CRYPTOPP_NO_VTABLE DL_Key
634
virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0;
635
virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
638
//! interface for DL public keys
640
class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T>
642
typedef DL_PublicKey<T> ThisClass;
647
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
649
return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
650
CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
653
void AssignFrom(const NameValuePairs &source);
656
virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
657
virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
658
virtual Element ExponentiatePublicElement(const Integer &exponent) const
660
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
661
return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
663
virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
665
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
666
return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
669
virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0;
670
virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
673
//! interface for DL private keys
675
class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T>
677
typedef DL_PrivateKey<T> ThisClass;
682
void MakePublicKey(DL_PublicKey<T> &pub) const
684
pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
685
pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
688
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
690
return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
691
CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
694
void AssignFrom(const NameValuePairs &source)
696
this->AccessAbstractGroupParameters().AssignFrom(source);
697
AssignFromHelper(this, source)
698
CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
701
virtual const Integer & GetPrivateExponent() const =0;
702
virtual void SetPrivateExponent(const Integer &x) =0;
706
void DL_PublicKey<T>::AssignFrom(const NameValuePairs &source)
708
DL_PrivateKey<T> *pPrivateKey = NULL;
709
if (source.GetThisPointer(pPrivateKey))
710
pPrivateKey->MakePublicKey(*this);
713
this->AccessAbstractGroupParameters().AssignFrom(source);
714
AssignFromHelper(this, source)
715
CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
722
template <class PK, class GP, class O = OID>
723
class DL_KeyImpl : public PK
726
typedef GP GroupParameters;
728
O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
729
// void BERDecode(BufferedTransformation &bt)
730
// {PK::BERDecode(bt);}
731
// void DEREncode(BufferedTransformation &bt) const
732
// {PK::DEREncode(bt);}
733
bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
734
{AccessGroupParameters().BERDecode(bt); return true;}
735
bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
736
{GetGroupParameters().DEREncode(bt); return true;}
738
const GP & GetGroupParameters() const {return m_groupParameters;}
739
GP & AccessGroupParameters() {return m_groupParameters;}
742
GP m_groupParameters;
746
class PKCS8PrivateKey;
750
class DL_PrivateKeyImpl : public DL_PrivateKey<CPP_TYPENAME GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
753
typedef typename GP::Element Element;
755
// GeneratableCryptoMaterial
756
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
758
bool pass = GetAbstractGroupParameters().Validate(rng, level);
760
const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
761
const Integer &x = GetPrivateExponent();
763
pass = pass && x.IsPositive() && x < q;
765
pass = pass && Integer::Gcd(x, q) == Integer::One();
769
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
771
return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
774
void AssignFrom(const NameValuePairs &source)
776
AssignFromHelper<DL_PrivateKey<Element> >(this, source);
779
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
781
if (!params.GetThisObject(this->AccessGroupParameters()))
782
this->AccessGroupParameters().GenerateRandom(rng, params);
783
// std::pair<const byte *, int> seed;
784
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
785
// Integer::ANY, Integer::Zero(), Integer::One(),
786
// params.GetValue("DeterministicKeyGenerationSeed", seed) ? &seed : NULL);
787
SetPrivateExponent(x);
790
bool SupportsPrecomputation() const {return true;}
792
void Precompute(unsigned int precomputationStorage=16)
793
{AccessAbstractGroupParameters().Precompute(precomputationStorage);}
795
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
796
{AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
798
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
799
{GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
802
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
803
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
806
const Integer & GetPrivateExponent() const {return m_x;}
807
void SetPrivateExponent(const Integer &x) {m_x = x;}
810
void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
812
void DEREncodePrivateKey(BufferedTransformation &bt) const
820
template <class BASE, class SIGNATURE_SCHEME>
821
class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE
824
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
826
BASE::GenerateRandom(rng, params);
828
if (FIPS_140_2_ComplianceEnabled())
830
typename SIGNATURE_SCHEME::Signer signer(*this);
831
typename SIGNATURE_SCHEME::Verifier verifier(signer);
832
SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
839
class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
842
typedef typename GP::Element Element;
845
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
847
bool pass = GetAbstractGroupParameters().Validate(rng, level);
848
pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
852
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
854
return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
857
void AssignFrom(const NameValuePairs &source)
859
AssignFromHelper<DL_PublicKey<Element> >(this, source);
862
bool SupportsPrecomputation() const {return true;}
864
void Precompute(unsigned int precomputationStorage=16)
866
AccessAbstractGroupParameters().Precompute(precomputationStorage);
867
AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
870
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
872
AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
873
AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
876
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
878
GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
879
GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
883
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
884
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
887
const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;}
888
DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;}
891
bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
892
{return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
895
typename GP::BasePrecomputation m_ypc;
898
//! interface for Elgamal-like signature algorithms
900
class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
903
virtual void Sign(const DL_GroupParameters<T> ¶ms, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
904
virtual bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
905
virtual Integer RecoverPresignature(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
906
{throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");}
907
virtual size_t RLen(const DL_GroupParameters<T> ¶ms) const
908
{return params.GetSubgroupOrder().ByteCount();}
909
virtual size_t SLen(const DL_GroupParameters<T> ¶ms) const
910
{return params.GetSubgroupOrder().ByteCount();}
913
//! interface for DL key agreement algorithms
915
class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
920
virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
921
virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
924
//! interface for key derivation algorithms used in DL cryptosystems
926
class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
929
virtual bool ParameterSupported(const char *name) const {return false;}
930
virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
933
//! interface for symmetric encryption algorithms used in DL cryptosystems
934
class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
937
virtual bool ParameterSupported(const char *name) const {return false;}
938
virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0;
939
virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0;
940
virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0;
941
virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const =0;
942
virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const =0;
947
class CRYPTOPP_NO_VTABLE DL_Base
950
typedef KI KeyInterface;
951
typedef typename KI::Element Element;
953
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
954
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
956
virtual KeyInterface & AccessKeyInterface() =0;
957
virtual const KeyInterface & GetKeyInterface() const =0;
961
template <class INTERFACE, class KEY_INTERFACE>
962
class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTERFACE, public DL_Base<KEY_INTERFACE>
965
size_t SignatureLength() const
967
return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
968
+ GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
970
size_t MaxRecoverableLength() const
971
{return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
972
size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
973
{assert(false); return 0;} // TODO
975
bool IsProbabilistic() const
977
bool AllowNonrecoverablePart() const
978
{return GetMessageEncodingInterface().AllowNonrecoverablePart();}
979
bool RecoverablePartFirst() const
980
{return GetMessageEncodingInterface().RecoverablePartFirst();}
983
size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
984
size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
986
virtual const DL_ElgamalLikeSignatureAlgorithm<CPP_TYPENAME KEY_INTERFACE::Element> & GetSignatureAlgorithm() const =0;
987
virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
988
virtual HashIdentifier GetHashIdentifier() const =0;
989
virtual size_t GetDigestSize() const =0;
994
class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
997
// for validation testing
998
void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
1000
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1001
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1002
const DL_PrivateKey<T> &key = this->GetKeyInterface();
1004
r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1005
alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1008
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
1010
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1011
ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
1012
this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
1013
recoverableMessage, recoverableMessageLength,
1014
ma.m_presignature, ma.m_presignature.size(),
1015
ma.m_semisignature);
1018
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
1020
this->GetMaterial().DoQuickSanityCheck();
1022
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1023
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1024
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1025
const DL_PrivateKey<T> &key = this->GetKeyInterface();
1027
SecByteBlock representative(this->MessageRepresentativeLength());
1028
this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1030
ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1031
ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1032
representative, this->MessageRepresentativeBitLength());
1034
Integer e(representative, representative.size());
1036
// hash message digest into random number k to prevent reusing the same k on a different messages
1037
// after virtual machine rollback
1038
if (rng.CanIncorporateEntropy())
1039
rng.IncorporateEntropy(representative, representative.size());
1040
Integer k(rng, 1, params.GetSubgroupOrder()-1);
1042
r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1043
alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1047
if (this->MaxRecoverableLength() > 0)
1048
r.Decode(ma.m_semisignature, ma.m_semisignature.size());
1050
r.Decode(ma.m_presignature, ma.m_presignature.size());
1051
alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s);
1054
size_t rLen = alg.RLen(params);
1055
r.Encode(signature, rLen);
1056
s.Encode(signature+rLen, alg.SLen(params));
1059
RestartMessageAccumulator(rng, ma);
1061
return this->SignatureLength();
1065
void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
1067
// k needs to be generated before hashing for signature schemes with recovery
1068
// but to defend against VM rollbacks we need to generate k after hashing.
1069
// so this code is commented out, since no DL-based signature scheme with recovery
1070
// has been implemented in Crypto++ anyway
1072
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1073
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1074
ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
1075
ma.m_presignature.New(params.GetEncodedElementSize(false));
1076
params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size());
1083
class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
1086
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
1088
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1089
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1090
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1092
size_t rLen = alg.RLen(params);
1093
ma.m_semisignature.Assign(signature, rLen);
1094
ma.m_s.Decode(signature+rLen, alg.SLen(params));
1096
this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
1099
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
1101
this->GetMaterial().DoQuickSanityCheck();
1103
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1104
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1105
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1106
const DL_PublicKey<T> &key = this->GetKeyInterface();
1108
SecByteBlock representative(this->MessageRepresentativeLength());
1109
this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1110
ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1111
representative, this->MessageRepresentativeBitLength());
1113
Integer e(representative, representative.size());
1115
Integer r(ma.m_semisignature, ma.m_semisignature.size());
1116
return alg.Verify(params, key, e, r, ma.m_s);
1119
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
1121
this->GetMaterial().DoQuickSanityCheck();
1123
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1124
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1125
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1126
const DL_PublicKey<T> &key = this->GetKeyInterface();
1128
SecByteBlock representative(this->MessageRepresentativeLength());
1129
this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1131
ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1132
ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1133
representative, this->MessageRepresentativeBitLength());
1135
Integer e(representative, representative.size());
1137
ma.m_presignature.New(params.GetEncodedElementSize(false));
1138
Integer r(ma.m_semisignature, ma.m_semisignature.size());
1139
alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
1141
return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
1142
ma.AccessHash(), this->GetHashIdentifier(),
1143
ma.m_presignature, ma.m_presignature.size(),
1144
ma.m_semisignature, ma.m_semisignature.size(),
1150
template <class PK, class KI>
1151
class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
1154
typedef typename DL_Base<KI>::Element Element;
1156
size_t MaxPlaintextLength(size_t ciphertextLength) const
1158
unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
1159
return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
1162
size_t CiphertextLength(size_t plaintextLength) const
1164
size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
1165
return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
1168
bool ParameterSupported(const char *name) const
1169
{return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
1172
virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1173
virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
1174
virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
1179
class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
1184
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const
1188
const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1189
const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1190
const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1191
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1192
const DL_PrivateKey<T> &key = this->GetKeyInterface();
1194
Element q = params.DecodeElement(ciphertext, true);
1195
size_t elementSize = params.GetEncodedElementSize(true);
1196
ciphertext += elementSize;
1197
ciphertextLength -= elementSize;
1199
Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
1201
SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
1202
derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1204
return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
1206
catch (DL_BadElement &)
1208
return DecodingResult();
1215
class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
1220
void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const
1222
const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1223
const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1224
const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1225
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1226
const DL_PublicKey<T> &key = this->GetKeyInterface();
1228
Integer x(rng, Integer::One(), params.GetMaxExponent());
1229
Element q = params.ExponentiateBase(x);
1230
params.EncodeElement(true, q, ciphertext);
1231
unsigned int elementSize = params.GetEncodedElementSize(true);
1232
ciphertext += elementSize;
1234
Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
1236
SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
1237
derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1239
encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
1244
template <class T1, class T2>
1245
struct DL_SchemeOptionsBase
1247
typedef T1 AlgorithmInfo;
1248
typedef T2 GroupParameters;
1249
typedef typename GroupParameters::Element Element;
1253
template <class T1, class T2>
1254
struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
1257
typedef typename Keys::PrivateKey PrivateKey;
1258
typedef typename Keys::PublicKey PublicKey;
1262
template <class T1, class T2, class T3, class T4, class T5>
1263
struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
1265
typedef T3 SignatureAlgorithm;
1266
typedef T4 MessageEncodingMethod;
1267
typedef T5 HashFunction;
1271
template <class T1, class T2, class T3, class T4, class T5>
1272
struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
1274
typedef T3 KeyAgreementAlgorithm;
1275
typedef T4 KeyDerivationAlgorithm;
1276
typedef T5 SymmetricEncryptionAlgorithm;
1280
template <class BASE, class SCHEME_OPTIONS, class KEY>
1281
class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
1284
typedef SCHEME_OPTIONS SchemeOptions;
1285
typedef typename KEY::Element Element;
1287
PrivateKey & AccessPrivateKey() {return m_key;}
1288
PublicKey & AccessPublicKey() {return m_key;}
1291
const KEY & GetKey() const {return m_key;}
1292
KEY & AccessKey() {return m_key;}
1295
typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
1296
const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
1298
// for signature scheme
1299
HashIdentifier GetHashIdentifier() const
1301
typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
1302
return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup();
1304
size_t GetDigestSize() const
1306
typedef CPP_TYPENAME SchemeOptions::HashFunction H;
1307
return H::DIGESTSIZE;
1315
template <class BASE, class SCHEME_OPTIONS, class KEY>
1316
class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
1319
typedef typename KEY::Element Element;
1322
const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
1323
{return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
1324
const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
1325
{return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
1326
const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
1327
{return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
1328
const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
1329
{return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
1330
HashIdentifier GetHashIdentifier() const
1331
{return HashIdentifier();}
1332
const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
1333
{return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
1337
template <class SCHEME_OPTIONS>
1338
class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
1341
PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
1343
std::auto_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>);
1344
this->RestartMessageAccumulator(rng, *p);
1350
template <class SCHEME_OPTIONS>
1351
class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
1354
PK_MessageAccumulator * NewVerificationAccumulator() const
1356
return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
1361
template <class SCHEME_OPTIONS>
1362
class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
1367
template <class SCHEME_OPTIONS>
1368
class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
1372
// ********************************************************
1376
class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain
1381
CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
1382
unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
1383
unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
1384
unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
1386
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
1388
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
1389
x.Encode(privateKey, PrivateKeyLength());
1392
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
1394
const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
1395
Integer x(privateKey, PrivateKeyLength());
1396
Element y = params.ExponentiateBase(x);
1397
params.EncodeElement(true, y, publicKey);
1400
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
1404
const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
1405
Integer x(privateKey, PrivateKeyLength());
1406
Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
1408
Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
1409
GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
1410
params.EncodeElement(false, z, agreedValue);
1412
catch (DL_BadElement &)
1419
const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
1422
virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1423
virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
1424
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
1427
enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
1428
typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
1429
typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
1430
typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
1432
//! DH key agreement algorithm
1433
template <class ELEMENT, class COFACTOR_OPTION>
1434
class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT>
1437
typedef ELEMENT Element;
1439
static const char * CRYPTOPP_API StaticAlgorithmName()
1440
{return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
1442
Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
1444
return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
1445
COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
1448
Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
1450
if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
1452
const Integer &k = params.GetCofactor();
1453
return params.ExponentiateElement(publicElement,
1454
ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
1456
else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
1457
return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
1460
assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
1462
if (!validateOtherPublicKey)
1463
return params.ExponentiateElement(publicElement, privateExponent);
1465
if (params.FastSubgroupCheckAvailable())
1467
if (!params.ValidateElement(2, publicElement, NULL))
1468
throw DL_BadElement();
1469
return params.ExponentiateElement(publicElement, privateExponent);
1473
const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
1475
params.SimultaneousExponentiate(r, publicElement, e, 2);
1476
if (!params.IsIdentity(r[0]))
1477
throw DL_BadElement();
1484
// ********************************************************
1486
//! A template implementing constructors for public key algorithm classes
1487
template <class BASE>
1488
class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
1491
PK_FinalTemplate() {}
1493
PK_FinalTemplate(const CryptoMaterial &key)
1494
{this->AccessKey().AssignFrom(key);}
1496
PK_FinalTemplate(BufferedTransformation &bt)
1497
{this->AccessKey().BERDecode(bt);}
1499
PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
1500
{this->AccessKey().AssignFrom(algorithm.GetMaterial());}
1502
PK_FinalTemplate(const Integer &v1)
1503
{this->AccessKey().Initialize(v1);}
1505
#if (defined(_MSC_VER) && _MSC_VER < 1300)
1507
template <class T1, class T2>
1508
PK_FinalTemplate(T1 &v1, T2 &v2)
1509
{this->AccessKey().Initialize(v1, v2);}
1511
template <class T1, class T2, class T3>
1512
PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
1513
{this->AccessKey().Initialize(v1, v2, v3);}
1515
template <class T1, class T2, class T3, class T4>
1516
PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
1517
{this->AccessKey().Initialize(v1, v2, v3, v4);}
1519
template <class T1, class T2, class T3, class T4, class T5>
1520
PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
1521
{this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1523
template <class T1, class T2, class T3, class T4, class T5, class T6>
1524
PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
1525
{this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1527
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1528
PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
1529
{this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1531
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1532
PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
1533
{this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1537
template <class T1, class T2>
1538
PK_FinalTemplate(const T1 &v1, const T2 &v2)
1539
{this->AccessKey().Initialize(v1, v2);}
1541
template <class T1, class T2, class T3>
1542
PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
1543
{this->AccessKey().Initialize(v1, v2, v3);}
1545
template <class T1, class T2, class T3, class T4>
1546
PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
1547
{this->AccessKey().Initialize(v1, v2, v3, v4);}
1549
template <class T1, class T2, class T3, class T4, class T5>
1550
PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
1551
{this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1553
template <class T1, class T2, class T3, class T4, class T5, class T6>
1554
PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
1555
{this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1557
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1558
PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
1559
{this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1561
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1562
PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8)
1563
{this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1565
template <class T1, class T2>
1566
PK_FinalTemplate(T1 &v1, const T2 &v2)
1567
{this->AccessKey().Initialize(v1, v2);}
1569
template <class T1, class T2, class T3>
1570
PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
1571
{this->AccessKey().Initialize(v1, v2, v3);}
1573
template <class T1, class T2, class T3, class T4>
1574
PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
1575
{this->AccessKey().Initialize(v1, v2, v3, v4);}
1577
template <class T1, class T2, class T3, class T4, class T5>
1578
PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
1579
{this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1581
template <class T1, class T2, class T3, class T4, class T5, class T6>
1582
PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
1583
{this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1585
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1586
PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
1587
{this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1589
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1590
PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8)
1591
{this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1596
//! Base class for public key encryption standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
1597
struct EncryptionStandard {};
1599
//! Base class for public key signature standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
1600
struct SignatureStandard {};
1602
template <class STANDARD, class KEYS, class ALG_INFO>
1605
//! Trapdoor Function Based Encryption Scheme
1606
template <class STANDARD, class KEYS, class ALG_INFO = TF_ES<STANDARD, KEYS, int> >
1607
class TF_ES : public KEYS
1609
typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
1612
//! see EncryptionStandard for a list of standards
1613
typedef STANDARD Standard;
1614
typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
1616
static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
1618
//! implements PK_Decryptor interface
1619
typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor;
1620
//! implements PK_Encryptor interface
1621
typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor;
1624
template <class STANDARD, class H, class KEYS, class ALG_INFO> // VC60 workaround: doesn't work if KEYS is first parameter
1627
//! Trapdoor Function Based Signature Scheme
1628
template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> > // VC60 workaround: doesn't work if KEYS is first parameter
1629
class TF_SS : public KEYS
1632
//! see SignatureStandard for a list of standards
1633
typedef STANDARD Standard;
1634
typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
1635
typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
1637
static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
1639
//! implements PK_Signer interface
1640
typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
1641
//! implements PK_Verifier interface
1642
typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
1645
template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
1648
//! Discrete Log Based Signature Scheme
1649
template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
1650
class DL_SS : public KEYS
1652
typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
1655
static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
1657
//! implements PK_Signer interface
1658
typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
1659
//! implements PK_Verifier interface
1660
typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
1663
//! Discrete Log Based Encryption Scheme
1664
template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
1665
class DL_ES : public KEYS
1667
typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
1670
//! implements PK_Decryptor interface
1671
typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor;
1672
//! implements PK_Encryptor interface
1673
typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor;