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