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

Generated on Wed Jul 21 19:15:31 2004 for Crypto++ by doxygen 1.3.7-20040704