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((const byte *)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
01037
01038 if (rng.CanIncorporateEntropy())
01039 rng.IncorporateEntropy(representative, representative.size());
01040 Integer k(rng, 1, params.GetSubgroupOrder()-1);
01041 Integer r, s;
01042 r = params.ConvertElementToInteger(params.ExponentiateBase(k));
01043 alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 size_t rLen = alg.RLen(params);
01055 r.Encode(signature, rLen);
01056 s.Encode(signature+rLen, alg.SLen(params));
01057
01058 if (restart)
01059 RestartMessageAccumulator(rng, ma);
01060
01061 return this->SignatureLength();
01062 }
01063
01064 protected:
01065 void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
01066 {
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 }
01079 };
01080
01081
01082 template <class T>
01083 class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
01084 {
01085 public:
01086 void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
01087 {
01088 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01089 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01090 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01091
01092 size_t rLen = alg.RLen(params);
01093 ma.m_semisignature.Assign(signature, rLen);
01094 ma.m_s.Decode(signature+rLen, alg.SLen(params));
01095
01096 this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
01097 }
01098
01099 bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
01100 {
01101 this->GetMaterial().DoQuickSanityCheck();
01102
01103 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01104 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01105 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01106 const DL_PublicKey<T> &key = this->GetKeyInterface();
01107
01108 SecByteBlock representative(this->MessageRepresentativeLength());
01109 this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
01110 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01111 representative, this->MessageRepresentativeBitLength());
01112 ma.m_empty = true;
01113 Integer e(representative, representative.size());
01114
01115 Integer r(ma.m_semisignature, ma.m_semisignature.size());
01116 return alg.Verify(params, key, e, r, ma.m_s);
01117 }
01118
01119 DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
01120 {
01121 this->GetMaterial().DoQuickSanityCheck();
01122
01123 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01124 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01125 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01126 const DL_PublicKey<T> &key = this->GetKeyInterface();
01127
01128 SecByteBlock representative(this->MessageRepresentativeLength());
01129 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
01130 NullRNG(),
01131 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
01132 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01133 representative, this->MessageRepresentativeBitLength());
01134 ma.m_empty = true;
01135 Integer e(representative, representative.size());
01136
01137 ma.m_presignature.New(params.GetEncodedElementSize(false));
01138 Integer r(ma.m_semisignature, ma.m_semisignature.size());
01139 alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
01140
01141 return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
01142 ma.AccessHash(), this->GetHashIdentifier(),
01143 ma.m_presignature, ma.m_presignature.size(),
01144 ma.m_semisignature, ma.m_semisignature.size(),
01145 recoveredMessage);
01146 }
01147 };
01148
01149
01150 template <class PK, class KI>
01151 class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
01152 {
01153 public:
01154 typedef typename DL_Base<KI>::Element Element;
01155
01156 size_t MaxPlaintextLength(size_t ciphertextLength) const
01157 {
01158 unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
01159 return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
01160 }
01161
01162 size_t CiphertextLength(size_t plaintextLength) const
01163 {
01164 size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
01165 return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
01166 }
01167
01168 bool ParameterSupported(const char *name) const
01169 {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
01170
01171 protected:
01172 virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
01173 virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
01174 virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
01175 };
01176
01177
01178 template <class T>
01179 class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
01180 {
01181 public:
01182 typedef T Element;
01183
01184 DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const
01185 {
01186 try
01187 {
01188 const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01189 const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01190 const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01191 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01192 const DL_PrivateKey<T> &key = this->GetKeyInterface();
01193
01194 Element q = params.DecodeElement(ciphertext, true);
01195 size_t elementSize = params.GetEncodedElementSize(true);
01196 ciphertext += elementSize;
01197 ciphertextLength -= elementSize;
01198
01199 Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
01200
01201 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
01202 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01203
01204 return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
01205 }
01206 catch (DL_BadElement &)
01207 {
01208 return DecodingResult();
01209 }
01210 }
01211 };
01212
01213
01214 template <class T>
01215 class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
01216 {
01217 public:
01218 typedef T Element;
01219
01220 void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const
01221 {
01222 const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01223 const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01224 const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01225 const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01226 const DL_PublicKey<T> &key = this->GetKeyInterface();
01227
01228 Integer x(rng, Integer::One(), params.GetMaxExponent());
01229 Element q = params.ExponentiateBase(x);
01230 params.EncodeElement(true, q, ciphertext);
01231 unsigned int elementSize = params.GetEncodedElementSize(true);
01232 ciphertext += elementSize;
01233
01234 Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
01235
01236 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
01237 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01238
01239 encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
01240 }
01241 };
01242
01243
01244 template <class T1, class T2>
01245 struct DL_SchemeOptionsBase
01246 {
01247 typedef T1 AlgorithmInfo;
01248 typedef T2 GroupParameters;
01249 typedef typename GroupParameters::Element Element;
01250 };
01251
01252
01253 template <class T1, class T2>
01254 struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
01255 {
01256 typedef T2 Keys;
01257 typedef typename Keys::PrivateKey PrivateKey;
01258 typedef typename Keys::PublicKey PublicKey;
01259 };
01260
01261
01262 template <class T1, class T2, class T3, class T4, class T5>
01263 struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
01264 {
01265 typedef T3 SignatureAlgorithm;
01266 typedef T4 MessageEncodingMethod;
01267 typedef T5 HashFunction;
01268 };
01269
01270
01271 template <class T1, class T2, class T3, class T4, class T5>
01272 struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
01273 {
01274 typedef T3 KeyAgreementAlgorithm;
01275 typedef T4 KeyDerivationAlgorithm;
01276 typedef T5 SymmetricEncryptionAlgorithm;
01277 };
01278
01279
01280 template <class BASE, class SCHEME_OPTIONS, class KEY>
01281 class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
01282 {
01283 public:
01284 typedef SCHEME_OPTIONS SchemeOptions;
01285 typedef typename KEY::Element Element;
01286
01287 PrivateKey & AccessPrivateKey() {return m_key;}
01288 PublicKey & AccessPublicKey() {return m_key;}
01289
01290
01291 const KEY & GetKey() const {return m_key;}
01292 KEY & AccessKey() {return m_key;}
01293
01294 protected:
01295 typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
01296 const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
01297
01298
01299 HashIdentifier GetHashIdentifier() const
01300 {
01301 typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
01302 return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup();
01303 }
01304 size_t GetDigestSize() const
01305 {
01306 typedef CPP_TYPENAME SchemeOptions::HashFunction H;
01307 return H::DIGESTSIZE;
01308 }
01309
01310 private:
01311 KEY m_key;
01312 };
01313
01314
01315 template <class BASE, class SCHEME_OPTIONS, class KEY>
01316 class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
01317 {
01318 public:
01319 typedef typename KEY::Element Element;
01320
01321 protected:
01322 const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
01323 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
01324 const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
01325 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
01326 const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
01327 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
01328 const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
01329 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
01330 HashIdentifier GetHashIdentifier() const
01331 {return HashIdentifier();}
01332 const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
01333 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
01334 };
01335
01336
01337 template <class SCHEME_OPTIONS>
01338 class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
01339 {
01340 public:
01341 PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
01342 {
01343 std::auto_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>);
01344 this->RestartMessageAccumulator(rng, *p);
01345 return p.release();
01346 }
01347 };
01348
01349
01350 template <class SCHEME_OPTIONS>
01351 class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
01352 {
01353 public:
01354 PK_MessageAccumulator * NewVerificationAccumulator() const
01355 {
01356 return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
01357 }
01358 };
01359
01360
01361 template <class SCHEME_OPTIONS>
01362 class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
01363 {
01364 };
01365
01366
01367 template <class SCHEME_OPTIONS>
01368 class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
01369 {
01370 };
01371
01372
01373
01374
01375 template <class T>
01376 class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain
01377 {
01378 public:
01379 typedef T Element;
01380
01381 CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
01382 unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
01383 unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
01384 unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
01385
01386 void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
01387 {
01388 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
01389 x.Encode(privateKey, PrivateKeyLength());
01390 }
01391
01392 void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
01393 {
01394 const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
01395 Integer x(privateKey, PrivateKeyLength());
01396 Element y = params.ExponentiateBase(x);
01397 params.EncodeElement(true, y, publicKey);
01398 }
01399
01400 bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
01401 {
01402 try
01403 {
01404 const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
01405 Integer x(privateKey, PrivateKeyLength());
01406 Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
01407
01408 Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
01409 GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
01410 params.EncodeElement(false, z, agreedValue);
01411 }
01412 catch (DL_BadElement &)
01413 {
01414 return false;
01415 }
01416 return true;
01417 }
01418
01419 const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
01420
01421 protected:
01422 virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
01423 virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
01424 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
01425 };
01426
01427 enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
01428 typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
01429 typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
01430 typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
01431
01432
01433 template <class ELEMENT, class COFACTOR_OPTION>
01434 class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT>
01435 {
01436 public:
01437 typedef ELEMENT Element;
01438
01439 static const char * CRYPTOPP_API StaticAlgorithmName()
01440 {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
01441
01442 Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
01443 {
01444 return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
01445 COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
01446 }
01447
01448 Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
01449 {
01450 if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
01451 {
01452 const Integer &k = params.GetCofactor();
01453 return params.ExponentiateElement(publicElement,
01454 ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
01455 }
01456 else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
01457 return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
01458 else
01459 {
01460 assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
01461
01462 if (!validateOtherPublicKey)
01463 return params.ExponentiateElement(publicElement, privateExponent);
01464
01465 if (params.FastSubgroupCheckAvailable())
01466 {
01467 if (!params.ValidateElement(2, publicElement, NULL))
01468 throw DL_BadElement();
01469 return params.ExponentiateElement(publicElement, privateExponent);
01470 }
01471 else
01472 {
01473 const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
01474 Element r[2];
01475 params.SimultaneousExponentiate(r, publicElement, e, 2);
01476 if (!params.IsIdentity(r[0]))
01477 throw DL_BadElement();
01478 return r[1];
01479 }
01480 }
01481 }
01482 };
01483
01484
01485
01486
01487 template <class BASE>
01488 class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
01489 {
01490 public:
01491 PK_FinalTemplate() {}
01492
01493 PK_FinalTemplate(const CryptoMaterial &key)
01494 {this->AccessKey().AssignFrom(key);}
01495
01496 PK_FinalTemplate(BufferedTransformation &bt)
01497 {this->AccessKey().BERDecode(bt);}
01498
01499 PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
01500 {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
01501
01502 PK_FinalTemplate(const Integer &v1)
01503 {this->AccessKey().Initialize(v1);}
01504
01505 #if (defined(_MSC_VER) && _MSC_VER < 1300)
01506
01507 template <class T1, class T2>
01508 PK_FinalTemplate(T1 &v1, T2 &v2)
01509 {this->AccessKey().Initialize(v1, v2);}
01510
01511 template <class T1, class T2, class T3>
01512 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
01513 {this->AccessKey().Initialize(v1, v2, v3);}
01514
01515 template <class T1, class T2, class T3, class T4>
01516 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
01517 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01518
01519 template <class T1, class T2, class T3, class T4, class T5>
01520 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
01521 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01522
01523 template <class T1, class T2, class T3, class T4, class T5, class T6>
01524 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
01525 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01526
01527 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01528 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
01529 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01530
01531 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01532 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
01533 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01534
01535 #else
01536
01537 template <class T1, class T2>
01538 PK_FinalTemplate(const T1 &v1, const T2 &v2)
01539 {this->AccessKey().Initialize(v1, v2);}
01540
01541 template <class T1, class T2, class T3>
01542 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
01543 {this->AccessKey().Initialize(v1, v2, v3);}
01544
01545 template <class T1, class T2, class T3, class T4>
01546 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
01547 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01548
01549 template <class T1, class T2, class T3, class T4, class T5>
01550 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
01551 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01552
01553 template <class T1, class T2, class T3, class T4, class T5, class T6>
01554 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
01555 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01556
01557 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01558 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
01559 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01560
01561 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01562 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)
01563 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01564
01565 template <class T1, class T2>
01566 PK_FinalTemplate(T1 &v1, const T2 &v2)
01567 {this->AccessKey().Initialize(v1, v2);}
01568
01569 template <class T1, class T2, class T3>
01570 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
01571 {this->AccessKey().Initialize(v1, v2, v3);}
01572
01573 template <class T1, class T2, class T3, class T4>
01574 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
01575 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01576
01577 template <class T1, class T2, class T3, class T4, class T5>
01578 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
01579 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01580
01581 template <class T1, class T2, class T3, class T4, class T5, class T6>
01582 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
01583 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01584
01585 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01586 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
01587 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01588
01589 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01590 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)
01591 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01592
01593 #endif
01594 };
01595
01596
01597 struct EncryptionStandard {};
01598
01599
01600 struct SignatureStandard {};
01601
01602 template <class STANDARD, class KEYS, class ALG_INFO>
01603 class TF_ES;
01604
01605
01606 template <class STANDARD, class KEYS, class ALG_INFO = TF_ES<STANDARD, KEYS, int> >
01607 class TF_ES : public KEYS
01608 {
01609 typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
01610
01611 public:
01612
01613 typedef STANDARD Standard;
01614 typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
01615
01616 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
01617
01618
01619 typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor;
01620
01621 typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor;
01622 };
01623
01624 template <class STANDARD, class H, class KEYS, class ALG_INFO>
01625 class TF_SS;
01626
01627
01628 template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> >
01629 class TF_SS : public KEYS
01630 {
01631 public:
01632
01633 typedef STANDARD Standard;
01634 typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
01635 typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
01636
01637 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
01638
01639
01640 typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
01641
01642 typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
01643 };
01644
01645 template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
01646 class DL_SS;
01647
01648
01649 template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
01650 class DL_SS : public KEYS
01651 {
01652 typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
01653
01654 public:
01655 static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
01656
01657
01658 typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
01659
01660 typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
01661 };
01662
01663
01664 template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
01665 class DL_ES : public KEYS
01666 {
01667 typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
01668
01669 public:
01670
01671 typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor;
01672
01673 typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor;
01674 };
01675
01676 NAMESPACE_END
01677
01678 #endif