00001
00002
00003 #ifndef CRYPTOPP_PUBKEY_H
00004 #define CRYPTOPP_PUBKEY_H
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "config.h"
00038
00039 #if CRYPTOPP_MSC_VERSION
00040 # pragma warning(push)
00041 # pragma warning(disable: 4702)
00042 #endif
00043
00044 #include "cryptlib.h"
00045 #include "integer.h"
00046 #include "modarith.h"
00047 #include "filters.h"
00048 #include "eprecomp.h"
00049 #include "fips140.h"
00050 #include "argnames.h"
00051 #include "smartptr.h"
00052 #include "stdcpp.h"
00053
00054
00055 #undef INTERFACE
00056
00057 NAMESPACE_BEGIN(CryptoPP)
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
00070 {
00071 public:
00072 virtual ~TrapdoorFunctionBounds() {}
00073
00074
00075
00076
00077 virtual Integer PreimageBound() const =0;
00078
00079
00080
00081 virtual Integer ImageBound() const =0;
00082
00083
00084
00085 virtual Integer MaxPreimage() const {return --PreimageBound();}
00086
00087
00088
00089 virtual Integer MaxImage() const {return --ImageBound();}
00090 };
00091
00092
00093
00094
00095
00096
00097
00098 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
00099 {
00100 public:
00101
00102
00103
00104
00105
00106
00107
00108
00109 virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
00110
00111
00112
00113
00114 virtual bool IsRandomized() const {return true;}
00115
00116 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00117 virtual ~RandomizedTrapdoorFunction() { }
00118 #endif
00119 };
00120
00121
00122
00123
00124
00125
00126
00127 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
00128 {
00129 public:
00130 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00131 virtual ~TrapdoorFunction() { }
00132 #endif
00133
00134
00135
00136
00137
00138
00139
00140
00141 Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
00142 {CRYPTOPP_UNUSED(rng); return ApplyFunction(x);}
00143 bool IsRandomized() const {return false;}
00144
00145
00146
00147
00148
00149
00150 virtual Integer ApplyFunction(const Integer &x) const =0;
00151 };
00152
00153
00154
00155
00156
00157
00158
00159 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
00160 {
00161 public:
00162 virtual ~RandomizedTrapdoorFunctionInverse() {}
00163
00164
00165
00166
00167
00168
00169
00170 virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
00171
00172
00173
00174
00175 virtual bool IsRandomized() const {return true;}
00176 };
00177
00178
00179
00180
00181
00182
00183
00184 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
00185 {
00186 public:
00187 virtual ~TrapdoorFunctionInverse() {}
00188
00189
00190
00191
00192
00193
00194
00195
00196 Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
00197 {return CalculateInverse(rng, x);}
00198
00199
00200
00201
00202 bool IsRandomized() const {return false;}
00203
00204 virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
00205 };
00206
00207
00208
00209
00210
00211 class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
00212 {
00213 public:
00214 virtual ~PK_EncryptionMessageEncodingMethod() {}
00215
00216 virtual bool ParameterSupported(const char *name) const
00217 {CRYPTOPP_UNUSED(name); return false;}
00218
00219
00220 virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0;
00221
00222 virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs ¶meters) const =0;
00223
00224 virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs ¶meters) const =0;
00225 };
00226
00227
00228
00229
00230
00231
00232
00233 template <class TFI, class MEI>
00234 class CRYPTOPP_NO_VTABLE TF_Base
00235 {
00236 protected:
00237 virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
00238
00239 typedef TFI TrapdoorFunctionInterface;
00240 virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
00241
00242 typedef MEI MessageEncodingInterface;
00243 virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
00244
00245 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00246 virtual ~TF_Base() { }
00247 #endif
00248 };
00249
00250
00251
00252
00253
00254
00255 template <class BASE>
00256 class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
00257 {
00258 public:
00259 size_t MaxPlaintextLength(size_t ciphertextLength) const
00260 {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
00261 size_t CiphertextLength(size_t plaintextLength) const
00262 {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
00263
00264 virtual size_t FixedMaxPlaintextLength() const =0;
00265 virtual size_t FixedCiphertextLength() const =0;
00266
00267 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00268 virtual ~PK_FixedLengthCryptoSystemImpl() { }
00269 #endif
00270 };
00271
00272
00273
00274
00275
00276 template <class INTERFACE, class BASE>
00277 class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
00278 {
00279 public:
00280 bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);}
00281 size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
00282 size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
00283
00284 protected:
00285 size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
00286
00287 size_t PaddedBlockBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().PreimageBound().BitCount(),1U);}
00288
00289 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00290 virtual ~TF_CryptoSystemBase() { }
00291 #endif
00292 };
00293
00294
00295
00296 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
00297 {
00298 public:
00299 DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const;
00300
00301 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00302 virtual ~TF_DecryptorBase() { }
00303 #endif
00304 };
00305
00306
00307
00308 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
00309 {
00310 public:
00311 void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const;
00312
00313 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00314 virtual ~TF_EncryptorBase() { }
00315 #endif
00316 };
00317
00318
00319
00320 typedef std::pair<const byte *, size_t> HashIdentifier;
00321
00322
00323
00324
00325
00326
00327
00328 class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
00329 {
00330 public:
00331 virtual ~PK_SignatureMessageEncodingMethod() {}
00332
00333 virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const
00334 {CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
00335 virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
00336 {CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
00337
00338 bool IsProbabilistic() const
00339 {return true;}
00340 bool AllowNonrecoverablePart() const
00341 {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00342 virtual bool RecoverablePartFirst() const
00343 {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00344
00345
00346 virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const
00347 {CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength);}
00348
00349
00350 virtual void ProcessRecoverableMessage(HashTransformation &hash,
00351 const byte *recoverableMessage, size_t recoverableMessageLength,
00352 const byte *presignature, size_t presignatureLength,
00353 SecByteBlock &semisignature) const
00354 {
00355 CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength);
00356 CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength); CRYPTOPP_UNUSED(semisignature);
00357 if (RecoverablePartFirst())
00358 assert(!"ProcessRecoverableMessage() not implemented");
00359 }
00360
00361 virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
00362 const byte *recoverableMessage, size_t recoverableMessageLength,
00363 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00364 byte *representative, size_t representativeBitLength) const =0;
00365
00366 virtual bool VerifyMessageRepresentative(
00367 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00368 byte *representative, size_t representativeBitLength) const =0;
00369
00370 virtual DecodingResult RecoverMessageFromRepresentative(
00371 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00372 byte *representative, size_t representativeBitLength,
00373 byte *recoveredMessage) const
00374 {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty);
00375 CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(recoveredMessage);
00376 throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00377
00378 virtual DecodingResult RecoverMessageFromSemisignature(
00379 HashTransformation &hash, HashIdentifier hashIdentifier,
00380 const byte *presignature, size_t presignatureLength,
00381 const byte *semisignature, size_t semisignatureLength,
00382 byte *recoveredMessage) const
00383 {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength);
00384 CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength); CRYPTOPP_UNUSED(recoveredMessage);
00385 throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00386
00387
00388 struct HashIdentifierLookup
00389 {
00390 template <class H> struct HashIdentifierLookup2
00391 {
00392 static HashIdentifier CRYPTOPP_API Lookup()
00393 {
00394 return HashIdentifier((const byte *)NULL, 0);
00395 }
00396 };
00397 };
00398 };
00399
00400
00401
00402
00403
00404 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
00405 {
00406 public:
00407 bool VerifyMessageRepresentative(
00408 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00409 byte *representative, size_t representativeBitLength) const;
00410 };
00411
00412
00413
00414
00415
00416 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
00417 {
00418 public:
00419 bool VerifyMessageRepresentative(
00420 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00421 byte *representative, size_t representativeBitLength) const;
00422 };
00423
00424
00425
00426
00427
00428 class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
00429 {
00430 public:
00431 void ComputeMessageRepresentative(RandomNumberGenerator &rng,
00432 const byte *recoverableMessage, size_t recoverableMessageLength,
00433 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00434 byte *representative, size_t representativeBitLength) const;
00435 };
00436
00437
00438
00439
00440
00441 class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
00442 {
00443 public:
00444 void ComputeMessageRepresentative(RandomNumberGenerator &rng,
00445 const byte *recoverableMessage, size_t recoverableMessageLength,
00446 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00447 byte *representative, size_t representativeBitLength) const;
00448 };
00449
00450
00451
00452
00453
00454 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
00455 {
00456 public:
00457 PK_MessageAccumulatorBase() : m_empty(true) {}
00458
00459 virtual HashTransformation & AccessHash() =0;
00460
00461 void Update(const byte *input, size_t length)
00462 {
00463 AccessHash().Update(input, length);
00464 m_empty = m_empty && length == 0;
00465 }
00466
00467 SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
00468 Integer m_k, m_s;
00469 bool m_empty;
00470 };
00471
00472
00473
00474
00475
00476 template <class HASH_ALGORITHM>
00477 class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
00478 {
00479 public:
00480 HashTransformation & AccessHash() {return this->m_object;}
00481 };
00482
00483
00484 template <class INTERFACE, class BASE>
00485 class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTERFACE, protected BASE
00486 {
00487 public:
00488 size_t SignatureLength() const
00489 {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
00490 size_t MaxRecoverableLength() const
00491 {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
00492 size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
00493 {CRYPTOPP_UNUSED(signatureLength); return this->MaxRecoverableLength();}
00494
00495 bool IsProbabilistic() const
00496 {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
00497 bool AllowNonrecoverablePart() const
00498 {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
00499 bool RecoverablePartFirst() const
00500 {return this->GetMessageEncodingInterface().RecoverablePartFirst();}
00501
00502 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00503 virtual ~TF_SignatureSchemeBase() { }
00504 #endif
00505
00506 protected:
00507 size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
00508
00509 size_t MessageRepresentativeBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().ImageBound().BitCount(),1U);}
00510 virtual HashIdentifier GetHashIdentifier() const =0;
00511 virtual size_t GetDigestSize() const =0;
00512 };
00513
00514
00515 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
00516 {
00517 public:
00518 void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const;
00519 size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
00520
00521 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00522 virtual ~TF_SignerBase() { }
00523 #endif
00524 };
00525
00526
00527 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
00528 {
00529 public:
00530 void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const;
00531 bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
00532 DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
00533
00534 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00535 virtual ~TF_VerifierBase() { }
00536 #endif
00537 };
00538
00539
00540
00541
00542 template <class T1, class T2, class T3>
00543 struct TF_CryptoSchemeOptions
00544 {
00545 typedef T1 AlgorithmInfo;
00546 typedef T2 Keys;
00547 typedef typename Keys::PrivateKey PrivateKey;
00548 typedef typename Keys::PublicKey PublicKey;
00549 typedef T3 MessageEncodingMethod;
00550 };
00551
00552
00553 template <class T1, class T2, class T3, class T4>
00554 struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3>
00555 {
00556 typedef T4 HashFunction;
00557 };
00558
00559
00560 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
00561 class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
00562 {
00563 public:
00564 typedef SCHEME_OPTIONS SchemeOptions;
00565 typedef KEY_CLASS KeyClass;
00566
00567 PublicKey & AccessPublicKey() {return AccessKey();}
00568 const PublicKey & GetPublicKey() const {return GetKey();}
00569
00570 PrivateKey & AccessPrivateKey() {return AccessKey();}
00571 const PrivateKey & GetPrivateKey() const {return GetKey();}
00572
00573 virtual const KeyClass & GetKey() const =0;
00574 virtual KeyClass & AccessKey() =0;
00575
00576 const KeyClass & GetTrapdoorFunction() const {return GetKey();}
00577
00578 PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
00579 {
00580 CRYPTOPP_UNUSED(rng);
00581 return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
00582 }
00583 PK_MessageAccumulator * NewVerificationAccumulator() const
00584 {
00585 return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
00586 }
00587
00588 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00589 virtual ~TF_ObjectImplBase() { }
00590 #endif
00591
00592 protected:
00593 const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
00594 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
00595 const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
00596 {return GetKey();}
00597 const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
00598 {return GetKey();}
00599
00600
00601 HashIdentifier GetHashIdentifier() const
00602 {
00603 typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
00604 return L::Lookup();
00605 }
00606 size_t GetDigestSize() const
00607 {
00608 typedef CPP_TYPENAME SchemeOptions::HashFunction H;
00609 return H::DIGESTSIZE;
00610 }
00611 };
00612
00613
00614 template <class BASE, class SCHEME_OPTIONS, class KEY>
00615 class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
00616 {
00617 public:
00618 TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {}
00619 void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;}
00620
00621 const KEY & GetKey() const {return *m_pKey;}
00622 KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");}
00623
00624 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00625 virtual ~TF_ObjectImplExtRef() { }
00626 #endif
00627
00628 private:
00629 const KEY * m_pKey;
00630 };
00631
00632
00633 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
00634 class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS>
00635 {
00636 public:
00637 typedef KEY_CLASS KeyClass;
00638
00639 const KeyClass & GetKey() const {return m_trapdoorFunction;}
00640 KeyClass & AccessKey() {return m_trapdoorFunction;}
00641
00642 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00643 virtual ~TF_ObjectImpl() { }
00644 #endif
00645
00646 private:
00647 KeyClass m_trapdoorFunction;
00648 };
00649
00650
00651 template <class SCHEME_OPTIONS>
00652 class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
00653 {
00654 };
00655
00656
00657 template <class SCHEME_OPTIONS>
00658 class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
00659 {
00660 };
00661
00662
00663 template <class SCHEME_OPTIONS>
00664 class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
00665 {
00666 };
00667
00668
00669 template <class SCHEME_OPTIONS>
00670 class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
00671 {
00672 };
00673
00674
00675
00676
00677 class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
00678 {
00679 public:
00680 virtual ~MaskGeneratingFunction() {}
00681 virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0;
00682 };
00683
00684 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);
00685
00686
00687 class P1363_MGF1 : public MaskGeneratingFunction
00688 {
00689 public:
00690 static const char * CRYPTOPP_API StaticAlgorithmName() {return "MGF1";}
00691 void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const
00692 {
00693 P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0);
00694 }
00695 };
00696
00697
00698
00699
00700 template <class H>
00701 class P1363_KDF2
00702 {
00703 public:
00704 static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
00705 {
00706 H h;
00707 P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
00708 }
00709 };
00710
00711
00712
00713
00714 class DL_BadElement : public InvalidDataFormat
00715 {
00716 public:
00717 DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
00718 };
00719
00720
00721 template <class T>
00722 class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters
00723 {
00724 typedef DL_GroupParameters<T> ThisClass;
00725
00726 public:
00727 typedef T Element;
00728
00729 DL_GroupParameters() : m_validationLevel(0) {}
00730
00731
00732 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
00733 {
00734 if (!GetBasePrecomputation().IsInitialized())
00735 return false;
00736
00737 if (m_validationLevel > level)
00738 return true;
00739
00740 bool pass = ValidateGroup(rng, level);
00741 pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
00742
00743 m_validationLevel = pass ? level+1 : 0;
00744
00745 return pass;
00746 }
00747
00748 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00749 {
00750 return GetValueHelper(this, name, valueType, pValue)
00751 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
00752 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
00753 ;
00754 }
00755
00756 bool SupportsPrecomputation() const {return true;}
00757
00758 void Precompute(unsigned int precomputationStorage=16)
00759 {
00760 AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
00761 }
00762
00763 void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
00764 {
00765 AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
00766 m_validationLevel = 0;
00767 }
00768
00769 void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
00770 {
00771 GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
00772 }
00773
00774
00775 virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
00776 virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
00777 virtual Element ExponentiateBase(const Integer &exponent) const
00778 {
00779 return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
00780 }
00781 virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
00782 {
00783 Element result;
00784 SimultaneousExponentiate(&result, base, &exponent, 1);
00785 return result;
00786 }
00787
00788 virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
00789 virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
00790 virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
00791 virtual const Integer & GetSubgroupOrder() const =0;
00792 virtual Integer GetMaxExponent() const =0;
00793 virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();}
00794 virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
00795 virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
00796 virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
00797 virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
00798 virtual Integer ConvertElementToInteger(const Element &element) const =0;
00799 virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
00800 virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
00801 virtual bool FastSubgroupCheckAvailable() const =0;
00802 virtual bool IsIdentity(const Element &element) const =0;
00803 virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
00804
00805 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00806 virtual ~DL_GroupParameters() { }
00807 #endif
00808
00809 protected:
00810 void ParametersChanged() {m_validationLevel = 0;}
00811
00812 private:
00813 mutable unsigned int m_validationLevel;
00814 };
00815
00816
00817 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<CPP_TYPENAME GROUP_PRECOMP::Element> >
00818 class DL_GroupParametersImpl : public BASE
00819 {
00820 public:
00821 typedef GROUP_PRECOMP GroupPrecomputation;
00822 typedef typename GROUP_PRECOMP::Element Element;
00823 typedef BASE_PRECOMP BasePrecomputation;
00824
00825 const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
00826 const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return m_gpc;}
00827 DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return m_gpc;}
00828
00829 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00830 virtual ~DL_GroupParametersImpl() { }
00831 #endif
00832
00833 protected:
00834 GROUP_PRECOMP m_groupPrecomputation;
00835 BASE_PRECOMP m_gpc;
00836 };
00837
00838
00839 template <class T>
00840 class CRYPTOPP_NO_VTABLE DL_Key
00841 {
00842 public:
00843 virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0;
00844 virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
00845 };
00846
00847
00848 template <class T>
00849 class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T>
00850 {
00851 typedef DL_PublicKey<T> ThisClass;
00852
00853 public:
00854 typedef T Element;
00855
00856 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00857 {
00858 return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
00859 CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
00860 }
00861
00862 void AssignFrom(const NameValuePairs &source);
00863
00864
00865 virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
00866 virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
00867 virtual Element ExponentiatePublicElement(const Integer &exponent) const
00868 {
00869 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
00870 return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
00871 }
00872 virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
00873 {
00874 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
00875 return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
00876 }
00877
00878 virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0;
00879 virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
00880
00881 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00882 virtual ~DL_PublicKey() { }
00883 #endif
00884 };
00885
00886
00887 template <class T>
00888 class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T>
00889 {
00890 typedef DL_PrivateKey<T> ThisClass;
00891
00892 public:
00893 typedef T Element;
00894
00895 void MakePublicKey(DL_PublicKey<T> &pub) const
00896 {
00897 pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
00898 pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
00899 }
00900
00901 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00902 {
00903 return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
00904 CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
00905 }
00906
00907 void AssignFrom(const NameValuePairs &source)
00908 {
00909 this->AccessAbstractGroupParameters().AssignFrom(source);
00910 AssignFromHelper(this, source)
00911 CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
00912 }
00913
00914 virtual const Integer & GetPrivateExponent() const =0;
00915 virtual void SetPrivateExponent(const Integer &x) =0;
00916
00917 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00918 virtual ~DL_PrivateKey() { }
00919 #endif
00920 };
00921
00922 template <class T>
00923 void DL_PublicKey<T>::AssignFrom(const NameValuePairs &source)
00924 {
00925 DL_PrivateKey<T> *pPrivateKey = NULL;
00926 if (source.GetThisPointer(pPrivateKey))
00927 pPrivateKey->MakePublicKey(*this);
00928 else
00929 {
00930 this->AccessAbstractGroupParameters().AssignFrom(source);
00931 AssignFromHelper(this, source)
00932 CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
00933 }
00934 }
00935
00936 class OID;
00937
00938
00939 template <class PK, class GP, class O = OID>
00940 class DL_KeyImpl : public PK
00941 {
00942 public:
00943 typedef GP GroupParameters;
00944
00945 O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
00946
00947
00948
00949
00950 bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
00951 {AccessGroupParameters().BERDecode(bt); return true;}
00952 bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
00953 {GetGroupParameters().DEREncode(bt); return true;}
00954
00955 const GP & GetGroupParameters() const {return m_groupParameters;}
00956 GP & AccessGroupParameters() {return m_groupParameters;}
00957
00958 private:
00959 GP m_groupParameters;
00960 };
00961
00962 class X509PublicKey;
00963 class PKCS8PrivateKey;
00964
00965
00966 template <class GP>
00967 class DL_PrivateKeyImpl : public DL_PrivateKey<CPP_TYPENAME GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
00968 {
00969 public:
00970 typedef typename GP::Element Element;
00971
00972
00973 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
00974 {
00975 bool pass = GetAbstractGroupParameters().Validate(rng, level);
00976
00977 const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
00978 const Integer &x = GetPrivateExponent();
00979
00980 pass = pass && x.IsPositive() && x < q;
00981 if (level >= 1)
00982 pass = pass && Integer::Gcd(x, q) == Integer::One();
00983 return pass;
00984 }
00985
00986 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00987 {
00988 return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
00989 }
00990
00991 void AssignFrom(const NameValuePairs &source)
00992 {
00993 AssignFromHelper<DL_PrivateKey<Element> >(this, source);
00994 }
00995
00996 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
00997 {
00998 if (!params.GetThisObject(this->AccessGroupParameters()))
00999 this->AccessGroupParameters().GenerateRandom(rng, params);
01000
01001 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
01002
01003
01004 SetPrivateExponent(x);
01005 }
01006
01007 bool SupportsPrecomputation() const {return true;}
01008
01009 void Precompute(unsigned int precomputationStorage=16)
01010 {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
01011
01012 void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
01013 {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
01014
01015 void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
01016 {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
01017
01018
01019 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
01020 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
01021
01022
01023 const Integer & GetPrivateExponent() const {return m_x;}
01024 void SetPrivateExponent(const Integer &x) {m_x = x;}
01025
01026
01027 void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
01028 {m_x.BERDecode(bt);}
01029 void DEREncodePrivateKey(BufferedTransformation &bt) const
01030 {m_x.DEREncode(bt);}
01031
01032 private:
01033 Integer m_x;
01034 };
01035
01036
01037 template <class BASE, class SIGNATURE_SCHEME>
01038 class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE
01039 {
01040 public:
01041 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
01042 {
01043 BASE::GenerateRandom(rng, params);
01044
01045 if (FIPS_140_2_ComplianceEnabled())
01046 {
01047 typename SIGNATURE_SCHEME::Signer signer(*this);
01048 typename SIGNATURE_SCHEME::Verifier verifier(signer);
01049 SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
01050 }
01051 }
01052 };
01053
01054
01055 template <class GP>
01056 class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
01057 {
01058 public:
01059 typedef typename GP::Element Element;
01060
01061
01062 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
01063 {
01064 bool pass = GetAbstractGroupParameters().Validate(rng, level);
01065 pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
01066 return pass;
01067 }
01068
01069 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
01070 {
01071 return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
01072 }
01073
01074 void AssignFrom(const NameValuePairs &source)
01075 {
01076 AssignFromHelper<DL_PublicKey<Element> >(this, source);
01077 }
01078
01079 bool SupportsPrecomputation() const {return true;}
01080
01081 void Precompute(unsigned int precomputationStorage=16)
01082 {
01083 AccessAbstractGroupParameters().Precompute(precomputationStorage);
01084 AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
01085 }
01086
01087 void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
01088 {
01089 AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
01090 AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
01091 }
01092
01093 void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
01094 {
01095 GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
01096 GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
01097 }
01098
01099
01100 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
01101 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
01102
01103
01104 const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;}
01105 DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;}
01106
01107
01108 bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
01109 {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
01110
01111 private:
01112 typename GP::BasePrecomputation m_ypc;
01113 };
01114
01115
01116 template <class T>
01117 class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
01118 {
01119 public:
01120 virtual void Sign(const DL_GroupParameters<T> ¶ms, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
01121 virtual bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
01122 virtual Integer RecoverPresignature(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
01123 {
01124 CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(publicKey); CRYPTOPP_UNUSED(r); CRYPTOPP_UNUSED(s);
01125 throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");
01126 }
01127 virtual size_t RLen(const DL_GroupParameters<T> ¶ms) const
01128 {return params.GetSubgroupOrder().ByteCount();}
01129 virtual size_t SLen(const DL_GroupParameters<T> ¶ms) const
01130 {return params.GetSubgroupOrder().ByteCount();}
01131 };
01132
01133
01134 template <class T>
01135 class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
01136 {
01137 public:
01138 typedef T Element;
01139
01140 virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
01141 virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
01142
01143 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01144 virtual ~DL_KeyAgreementAlgorithm() { }
01145 #endif
01146 };
01147
01148
01149 template <class T>
01150 class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
01151 {
01152 public:
01153 virtual bool ParameterSupported(const char *name) const
01154 {CRYPTOPP_UNUSED(name); return false;}
01155 virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
01156
01157 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01158 virtual ~DL_KeyDerivationAlgorithm() { }
01159 #endif
01160 };
01161
01162
01163 class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
01164 {
01165 public:
01166 virtual bool ParameterSupported(const char *name) const
01167 {CRYPTOPP_UNUSED(name); return false;}
01168 virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0;
01169 virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0;
01170 virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0;
01171 virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const =0;
01172 virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const =0;
01173
01174 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01175 virtual ~DL_SymmetricEncryptionAlgorithm() { }
01176 #endif
01177 };
01178
01179
01180 template <class KI>
01181 class CRYPTOPP_NO_VTABLE DL_Base
01182 {
01183 protected:
01184 typedef KI KeyInterface;
01185 typedef typename KI::Element Element;
01186
01187 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
01188 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
01189
01190 virtual KeyInterface & AccessKeyInterface() =0;
01191 virtual const KeyInterface & GetKeyInterface() const =0;
01192
01193 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01194 virtual ~DL_Base() { }
01195 #endif
01196 };
01197
01198
01199 template <class INTERFACE, class KEY_INTERFACE>
01200 class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTERFACE, public DL_Base<KEY_INTERFACE>
01201 {
01202 public:
01203 size_t SignatureLength() const
01204 {
01205 return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
01206 + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
01207 }
01208 size_t MaxRecoverableLength() const
01209 {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
01210 size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
01211 {CRYPTOPP_UNUSED(signatureLength); assert(false); return 0;}
01212
01213 bool IsProbabilistic() const
01214 {return true;}
01215 bool AllowNonrecoverablePart() const
01216 {return GetMessageEncodingInterface().AllowNonrecoverablePart();}
01217 bool RecoverablePartFirst() const
01218 {return GetMessageEncodingInterface().RecoverablePartFirst();}
01219
01220 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01221 virtual ~DL_SignatureSchemeBase() { }
01222 #endif
01223
01224 protected:
01225 size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
01226 size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
01227
01228 virtual const DL_ElgamalLikeSignatureAlgorithm<CPP_TYPENAME KEY_INTERFACE::Element> & GetSignatureAlgorithm() const =0;
01229 virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
01230 virtual HashIdentifier GetHashIdentifier() const =0;
01231 virtual size_t GetDigestSize() const =0;
01232 };
01233
01234
01235 template <class T>
01236 class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
01237 {
01238 public:
01239
01240 void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
01241 {
01242 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01243 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01244 const DL_PrivateKey<T> &key = this->GetKeyInterface();
01245
01246 r = params.ConvertElementToInteger(params.ExponentiateBase(k));
01247 alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
01248 }
01249
01250 void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
01251 {
01252 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01253 ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
01254 this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
01255 recoverableMessage, recoverableMessageLength,
01256 ma.m_presignature, ma.m_presignature.size(),
01257 ma.m_semisignature);
01258 }
01259
01260 size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
01261 {
01262 this->GetMaterial().DoQuickSanityCheck();
01263
01264 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01265 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01266 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01267 const DL_PrivateKey<T> &key = this->GetKeyInterface();
01268
01269 SecByteBlock representative(this->MessageRepresentativeLength());
01270 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
01271 rng,
01272 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
01273 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01274 representative, this->MessageRepresentativeBitLength());
01275 ma.m_empty = true;
01276 Integer e(representative, representative.size());
01277
01278
01279
01280 if (rng.CanIncorporateEntropy())
01281 rng.IncorporateEntropy(representative, representative.size());
01282 Integer k(rng, 1, params.GetSubgroupOrder()-1);
01283 Integer r, s;
01284 r = params.ConvertElementToInteger(params.ExponentiateBase(k));
01285 alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 size_t rLen = alg.RLen(params);
01297 r.Encode(signature, rLen);
01298 s.Encode(signature+rLen, alg.SLen(params));
01299
01300 if (restart)
01301 RestartMessageAccumulator(rng, ma);
01302
01303 return this->SignatureLength();
01304 }
01305
01306 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01307 virtual ~DL_SignerBase() { }
01308 #endif
01309
01310 protected:
01311 void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
01312 {
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324 CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(ma);
01325 }
01326 };
01327
01328
01329 template <class T>
01330 class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
01331 {
01332 public:
01333 void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
01334 {
01335 CRYPTOPP_UNUSED(signature); CRYPTOPP_UNUSED(signatureLength);
01336 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01337 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01338 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01339
01340 size_t rLen = alg.RLen(params);
01341 ma.m_semisignature.Assign(signature, rLen);
01342 ma.m_s.Decode(signature+rLen, alg.SLen(params));
01343
01344 this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
01345 }
01346
01347 bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
01348 {
01349 this->GetMaterial().DoQuickSanityCheck();
01350
01351 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01352 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01353 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01354 const DL_PublicKey<T> &key = this->GetKeyInterface();
01355
01356 SecByteBlock representative(this->MessageRepresentativeLength());
01357 this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
01358 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01359 representative, this->MessageRepresentativeBitLength());
01360 ma.m_empty = true;
01361 Integer e(representative, representative.size());
01362
01363 Integer r(ma.m_semisignature, ma.m_semisignature.size());
01364 return alg.Verify(params, key, e, r, ma.m_s);
01365 }
01366
01367 DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
01368 {
01369 this->GetMaterial().DoQuickSanityCheck();
01370
01371 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01372 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01373 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01374 const DL_PublicKey<T> &key = this->GetKeyInterface();
01375
01376 SecByteBlock representative(this->MessageRepresentativeLength());
01377 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
01378 NullRNG(),
01379 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
01380 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01381 representative, this->MessageRepresentativeBitLength());
01382 ma.m_empty = true;
01383 Integer e(representative, representative.size());
01384
01385 ma.m_presignature.New(params.GetEncodedElementSize(false));
01386 Integer r(ma.m_semisignature, ma.m_semisignature.size());
01387 alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
01388
01389 return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
01390 ma.AccessHash(), this->GetHashIdentifier(),
01391 ma.m_presignature, ma.m_presignature.size(),
01392 ma.m_semisignature, ma.m_semisignature.size(),
01393 recoveredMessage);
01394 }
01395
01396 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01397 virtual ~DL_VerifierBase() { }
01398 #endif
01399 };
01400
01401
01402 template <class PK, class KI>
01403 class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
01404 {
01405 public:
01406 typedef typename DL_Base<KI>::Element Element;
01407
01408 size_t MaxPlaintextLength(size_t ciphertextLength) const
01409 {
01410 unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
01411 return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
01412 }
01413
01414 size_t CiphertextLength(size_t plaintextLength) const
01415 {
01416 size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
01417 return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
01418 }
01419
01420 bool ParameterSupported(const char *name) const
01421 {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
01422
01423 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01424 virtual ~DL_CryptoSystemBase() { }
01425 #endif
01426
01427 protected:
01428 virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
01429 virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
01430 virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
01431 };
01432
01433
01434 template <class T>
01435 class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
01436 {
01437 public:
01438 typedef T Element;
01439
01440 DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const
01441 {
01442 try
01443 {
01444 CRYPTOPP_UNUSED(rng);
01445 const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01446 const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01447 const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01448 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01449 const DL_PrivateKey<T> &key = this->GetKeyInterface();
01450
01451 Element q = params.DecodeElement(ciphertext, true);
01452 size_t elementSize = params.GetEncodedElementSize(true);
01453 ciphertext += elementSize;
01454 ciphertextLength -= elementSize;
01455
01456 Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
01457
01458 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
01459 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01460
01461 return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
01462 }
01463 catch (DL_BadElement &)
01464 {
01465 return DecodingResult();
01466 }
01467 }
01468
01469 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01470 virtual ~DL_DecryptorBase() { }
01471 #endif
01472 };
01473
01474
01475 template <class T>
01476 class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
01477 {
01478 public:
01479 typedef T Element;
01480
01481 void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const
01482 {
01483 const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01484 const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01485 const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01486 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01487 const DL_PublicKey<T> &key = this->GetKeyInterface();
01488
01489 Integer x(rng, Integer::One(), params.GetMaxExponent());
01490 Element q = params.ExponentiateBase(x);
01491 params.EncodeElement(true, q, ciphertext);
01492 unsigned int elementSize = params.GetEncodedElementSize(true);
01493 ciphertext += elementSize;
01494
01495 Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
01496
01497 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
01498 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01499
01500 encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
01501 }
01502
01503 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01504 virtual ~DL_EncryptorBase() { }
01505 #endif
01506 };
01507
01508
01509 template <class T1, class T2>
01510 struct DL_SchemeOptionsBase
01511 {
01512 typedef T1 AlgorithmInfo;
01513 typedef T2 GroupParameters;
01514 typedef typename GroupParameters::Element Element;
01515 };
01516
01517
01518 template <class T1, class T2>
01519 struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
01520 {
01521 typedef T2 Keys;
01522 typedef typename Keys::PrivateKey PrivateKey;
01523 typedef typename Keys::PublicKey PublicKey;
01524 };
01525
01526
01527 template <class T1, class T2, class T3, class T4, class T5>
01528 struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
01529 {
01530 typedef T3 SignatureAlgorithm;
01531 typedef T4 MessageEncodingMethod;
01532 typedef T5 HashFunction;
01533 };
01534
01535
01536 template <class T1, class T2, class T3, class T4, class T5>
01537 struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
01538 {
01539 typedef T3 KeyAgreementAlgorithm;
01540 typedef T4 KeyDerivationAlgorithm;
01541 typedef T5 SymmetricEncryptionAlgorithm;
01542 };
01543
01544
01545 template <class BASE, class SCHEME_OPTIONS, class KEY>
01546 class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
01547 {
01548 public:
01549 typedef SCHEME_OPTIONS SchemeOptions;
01550 typedef typename KEY::Element Element;
01551
01552 PrivateKey & AccessPrivateKey() {return m_key;}
01553 PublicKey & AccessPublicKey() {return m_key;}
01554
01555
01556 const KEY & GetKey() const {return m_key;}
01557 KEY & AccessKey() {return m_key;}
01558
01559 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01560 virtual ~DL_ObjectImplBase() { }
01561 #endif
01562
01563 protected:
01564 typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
01565 const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
01566
01567
01568 HashIdentifier GetHashIdentifier() const
01569 {
01570 typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
01571 return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup();
01572 }
01573 size_t GetDigestSize() const
01574 {
01575 typedef CPP_TYPENAME SchemeOptions::HashFunction H;
01576 return H::DIGESTSIZE;
01577 }
01578
01579 private:
01580 KEY m_key;
01581 };
01582
01583
01584 template <class BASE, class SCHEME_OPTIONS, class KEY>
01585 class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
01586 {
01587 public:
01588 typedef typename KEY::Element Element;
01589
01590 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01591 virtual ~DL_ObjectImpl() { }
01592 #endif
01593
01594 protected:
01595 const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
01596 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
01597 const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
01598 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
01599 const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
01600 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
01601 const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
01602 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
01603 HashIdentifier GetHashIdentifier() const
01604 {return HashIdentifier();}
01605 const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
01606 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
01607 };
01608
01609
01610 template <class SCHEME_OPTIONS>
01611 class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
01612 {
01613 public:
01614 PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
01615 {
01616 member_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>);
01617 this->RestartMessageAccumulator(rng, *p);
01618 return p.release();
01619 }
01620 };
01621
01622
01623 template <class SCHEME_OPTIONS>
01624 class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
01625 {
01626 public:
01627 PK_MessageAccumulator * NewVerificationAccumulator() const
01628 {
01629 return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
01630 }
01631 };
01632
01633
01634 template <class SCHEME_OPTIONS>
01635 class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
01636 {
01637 };
01638
01639
01640 template <class SCHEME_OPTIONS>
01641 class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
01642 {
01643 };
01644
01645
01646
01647
01648 template <class T>
01649 class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain
01650 {
01651 public:
01652 typedef T Element;
01653
01654 CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
01655 unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
01656 unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
01657 unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
01658
01659 void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
01660 {
01661 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
01662 x.Encode(privateKey, PrivateKeyLength());
01663 }
01664
01665 void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
01666 {
01667 CRYPTOPP_UNUSED(rng);
01668 const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
01669 Integer x(privateKey, PrivateKeyLength());
01670 Element y = params.ExponentiateBase(x);
01671 params.EncodeElement(true, y, publicKey);
01672 }
01673
01674 bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
01675 {
01676 try
01677 {
01678 const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
01679 Integer x(privateKey, PrivateKeyLength());
01680 Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
01681
01682 Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
01683 GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
01684 params.EncodeElement(false, z, agreedValue);
01685 }
01686 catch (DL_BadElement &)
01687 {
01688 return false;
01689 }
01690 return true;
01691 }
01692
01693 const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
01694
01695 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01696 virtual ~DL_SimpleKeyAgreementDomainBase() { }
01697 #endif
01698
01699 protected:
01700 virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
01701 virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
01702 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
01703 };
01704
01705 enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
01706 typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
01707 typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
01708 typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
01709
01710
01711 template <class ELEMENT, class COFACTOR_OPTION>
01712 class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT>
01713 {
01714 public:
01715 typedef ELEMENT Element;
01716
01717 static const char * CRYPTOPP_API StaticAlgorithmName()
01718 {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
01719
01720 Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
01721 {
01722 return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
01723 COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
01724 }
01725
01726 Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
01727 {
01728 if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
01729 {
01730 const Integer &k = params.GetCofactor();
01731 return params.ExponentiateElement(publicElement,
01732 ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
01733 }
01734 else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
01735 return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
01736 else
01737 {
01738 assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
01739
01740 if (!validateOtherPublicKey)
01741 return params.ExponentiateElement(publicElement, privateExponent);
01742
01743 if (params.FastSubgroupCheckAvailable())
01744 {
01745 if (!params.ValidateElement(2, publicElement, NULL))
01746 throw DL_BadElement();
01747 return params.ExponentiateElement(publicElement, privateExponent);
01748 }
01749 else
01750 {
01751 const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
01752 Element r[2];
01753 params.SimultaneousExponentiate(r, publicElement, e, 2);
01754 if (!params.IsIdentity(r[0]))
01755 throw DL_BadElement();
01756 return r[1];
01757 }
01758 }
01759 }
01760
01761 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
01762 virtual ~DL_KeyAgreementAlgorithm_DH() {}
01763 #endif
01764 };
01765
01766
01767
01768
01769 template <class BASE>
01770 class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
01771 {
01772 public:
01773 PK_FinalTemplate() {}
01774
01775 PK_FinalTemplate(const CryptoMaterial &key)
01776 {this->AccessKey().AssignFrom(key);}
01777
01778 PK_FinalTemplate(BufferedTransformation &bt)
01779 {this->AccessKey().BERDecode(bt);}
01780
01781 PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
01782 {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
01783
01784 PK_FinalTemplate(const Integer &v1)
01785 {this->AccessKey().Initialize(v1);}
01786
01787 #if (defined(_MSC_VER) && _MSC_VER < 1300)
01788
01789 template <class T1, class T2>
01790 PK_FinalTemplate(T1 &v1, T2 &v2)
01791 {this->AccessKey().Initialize(v1, v2);}
01792
01793 template <class T1, class T2, class T3>
01794 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
01795 {this->AccessKey().Initialize(v1, v2, v3);}
01796
01797 template <class T1, class T2, class T3, class T4>
01798 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
01799 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01800
01801 template <class T1, class T2, class T3, class T4, class T5>
01802 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
01803 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01804
01805 template <class T1, class T2, class T3, class T4, class T5, class T6>
01806 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
01807 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01808
01809 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01810 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
01811 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01812
01813 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01814 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
01815 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01816
01817 #else
01818
01819 template <class T1, class T2>
01820 PK_FinalTemplate(const T1 &v1, const T2 &v2)
01821 {this->AccessKey().Initialize(v1, v2);}
01822
01823 template <class T1, class T2, class T3>
01824 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
01825 {this->AccessKey().Initialize(v1, v2, v3);}
01826
01827 template <class T1, class T2, class T3, class T4>
01828 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
01829 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01830
01831 template <class T1, class T2, class T3, class T4, class T5>
01832 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
01833 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01834
01835 template <class T1, class T2, class T3, class T4, class T5, class T6>
01836 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
01837 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01838
01839 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01840 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
01841 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01842
01843 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01844 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)
01845 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01846
01847 template <class T1, class T2>
01848 PK_FinalTemplate(T1 &v1, const T2 &v2)
01849 {this->AccessKey().Initialize(v1, v2);}
01850
01851 template <class T1, class T2, class T3>
01852 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
01853 {this->AccessKey().Initialize(v1, v2, v3);}
01854
01855 template <class T1, class T2, class T3, class T4>
01856 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
01857 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01858
01859 template <class T1, class T2, class T3, class T4, class T5>
01860 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
01861 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01862
01863 template <class T1, class T2, class T3, class T4, class T5, class T6>
01864 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
01865 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01866
01867 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01868 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
01869 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01870
01871 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01872 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)
01873 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01874
01875 #endif
01876 };
01877
01878
01879
01880
01881 struct EncryptionStandard {};
01882
01883
01884
01885
01886 struct SignatureStandard {};
01887
01888 template <class STANDARD, class KEYS, class ALG_INFO>
01889 class TF_ES;
01890
01891
01892 template <class STANDARD, class KEYS, class ALG_INFO = TF_ES<STANDARD, KEYS, int> >
01893 class TF_ES : public KEYS
01894 {
01895 typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
01896
01897 public:
01898
01899 typedef STANDARD Standard;
01900 typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
01901
01902 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
01903
01904
01905 typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor;
01906
01907 typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor;
01908 };
01909
01910 template <class STANDARD, class H, class KEYS, class ALG_INFO>
01911 class TF_SS;
01912
01913
01914 template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> >
01915 class TF_SS : public KEYS
01916 {
01917 public:
01918
01919 typedef STANDARD Standard;
01920 typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
01921 typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
01922
01923 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
01924
01925
01926 typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
01927
01928 typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
01929 };
01930
01931 template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
01932 class DL_SS;
01933
01934
01935 template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
01936 class DL_SS : public KEYS
01937 {
01938 typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
01939
01940 public:
01941 static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
01942
01943
01944 typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
01945
01946 typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
01947 };
01948
01949
01950 template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
01951 class DL_ES : public KEYS
01952 {
01953 typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
01954
01955 public:
01956
01957 typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor;
01958
01959 typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor;
01960 };
01961
01962 NAMESPACE_END
01963
01964 #if CRYPTOPP_MSC_VERSION
01965 # pragma warning(pop)
01966 #endif
01967
01968 #endif