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