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