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