File indexing completed on 2025-01-18 09:55:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #ifndef CRYPTOPP_PUBKEY_H
0035 #define CRYPTOPP_PUBKEY_H
0036
0037 #include "config.h"
0038
0039 #if CRYPTOPP_MSC_VERSION
0040 # pragma warning(push)
0041 # pragma warning(disable: 4702)
0042 #endif
0043
0044 #include "cryptlib.h"
0045 #include "integer.h"
0046 #include "algebra.h"
0047 #include "modarith.h"
0048 #include "filters.h"
0049 #include "eprecomp.h"
0050 #include "fips140.h"
0051 #include "argnames.h"
0052 #include "smartptr.h"
0053 #include "stdcpp.h"
0054
0055 #if defined(__SUNPRO_CC)
0056 # define MAYBE_RETURN(x) return x
0057 #else
0058 # define MAYBE_RETURN(x) CRYPTOPP_UNUSED(x)
0059 #endif
0060
0061 NAMESPACE_BEGIN(CryptoPP)
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
0073 {
0074 public:
0075 virtual ~TrapdoorFunctionBounds() {}
0076
0077
0078
0079
0080 virtual Integer PreimageBound() const =0;
0081
0082
0083
0084 virtual Integer ImageBound() const =0;
0085
0086
0087
0088 virtual Integer MaxPreimage() const {return --PreimageBound();}
0089
0090
0091
0092 virtual Integer MaxImage() const {return --ImageBound();}
0093 };
0094
0095
0096
0097
0098
0099
0100 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
0101 {
0102 public:
0103 virtual ~RandomizedTrapdoorFunction() {}
0104
0105
0106
0107
0108
0109
0110
0111
0112 virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
0113
0114
0115
0116
0117 virtual bool IsRandomized() const {return true;}
0118 };
0119
0120
0121
0122
0123
0124
0125 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
0126 {
0127 public:
0128 virtual ~TrapdoorFunction() {}
0129
0130
0131
0132
0133
0134
0135
0136
0137 Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
0138 {CRYPTOPP_UNUSED(rng); return ApplyFunction(x);}
0139 bool IsRandomized() const {return false;}
0140
0141
0142
0143
0144
0145
0146 virtual Integer ApplyFunction(const Integer &x) const =0;
0147 };
0148
0149
0150
0151
0152
0153
0154 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
0155 {
0156 public:
0157 virtual ~RandomizedTrapdoorFunctionInverse() {}
0158
0159
0160
0161
0162
0163
0164
0165 virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
0166
0167
0168
0169
0170 virtual bool IsRandomized() const {return true;}
0171 };
0172
0173
0174
0175
0176
0177
0178 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
0179 {
0180 public:
0181 virtual ~TrapdoorFunctionInverse() {}
0182
0183
0184
0185
0186
0187
0188
0189
0190 Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
0191 {return CalculateInverse(rng, x);}
0192
0193
0194
0195
0196 bool IsRandomized() const {return false;}
0197
0198
0199
0200
0201
0202 virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
0203 };
0204
0205
0206
0207
0208 class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
0209 {
0210 public:
0211 virtual ~PK_EncryptionMessageEncodingMethod() {}
0212
0213 virtual bool ParameterSupported(const char *name) const
0214 {CRYPTOPP_UNUSED(name); return false;}
0215
0216
0217 virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0;
0218
0219 virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs ¶meters) const =0;
0220
0221 virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs ¶meters) const =0;
0222 };
0223
0224
0225
0226
0227
0228
0229 template <class TFI, class MEI>
0230 class CRYPTOPP_NO_VTABLE TF_Base
0231 {
0232 protected:
0233 virtual ~TF_Base() {}
0234
0235 virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
0236
0237 typedef TFI TrapdoorFunctionInterface;
0238 virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
0239
0240 typedef MEI MessageEncodingInterface;
0241 virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
0242 };
0243
0244
0245
0246
0247
0248 template <class BASE>
0249 class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
0250 {
0251 public:
0252 virtual ~PK_FixedLengthCryptoSystemImpl() {}
0253
0254 size_t MaxPlaintextLength(size_t ciphertextLength) const
0255 {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
0256 size_t CiphertextLength(size_t plaintextLength) const
0257 {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
0258
0259 virtual size_t FixedMaxPlaintextLength() const =0;
0260 virtual size_t FixedCiphertextLength() const =0;
0261 };
0262
0263
0264
0265
0266 template <class INTFACE, class BASE>
0267 class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTFACE>, protected BASE
0268 {
0269 public:
0270 virtual ~TF_CryptoSystemBase() {}
0271
0272 bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);}
0273 size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
0274 size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
0275
0276 protected:
0277 size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
0278
0279 size_t PaddedBlockBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().PreimageBound().BitCount(),1U);}
0280 };
0281
0282
0283 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
0284 {
0285 public:
0286 virtual ~TF_DecryptorBase() {}
0287
0288 DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const;
0289 };
0290
0291
0292 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
0293 {
0294 public:
0295 virtual ~TF_EncryptorBase() {}
0296
0297 void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const;
0298 };
0299
0300
0301
0302
0303 typedef std::pair<const byte *, unsigned int> HashIdentifier;
0304
0305
0306
0307
0308
0309
0310 class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
0311 {
0312 public:
0313 virtual ~PK_SignatureMessageEncodingMethod() {}
0314
0315 virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const
0316 {CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
0317 virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
0318 {CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
0319
0320
0321
0322
0323
0324
0325
0326 bool IsProbabilistic() const
0327 {return true;}
0328 bool AllowNonrecoverablePart() const
0329 {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
0330 virtual bool RecoverablePartFirst() const
0331 {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
0332
0333
0334 virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const
0335 {CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength);}
0336
0337
0338 virtual void ProcessRecoverableMessage(HashTransformation &hash,
0339 const byte *recoverableMessage, size_t recoverableMessageLength,
0340 const byte *presignature, size_t presignatureLength,
0341 SecByteBlock &semisignature) const
0342 {
0343 CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength);
0344 CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength); CRYPTOPP_UNUSED(semisignature);
0345 if (RecoverablePartFirst())
0346 CRYPTOPP_ASSERT(!"ProcessRecoverableMessage() not implemented");
0347 }
0348
0349 virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
0350 const byte *recoverableMessage, size_t recoverableMessageLength,
0351 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
0352 byte *representative, size_t representativeBitLength) const =0;
0353
0354 virtual bool VerifyMessageRepresentative(
0355 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
0356 byte *representative, size_t representativeBitLength) const =0;
0357
0358 virtual DecodingResult RecoverMessageFromRepresentative(
0359 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
0360 byte *representative, size_t representativeBitLength,
0361 byte *recoveredMessage) const
0362 {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty);
0363 CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(recoveredMessage);
0364 throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
0365
0366 virtual DecodingResult RecoverMessageFromSemisignature(
0367 HashTransformation &hash, HashIdentifier hashIdentifier,
0368 const byte *presignature, size_t presignatureLength,
0369 const byte *semisignature, size_t semisignatureLength,
0370 byte *recoveredMessage) const
0371 {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength);
0372 CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength); CRYPTOPP_UNUSED(recoveredMessage);
0373 throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
0374
0375
0376 struct HashIdentifierLookup
0377 {
0378 template <class H> struct HashIdentifierLookup2
0379 {
0380 static HashIdentifier CRYPTOPP_API Lookup()
0381 {
0382 return HashIdentifier(static_cast<const byte *>(NULLPTR), 0);
0383 }
0384 };
0385 };
0386 };
0387
0388
0389
0390
0391 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
0392 {
0393 public:
0394 bool VerifyMessageRepresentative(
0395 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
0396 byte *representative, size_t representativeBitLength) const;
0397 };
0398
0399
0400
0401
0402 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
0403 {
0404 public:
0405 bool VerifyMessageRepresentative(
0406 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
0407 byte *representative, size_t representativeBitLength) const;
0408 };
0409
0410
0411
0412
0413 class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
0414 {
0415 public:
0416 void ComputeMessageRepresentative(RandomNumberGenerator &rng,
0417 const byte *recoverableMessage, size_t recoverableMessageLength,
0418 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
0419 byte *representative, size_t representativeBitLength) const;
0420 };
0421
0422
0423
0424
0425 class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
0426 {
0427 public:
0428 void ComputeMessageRepresentative(RandomNumberGenerator &rng,
0429 const byte *recoverableMessage, size_t recoverableMessageLength,
0430 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
0431 byte *representative, size_t representativeBitLength) const;
0432 };
0433
0434 #if 0
0435
0436
0437
0438 class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_SM2 : public PK_DeterministicSignatureMessageEncodingMethod
0439 {
0440 public:
0441 void ComputeMessageRepresentative(RandomNumberGenerator &rng,
0442 const byte *recoverableMessage, size_t recoverableMessageLength,
0443 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
0444 byte *representative, size_t representativeBitLength) const;
0445 };
0446 #endif
0447
0448
0449
0450
0451 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
0452 {
0453 public:
0454 PK_MessageAccumulatorBase() : m_empty(true) {}
0455
0456 virtual HashTransformation & AccessHash() =0;
0457
0458 void Update(const byte *input, size_t length)
0459 {
0460 AccessHash().Update(input, length);
0461 m_empty = m_empty && length == 0;
0462 }
0463
0464 SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
0465 Integer m_k, m_s;
0466 bool m_empty;
0467 };
0468
0469
0470
0471
0472 template <class HASH_ALGORITHM>
0473 class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
0474 {
0475 public:
0476 HashTransformation & AccessHash() {return this->m_object;}
0477 };
0478
0479
0480
0481
0482 template <class INTFACE, class BASE>
0483 class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTFACE, protected BASE
0484 {
0485 public:
0486 virtual ~TF_SignatureSchemeBase() {}
0487
0488 size_t SignatureLength() const
0489 {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
0490 size_t MaxRecoverableLength() const
0491 {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
0492 size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
0493 {CRYPTOPP_UNUSED(signatureLength); return this->MaxRecoverableLength();}
0494
0495 bool IsProbabilistic() const
0496 {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
0497 bool AllowNonrecoverablePart() const
0498 {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
0499 bool RecoverablePartFirst() const
0500 {return this->GetMessageEncodingInterface().RecoverablePartFirst();}
0501
0502 protected:
0503 size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
0504
0505 size_t MessageRepresentativeBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().ImageBound().BitCount(),1U);}
0506 virtual HashIdentifier GetHashIdentifier() const =0;
0507 virtual size_t GetDigestSize() const =0;
0508 };
0509
0510
0511 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
0512 {
0513 public:
0514 virtual ~TF_SignerBase() {}
0515
0516 void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const;
0517 size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
0518 };
0519
0520
0521 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
0522 {
0523 public:
0524 virtual ~TF_VerifierBase() {}
0525
0526 void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const;
0527 bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
0528 DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
0529 };
0530
0531
0532
0533
0534
0535
0536
0537 template <class T1, class T2, class T3>
0538 struct TF_CryptoSchemeOptions
0539 {
0540 typedef T1 AlgorithmInfo;
0541 typedef T2 Keys;
0542 typedef typename Keys::PrivateKey PrivateKey;
0543 typedef typename Keys::PublicKey PublicKey;
0544 typedef T3 MessageEncodingMethod;
0545 };
0546
0547
0548
0549
0550
0551
0552 template <class T1, class T2, class T3, class T4>
0553 struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3>
0554 {
0555 typedef T4 HashFunction;
0556 };
0557
0558
0559
0560
0561
0562 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
0563 class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
0564 {
0565 public:
0566 typedef SCHEME_OPTIONS SchemeOptions;
0567 typedef KEY_CLASS KeyClass;
0568
0569 virtual ~TF_ObjectImplBase() {}
0570
0571 PublicKey & AccessPublicKey() {return AccessKey();}
0572 const PublicKey & GetPublicKey() const {return GetKey();}
0573
0574 PrivateKey & AccessPrivateKey() {return AccessKey();}
0575 const PrivateKey & GetPrivateKey() const {return GetKey();}
0576
0577 virtual const KeyClass & GetKey() const =0;
0578 virtual KeyClass & AccessKey() =0;
0579
0580 const KeyClass & GetTrapdoorFunction() const {return GetKey();}
0581
0582 PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
0583 {
0584 CRYPTOPP_UNUSED(rng);
0585 return new PK_MessageAccumulatorImpl<typename SCHEME_OPTIONS::HashFunction>;
0586 }
0587 PK_MessageAccumulator * NewVerificationAccumulator() const
0588 {
0589 return new PK_MessageAccumulatorImpl<typename SCHEME_OPTIONS::HashFunction>;
0590 }
0591
0592 protected:
0593 const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
0594 {return Singleton<typename SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
0595 const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
0596 {return GetKey();}
0597 const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
0598 {return GetKey();}
0599
0600
0601 HashIdentifier GetHashIdentifier() const
0602 {
0603 typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<typename SchemeOptions::HashFunction> L;
0604 return L::Lookup();
0605 }
0606 size_t GetDigestSize() const
0607 {
0608 typedef typename SchemeOptions::HashFunction H;
0609 return H::DIGESTSIZE;
0610 }
0611 };
0612
0613
0614
0615
0616
0617
0618 template <class BASE, class SCHEME_OPTIONS, class KEY>
0619 class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
0620 {
0621 public:
0622 virtual ~TF_ObjectImplExtRef() {}
0623
0624 TF_ObjectImplExtRef(const KEY *pKey = NULLPTR) : m_pKey(pKey) {}
0625 void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;}
0626
0627 const KEY & GetKey() const {return *m_pKey;}
0628 KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");}
0629
0630 private:
0631 const KEY * m_pKey;
0632 };
0633
0634
0635
0636
0637
0638
0639 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
0640 class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS>
0641 {
0642 public:
0643 typedef KEY_CLASS KeyClass;
0644
0645 virtual ~TF_ObjectImpl() {}
0646
0647 const KeyClass & GetKey() const {return m_trapdoorFunction;}
0648 KeyClass & AccessKey() {return m_trapdoorFunction;}
0649
0650 private:
0651 KeyClass m_trapdoorFunction;
0652 };
0653
0654
0655
0656 template <class SCHEME_OPTIONS>
0657 class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
0658 {
0659 };
0660
0661
0662
0663 template <class SCHEME_OPTIONS>
0664 class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
0665 {
0666 };
0667
0668
0669
0670 template <class SCHEME_OPTIONS>
0671 class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
0672 {
0673 };
0674
0675
0676
0677 template <class SCHEME_OPTIONS>
0678 class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
0679 {
0680 };
0681
0682
0683
0684
0685
0686
0687 class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
0688 {
0689 public:
0690 virtual ~MaskGeneratingFunction() {}
0691
0692
0693
0694
0695
0696
0697
0698
0699 virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0;
0700 };
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713 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);
0714
0715
0716
0717
0718 class P1363_MGF1 : public MaskGeneratingFunction
0719 {
0720 public:
0721
0722
0723
0724
0725 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "MGF1";}
0726
0727
0728
0729
0730
0731
0732
0733
0734 void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const
0735 {
0736 P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULLPTR, 0, mask, 0);
0737 }
0738 };
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748 template <class H>
0749 class P1363_KDF2
0750 {
0751 public:
0752
0753
0754
0755
0756
0757
0758
0759
0760 static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
0761 {
0762 H h;
0763 P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
0764 }
0765 };
0766
0767
0768
0769
0770
0771 class DL_BadElement : public InvalidDataFormat
0772 {
0773 public:
0774 DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
0775 };
0776
0777
0778
0779
0780 template <class T>
0781 class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters
0782 {
0783 typedef DL_GroupParameters<T> ThisClass;
0784
0785 public:
0786 typedef T Element;
0787
0788 virtual ~DL_GroupParameters() {}
0789
0790 DL_GroupParameters() : m_validationLevel(0) {}
0791
0792
0793 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
0794 {
0795 if (!GetBasePrecomputation().IsInitialized())
0796 return false;
0797
0798 if (m_validationLevel > level)
0799 return true;
0800
0801 CRYPTOPP_ASSERT(ValidateGroup(rng, level));
0802 bool pass = ValidateGroup(rng, level);
0803 CRYPTOPP_ASSERT(ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation()));
0804 pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
0805
0806 m_validationLevel = pass ? level+1 : 0;
0807
0808 return pass;
0809 }
0810
0811 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
0812 {
0813 return GetValueHelper(this, name, valueType, pValue)
0814 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
0815 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
0816 ;
0817 }
0818
0819
0820
0821
0822 bool SupportsPrecomputation() const {return true;}
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832 void Precompute(unsigned int precomputationStorage=16)
0833 {
0834 AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
0835 }
0836
0837
0838
0839
0840
0841 void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
0842 {
0843 AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
0844 m_validationLevel = 0;
0845 }
0846
0847
0848
0849
0850
0851 void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
0852 {
0853 GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
0854 }
0855
0856
0857
0858
0859 virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
0860
0861
0862
0863
0864 virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
0865
0866
0867
0868
0869 virtual Element ExponentiateBase(const Integer &exponent) const
0870 {
0871 return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
0872 }
0873
0874
0875
0876
0877
0878
0879 virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
0880 {
0881 Element result;
0882 SimultaneousExponentiate(&result, base, &exponent, 1);
0883 return result;
0884 }
0885
0886
0887
0888 virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
0889
0890
0891
0892 virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
0893
0894
0895
0896 virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
0897
0898
0899
0900 virtual const Integer & GetSubgroupOrder() const =0;
0901
0902
0903
0904 virtual Integer GetMaxExponent() const =0;
0905
0906
0907
0908
0909 virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();}
0910
0911
0912
0913
0914 virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
0915
0916
0917
0918
0919
0920
0921
0922 virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
0923
0924
0925
0926
0927
0928
0929
0930 virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
0931
0932
0933
0934
0935
0936
0937
0938 virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
0939
0940
0941
0942
0943
0944 virtual Integer ConvertElementToInteger(const Element &element) const =0;
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960 virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977 virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
0978
0979 virtual bool FastSubgroupCheckAvailable() const =0;
0980
0981
0982
0983
0984
0985
0986
0987 virtual bool IsIdentity(const Element &element) const =0;
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999 virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
1000
1001 protected:
1002 void ParametersChanged() {m_validationLevel = 0;}
1003
1004 private:
1005 mutable unsigned int m_validationLevel;
1006 };
1007
1008
1009
1010
1011
1012 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<typename GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<typename GROUP_PRECOMP::Element> >
1013 class DL_GroupParametersImpl : public BASE
1014 {
1015 public:
1016 typedef GROUP_PRECOMP GroupPrecomputation;
1017 typedef typename GROUP_PRECOMP::Element Element;
1018 typedef BASE_PRECOMP BasePrecomputation;
1019
1020 virtual ~DL_GroupParametersImpl() {}
1021
1022
1023
1024 const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
1025
1026
1027
1028 const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return m_gpc;}
1029
1030
1031
1032 DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return m_gpc;}
1033
1034 protected:
1035 GROUP_PRECOMP m_groupPrecomputation;
1036 BASE_PRECOMP m_gpc;
1037 };
1038
1039
1040
1041
1042 template <class T>
1043 class CRYPTOPP_NO_VTABLE DL_Key
1044 {
1045 public:
1046 virtual ~DL_Key() {}
1047
1048
1049
1050 virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0;
1051
1052
1053 virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
1054 };
1055
1056
1057 template <class T>
1058 class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T>
1059 {
1060 typedef DL_PublicKey<T> ThisClass;
1061
1062 public:
1063 typedef T Element;
1064
1065 virtual ~DL_PublicKey();
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1078 {
1079 return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
1080 CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
1081 }
1082
1083
1084
1085 void AssignFrom(const NameValuePairs &source);
1086
1087
1088
1089 virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
1090
1091
1092
1093 virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
1094
1095
1096
1097
1098 virtual Element ExponentiatePublicElement(const Integer &exponent) const
1099 {
1100 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1101 return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
1102 }
1103
1104
1105
1106
1107
1108
1109
1110 virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
1111 {
1112 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1113 return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
1114 }
1115
1116
1117
1118
1119
1120 virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0;
1121
1122
1123
1124
1125
1126 virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
1127 };
1128
1129
1130 template<class T>
1131 DL_PublicKey<T>::~DL_PublicKey() {}
1132
1133
1134 template <class T>
1135 class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T>
1136 {
1137 typedef DL_PrivateKey<T> ThisClass;
1138
1139 public:
1140 typedef T Element;
1141
1142 virtual ~DL_PrivateKey();
1143
1144
1145
1146 void MakePublicKey(DL_PublicKey<T> &pub) const
1147 {
1148 pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
1149 pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
1150 }
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1163 {
1164 return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
1165 CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
1166 }
1167
1168
1169
1170 void AssignFrom(const NameValuePairs &source)
1171 {
1172 this->AccessAbstractGroupParameters().AssignFrom(source);
1173 AssignFromHelper(this, source)
1174 CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
1175 }
1176
1177
1178
1179
1180 virtual const Integer & GetPrivateExponent() const =0;
1181
1182
1183
1184 virtual void SetPrivateExponent(const Integer &x) =0;
1185 };
1186
1187
1188 template<class T>
1189 DL_PrivateKey<T>::~DL_PrivateKey() {}
1190
1191 template <class T>
1192 void DL_PublicKey<T>::AssignFrom(const NameValuePairs &source)
1193 {
1194 DL_PrivateKey<T> *pPrivateKey = NULLPTR;
1195 if (source.GetThisPointer(pPrivateKey))
1196 pPrivateKey->MakePublicKey(*this);
1197 else
1198 {
1199 this->AccessAbstractGroupParameters().AssignFrom(source);
1200 AssignFromHelper(this, source)
1201 CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
1202 }
1203 }
1204
1205 class OID;
1206
1207
1208
1209
1210
1211 template <class PK, class GP, class O = OID>
1212 class DL_KeyImpl : public PK
1213 {
1214 public:
1215 typedef GP GroupParameters;
1216
1217 virtual ~DL_KeyImpl() {}
1218
1219 O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
1220 bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
1221 {AccessGroupParameters().BERDecode(bt); return true;}
1222 bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
1223 {GetGroupParameters().DEREncode(bt); return true;}
1224
1225 const GP & GetGroupParameters() const {return m_groupParameters;}
1226 GP & AccessGroupParameters() {return m_groupParameters;}
1227
1228 private:
1229 GP m_groupParameters;
1230 };
1231
1232 class X509PublicKey;
1233 class PKCS8PrivateKey;
1234
1235
1236
1237 template <class GP>
1238 class DL_PrivateKeyImpl : public DL_PrivateKey<typename GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
1239 {
1240 public:
1241 typedef typename GP::Element Element;
1242
1243 virtual ~DL_PrivateKeyImpl() {}
1244
1245
1246 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
1247 {
1248 CRYPTOPP_ASSERT(GetAbstractGroupParameters().Validate(rng, level));
1249 bool pass = GetAbstractGroupParameters().Validate(rng, level);
1250
1251 const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
1252 const Integer &x = GetPrivateExponent();
1253
1254 CRYPTOPP_ASSERT(x.IsPositive());
1255 CRYPTOPP_ASSERT(x < q);
1256 pass = pass && x.IsPositive() && x < q;
1257
1258 if (level >= 1)
1259 {
1260 CRYPTOPP_ASSERT(Integer::Gcd(x, q) == Integer::One());
1261 pass = pass && Integer::Gcd(x, q) == Integer::One();
1262 }
1263 return pass;
1264 }
1265
1266 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1267 {
1268 return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
1269 }
1270
1271 void AssignFrom(const NameValuePairs &source)
1272 {
1273 AssignFromHelper<DL_PrivateKey<Element> >(this, source);
1274 }
1275
1276 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
1277 {
1278 if (!params.GetThisObject(this->AccessGroupParameters()))
1279 this->AccessGroupParameters().GenerateRandom(rng, params);
1280 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
1281 SetPrivateExponent(x);
1282 }
1283
1284 bool SupportsPrecomputation() const {return true;}
1285
1286 void Precompute(unsigned int precomputationStorage=16)
1287 {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
1288
1289 void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
1290 {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
1291
1292 void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
1293 {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
1294
1295
1296 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
1297 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
1298
1299
1300 const Integer & GetPrivateExponent() const {return m_x;}
1301 void SetPrivateExponent(const Integer &x) {m_x = x;}
1302
1303
1304 void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
1305 {m_x.BERDecode(bt);}
1306 void DEREncodePrivateKey(BufferedTransformation &bt) const
1307 {m_x.DEREncode(bt);}
1308
1309 private:
1310 Integer m_x;
1311 };
1312
1313 template <class BASE, class SIGNATURE_SCHEME>
1314 class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE
1315 {
1316 public:
1317 virtual ~DL_PrivateKey_WithSignaturePairwiseConsistencyTest() {}
1318
1319 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
1320 {
1321 BASE::GenerateRandom(rng, params);
1322
1323 if (FIPS_140_2_ComplianceEnabled())
1324 {
1325 typename SIGNATURE_SCHEME::Signer signer(*this);
1326 typename SIGNATURE_SCHEME::Verifier verifier(signer);
1327 SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
1328 }
1329 }
1330 };
1331
1332
1333
1334 template <class GP>
1335 class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
1336 {
1337 public:
1338 typedef typename GP::Element Element;
1339
1340 virtual ~DL_PublicKeyImpl();
1341
1342
1343 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
1344 {
1345 CRYPTOPP_ASSERT(GetAbstractGroupParameters().Validate(rng, level));
1346 bool pass = GetAbstractGroupParameters().Validate(rng, level);
1347 CRYPTOPP_ASSERT(GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation()));
1348 pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
1349 return pass;
1350 }
1351
1352 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1353 {
1354 return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
1355 }
1356
1357 void AssignFrom(const NameValuePairs &source)
1358 {
1359 AssignFromHelper<DL_PublicKey<Element> >(this, source);
1360 }
1361
1362 bool SupportsPrecomputation() const {return true;}
1363
1364 void Precompute(unsigned int precomputationStorage=16)
1365 {
1366 AccessAbstractGroupParameters().Precompute(precomputationStorage);
1367 AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
1368 }
1369
1370 void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
1371 {
1372 AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
1373 AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
1374 }
1375
1376 void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
1377 {
1378 GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
1379 GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
1380 }
1381
1382
1383 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
1384 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
1385
1386
1387 const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;}
1388 DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;}
1389
1390
1391 bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
1392 {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
1393
1394 private:
1395 typename GP::BasePrecomputation m_ypc;
1396 };
1397
1398
1399 template<class GP>
1400 DL_PublicKeyImpl<GP>::~DL_PublicKeyImpl() {}
1401
1402
1403
1404
1405 template <class T>
1406 class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
1407 {
1408 public:
1409 virtual ~DL_ElgamalLikeSignatureAlgorithm() {}
1410
1411
1412
1413
1414
1415
1416
1417
1418 virtual void Sign(const DL_GroupParameters<T> ¶ms, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
1419
1420
1421
1422
1423
1424
1425
1426 virtual bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
1427
1428
1429
1430
1431
1432
1433 virtual Integer RecoverPresignature(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
1434 {
1435 CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(publicKey); CRYPTOPP_UNUSED(r); CRYPTOPP_UNUSED(s);
1436 throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");
1437 MAYBE_RETURN(Integer::Zero());
1438 }
1439
1440
1441
1442 virtual size_t RLen(const DL_GroupParameters<T> ¶ms) const
1443 {return params.GetSubgroupOrder().ByteCount();}
1444
1445
1446
1447 virtual size_t SLen(const DL_GroupParameters<T> ¶ms) const
1448 {return params.GetSubgroupOrder().ByteCount();}
1449
1450
1451
1452
1453 virtual bool IsDeterministic() const
1454 {return false;}
1455 };
1456
1457
1458
1459 class CRYPTOPP_NO_VTABLE DeterministicSignatureAlgorithm
1460 {
1461 public:
1462 virtual ~DeterministicSignatureAlgorithm() {}
1463
1464
1465
1466
1467
1468 virtual Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const =0;
1469 };
1470
1471
1472
1473
1474
1475 template <class T>
1476 class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
1477 {
1478 public:
1479 typedef T Element;
1480
1481 virtual ~DL_KeyAgreementAlgorithm() {}
1482
1483 virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
1484 virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
1485 };
1486
1487
1488
1489
1490
1491 template <class T>
1492 class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
1493 {
1494 public:
1495 virtual ~DL_KeyDerivationAlgorithm() {}
1496
1497 virtual bool ParameterSupported(const char *name) const
1498 {CRYPTOPP_UNUSED(name); return false;}
1499 virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
1500 };
1501
1502
1503
1504 class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
1505 {
1506 public:
1507 virtual ~DL_SymmetricEncryptionAlgorithm() {}
1508
1509 virtual bool ParameterSupported(const char *name) const
1510 {CRYPTOPP_UNUSED(name); return false;}
1511 virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0;
1512 virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0;
1513 virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0;
1514 virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const =0;
1515 virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const =0;
1516 };
1517
1518
1519
1520 template <class KI>
1521 class CRYPTOPP_NO_VTABLE DL_Base
1522 {
1523 protected:
1524 typedef KI KeyInterface;
1525 typedef typename KI::Element Element;
1526
1527 virtual ~DL_Base() {}
1528
1529 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
1530 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
1531
1532 virtual KeyInterface & AccessKeyInterface() =0;
1533 virtual const KeyInterface & GetKeyInterface() const =0;
1534 };
1535
1536
1537
1538
1539
1540
1541 template <class INTFACE, class KEY_INTFACE>
1542 class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTFACE, public DL_Base<KEY_INTFACE>
1543 {
1544 public:
1545 virtual ~DL_SignatureSchemeBase() {}
1546
1547
1548
1549
1550 size_t SignatureLength() const
1551 {
1552 return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
1553 + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
1554 }
1555
1556
1557
1558 size_t MaxRecoverableLength() const
1559 {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
1560
1561
1562
1563
1564
1565 size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
1566 {CRYPTOPP_UNUSED(signatureLength); CRYPTOPP_ASSERT(false); return 0;}
1567
1568
1569
1570 bool IsProbabilistic() const
1571 {return true;}
1572
1573
1574
1575 bool AllowNonrecoverablePart() const
1576 {return GetMessageEncodingInterface().AllowNonrecoverablePart();}
1577
1578
1579
1580 bool RecoverablePartFirst() const
1581 {return GetMessageEncodingInterface().RecoverablePartFirst();}
1582
1583 protected:
1584 size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
1585 size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
1586
1587
1588 virtual bool IsDeterministic() const {return false;}
1589
1590 virtual const DL_ElgamalLikeSignatureAlgorithm<typename KEY_INTFACE::Element> & GetSignatureAlgorithm() const =0;
1591 virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
1592 virtual HashIdentifier GetHashIdentifier() const =0;
1593 virtual size_t GetDigestSize() const =0;
1594 };
1595
1596
1597
1598
1599 template <class T>
1600 class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
1601 {
1602 public:
1603 virtual ~DL_SignerBase() {}
1604
1605
1606
1607
1608
1609
1610 void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
1611 {
1612 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1613 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1614 const DL_PrivateKey<T> &key = this->GetKeyInterface();
1615
1616 r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1617 alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1618 }
1619
1620 void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
1621 {
1622 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1623 ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
1624 this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
1625 recoverableMessage, recoverableMessageLength,
1626 ma.m_presignature, ma.m_presignature.size(),
1627 ma.m_semisignature);
1628 }
1629
1630 size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
1631 {
1632 this->GetMaterial().DoQuickSanityCheck();
1633
1634 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1635 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1636 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1637 const DL_PrivateKey<T> &key = this->GetKeyInterface();
1638
1639 SecByteBlock representative(this->MessageRepresentativeLength());
1640 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1641 rng,
1642 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1643 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1644 representative, this->MessageRepresentativeBitLength());
1645 ma.m_empty = true;
1646 Integer e(representative, representative.size());
1647
1648
1649
1650 if (rng.CanIncorporateEntropy())
1651 rng.IncorporateEntropy(representative, representative.size());
1652
1653 Integer k, ks;
1654 const Integer& q = params.GetSubgroupOrder();
1655 if (alg.IsDeterministic())
1656 {
1657 const Integer& x = key.GetPrivateExponent();
1658 const DeterministicSignatureAlgorithm& det = dynamic_cast<const DeterministicSignatureAlgorithm&>(alg);
1659 k = det.GenerateRandom(x, q, e);
1660 }
1661 else
1662 {
1663 k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
1664 }
1665
1666
1667
1668 ks = k + q;
1669 if (ks.BitCount() == q.BitCount()) {
1670 ks += q;
1671 }
1672
1673 Integer r, s;
1674 r = params.ConvertElementToInteger(params.ExponentiateBase(ks));
1675 alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686 const size_t rLen = alg.RLen(params);
1687 r.Encode(signature, rLen);
1688 s.Encode(signature+rLen, alg.SLen(params));
1689
1690 if (restart)
1691 RestartMessageAccumulator(rng, ma);
1692
1693 return this->SignatureLength();
1694 }
1695
1696 protected:
1697 void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
1698 {
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710 CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(ma);
1711 }
1712 };
1713
1714
1715
1716
1717 template <class T>
1718 class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
1719 {
1720 public:
1721 virtual ~DL_VerifierBase() {}
1722
1723 void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
1724 {
1725 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1726 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1727 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1728
1729
1730
1731
1732 const size_t rLen = alg.RLen(params);
1733 const size_t sLen = alg.SLen(params);
1734 CRYPTOPP_ASSERT(signatureLength >= rLen + sLen);
1735 if (signatureLength < rLen + sLen)
1736 throw InvalidDataFormat("DL_VerifierBase: signature length is not valid.");
1737
1738 ma.m_semisignature.Assign(signature, rLen);
1739 ma.m_s.Decode(signature+rLen, sLen);
1740
1741 this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
1742 }
1743
1744 bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
1745 {
1746 this->GetMaterial().DoQuickSanityCheck();
1747
1748 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1749 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1750 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1751 const DL_PublicKey<T> &key = this->GetKeyInterface();
1752
1753 SecByteBlock representative(this->MessageRepresentativeLength());
1754 this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1755 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1756 representative, this->MessageRepresentativeBitLength());
1757 ma.m_empty = true;
1758 Integer e(representative, representative.size());
1759
1760 Integer r(ma.m_semisignature, ma.m_semisignature.size());
1761 return alg.Verify(params, key, e, r, ma.m_s);
1762 }
1763
1764 DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
1765 {
1766 this->GetMaterial().DoQuickSanityCheck();
1767
1768 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1769 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1770 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1771 const DL_PublicKey<T> &key = this->GetKeyInterface();
1772
1773 SecByteBlock representative(this->MessageRepresentativeLength());
1774 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1775 NullRNG(),
1776 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1777 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1778 representative, this->MessageRepresentativeBitLength());
1779 ma.m_empty = true;
1780 Integer e(representative, representative.size());
1781
1782 ma.m_presignature.New(params.GetEncodedElementSize(false));
1783 Integer r(ma.m_semisignature, ma.m_semisignature.size());
1784 alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
1785
1786 return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
1787 ma.AccessHash(), this->GetHashIdentifier(),
1788 ma.m_presignature, ma.m_presignature.size(),
1789 ma.m_semisignature, ma.m_semisignature.size(),
1790 recoveredMessage);
1791 }
1792 };
1793
1794
1795
1796
1797 template <class PK, class KI>
1798 class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
1799 {
1800 public:
1801 typedef typename DL_Base<KI>::Element Element;
1802
1803 virtual ~DL_CryptoSystemBase() {}
1804
1805 size_t MaxPlaintextLength(size_t ciphertextLength) const
1806 {
1807 unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
1808 return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
1809 }
1810
1811 size_t CiphertextLength(size_t plaintextLength) const
1812 {
1813 size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
1814 return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
1815 }
1816
1817 bool ParameterSupported(const char *name) const
1818 {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
1819
1820 protected:
1821 virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1822 virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
1823 virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
1824 };
1825
1826
1827
1828
1829 template <class T>
1830 class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
1831 {
1832 public:
1833 typedef T Element;
1834
1835 virtual ~DL_DecryptorBase() {}
1836
1837 DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const
1838 {
1839 try
1840 {
1841 CRYPTOPP_UNUSED(rng);
1842 const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1843 const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1844 const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1845 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1846 const DL_PrivateKey<T> &key = this->GetKeyInterface();
1847
1848 Element q = params.DecodeElement(ciphertext, true);
1849 size_t elementSize = params.GetEncodedElementSize(true);
1850 ciphertext += elementSize;
1851 ciphertextLength -= elementSize;
1852
1853 Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
1854
1855 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
1856 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1857
1858 return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
1859 }
1860 catch (DL_BadElement &)
1861 {
1862 return DecodingResult();
1863 }
1864 }
1865 };
1866
1867
1868
1869
1870 template <class T>
1871 class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
1872 {
1873 public:
1874 typedef T Element;
1875
1876 virtual ~DL_EncryptorBase() {}
1877
1878 void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const
1879 {
1880 const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1881 const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1882 const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1883 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
1884 const DL_PublicKey<T> &key = this->GetKeyInterface();
1885
1886 Integer x(rng, Integer::One(), params.GetMaxExponent());
1887 Element q = params.ExponentiateBase(x);
1888 params.EncodeElement(true, q, ciphertext);
1889 unsigned int elementSize = params.GetEncodedElementSize(true);
1890 ciphertext += elementSize;
1891
1892 Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
1893
1894 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
1895 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1896
1897 encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
1898 }
1899 };
1900
1901
1902
1903
1904 template <class T1, class T2>
1905 struct DL_SchemeOptionsBase
1906 {
1907 typedef T1 AlgorithmInfo;
1908 typedef T2 GroupParameters;
1909 typedef typename GroupParameters::Element Element;
1910 };
1911
1912
1913
1914
1915 template <class T1, class T2>
1916 struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
1917 {
1918 typedef T2 Keys;
1919 typedef typename Keys::PrivateKey PrivateKey;
1920 typedef typename Keys::PublicKey PublicKey;
1921 };
1922
1923
1924
1925
1926
1927
1928
1929 template <class T1, class T2, class T3, class T4, class T5>
1930 struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
1931 {
1932 typedef T3 SignatureAlgorithm;
1933 typedef T4 MessageEncodingMethod;
1934 typedef T5 HashFunction;
1935 };
1936
1937
1938
1939
1940
1941
1942
1943 template <class T1, class T2, class T3, class T4, class T5>
1944 struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
1945 {
1946 typedef T3 KeyAgreementAlgorithm;
1947 typedef T4 KeyDerivationAlgorithm;
1948 typedef T5 SymmetricEncryptionAlgorithm;
1949 };
1950
1951
1952
1953
1954
1955 template <class BASE, class SCHEME_OPTIONS, class KEY>
1956 class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
1957 {
1958 public:
1959 typedef SCHEME_OPTIONS SchemeOptions;
1960 typedef typename KEY::Element Element;
1961
1962 virtual ~DL_ObjectImplBase() {}
1963
1964 PrivateKey & AccessPrivateKey() {return m_key;}
1965 PublicKey & AccessPublicKey() {return m_key;}
1966
1967
1968 const KEY & GetKey() const {return m_key;}
1969 KEY & AccessKey() {return m_key;}
1970
1971 protected:
1972 typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
1973 const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
1974
1975
1976 HashIdentifier GetHashIdentifier() const
1977 {
1978 typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
1979 return HashLookup::template HashIdentifierLookup2<typename SchemeOptions::HashFunction>::Lookup();
1980 }
1981 size_t GetDigestSize() const
1982 {
1983 typedef typename SchemeOptions::HashFunction H;
1984 return H::DIGESTSIZE;
1985 }
1986
1987 private:
1988 KEY m_key;
1989 };
1990
1991
1992
1993
1994
1995 template <class BASE, class SCHEME_OPTIONS, class KEY>
1996 class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
1997 {
1998 public:
1999 typedef typename KEY::Element Element;
2000
2001 virtual ~DL_ObjectImpl() {}
2002
2003 protected:
2004 const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
2005 {return Singleton<typename SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
2006 const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
2007 {return Singleton<typename SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
2008 const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
2009 {return Singleton<typename SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
2010 const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
2011 {return Singleton<typename SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
2012 HashIdentifier GetHashIdentifier() const
2013 {return HashIdentifier();}
2014 const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
2015 {return Singleton<typename SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
2016 };
2017
2018
2019
2020 template <class SCHEME_OPTIONS>
2021 class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
2022 {
2023 public:
2024 PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
2025 {
2026 member_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<typename SCHEME_OPTIONS::HashFunction>);
2027 this->RestartMessageAccumulator(rng, *p);
2028 return p.release();
2029 }
2030 };
2031
2032
2033
2034 template <class SCHEME_OPTIONS>
2035 class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
2036 {
2037 public:
2038 PK_MessageAccumulator * NewVerificationAccumulator() const
2039 {
2040 return new PK_MessageAccumulatorImpl<typename SCHEME_OPTIONS::HashFunction>;
2041 }
2042 };
2043
2044
2045
2046 template <class SCHEME_OPTIONS>
2047 class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
2048 {
2049 };
2050
2051
2052
2053 template <class SCHEME_OPTIONS>
2054 class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
2055 {
2056 };
2057
2058
2059
2060
2061
2062 template <class T>
2063 class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain
2064 {
2065 public:
2066 typedef T Element;
2067
2068 virtual ~DL_SimpleKeyAgreementDomainBase() {}
2069
2070 CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
2071 unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
2072 unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
2073 unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
2074
2075 void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
2076 {
2077 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
2078 x.Encode(privateKey, PrivateKeyLength());
2079 }
2080
2081 void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
2082 {
2083 CRYPTOPP_UNUSED(rng);
2084 const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
2085 Integer x(privateKey, PrivateKeyLength());
2086 Element y = params.ExponentiateBase(x);
2087 params.EncodeElement(true, y, publicKey);
2088 }
2089
2090 bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
2091 {
2092 try
2093 {
2094 const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
2095 Integer x(privateKey, PrivateKeyLength());
2096 Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
2097
2098 Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
2099 GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
2100 params.EncodeElement(false, z, agreedValue);
2101 }
2102 catch (DL_BadElement &)
2103 {
2104 return false;
2105 }
2106 return true;
2107 }
2108
2109
2110
2111 const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
2112
2113 protected:
2114 virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
2115 virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
2116 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
2117 };
2118
2119
2120
2121
2122
2123 enum CofactorMultiplicationOption {
2124
2125 NO_COFACTOR_MULTIPLICTION,
2126
2127
2128
2129 COMPATIBLE_COFACTOR_MULTIPLICTION,
2130
2131
2132
2133 INCOMPATIBLE_COFACTOR_MULTIPLICTION};
2134
2135 typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
2136 typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
2137 typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
2138
2139
2140 template <class ELEMENT, class COFACTOR_OPTION>
2141 class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT>
2142 {
2143 public:
2144 typedef ELEMENT Element;
2145
2146 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName()
2147 {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
2148
2149 virtual ~DL_KeyAgreementAlgorithm_DH() {}
2150
2151 Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
2152 {
2153 return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
2154 COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
2155 }
2156
2157 Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
2158 {
2159 if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
2160 {
2161 const Integer &k = params.GetCofactor();
2162 return params.ExponentiateElement(publicElement,
2163 ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
2164 }
2165 else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
2166 return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
2167 else
2168 {
2169 CRYPTOPP_ASSERT(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
2170
2171 if (!validateOtherPublicKey)
2172 return params.ExponentiateElement(publicElement, privateExponent);
2173
2174 if (params.FastSubgroupCheckAvailable())
2175 {
2176 if (!params.ValidateElement(2, publicElement, NULLPTR))
2177 throw DL_BadElement();
2178 return params.ExponentiateElement(publicElement, privateExponent);
2179 }
2180 else
2181 {
2182 const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
2183 Element r[2];
2184 params.SimultaneousExponentiate(r, publicElement, e, 2);
2185 if (!params.IsIdentity(r[0]))
2186 throw DL_BadElement();
2187 return r[1];
2188 }
2189 }
2190 }
2191 };
2192
2193
2194
2195
2196 template <class BASE>
2197 class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
2198 {
2199 public:
2200 PK_FinalTemplate() {}
2201
2202 PK_FinalTemplate(const CryptoMaterial &key)
2203 {this->AccessKey().AssignFrom(key);}
2204
2205 PK_FinalTemplate(BufferedTransformation &bt)
2206 {this->AccessKey().BERDecode(bt);}
2207
2208 PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
2209 {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
2210
2211 PK_FinalTemplate(const Integer &v1)
2212 {this->AccessKey().Initialize(v1);}
2213
2214 template <class T1, class T2>
2215 PK_FinalTemplate(const T1 &v1, const T2 &v2)
2216 {this->AccessKey().Initialize(v1, v2);}
2217
2218 template <class T1, class T2, class T3>
2219 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
2220 {this->AccessKey().Initialize(v1, v2, v3);}
2221
2222 template <class T1, class T2, class T3, class T4>
2223 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
2224 {this->AccessKey().Initialize(v1, v2, v3, v4);}
2225
2226 template <class T1, class T2, class T3, class T4, class T5>
2227 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
2228 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
2229
2230 template <class T1, class T2, class T3, class T4, class T5, class T6>
2231 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
2232 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
2233
2234 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
2235 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
2236 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
2237
2238 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
2239 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)
2240 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
2241
2242 template <class T1, class T2>
2243 PK_FinalTemplate(T1 &v1, const T2 &v2)
2244 {this->AccessKey().Initialize(v1, v2);}
2245
2246 template <class T1, class T2, class T3>
2247 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
2248 {this->AccessKey().Initialize(v1, v2, v3);}
2249
2250 template <class T1, class T2, class T3, class T4>
2251 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
2252 {this->AccessKey().Initialize(v1, v2, v3, v4);}
2253
2254 template <class T1, class T2, class T3, class T4, class T5>
2255 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
2256 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
2257
2258 template <class T1, class T2, class T3, class T4, class T5, class T6>
2259 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
2260 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
2261
2262 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
2263 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
2264 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
2265
2266 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
2267 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)
2268 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
2269 };
2270
2271
2272
2273
2274 struct EncryptionStandard {};
2275
2276
2277
2278
2279 struct SignatureStandard {};
2280
2281
2282
2283
2284
2285 template <class KEYS, class STANDARD, class ALG_INFO>
2286 class TF_ES;
2287
2288 template <class KEYS, class STANDARD, class ALG_INFO = TF_ES<KEYS, STANDARD, int> >
2289 class TF_ES : public KEYS
2290 {
2291 typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
2292
2293 public:
2294
2295 typedef STANDARD Standard;
2296 typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
2297
2298 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
2299
2300
2301 typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor;
2302
2303 typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor;
2304 };
2305
2306
2307
2308
2309
2310
2311 template <class KEYS, class STANDARD, class H, class ALG_INFO>
2312 class TF_SS;
2313
2314 template <class KEYS, class STANDARD, class H, class ALG_INFO = TF_SS<KEYS, STANDARD, H, int> >
2315 class TF_SS : public KEYS
2316 {
2317 public:
2318
2319 typedef STANDARD Standard;
2320 typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
2321 typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
2322
2323 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
2324
2325
2326 typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
2327
2328 typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
2329 };
2330
2331
2332
2333
2334
2335
2336
2337 template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
2338 class DL_SS;
2339
2340 template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
2341 class DL_SS : public KEYS
2342 {
2343 typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
2344
2345 public:
2346 static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
2347
2348
2349 typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
2350
2351 typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
2352 };
2353
2354
2355
2356
2357
2358
2359
2360 template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
2361 class DL_ES : public KEYS
2362 {
2363 typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
2364
2365 public:
2366
2367 typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor;
2368
2369 typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor;
2370 };
2371
2372 NAMESPACE_END
2373
2374 #if CRYPTOPP_MSC_VERSION
2375 # pragma warning(pop)
2376 #endif
2377
2378 #endif