Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

pubkey.h

Go to the documentation of this file.
00001 // pubkey.h - written and placed in the public domain by Wei Dai 00002 00003 #ifndef CRYPTOPP_PUBKEY_H 00004 #define CRYPTOPP_PUBKEY_H 00005 00006 /** \file 00007 00008 This file contains helper classes/functions for implementing public key algorithms. 00009 00010 The class hierachies in this .h file tend to look like this: 00011 <pre> 00012 x1 00013 / \ 00014 y1 z1 00015 | | 00016 x2<y1> x2<z1> 00017 | | 00018 y2 z2 00019 | | 00020 x3<y2> x3<z2> 00021 | | 00022 y3 z3 00023 </pre> 00024 - x1, y1, z1 are abstract interface classes defined in cryptlib.h 00025 - x2, y2, z2 are implementations of the interfaces using "abstract policies", which 00026 are pure virtual functions that should return interfaces to interchangeable algorithms. 00027 These classes have "Base" suffixes. 00028 - x3, y3, z3 hold actual algorithms and implement those virtual functions. 00029 These classes have "Impl" suffixes. 00030 00031 The "TF_" prefix means an implementation using trapdoor functions on integers. 00032 The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard). 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 // VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file 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 //! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus) 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 // for verification, DL 00188 virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, unsigned int semisignatureLength) const {} 00189 00190 // for signature 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( // for TF 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( // for DL 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 // VC60 workaround 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 // for signature scheme 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 // VC60 workaround: this function causes internal compiler error 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 // to be thrown by DecodeElement and AgreeWithStaticPrivateKey 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 // CryptoMaterial 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 // non-inherited 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; // order of subgroup generated by base element 00619 virtual Integer GetMaxExponent() const =0; 00620 virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();} // one of these two needs to be overriden 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 // non-inherited 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> &params = 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> &params = 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 // void BERDecode(BufferedTransformation &bt) 00758 // {PK::BERDecode(bt);} 00759 // void DEREncode(BufferedTransformation &bt) const 00760 // {PK::DEREncode(bt);} 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 // GeneratableCryptoMaterial 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 &params) 00808 { 00809 if (!params.GetThisObject(AccessGroupParameters())) 00810 AccessGroupParameters().GenerateRandom(rng, params); 00811 // std::pair<const byte *, int> seed; 00812 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); 00813 // Integer::ANY, Integer::Zero(), Integer::One(), 00814 // params.GetValue("DeterministicKeyGenerationSeed", seed) ? &seed : NULL); 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 // DL_Key 00830 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetGroupParameters();} 00831 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessGroupParameters();} 00832 00833 // DL_PrivateKey 00834 const Integer & GetPrivateExponent() const {return m_x;} 00835 void SetPrivateExponent(const Integer &x) {m_x = x;} 00836 00837 // PKCS8PrivateKey 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 &params) 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 // CryptoMaterial 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 // DL_Key 00911 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetGroupParameters();} 00912 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessGroupParameters();} 00913 00914 // DL_PublicKey 00915 const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;} 00916 DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;} 00917 00918 // non-inherited 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 // virtual Integer EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLength) const =0; 00932 virtual void Sign(const DL_GroupParameters<T> &params, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0; 00933 virtual bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0; 00934 virtual Integer RecoverPresignature(const DL_GroupParameters<T> &params, 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> &params) const 00937 {return params.GetSubgroupOrder().ByteCount();} 00938 virtual unsigned int SLen(const DL_GroupParameters<T> &params) 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> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0; 00950 virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, 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> &params, 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;} // TODO 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 // for validation testing 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> &params = 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> &params = 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> &params = 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> &params = 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> &params = 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> &params = 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> &params = 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> &params = 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 // KeyAccessor 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 // for signature scheme 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> &params = 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> &params = 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 //! DH key agreement algorithm 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> &params, 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> &params, 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 //! A template implementing constructors for public key algorithm classes 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 //! Base class for public key encryption standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms. 01627 struct EncryptionStandard {}; 01628 01629 //! Base class for public key signature standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms. 01630 struct SignatureStandard {}; 01631 01632 template <class STANDARD, class KEYS, class ALG_INFO> 01633 class TF_ES; 01634 01635 //! Trapdoor Function Based Encryption Scheme 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 //! see EncryptionStandard for a list of standards 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 //! implements PK_Decryptor interface 01649 typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor; 01650 //! implements PK_Encryptor interface 01651 typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor; 01652 }; 01653 01654 template <class STANDARD, class H, class KEYS, class ALG_INFO> // VC60 workaround: doesn't work if KEYS is first parameter 01655 class TF_SS; 01656 01657 //! Trapdoor Function Based Signature Scheme 01658 template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> > // VC60 workaround: doesn't work if KEYS is first parameter 01659 class TF_SS : public KEYS 01660 { 01661 public: 01662 //! see SignatureStandard for a list of standards 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 //! implements PK_Signer interface 01670 typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer; 01671 //! implements PK_Verifier interface 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 //! Discrete Log Based Signature Scheme 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 //! implements PK_Signer interface 01688 typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer; 01689 //! implements PK_Verifier interface 01690 typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier; 01691 }; 01692 01693 //! Discrete Log Based Encryption Scheme 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 //! implements PK_Decryptor interface 01701 typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor; 01702 //! implements PK_Encryptor interface 01703 typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor; 01704 }; 01705 01706 NAMESPACE_END 01707 01708 #endif

Generated on Wed Jul 28 08:07:08 2004 for Crypto++ by doxygen 1.3.7