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