pubkey.h 98 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378
  1. // pubkey.h - originally written and placed in the public domain by Wei Dai
  2. /// \file pubkey.h
  3. /// \brief This file contains helper classes/functions for implementing public key algorithms.
  4. /// \details The class hierarchies in this header file tend to look like this:
  5. ///
  6. /// <pre>
  7. /// x1
  8. /// +--+
  9. /// | |
  10. /// y1 z1
  11. /// | |
  12. /// x2<y1> x2<z1>
  13. /// | |
  14. /// y2 z2
  15. /// | |
  16. /// x3<y2> x3<z2>
  17. /// | |
  18. /// y3 z3
  19. /// </pre>
  20. ///
  21. /// <ul>
  22. /// <li>x1, y1, z1 are abstract interface classes defined in cryptlib.h
  23. /// <li>x2, y2, z2 are implementations of the interfaces using "abstract policies", which
  24. /// are pure virtual functions that should return interfaces to interchangeable algorithms.
  25. /// These classes have Base suffixes.
  26. /// <li>x3, y3, z3 hold actual algorithms and implement those virtual functions.
  27. /// These classes have Impl suffixes.
  28. /// </ul>
  29. ///
  30. /// \details The TF_ prefix means an implementation using trapdoor functions on integers.
  31. /// \details The DL_ prefix means an implementation using group operations in groups where discrete log is hard.
  32. #ifndef CRYPTOPP_PUBKEY_H
  33. #define CRYPTOPP_PUBKEY_H
  34. #include "config.h"
  35. #if CRYPTOPP_MSC_VERSION
  36. # pragma warning(push)
  37. # pragma warning(disable: 4702)
  38. #endif
  39. #include "cryptlib.h"
  40. #include "integer.h"
  41. #include "algebra.h"
  42. #include "modarith.h"
  43. #include "filters.h"
  44. #include "eprecomp.h"
  45. #include "fips140.h"
  46. #include "argnames.h"
  47. #include "smartptr.h"
  48. #include "stdcpp.h"
  49. #if defined(__SUNPRO_CC)
  50. # define MAYBE_RETURN(x) return x
  51. #else
  52. # define MAYBE_RETURN(x) CRYPTOPP_UNUSED(x)
  53. #endif
  54. NAMESPACE_BEGIN(CryptoPP)
  55. /// \brief Provides range for plaintext and ciphertext lengths
  56. /// \details A trapdoor function is a function that is easy to compute in one direction,
  57. /// but difficult to compute in the opposite direction without special knowledge.
  58. /// The special knowledge is usually the private key.
  59. /// \details Trapdoor functions only handle messages of a limited length or size.
  60. /// MaxPreimage is the plaintext's maximum length, and MaxImage is the
  61. /// ciphertext's maximum length.
  62. /// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  63. /// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  64. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
  65. {
  66. public:
  67. virtual ~TrapdoorFunctionBounds() {}
  68. /// \brief Returns the maximum size of a message before the trapdoor function is applied
  69. /// \return the maximum size of a message before the trapdoor function is applied
  70. /// \details Derived classes must implement PreimageBound().
  71. virtual Integer PreimageBound() const =0;
  72. /// \brief Returns the maximum size of a representation after the trapdoor function is applied
  73. /// \return the maximum size of a representation after the trapdoor function is applied
  74. /// \details Derived classes must implement ImageBound().
  75. virtual Integer ImageBound() const =0;
  76. /// \brief Returns the maximum size of a message before the trapdoor function is applied bound to a public key
  77. /// \return the maximum size of a message before the trapdoor function is applied bound to a public key
  78. /// \details The default implementation returns <tt>PreimageBound() - 1</tt>.
  79. virtual Integer MaxPreimage() const {return --PreimageBound();}
  80. /// \brief Returns the maximum size of a representation after the trapdoor function is applied bound to a public key
  81. /// \return the maximum size of a representation after the trapdoor function is applied bound to a public key
  82. /// \details The default implementation returns <tt>ImageBound() - 1</tt>.
  83. virtual Integer MaxImage() const {return --ImageBound();}
  84. };
  85. /// \brief Applies the trapdoor function, using random data if required
  86. /// \details ApplyFunction() is the foundation for encrypting a message under a public key.
  87. /// Derived classes will override it at some point.
  88. /// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  89. /// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  90. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
  91. {
  92. public:
  93. virtual ~RandomizedTrapdoorFunction() {}
  94. /// \brief Applies the trapdoor function, using random data if required
  95. /// \param rng a RandomNumberGenerator derived class
  96. /// \param x the message on which the encryption function is applied
  97. /// \return the message x encrypted under the public key
  98. /// \details ApplyRandomizedFunction is a generalization of encryption under a public key
  99. /// cryptosystem. The RandomNumberGenerator may (or may not) be required.
  100. /// Derived classes must implement it.
  101. virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
  102. /// \brief Determines if the encryption algorithm is randomized
  103. /// \return true if the encryption algorithm is randomized, false otherwise
  104. /// \details If IsRandomized() returns false, then NullRNG() can be used.
  105. virtual bool IsRandomized() const {return true;}
  106. };
  107. /// \brief Applies the trapdoor function
  108. /// \details ApplyFunction() is the foundation for encrypting a message under a public key.
  109. /// Derived classes will override it at some point.
  110. /// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  111. /// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  112. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
  113. {
  114. public:
  115. virtual ~TrapdoorFunction() {}
  116. /// \brief Applies the trapdoor function
  117. /// \param rng a RandomNumberGenerator derived class
  118. /// \param x the message on which the encryption function is applied
  119. /// \details ApplyRandomizedFunction is a generalization of encryption under a public key
  120. /// cryptosystem. The RandomNumberGenerator may (or may not) be required.
  121. /// \details Internally, ApplyRandomizedFunction() calls ApplyFunction()
  122. /// without the RandomNumberGenerator.
  123. Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
  124. {CRYPTOPP_UNUSED(rng); return ApplyFunction(x);}
  125. bool IsRandomized() const {return false;}
  126. /// \brief Applies the trapdoor
  127. /// \param x the message on which the encryption function is applied
  128. /// \return the message x encrypted under the public key
  129. /// \details ApplyFunction is a generalization of encryption under a public key
  130. /// cryptosystem. Derived classes must implement it.
  131. virtual Integer ApplyFunction(const Integer &x) const =0;
  132. };
  133. /// \brief Applies the inverse of the trapdoor function, using random data if required
  134. /// \details CalculateInverse() is the foundation for decrypting a message under a private key
  135. /// in a public key cryptosystem. Derived classes will override it at some point.
  136. /// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  137. /// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  138. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
  139. {
  140. public:
  141. virtual ~RandomizedTrapdoorFunctionInverse() {}
  142. /// \brief Applies the inverse of the trapdoor function, using random data if required
  143. /// \param rng a RandomNumberGenerator derived class
  144. /// \param x the message on which the decryption function is applied
  145. /// \return the message x decrypted under the private key
  146. /// \details CalculateRandomizedInverse is a generalization of decryption using the private key
  147. /// The RandomNumberGenerator may (or may not) be required. Derived classes must implement it.
  148. virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
  149. /// \brief Determines if the decryption algorithm is randomized
  150. /// \return true if the decryption algorithm is randomized, false otherwise
  151. /// \details If IsRandomized() returns false, then NullRNG() can be used.
  152. virtual bool IsRandomized() const {return true;}
  153. };
  154. /// \brief Applies the inverse of the trapdoor function
  155. /// \details CalculateInverse() is the foundation for decrypting a message under a private key
  156. /// in a public key cryptosystem. Derived classes will override it at some point.
  157. /// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  158. /// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  159. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
  160. {
  161. public:
  162. virtual ~TrapdoorFunctionInverse() {}
  163. /// \brief Applies the inverse of the trapdoor function
  164. /// \param rng a RandomNumberGenerator derived class
  165. /// \param x the message on which the decryption function is applied
  166. /// \return the message x decrypted under the private key
  167. /// \details CalculateRandomizedInverse is a generalization of decryption using the private key
  168. /// \details Internally, CalculateRandomizedInverse() calls CalculateInverse()
  169. /// without the RandomNumberGenerator.
  170. Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
  171. {return CalculateInverse(rng, x);}
  172. /// \brief Determines if the decryption algorithm is randomized
  173. /// \return true if the decryption algorithm is randomized, false otherwise
  174. /// \details If IsRandomized() returns false, then NullRNG() can be used.
  175. bool IsRandomized() const {return false;}
  176. /// \brief Calculates the inverse of an element
  177. /// \param rng a RandomNumberGenerator derived class
  178. /// \param x the element
  179. /// \return the inverse of the element in the group
  180. virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
  181. };
  182. // ********************************************************
  183. /// \brief Message encoding method for public key encryption
  184. class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
  185. {
  186. public:
  187. virtual ~PK_EncryptionMessageEncodingMethod() {}
  188. virtual bool ParameterSupported(const char *name) const
  189. {CRYPTOPP_UNUSED(name); return false;}
  190. /// max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
  191. virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0;
  192. virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs &parameters) const =0;
  193. virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs &parameters) const =0;
  194. };
  195. // ********************************************************
  196. /// \brief The base for trapdoor based cryptosystems
  197. /// \tparam TFI trapdoor function interface derived class
  198. /// \tparam MEI message encoding interface derived class
  199. template <class TFI, class MEI>
  200. class CRYPTOPP_NO_VTABLE TF_Base
  201. {
  202. protected:
  203. virtual ~TF_Base() {}
  204. virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
  205. typedef TFI TrapdoorFunctionInterface;
  206. virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
  207. typedef MEI MessageEncodingInterface;
  208. virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
  209. };
  210. // ********************************************************
  211. /// \brief Public key trapdoor function default implementation
  212. /// \tparam BASE public key cryptosystem with a fixed length
  213. template <class BASE>
  214. class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
  215. {
  216. public:
  217. virtual ~PK_FixedLengthCryptoSystemImpl() {}
  218. size_t MaxPlaintextLength(size_t ciphertextLength) const
  219. {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
  220. size_t CiphertextLength(size_t plaintextLength) const
  221. {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
  222. virtual size_t FixedMaxPlaintextLength() const =0;
  223. virtual size_t FixedCiphertextLength() const =0;
  224. };
  225. /// \brief Trapdoor function cryptosystem base class
  226. /// \tparam INTFACE public key cryptosystem base interface
  227. /// \tparam BASE public key cryptosystem implementation base
  228. template <class INTFACE, class BASE>
  229. class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTFACE>, protected BASE
  230. {
  231. public:
  232. virtual ~TF_CryptoSystemBase() {}
  233. bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);}
  234. size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
  235. size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
  236. protected:
  237. size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
  238. // Coverity finding on potential overflow/underflow.
  239. size_t PaddedBlockBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().PreimageBound().BitCount(),1U);}
  240. };
  241. /// \brief Trapdoor function cryptosystems decryption base class
  242. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
  243. {
  244. public:
  245. virtual ~TF_DecryptorBase() {}
  246. DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
  247. };
  248. /// \brief Trapdoor function cryptosystems encryption base class
  249. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
  250. {
  251. public:
  252. virtual ~TF_EncryptorBase() {}
  253. void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
  254. };
  255. // ********************************************************
  256. // Typedef change due to Clang, http://github.com/weidai11/cryptopp/issues/300
  257. typedef std::pair<const byte *, unsigned int> HashIdentifier;
  258. /// \brief Interface for message encoding method for public key signature schemes.
  259. /// \details PK_SignatureMessageEncodingMethod provides interfaces for message
  260. /// encoding method for public key signature schemes. The methods support both
  261. /// trapdoor functions (<tt>TF_*</tt>) and discrete logarithm (<tt>DL_*</tt>)
  262. /// based schemes.
  263. class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
  264. {
  265. public:
  266. virtual ~PK_SignatureMessageEncodingMethod() {}
  267. virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const
  268. {CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
  269. virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
  270. {CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
  271. /// \brief Determines whether an encoding method requires a random number generator
  272. /// \return true if the encoding method requires a RandomNumberGenerator()
  273. /// \details if IsProbabilistic() returns false, then NullRNG() can be passed to functions that take
  274. /// RandomNumberGenerator().
  275. /// \sa Bellare and Rogaway<a href="http://grouper.ieee.org/groups/1363/P1363a/contributions/pss-submission.pdf">PSS:
  276. /// Provably Secure Encoding Method for Digital Signatures</a>
  277. bool IsProbabilistic() const
  278. {return true;}
  279. bool AllowNonrecoverablePart() const
  280. {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
  281. virtual bool RecoverablePartFirst() const
  282. {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
  283. // for verification, DL
  284. virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const
  285. {CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength);}
  286. // for signature
  287. virtual void ProcessRecoverableMessage(HashTransformation &hash,
  288. const byte *recoverableMessage, size_t recoverableMessageLength,
  289. const byte *presignature, size_t presignatureLength,
  290. SecByteBlock &semisignature) const
  291. {
  292. CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength);
  293. CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength); CRYPTOPP_UNUSED(semisignature);
  294. if (RecoverablePartFirst())
  295. CRYPTOPP_ASSERT(!"ProcessRecoverableMessage() not implemented");
  296. }
  297. virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
  298. const byte *recoverableMessage, size_t recoverableMessageLength,
  299. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  300. byte *representative, size_t representativeBitLength) const =0;
  301. virtual bool VerifyMessageRepresentative(
  302. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  303. byte *representative, size_t representativeBitLength) const =0;
  304. virtual DecodingResult RecoverMessageFromRepresentative( // for TF
  305. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  306. byte *representative, size_t representativeBitLength,
  307. byte *recoveredMessage) const
  308. {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty);
  309. CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(recoveredMessage);
  310. throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
  311. virtual DecodingResult RecoverMessageFromSemisignature( // for DL
  312. HashTransformation &hash, HashIdentifier hashIdentifier,
  313. const byte *presignature, size_t presignatureLength,
  314. const byte *semisignature, size_t semisignatureLength,
  315. byte *recoveredMessage) const
  316. {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength);
  317. CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength); CRYPTOPP_UNUSED(recoveredMessage);
  318. throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
  319. // VC60 workaround
  320. struct HashIdentifierLookup
  321. {
  322. template <class H> struct HashIdentifierLookup2
  323. {
  324. static HashIdentifier CRYPTOPP_API Lookup()
  325. {
  326. return HashIdentifier(static_cast<const byte *>(NULLPTR), 0);
  327. }
  328. };
  329. };
  330. };
  331. /// \brief Interface for message encoding method for public key signature schemes.
  332. /// \details PK_DeterministicSignatureMessageEncodingMethod provides interfaces
  333. /// for message encoding method for public key signature schemes.
  334. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
  335. {
  336. public:
  337. bool VerifyMessageRepresentative(
  338. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  339. byte *representative, size_t representativeBitLength) const;
  340. };
  341. /// \brief Interface for message encoding method for public key signature schemes.
  342. /// \details PK_RecoverableSignatureMessageEncodingMethod provides interfaces
  343. /// for message encoding method for public key signature schemes.
  344. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
  345. {
  346. public:
  347. bool VerifyMessageRepresentative(
  348. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  349. byte *representative, size_t representativeBitLength) const;
  350. };
  351. /// \brief Interface for message encoding method for public key signature schemes.
  352. /// \details DL_SignatureMessageEncodingMethod_DSA provides interfaces
  353. /// for message encoding method for DSA.
  354. class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
  355. {
  356. public:
  357. void ComputeMessageRepresentative(RandomNumberGenerator &rng,
  358. const byte *recoverableMessage, size_t recoverableMessageLength,
  359. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  360. byte *representative, size_t representativeBitLength) const;
  361. };
  362. /// \brief Interface for message encoding method for public key signature schemes.
  363. /// \details DL_SignatureMessageEncodingMethod_NR provides interfaces
  364. /// for message encoding method for Nyberg-Rueppel.
  365. class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
  366. {
  367. public:
  368. void ComputeMessageRepresentative(RandomNumberGenerator &rng,
  369. const byte *recoverableMessage, size_t recoverableMessageLength,
  370. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  371. byte *representative, size_t representativeBitLength) const;
  372. };
  373. #if 0
  374. /// \brief Interface for message encoding method for public key signature schemes.
  375. /// \details DL_SignatureMessageEncodingMethod_SM2 provides interfaces
  376. /// for message encoding method for SM2.
  377. class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_SM2 : public PK_DeterministicSignatureMessageEncodingMethod
  378. {
  379. public:
  380. void ComputeMessageRepresentative(RandomNumberGenerator &rng,
  381. const byte *recoverableMessage, size_t recoverableMessageLength,
  382. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  383. byte *representative, size_t representativeBitLength) const;
  384. };
  385. #endif
  386. /// \brief Interface for message encoding method for public key signature schemes.
  387. /// \details PK_MessageAccumulatorBase provides interfaces
  388. /// for message encoding method.
  389. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
  390. {
  391. public:
  392. PK_MessageAccumulatorBase() : m_empty(true) {}
  393. virtual HashTransformation & AccessHash() =0;
  394. void Update(const byte *input, size_t length)
  395. {
  396. AccessHash().Update(input, length);
  397. m_empty = m_empty && length == 0;
  398. }
  399. SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
  400. Integer m_k, m_s;
  401. bool m_empty;
  402. };
  403. /// \brief Interface for message encoding method for public key signature schemes.
  404. /// \details PK_MessageAccumulatorBase provides interfaces
  405. /// for message encoding method.
  406. template <class HASH_ALGORITHM>
  407. class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
  408. {
  409. public:
  410. HashTransformation & AccessHash() {return this->m_object;}
  411. };
  412. /// \brief Trapdoor Function (TF) Signature Scheme base class
  413. /// \tparam INTFACE interface
  414. /// \tparam BASE base class
  415. template <class INTFACE, class BASE>
  416. class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTFACE, protected BASE
  417. {
  418. public:
  419. virtual ~TF_SignatureSchemeBase() {}
  420. size_t SignatureLength() const
  421. {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
  422. size_t MaxRecoverableLength() const
  423. {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
  424. size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
  425. {CRYPTOPP_UNUSED(signatureLength); return this->MaxRecoverableLength();}
  426. bool IsProbabilistic() const
  427. {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
  428. bool AllowNonrecoverablePart() const
  429. {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
  430. bool RecoverablePartFirst() const
  431. {return this->GetMessageEncodingInterface().RecoverablePartFirst();}
  432. protected:
  433. size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
  434. // Coverity finding on potential overflow/underflow.
  435. size_t MessageRepresentativeBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().ImageBound().BitCount(),1U);}
  436. virtual HashIdentifier GetHashIdentifier() const =0;
  437. virtual size_t GetDigestSize() const =0;
  438. };
  439. /// \brief Trapdoor Function (TF) Signer base class
  440. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
  441. {
  442. public:
  443. virtual ~TF_SignerBase() {}
  444. void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const;
  445. size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
  446. };
  447. /// \brief Trapdoor Function (TF) Verifier base class
  448. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
  449. {
  450. public:
  451. virtual ~TF_VerifierBase() {}
  452. void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const;
  453. bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
  454. DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
  455. };
  456. // ********************************************************
  457. /// \brief Trapdoor Function (TF) scheme options
  458. /// \tparam T1 algorithm info class
  459. /// \tparam T2 keys class with public and private key
  460. /// \tparam T3 message encoding class
  461. template <class T1, class T2, class T3>
  462. struct TF_CryptoSchemeOptions
  463. {
  464. typedef T1 AlgorithmInfo;
  465. typedef T2 Keys;
  466. typedef typename Keys::PrivateKey PrivateKey;
  467. typedef typename Keys::PublicKey PublicKey;
  468. typedef T3 MessageEncodingMethod;
  469. };
  470. /// \brief Trapdoor Function (TF) signature scheme options
  471. /// \tparam T1 algorithm info class
  472. /// \tparam T2 keys class with public and private key
  473. /// \tparam T3 message encoding class
  474. /// \tparam T4 HashTransformation class
  475. template <class T1, class T2, class T3, class T4>
  476. struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3>
  477. {
  478. typedef T4 HashFunction;
  479. };
  480. /// \brief Trapdoor Function (TF) base implementation
  481. /// \tparam BASE base class
  482. /// \tparam SCHEME_OPTIONS scheme options class
  483. /// \tparam KEY_CLASS key class
  484. template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
  485. class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
  486. {
  487. public:
  488. typedef SCHEME_OPTIONS SchemeOptions;
  489. typedef KEY_CLASS KeyClass;
  490. virtual ~TF_ObjectImplBase() {}
  491. PublicKey & AccessPublicKey() {return AccessKey();}
  492. const PublicKey & GetPublicKey() const {return GetKey();}
  493. PrivateKey & AccessPrivateKey() {return AccessKey();}
  494. const PrivateKey & GetPrivateKey() const {return GetKey();}
  495. virtual const KeyClass & GetKey() const =0;
  496. virtual KeyClass & AccessKey() =0;
  497. const KeyClass & GetTrapdoorFunction() const {return GetKey();}
  498. PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
  499. {
  500. CRYPTOPP_UNUSED(rng);
  501. return new PK_MessageAccumulatorImpl<typename SCHEME_OPTIONS::HashFunction>;
  502. }
  503. PK_MessageAccumulator * NewVerificationAccumulator() const
  504. {
  505. return new PK_MessageAccumulatorImpl<typename SCHEME_OPTIONS::HashFunction>;
  506. }
  507. protected:
  508. const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
  509. {return Singleton<typename SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
  510. const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
  511. {return GetKey();}
  512. const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
  513. {return GetKey();}
  514. // for signature scheme
  515. HashIdentifier GetHashIdentifier() const
  516. {
  517. typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<typename SchemeOptions::HashFunction> L;
  518. return L::Lookup();
  519. }
  520. size_t GetDigestSize() const
  521. {
  522. typedef typename SchemeOptions::HashFunction H;
  523. return H::DIGESTSIZE;
  524. }
  525. };
  526. /// \brief Trapdoor Function (TF) signature with external reference
  527. /// \tparam BASE base class
  528. /// \tparam SCHEME_OPTIONS scheme options class
  529. /// \tparam KEY key class
  530. /// \details TF_ObjectImplExtRef() holds a pointer to an external key structure
  531. template <class BASE, class SCHEME_OPTIONS, class KEY>
  532. class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
  533. {
  534. public:
  535. virtual ~TF_ObjectImplExtRef() {}
  536. TF_ObjectImplExtRef(const KEY *pKey = NULLPTR) : m_pKey(pKey) {}
  537. void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;}
  538. const KEY & GetKey() const {return *m_pKey;}
  539. KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");}
  540. private:
  541. const KEY * m_pKey;
  542. };
  543. /// \brief Trapdoor Function (TF) signature scheme options
  544. /// \tparam BASE base class
  545. /// \tparam SCHEME_OPTIONS scheme options class
  546. /// \tparam KEY_CLASS key class
  547. /// \details TF_ObjectImpl() holds a reference to a trapdoor function
  548. template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
  549. class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS>
  550. {
  551. public:
  552. typedef KEY_CLASS KeyClass;
  553. virtual ~TF_ObjectImpl() {}
  554. const KeyClass & GetKey() const {return m_trapdoorFunction;}
  555. KeyClass & AccessKey() {return m_trapdoorFunction;}
  556. private:
  557. KeyClass m_trapdoorFunction;
  558. };
  559. /// \brief Trapdoor Function (TF) decryptor options
  560. /// \tparam SCHEME_OPTIONS scheme options class
  561. template <class SCHEME_OPTIONS>
  562. class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
  563. {
  564. };
  565. /// \brief Trapdoor Function (TF) encryptor options
  566. /// \tparam SCHEME_OPTIONS scheme options class
  567. template <class SCHEME_OPTIONS>
  568. class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
  569. {
  570. };
  571. /// \brief Trapdoor Function (TF) encryptor options
  572. /// \tparam SCHEME_OPTIONS scheme options class
  573. template <class SCHEME_OPTIONS>
  574. class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
  575. {
  576. };
  577. /// \brief Trapdoor Function (TF) encryptor options
  578. /// \tparam SCHEME_OPTIONS scheme options class
  579. template <class SCHEME_OPTIONS>
  580. class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
  581. {
  582. };
  583. // ********************************************************
  584. /// \brief Mask generation function interface
  585. /// \sa P1363_KDF2, P1363_MGF1
  586. /// \since Crypto++ 2.0
  587. class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
  588. {
  589. public:
  590. virtual ~MaskGeneratingFunction() {}
  591. /// \brief Generate and apply mask
  592. /// \param hash HashTransformation derived class
  593. /// \param output the destination byte array
  594. /// \param outputLength the size of the destination byte array
  595. /// \param input the message to hash
  596. /// \param inputLength the size of the message
  597. /// \param mask flag indicating whether to apply the mask
  598. virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0;
  599. };
  600. /// \fn P1363_MGF1KDF2_Common
  601. /// \brief P1363 mask generation function
  602. /// \param hash HashTransformation derived class
  603. /// \param output the destination byte array
  604. /// \param outputLength the size of the destination byte array
  605. /// \param input the message to hash
  606. /// \param inputLength the size of the message
  607. /// \param derivationParams additional derivation parameters
  608. /// \param derivationParamsLength the size of the additional derivation parameters
  609. /// \param mask flag indicating whether to apply the mask
  610. /// \param counterStart starting counter value used in generation function
  611. CRYPTOPP_DLL void CRYPTOPP_API P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart);
  612. /// \brief P1363 mask generation function
  613. /// \sa P1363_KDF2, MaskGeneratingFunction
  614. /// \since Crypto++ 2.0
  615. class P1363_MGF1 : public MaskGeneratingFunction
  616. {
  617. public:
  618. /// \brief The algorithm name
  619. /// \return the algorithm name
  620. /// \details StaticAlgorithmName returns the algorithm's name as a static
  621. /// member function.
  622. CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "MGF1";}
  623. /// \brief P1363 mask generation function
  624. /// \param hash HashTransformation derived class
  625. /// \param output the destination byte array
  626. /// \param outputLength the size of the destination byte array
  627. /// \param input the message to hash
  628. /// \param inputLength the size of the message
  629. /// \param mask flag indicating whether to apply the mask
  630. void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const
  631. {
  632. P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULLPTR, 0, mask, 0);
  633. }
  634. };
  635. // ********************************************************
  636. /// \brief P1363 key derivation function
  637. /// \tparam H hash function used in the derivation
  638. /// \sa P1363_MGF1, KeyDerivationFunction, <A
  639. /// HREF="https://www.cryptopp.com/wiki/P1363_KDF2">P1363_KDF2</A>
  640. /// on the Crypto++ wiki
  641. /// \since Crypto++ 2.0
  642. template <class H>
  643. class P1363_KDF2
  644. {
  645. public:
  646. /// \brief P1363 key derivation function
  647. /// \param output the destination byte array
  648. /// \param outputLength the size of the destination byte array
  649. /// \param input the message to hash
  650. /// \param inputLength the size of the message
  651. /// \param derivationParams additional derivation parameters
  652. /// \param derivationParamsLength the size of the additional derivation parameters
  653. /// \details DeriveKey calls P1363_MGF1KDF2_Common
  654. static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
  655. {
  656. H h;
  657. P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
  658. }
  659. };
  660. // ********************************************************
  661. /// \brief Exception thrown when an invalid group element is encountered
  662. /// \details Thrown by DecodeElement and AgreeWithStaticPrivateKey
  663. class DL_BadElement : public InvalidDataFormat
  664. {
  665. public:
  666. DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
  667. };
  668. /// \brief Interface for Discrete Log (DL) group parameters
  669. /// \tparam T element in the group
  670. /// \details The element is usually an Integer, \ref ECP "ECP::Point" or \ref EC2N "EC2N::Point"
  671. template <class T>
  672. class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters
  673. {
  674. typedef DL_GroupParameters<T> ThisClass;
  675. public:
  676. typedef T Element;
  677. virtual ~DL_GroupParameters() {}
  678. DL_GroupParameters() : m_validationLevel(0) {}
  679. // CryptoMaterial
  680. bool Validate(RandomNumberGenerator &rng, unsigned int level) const
  681. {
  682. if (!GetBasePrecomputation().IsInitialized())
  683. return false;
  684. if (m_validationLevel > level)
  685. return true;
  686. CRYPTOPP_ASSERT(ValidateGroup(rng, level));
  687. bool pass = ValidateGroup(rng, level);
  688. CRYPTOPP_ASSERT(ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation()));
  689. pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
  690. m_validationLevel = pass ? level+1 : 0;
  691. return pass;
  692. }
  693. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  694. {
  695. return GetValueHelper(this, name, valueType, pValue)
  696. CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
  697. CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
  698. ;
  699. }
  700. /// \brief Determines whether the object supports precomputation
  701. /// \return true if the object supports precomputation, false otherwise
  702. /// \sa Precompute()
  703. bool SupportsPrecomputation() const {return true;}
  704. /// \brief Perform precomputation
  705. /// \param precomputationStorage the suggested number of objects for the precompute table
  706. /// \throw NotImplemented
  707. /// \details The exact semantics of Precompute() varies, but it typically means calculate
  708. /// a table of n objects that can be used later to speed up computation.
  709. /// \details If a derived class does not override Precompute(), then the base class throws
  710. /// NotImplemented.
  711. /// \sa SupportsPrecomputation(), LoadPrecomputation(), SavePrecomputation()
  712. void Precompute(unsigned int precomputationStorage=16)
  713. {
  714. AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
  715. }
  716. /// \brief Retrieve previously saved precomputation
  717. /// \param storedPrecomputation BufferedTransformation with the saved precomputation
  718. /// \throw NotImplemented
  719. /// \sa SupportsPrecomputation(), Precompute()
  720. void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
  721. {
  722. AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
  723. m_validationLevel = 0;
  724. }
  725. /// \brief Save precomputation for later use
  726. /// \param storedPrecomputation BufferedTransformation to write the precomputation
  727. /// \throw NotImplemented
  728. /// \sa SupportsPrecomputation(), Precompute()
  729. void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
  730. {
  731. GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
  732. }
  733. /// \brief Retrieves the subgroup generator
  734. /// \return the subgroup generator
  735. /// \details The subgroup generator is retrieved from the base precomputation
  736. virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
  737. /// \brief Sets the subgroup generator
  738. /// \param base the new subgroup generator
  739. /// \details The subgroup generator is set in the base precomputation
  740. virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
  741. /// \brief Exponentiates the base
  742. /// \return the element after exponentiation
  743. /// \details ExponentiateBase() calls GetBasePrecomputation() and then exponentiates.
  744. virtual Element ExponentiateBase(const Integer &exponent) const
  745. {
  746. return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
  747. }
  748. /// \brief Exponentiates an element
  749. /// \param base the base element
  750. /// \param exponent the exponent to raise the base
  751. /// \return the result of the exponentiation
  752. /// \details Internally, ExponentiateElement() calls SimultaneousExponentiate().
  753. virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
  754. {
  755. Element result;
  756. SimultaneousExponentiate(&result, base, &exponent, 1);
  757. return result;
  758. }
  759. /// \brief Retrieves the group precomputation
  760. /// \return a const reference to the group precomputation
  761. virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
  762. /// \brief Retrieves the group precomputation
  763. /// \return a const reference to the group precomputation using a fixed base
  764. virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
  765. /// \brief Retrieves the group precomputation
  766. /// \return a non-const reference to the group precomputation using a fixed base
  767. virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
  768. /// \brief Retrieves the subgroup order
  769. /// \return the order of subgroup generated by the base element
  770. virtual const Integer & GetSubgroupOrder() const =0;
  771. /// \brief Retrieves the maximum exponent for the group
  772. /// \return the maximum exponent for the group
  773. virtual Integer GetMaxExponent() const =0;
  774. /// \brief Retrieves the order of the group
  775. /// \return the order of the group
  776. /// \details Either GetGroupOrder() or GetCofactor() must be overridden in a derived class.
  777. virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();}
  778. /// \brief Retrieves the cofactor
  779. /// \return the cofactor
  780. /// \details Either GetGroupOrder() or GetCofactor() must be overridden in a derived class.
  781. virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
  782. /// \brief Retrieves the encoded element's size
  783. /// \param reversible flag indicating the encoding format
  784. /// \return encoded element's size, in bytes
  785. /// \details The format of the encoded element varies by the underlying type of the element and the
  786. /// reversible flag. GetEncodedElementSize() must be implemented in a derived class.
  787. /// \sa GetEncodedElementSize(), EncodeElement(), DecodeElement()
  788. virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
  789. /// \brief Encodes the element
  790. /// \param reversible flag indicating the encoding format
  791. /// \param element reference to the element to encode
  792. /// \param encoded destination byte array for the encoded element
  793. /// \details EncodeElement() must be implemented in a derived class.
  794. /// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
  795. virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
  796. /// \brief Decodes the element
  797. /// \param encoded byte array with the encoded element
  798. /// \param checkForGroupMembership flag indicating if the element should be validated
  799. /// \return Element after decoding
  800. /// \details DecodeElement() must be implemented in a derived class.
  801. /// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
  802. virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
  803. /// \brief Converts an element to an Integer
  804. /// \param element the element to convert to an Integer
  805. /// \return Element after converting to an Integer
  806. /// \details ConvertElementToInteger() must be implemented in a derived class.
  807. virtual Integer ConvertElementToInteger(const Element &element) const =0;
  808. /// \brief Check the group for errors
  809. /// \param rng RandomNumberGenerator for objects which use randomized testing
  810. /// \param level level of thoroughness
  811. /// \return true if the tests succeed, false otherwise
  812. /// \details There are four levels of thoroughness:
  813. /// <ul>
  814. /// <li>0 - using this object won't cause a crash or exception
  815. /// <li>1 - this object will probably function, and encrypt, sign, other operations correctly
  816. /// <li>2 - ensure this object will function correctly, and perform reasonable security checks
  817. /// <li>3 - perform reasonable security checks, and do checks that may take a long time
  818. /// </ul>
  819. /// \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can be used for level 0.
  820. /// Level 1 may not check for weak keys and such. Levels 2 and 3 are recommended.
  821. /// \details ValidateGroup() must be implemented in a derived class.
  822. virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
  823. /// \brief Check the element for errors
  824. /// \param level level of thoroughness
  825. /// \param element element to check
  826. /// \param precomp optional pointer to DL_FixedBasePrecomputation
  827. /// \return true if the tests succeed, false otherwise
  828. /// \details There are four levels of thoroughness:
  829. /// <ul>
  830. /// <li>0 - using this object won't cause a crash or exception
  831. /// <li>1 - this object will probably function, and encrypt, sign, other operations correctly
  832. /// <li>2 - ensure this object will function correctly, and perform reasonable security checks
  833. /// <li>3 - perform reasonable security checks, and do checks that may take a long time
  834. /// </ul>
  835. /// \details Level 0 performs group membership checks. Level 1 may not check for weak keys and such.
  836. /// Levels 2 and 3 are recommended.
  837. /// \details ValidateElement() must be implemented in a derived class.
  838. virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
  839. virtual bool FastSubgroupCheckAvailable() const =0;
  840. /// \brief Determines if an element is an identity
  841. /// \param element element to check
  842. /// \return true if the element is an identity, false otherwise
  843. /// \details The identity element or or neutral element is a special element in a group that leaves
  844. /// other elements unchanged when combined with it.
  845. /// \details IsIdentity() must be implemented in a derived class.
  846. virtual bool IsIdentity(const Element &element) const =0;
  847. /// \brief Exponentiates a base to multiple exponents
  848. /// \param results an array of Elements
  849. /// \param base the base to raise to the exponents
  850. /// \param exponents an array of exponents
  851. /// \param exponentsCount the number of exponents in the array
  852. /// \details SimultaneousExponentiate() raises the base to each exponent in the exponents array and stores the
  853. /// result at the respective position in the results array.
  854. /// \details SimultaneousExponentiate() must be implemented in a derived class.
  855. /// \pre <tt>COUNTOF(results) == exponentsCount</tt>
  856. /// \pre <tt>COUNTOF(exponents) == exponentsCount</tt>
  857. virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
  858. protected:
  859. void ParametersChanged() {m_validationLevel = 0;}
  860. private:
  861. mutable unsigned int m_validationLevel;
  862. };
  863. /// \brief Base implementation of Discrete Log (DL) group parameters
  864. /// \tparam GROUP_PRECOMP group precomputation class
  865. /// \tparam BASE_PRECOMP fixed base precomputation class
  866. /// \tparam BASE class or type of an element
  867. template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<typename GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<typename GROUP_PRECOMP::Element> >
  868. class DL_GroupParametersImpl : public BASE
  869. {
  870. public:
  871. typedef GROUP_PRECOMP GroupPrecomputation;
  872. typedef typename GROUP_PRECOMP::Element Element;
  873. typedef BASE_PRECOMP BasePrecomputation;
  874. virtual ~DL_GroupParametersImpl() {}
  875. /// \brief Retrieves the group precomputation
  876. /// \return a const reference to the group precomputation
  877. const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
  878. /// \brief Retrieves the group precomputation
  879. /// \return a const reference to the group precomputation using a fixed base
  880. const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return m_gpc;}
  881. /// \brief Retrieves the group precomputation
  882. /// \return a non-const reference to the group precomputation using a fixed base
  883. DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return m_gpc;}
  884. protected:
  885. GROUP_PRECOMP m_groupPrecomputation;
  886. BASE_PRECOMP m_gpc;
  887. };
  888. /// \brief Base class for a Discrete Log (DL) key
  889. /// \tparam T class or type of an element
  890. /// \details The element is usually an Integer, \ref ECP "ECP::Point" or \ref EC2N "EC2N::Point"
  891. template <class T>
  892. class CRYPTOPP_NO_VTABLE DL_Key
  893. {
  894. public:
  895. virtual ~DL_Key() {}
  896. /// \brief Retrieves abstract group parameters
  897. /// \return a const reference to the group parameters
  898. virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0;
  899. /// \brief Retrieves abstract group parameters
  900. /// \return a non-const reference to the group parameters
  901. virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
  902. };
  903. /// \brief Interface for Discrete Log (DL) public keys
  904. template <class T>
  905. class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T>
  906. {
  907. typedef DL_PublicKey<T> ThisClass;
  908. public:
  909. typedef T Element;
  910. virtual ~DL_PublicKey();
  911. /// \brief Get a named value
  912. /// \param name the name of the object or value to retrieve
  913. /// \param valueType reference to a variable that receives the value
  914. /// \param pValue void pointer to a variable that receives the value
  915. /// \return true if the value was retrieved, false otherwise
  916. /// \details GetVoidValue() retrieves the value of name if it exists.
  917. /// \note GetVoidValue() is an internal function and should be implemented
  918. /// by derived classes. Users should use one of the other functions instead.
  919. /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
  920. /// GetRequiredParameter() and GetRequiredIntParameter()
  921. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  922. {
  923. return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
  924. CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
  925. }
  926. /// \brief Initialize or reinitialize this key
  927. /// \param source NameValuePairs to assign
  928. void AssignFrom(const NameValuePairs &source);
  929. /// \brief Retrieves the public element
  930. /// \return the public element
  931. virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
  932. /// \brief Sets the public element
  933. /// \param y the public element
  934. virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
  935. /// \brief Exponentiates this element
  936. /// \param exponent the exponent to raise the base
  937. /// \return the public element raised to the exponent
  938. virtual Element ExponentiatePublicElement(const Integer &exponent) const
  939. {
  940. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  941. return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
  942. }
  943. /// \brief Exponentiates an element
  944. /// \param baseExp the first exponent
  945. /// \param publicExp the second exponent
  946. /// \return the public element raised to the exponent
  947. /// \details CascadeExponentiateBaseAndPublicElement raises the public element to
  948. /// the base element and precomputation.
  949. virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
  950. {
  951. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  952. return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
  953. }
  954. /// \brief Accesses the public precomputation
  955. /// \details GetPublicPrecomputation returns a const reference, while
  956. /// AccessPublicPrecomputation returns a non-const reference. Must be
  957. /// overridden in derived classes.
  958. virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0;
  959. /// \brief Accesses the public precomputation
  960. /// \details GetPublicPrecomputation returns a const reference, while
  961. /// AccessPublicPrecomputation returns a non-const reference. Must be
  962. /// overridden in derived classes.
  963. virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
  964. };
  965. // Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499
  966. template<class T>
  967. DL_PublicKey<T>::~DL_PublicKey() {}
  968. /// \brief Interface for Discrete Log (DL) private keys
  969. template <class T>
  970. class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T>
  971. {
  972. typedef DL_PrivateKey<T> ThisClass;
  973. public:
  974. typedef T Element;
  975. virtual ~DL_PrivateKey();
  976. /// \brief Initializes a public key from this key
  977. /// \param pub reference to a public key
  978. void MakePublicKey(DL_PublicKey<T> &pub) const
  979. {
  980. pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
  981. pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
  982. }
  983. /// \brief Get a named value
  984. /// \param name the name of the object or value to retrieve
  985. /// \param valueType reference to a variable that receives the value
  986. /// \param pValue void pointer to a variable that receives the value
  987. /// \return true if the value was retrieved, false otherwise
  988. /// \details GetVoidValue() retrieves the value of name if it exists.
  989. /// \note GetVoidValue() is an internal function and should be implemented
  990. /// by derived classes. Users should use one of the other functions instead.
  991. /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
  992. /// GetRequiredParameter() and GetRequiredIntParameter()
  993. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  994. {
  995. return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
  996. CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
  997. }
  998. /// \brief Initialize or reinitialize this key
  999. /// \param source NameValuePairs to assign
  1000. void AssignFrom(const NameValuePairs &source)
  1001. {
  1002. this->AccessAbstractGroupParameters().AssignFrom(source);
  1003. AssignFromHelper(this, source)
  1004. CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
  1005. }
  1006. /// \brief Retrieves the private exponent
  1007. /// \return the private exponent
  1008. /// \details Must be overridden in derived classes.
  1009. virtual const Integer & GetPrivateExponent() const =0;
  1010. /// \brief Sets the private exponent
  1011. /// \param x the private exponent
  1012. /// \details Must be overridden in derived classes.
  1013. virtual void SetPrivateExponent(const Integer &x) =0;
  1014. };
  1015. // Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499
  1016. template<class T>
  1017. DL_PrivateKey<T>::~DL_PrivateKey() {}
  1018. template <class T>
  1019. void DL_PublicKey<T>::AssignFrom(const NameValuePairs &source)
  1020. {
  1021. DL_PrivateKey<T> *pPrivateKey = NULLPTR;
  1022. if (source.GetThisPointer(pPrivateKey))
  1023. pPrivateKey->MakePublicKey(*this);
  1024. else
  1025. {
  1026. this->AccessAbstractGroupParameters().AssignFrom(source);
  1027. AssignFromHelper(this, source)
  1028. CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
  1029. }
  1030. }
  1031. class OID;
  1032. /// \brief Discrete Log (DL) key base implementation
  1033. /// \tparam PK Key class
  1034. /// \tparam GP GroupParameters class
  1035. /// \tparam O OID class
  1036. template <class PK, class GP, class O = OID>
  1037. class DL_KeyImpl : public PK
  1038. {
  1039. public:
  1040. typedef GP GroupParameters;
  1041. virtual ~DL_KeyImpl() {}
  1042. O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
  1043. bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
  1044. {AccessGroupParameters().BERDecode(bt); return true;}
  1045. bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
  1046. {GetGroupParameters().DEREncode(bt); return true;}
  1047. const GP & GetGroupParameters() const {return m_groupParameters;}
  1048. GP & AccessGroupParameters() {return m_groupParameters;}
  1049. private:
  1050. GP m_groupParameters;
  1051. };
  1052. class X509PublicKey;
  1053. class PKCS8PrivateKey;
  1054. /// \brief Discrete Log (DL) private key base implementation
  1055. /// \tparam GP GroupParameters class
  1056. template <class GP>
  1057. class DL_PrivateKeyImpl : public DL_PrivateKey<typename GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
  1058. {
  1059. public:
  1060. typedef typename GP::Element Element;
  1061. virtual ~DL_PrivateKeyImpl() {}
  1062. // GeneratableCryptoMaterial
  1063. bool Validate(RandomNumberGenerator &rng, unsigned int level) const
  1064. {
  1065. CRYPTOPP_ASSERT(GetAbstractGroupParameters().Validate(rng, level));
  1066. bool pass = GetAbstractGroupParameters().Validate(rng, level);
  1067. const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
  1068. const Integer &x = GetPrivateExponent();
  1069. CRYPTOPP_ASSERT(x.IsPositive());
  1070. CRYPTOPP_ASSERT(x < q);
  1071. pass = pass && x.IsPositive() && x < q;
  1072. if (level >= 1)
  1073. {
  1074. CRYPTOPP_ASSERT(Integer::Gcd(x, q) == Integer::One());
  1075. pass = pass && Integer::Gcd(x, q) == Integer::One();
  1076. }
  1077. return pass;
  1078. }
  1079. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  1080. {
  1081. return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
  1082. }
  1083. void AssignFrom(const NameValuePairs &source)
  1084. {
  1085. AssignFromHelper<DL_PrivateKey<Element> >(this, source);
  1086. }
  1087. void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
  1088. {
  1089. if (!params.GetThisObject(this->AccessGroupParameters()))
  1090. this->AccessGroupParameters().GenerateRandom(rng, params);
  1091. Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
  1092. SetPrivateExponent(x);
  1093. }
  1094. bool SupportsPrecomputation() const {return true;}
  1095. void Precompute(unsigned int precomputationStorage=16)
  1096. {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
  1097. void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
  1098. {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
  1099. void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
  1100. {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
  1101. // DL_Key
  1102. const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
  1103. DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
  1104. // DL_PrivateKey
  1105. const Integer & GetPrivateExponent() const {return m_x;}
  1106. void SetPrivateExponent(const Integer &x) {m_x = x;}
  1107. // PKCS8PrivateKey
  1108. void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
  1109. {m_x.BERDecode(bt);}
  1110. void DEREncodePrivateKey(BufferedTransformation &bt) const
  1111. {m_x.DEREncode(bt);}
  1112. private:
  1113. Integer m_x;
  1114. };
  1115. template <class BASE, class SIGNATURE_SCHEME>
  1116. class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE
  1117. {
  1118. public:
  1119. virtual ~DL_PrivateKey_WithSignaturePairwiseConsistencyTest() {}
  1120. void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
  1121. {
  1122. BASE::GenerateRandom(rng, params);
  1123. if (FIPS_140_2_ComplianceEnabled())
  1124. {
  1125. typename SIGNATURE_SCHEME::Signer signer(*this);
  1126. typename SIGNATURE_SCHEME::Verifier verifier(signer);
  1127. SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
  1128. }
  1129. }
  1130. };
  1131. /// \brief Discrete Log (DL) public key base implementation
  1132. /// \tparam GP GroupParameters class
  1133. template <class GP>
  1134. class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
  1135. {
  1136. public:
  1137. typedef typename GP::Element Element;
  1138. virtual ~DL_PublicKeyImpl();
  1139. // CryptoMaterial
  1140. bool Validate(RandomNumberGenerator &rng, unsigned int level) const
  1141. {
  1142. CRYPTOPP_ASSERT(GetAbstractGroupParameters().Validate(rng, level));
  1143. bool pass = GetAbstractGroupParameters().Validate(rng, level);
  1144. CRYPTOPP_ASSERT(GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation()));
  1145. pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
  1146. return pass;
  1147. }
  1148. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  1149. {
  1150. return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
  1151. }
  1152. void AssignFrom(const NameValuePairs &source)
  1153. {
  1154. AssignFromHelper<DL_PublicKey<Element> >(this, source);
  1155. }
  1156. bool SupportsPrecomputation() const {return true;}
  1157. void Precompute(unsigned int precomputationStorage=16)
  1158. {
  1159. AccessAbstractGroupParameters().Precompute(precomputationStorage);
  1160. AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
  1161. }
  1162. void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
  1163. {
  1164. AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
  1165. AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
  1166. }
  1167. void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
  1168. {
  1169. GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
  1170. GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
  1171. }
  1172. // DL_Key
  1173. const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
  1174. DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
  1175. // DL_PublicKey
  1176. const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;}
  1177. DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;}
  1178. // non-inherited
  1179. bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
  1180. {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
  1181. private:
  1182. typename GP::BasePrecomputation m_ypc;
  1183. };
  1184. // Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499
  1185. template<class GP>
  1186. DL_PublicKeyImpl<GP>::~DL_PublicKeyImpl() {}
  1187. /// \brief Interface for Elgamal-like signature algorithms
  1188. /// \tparam T Field element type or class
  1189. /// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
  1190. template <class T>
  1191. class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
  1192. {
  1193. public:
  1194. virtual ~DL_ElgamalLikeSignatureAlgorithm() {}
  1195. /// \brief Sign a message using a private key
  1196. /// \param params GroupParameters
  1197. /// \param privateKey private key
  1198. /// \param k signing exponent
  1199. /// \param e encoded message
  1200. /// \param r r part of signature
  1201. /// \param s s part of signature
  1202. virtual void Sign(const DL_GroupParameters<T> &params, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
  1203. /// \brief Verify a message using a public key
  1204. /// \param params GroupParameters
  1205. /// \param publicKey public key
  1206. /// \param e encoded message
  1207. /// \param r r part of signature
  1208. /// \param s s part of signature
  1209. virtual bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
  1210. /// \brief Recover a Presignature
  1211. /// \param params GroupParameters
  1212. /// \param publicKey public key
  1213. /// \param r r part of signature
  1214. /// \param s s part of signature
  1215. virtual Integer RecoverPresignature(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
  1216. {
  1217. CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(publicKey); CRYPTOPP_UNUSED(r); CRYPTOPP_UNUSED(s);
  1218. throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");
  1219. MAYBE_RETURN(Integer::Zero());
  1220. }
  1221. /// \brief Retrieve R length
  1222. /// \param params GroupParameters
  1223. virtual size_t RLen(const DL_GroupParameters<T> &params) const
  1224. {return params.GetSubgroupOrder().ByteCount();}
  1225. /// \brief Retrieve S length
  1226. /// \param params GroupParameters
  1227. virtual size_t SLen(const DL_GroupParameters<T> &params) const
  1228. {return params.GetSubgroupOrder().ByteCount();}
  1229. /// \brief Signature scheme flag
  1230. /// \return true if the signature scheme is deterministic, false otherwise
  1231. /// \details IsDeterministic() is provided for DL signers. It is used by RFC 6979 signature schemes.
  1232. virtual bool IsDeterministic() const
  1233. {return false;}
  1234. };
  1235. /// \brief Interface for deterministic signers
  1236. /// \details RFC 6979 signers which generate k based on the encoded message and private key
  1237. class CRYPTOPP_NO_VTABLE DeterministicSignatureAlgorithm
  1238. {
  1239. public:
  1240. virtual ~DeterministicSignatureAlgorithm() {}
  1241. /// \brief Generate k
  1242. /// \param x private key
  1243. /// \param q subgroup generator
  1244. /// \param e encoded message
  1245. virtual Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const =0;
  1246. };
  1247. /// \brief Interface for DL key agreement algorithms
  1248. /// \tparam T Field element type or class
  1249. /// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
  1250. /// \sa DLIES, ECIES, ECIES_P1363
  1251. template <class T>
  1252. class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
  1253. {
  1254. public:
  1255. typedef T Element;
  1256. virtual ~DL_KeyAgreementAlgorithm() {}
  1257. virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
  1258. virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
  1259. };
  1260. /// \brief Interface for key derivation algorithms used in DL cryptosystems
  1261. /// \tparam T Field element type or class
  1262. /// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
  1263. /// \sa DLIES, ECIES, ECIES_P1363
  1264. template <class T>
  1265. class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
  1266. {
  1267. public:
  1268. virtual ~DL_KeyDerivationAlgorithm() {}
  1269. virtual bool ParameterSupported(const char *name) const
  1270. {CRYPTOPP_UNUSED(name); return false;}
  1271. virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
  1272. };
  1273. /// \brief Interface for symmetric encryption algorithms used in DL cryptosystems
  1274. /// \sa DLIES, ECIES, ECIES_P1363
  1275. class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
  1276. {
  1277. public:
  1278. virtual ~DL_SymmetricEncryptionAlgorithm() {}
  1279. virtual bool ParameterSupported(const char *name) const
  1280. {CRYPTOPP_UNUSED(name); return false;}
  1281. virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0;
  1282. virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0;
  1283. virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0;
  1284. virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const =0;
  1285. virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const =0;
  1286. };
  1287. /// \brief Discrete Log (DL) base interface
  1288. /// \tparam KI public or private key interface
  1289. template <class KI>
  1290. class CRYPTOPP_NO_VTABLE DL_Base
  1291. {
  1292. protected:
  1293. typedef KI KeyInterface;
  1294. typedef typename KI::Element Element;
  1295. virtual ~DL_Base() {}
  1296. const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
  1297. DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
  1298. virtual KeyInterface & AccessKeyInterface() =0;
  1299. virtual const KeyInterface & GetKeyInterface() const =0;
  1300. };
  1301. /// \brief Discrete Log (DL) signature scheme base implementation
  1302. /// \tparam INTFACE PK_Signer or PK_Verifier derived class
  1303. /// \tparam KEY_INTFACE DL_Base key base used in the scheme
  1304. /// \details DL_SignatureSchemeBase provides common functions for signers and verifiers.
  1305. /// DL_Base<DL_PrivateKey> is used for signers, and DL_Base<DL_PublicKey> is used for verifiers.
  1306. template <class INTFACE, class KEY_INTFACE>
  1307. class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTFACE, public DL_Base<KEY_INTFACE>
  1308. {
  1309. public:
  1310. virtual ~DL_SignatureSchemeBase() {}
  1311. /// \brief Provides the signature length
  1312. /// \return signature length, in bytes
  1313. /// \details SignatureLength returns the size required for <tt>r+s</tt>.
  1314. size_t SignatureLength() const
  1315. {
  1316. return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
  1317. + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
  1318. }
  1319. /// \brief Provides the maximum recoverable length
  1320. /// \return maximum recoverable length, in bytes
  1321. size_t MaxRecoverableLength() const
  1322. {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
  1323. /// \brief Provides the maximum recoverable length
  1324. /// \param signatureLength the size of the signature
  1325. /// \return maximum recoverable length based on signature length, in bytes
  1326. /// \details this function is not implemented and always returns 0.
  1327. size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
  1328. {CRYPTOPP_UNUSED(signatureLength); CRYPTOPP_ASSERT(false); return 0;} // TODO
  1329. /// \brief Determines if the scheme is probabilistic
  1330. /// \return true if the scheme is probabilistic, false otherwise
  1331. bool IsProbabilistic() const
  1332. {return true;}
  1333. /// \brief Determines if the scheme has non-recoverable part
  1334. /// \return true if the message encoding has a non-recoverable part, false otherwise.
  1335. bool AllowNonrecoverablePart() const
  1336. {return GetMessageEncodingInterface().AllowNonrecoverablePart();}
  1337. /// \brief Determines if the scheme allows recoverable part first
  1338. /// \return true if the message encoding allows the recoverable part, false otherwise.
  1339. bool RecoverablePartFirst() const
  1340. {return GetMessageEncodingInterface().RecoverablePartFirst();}
  1341. protected:
  1342. size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
  1343. size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
  1344. // true if the scheme conforms to RFC 6979
  1345. virtual bool IsDeterministic() const {return false;}
  1346. virtual const DL_ElgamalLikeSignatureAlgorithm<typename KEY_INTFACE::Element> & GetSignatureAlgorithm() const =0;
  1347. virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
  1348. virtual HashIdentifier GetHashIdentifier() const =0;
  1349. virtual size_t GetDigestSize() const =0;
  1350. };
  1351. /// \brief Discrete Log (DL) signature scheme signer base implementation
  1352. /// \tparam T Field element type or class
  1353. /// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
  1354. template <class T>
  1355. class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
  1356. {
  1357. public:
  1358. virtual ~DL_SignerBase() {}
  1359. /// \brief Testing interface
  1360. /// \param k Integer
  1361. /// \param e Integer
  1362. /// \param r Integer
  1363. /// \param s Integer
  1364. void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
  1365. {
  1366. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1367. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1368. const DL_PrivateKey<T> &key = this->GetKeyInterface();
  1369. r = params.ConvertElementToInteger(params.ExponentiateBase(k));
  1370. alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
  1371. }
  1372. void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
  1373. {
  1374. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1375. ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
  1376. this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
  1377. recoverableMessage, recoverableMessageLength,
  1378. ma.m_presignature, ma.m_presignature.size(),
  1379. ma.m_semisignature);
  1380. }
  1381. size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
  1382. {
  1383. this->GetMaterial().DoQuickSanityCheck();
  1384. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1385. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1386. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1387. const DL_PrivateKey<T> &key = this->GetKeyInterface();
  1388. SecByteBlock representative(this->MessageRepresentativeLength());
  1389. this->GetMessageEncodingInterface().ComputeMessageRepresentative(
  1390. rng,
  1391. ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
  1392. ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
  1393. representative, this->MessageRepresentativeBitLength());
  1394. ma.m_empty = true;
  1395. Integer e(representative, representative.size());
  1396. // hash message digest into random number k to prevent reusing the same k on
  1397. // different messages after virtual machine rollback
  1398. if (rng.CanIncorporateEntropy())
  1399. rng.IncorporateEntropy(representative, representative.size());
  1400. Integer k, ks;
  1401. const Integer& q = params.GetSubgroupOrder();
  1402. if (alg.IsDeterministic())
  1403. {
  1404. const Integer& x = key.GetPrivateExponent();
  1405. const DeterministicSignatureAlgorithm& det = dynamic_cast<const DeterministicSignatureAlgorithm&>(alg);
  1406. k = det.GenerateRandom(x, q, e);
  1407. }
  1408. else
  1409. {
  1410. k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
  1411. }
  1412. // Due to timing attack on nonce length by Jancar
  1413. // https://github.com/weidai11/cryptopp/issues/869
  1414. ks = k + q;
  1415. if (ks.BitCount() == q.BitCount()) {
  1416. ks += q;
  1417. }
  1418. Integer r, s;
  1419. r = params.ConvertElementToInteger(params.ExponentiateBase(ks));
  1420. alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
  1421. /*
  1422. Integer r, s;
  1423. if (this->MaxRecoverableLength() > 0)
  1424. r.Decode(ma.m_semisignature, ma.m_semisignature.size());
  1425. else
  1426. r.Decode(ma.m_presignature, ma.m_presignature.size());
  1427. alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s);
  1428. */
  1429. const size_t rLen = alg.RLen(params);
  1430. r.Encode(signature, rLen);
  1431. s.Encode(signature+rLen, alg.SLen(params));
  1432. if (restart)
  1433. RestartMessageAccumulator(rng, ma);
  1434. return this->SignatureLength();
  1435. }
  1436. protected:
  1437. void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
  1438. {
  1439. // k needs to be generated before hashing for signature schemes with recovery
  1440. // but to defend against VM rollbacks we need to generate k after hashing.
  1441. // so this code is commented out, since no DL-based signature scheme with recovery
  1442. // has been implemented in Crypto++ anyway
  1443. /*
  1444. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1445. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1446. ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
  1447. ma.m_presignature.New(params.GetEncodedElementSize(false));
  1448. params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size());
  1449. */
  1450. CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(ma);
  1451. }
  1452. };
  1453. /// \brief Discret Log (DL) Verifier base class
  1454. /// \tparam T Field element type or class
  1455. /// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
  1456. template <class T>
  1457. class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
  1458. {
  1459. public:
  1460. virtual ~DL_VerifierBase() {}
  1461. void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
  1462. {
  1463. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1464. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1465. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1466. // Validation due to https://github.com/weidai11/cryptopp/issues/981
  1467. // We allow a caller to provide R and S in oversized buffer. R and S
  1468. // are read based on the field element size, and not the buffer size.
  1469. const size_t rLen = alg.RLen(params);
  1470. const size_t sLen = alg.SLen(params);
  1471. CRYPTOPP_ASSERT(signatureLength >= rLen + sLen);
  1472. if (signatureLength < rLen + sLen)
  1473. throw InvalidDataFormat("DL_VerifierBase: signature length is not valid.");
  1474. ma.m_semisignature.Assign(signature, rLen);
  1475. ma.m_s.Decode(signature+rLen, sLen);
  1476. this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
  1477. }
  1478. bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
  1479. {
  1480. this->GetMaterial().DoQuickSanityCheck();
  1481. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1482. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1483. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1484. const DL_PublicKey<T> &key = this->GetKeyInterface();
  1485. SecByteBlock representative(this->MessageRepresentativeLength());
  1486. this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
  1487. ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
  1488. representative, this->MessageRepresentativeBitLength());
  1489. ma.m_empty = true;
  1490. Integer e(representative, representative.size());
  1491. Integer r(ma.m_semisignature, ma.m_semisignature.size());
  1492. return alg.Verify(params, key, e, r, ma.m_s);
  1493. }
  1494. DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
  1495. {
  1496. this->GetMaterial().DoQuickSanityCheck();
  1497. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1498. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1499. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1500. const DL_PublicKey<T> &key = this->GetKeyInterface();
  1501. SecByteBlock representative(this->MessageRepresentativeLength());
  1502. this->GetMessageEncodingInterface().ComputeMessageRepresentative(
  1503. NullRNG(),
  1504. ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
  1505. ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
  1506. representative, this->MessageRepresentativeBitLength());
  1507. ma.m_empty = true;
  1508. Integer e(representative, representative.size());
  1509. ma.m_presignature.New(params.GetEncodedElementSize(false));
  1510. Integer r(ma.m_semisignature, ma.m_semisignature.size());
  1511. alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
  1512. return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
  1513. ma.AccessHash(), this->GetHashIdentifier(),
  1514. ma.m_presignature, ma.m_presignature.size(),
  1515. ma.m_semisignature, ma.m_semisignature.size(),
  1516. recoveredMessage);
  1517. }
  1518. };
  1519. /// \brief Discrete Log (DL) cryptosystem base implementation
  1520. /// \tparam PK field element type
  1521. /// \tparam KI public or private key interface
  1522. template <class PK, class KI>
  1523. class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
  1524. {
  1525. public:
  1526. typedef typename DL_Base<KI>::Element Element;
  1527. virtual ~DL_CryptoSystemBase() {}
  1528. size_t MaxPlaintextLength(size_t ciphertextLength) const
  1529. {
  1530. unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
  1531. return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
  1532. }
  1533. size_t CiphertextLength(size_t plaintextLength) const
  1534. {
  1535. size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
  1536. return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
  1537. }
  1538. bool ParameterSupported(const char *name) const
  1539. {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
  1540. protected:
  1541. virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
  1542. virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
  1543. virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
  1544. };
  1545. /// \brief Discrete Log (DL) decryptor base implementation
  1546. /// \tparam T Field element type or class
  1547. /// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
  1548. template <class T>
  1549. class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
  1550. {
  1551. public:
  1552. typedef T Element;
  1553. virtual ~DL_DecryptorBase() {}
  1554. DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
  1555. {
  1556. try
  1557. {
  1558. CRYPTOPP_UNUSED(rng);
  1559. const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
  1560. const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
  1561. const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
  1562. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1563. const DL_PrivateKey<T> &key = this->GetKeyInterface();
  1564. Element q = params.DecodeElement(ciphertext, true);
  1565. size_t elementSize = params.GetEncodedElementSize(true);
  1566. ciphertext += elementSize;
  1567. ciphertextLength -= elementSize;
  1568. Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
  1569. SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
  1570. derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
  1571. return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
  1572. }
  1573. catch (DL_BadElement &)
  1574. {
  1575. return DecodingResult();
  1576. }
  1577. }
  1578. };
  1579. /// \brief Discrete Log (DL) encryptor base implementation
  1580. /// \tparam T Field element type or class
  1581. /// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
  1582. template <class T>
  1583. class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
  1584. {
  1585. public:
  1586. typedef T Element;
  1587. virtual ~DL_EncryptorBase() {}
  1588. void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const
  1589. {
  1590. const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
  1591. const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
  1592. const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
  1593. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1594. const DL_PublicKey<T> &key = this->GetKeyInterface();
  1595. Integer x(rng, Integer::One(), params.GetMaxExponent());
  1596. Element q = params.ExponentiateBase(x);
  1597. params.EncodeElement(true, q, ciphertext);
  1598. unsigned int elementSize = params.GetEncodedElementSize(true);
  1599. ciphertext += elementSize;
  1600. Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
  1601. SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
  1602. derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
  1603. encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
  1604. }
  1605. };
  1606. /// \brief Discrete Log (DL) scheme options
  1607. /// \tparam T1 algorithm information
  1608. /// \tparam T2 group parameters for the scheme
  1609. template <class T1, class T2>
  1610. struct DL_SchemeOptionsBase
  1611. {
  1612. typedef T1 AlgorithmInfo;
  1613. typedef T2 GroupParameters;
  1614. typedef typename GroupParameters::Element Element;
  1615. };
  1616. /// \brief Discrete Log (DL) key options
  1617. /// \tparam T1 algorithm information
  1618. /// \tparam T2 keys used in the scheme
  1619. template <class T1, class T2>
  1620. struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
  1621. {
  1622. typedef T2 Keys;
  1623. typedef typename Keys::PrivateKey PrivateKey;
  1624. typedef typename Keys::PublicKey PublicKey;
  1625. };
  1626. /// \brief Discrete Log (DL) signature scheme options
  1627. /// \tparam T1 algorithm information
  1628. /// \tparam T2 keys used in the scheme
  1629. /// \tparam T3 signature algorithm
  1630. /// \tparam T4 message encoding method
  1631. /// \tparam T5 hash function
  1632. template <class T1, class T2, class T3, class T4, class T5>
  1633. struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
  1634. {
  1635. typedef T3 SignatureAlgorithm;
  1636. typedef T4 MessageEncodingMethod;
  1637. typedef T5 HashFunction;
  1638. };
  1639. /// \brief Discrete Log (DL) crypto scheme options
  1640. /// \tparam T1 algorithm information
  1641. /// \tparam T2 keys used in the scheme
  1642. /// \tparam T3 key agreement algorithm
  1643. /// \tparam T4 key derivation algorithm
  1644. /// \tparam T5 symmetric encryption algorithm
  1645. template <class T1, class T2, class T3, class T4, class T5>
  1646. struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
  1647. {
  1648. typedef T3 KeyAgreementAlgorithm;
  1649. typedef T4 KeyDerivationAlgorithm;
  1650. typedef T5 SymmetricEncryptionAlgorithm;
  1651. };
  1652. /// \brief Discrete Log (DL) base object implementation
  1653. /// \tparam BASE TODO
  1654. /// \tparam SCHEME_OPTIONS options for the scheme
  1655. /// \tparam KEY key used in the scheme
  1656. template <class BASE, class SCHEME_OPTIONS, class KEY>
  1657. class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
  1658. {
  1659. public:
  1660. typedef SCHEME_OPTIONS SchemeOptions;
  1661. typedef typename KEY::Element Element;
  1662. virtual ~DL_ObjectImplBase() {}
  1663. PrivateKey & AccessPrivateKey() {return m_key;}
  1664. PublicKey & AccessPublicKey() {return m_key;}
  1665. // KeyAccessor
  1666. const KEY & GetKey() const {return m_key;}
  1667. KEY & AccessKey() {return m_key;}
  1668. protected:
  1669. typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
  1670. const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
  1671. // for signature scheme
  1672. HashIdentifier GetHashIdentifier() const
  1673. {
  1674. typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
  1675. return HashLookup::template HashIdentifierLookup2<typename SchemeOptions::HashFunction>::Lookup();
  1676. }
  1677. size_t GetDigestSize() const
  1678. {
  1679. typedef typename SchemeOptions::HashFunction H;
  1680. return H::DIGESTSIZE;
  1681. }
  1682. private:
  1683. KEY m_key;
  1684. };
  1685. /// \brief Discrete Log (DL) object implementation
  1686. /// \tparam BASE TODO
  1687. /// \tparam SCHEME_OPTIONS options for the scheme
  1688. /// \tparam KEY key used in the scheme
  1689. template <class BASE, class SCHEME_OPTIONS, class KEY>
  1690. class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
  1691. {
  1692. public:
  1693. typedef typename KEY::Element Element;
  1694. virtual ~DL_ObjectImpl() {}
  1695. protected:
  1696. const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
  1697. {return Singleton<typename SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
  1698. const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
  1699. {return Singleton<typename SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
  1700. const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
  1701. {return Singleton<typename SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
  1702. const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
  1703. {return Singleton<typename SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
  1704. HashIdentifier GetHashIdentifier() const
  1705. {return HashIdentifier();}
  1706. const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
  1707. {return Singleton<typename SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
  1708. };
  1709. /// \brief Discrete Log (DL) signer implementation
  1710. /// \tparam SCHEME_OPTIONS options for the scheme
  1711. template <class SCHEME_OPTIONS>
  1712. class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
  1713. {
  1714. public:
  1715. PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
  1716. {
  1717. member_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<typename SCHEME_OPTIONS::HashFunction>);
  1718. this->RestartMessageAccumulator(rng, *p);
  1719. return p.release();
  1720. }
  1721. };
  1722. /// \brief Discrete Log (DL) verifier implementation
  1723. /// \tparam SCHEME_OPTIONS options for the scheme
  1724. template <class SCHEME_OPTIONS>
  1725. class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
  1726. {
  1727. public:
  1728. PK_MessageAccumulator * NewVerificationAccumulator() const
  1729. {
  1730. return new PK_MessageAccumulatorImpl<typename SCHEME_OPTIONS::HashFunction>;
  1731. }
  1732. };
  1733. /// \brief Discrete Log (DL) encryptor implementation
  1734. /// \tparam SCHEME_OPTIONS options for the scheme
  1735. template <class SCHEME_OPTIONS>
  1736. class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
  1737. {
  1738. };
  1739. /// \brief Discrete Log (DL) decryptor implementation
  1740. /// \tparam SCHEME_OPTIONS options for the scheme
  1741. template <class SCHEME_OPTIONS>
  1742. class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
  1743. {
  1744. };
  1745. // ********************************************************
  1746. /// \brief Discrete Log (DL) simple key agreement base implementation
  1747. /// \tparam T class or type
  1748. template <class T>
  1749. class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain
  1750. {
  1751. public:
  1752. typedef T Element;
  1753. virtual ~DL_SimpleKeyAgreementDomainBase() {}
  1754. CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
  1755. unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
  1756. unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
  1757. unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
  1758. void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
  1759. {
  1760. Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
  1761. x.Encode(privateKey, PrivateKeyLength());
  1762. }
  1763. void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
  1764. {
  1765. CRYPTOPP_UNUSED(rng);
  1766. const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
  1767. Integer x(privateKey, PrivateKeyLength());
  1768. Element y = params.ExponentiateBase(x);
  1769. params.EncodeElement(true, y, publicKey);
  1770. }
  1771. bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
  1772. {
  1773. try
  1774. {
  1775. const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
  1776. Integer x(privateKey, PrivateKeyLength());
  1777. Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
  1778. Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
  1779. GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
  1780. params.EncodeElement(false, z, agreedValue);
  1781. }
  1782. catch (DL_BadElement &)
  1783. {
  1784. return false;
  1785. }
  1786. return true;
  1787. }
  1788. /// \brief Retrieves a reference to the group generator
  1789. /// \return const reference to the group generator
  1790. const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
  1791. protected:
  1792. virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
  1793. virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
  1794. const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
  1795. };
  1796. /// \brief Methods for avoiding "Small-Subgroup" attacks on Diffie-Hellman Key Agreement
  1797. /// \details Additional methods exist and include public key validation and choice of prime p.
  1798. /// \sa <A HREF="http://tools.ietf.org/html/rfc2785">Methods for Avoiding the "Small-Subgroup" Attacks on the
  1799. /// Diffie-Hellman Key Agreement Method for S/MIME</A>
  1800. enum CofactorMultiplicationOption {
  1801. /// \brief No cofactor multiplication applied
  1802. NO_COFACTOR_MULTIPLICTION,
  1803. /// \brief Cofactor multiplication compatible with ordinary Diffie-Hellman
  1804. /// \details Modifies the computation of ZZ by including j (the cofactor) in the computations and is
  1805. /// compatible with ordinary Diffie-Hellman.
  1806. COMPATIBLE_COFACTOR_MULTIPLICTION,
  1807. /// \brief Cofactor multiplication incompatible with ordinary Diffie-Hellman
  1808. /// \details Modifies the computation of ZZ by including j (the cofactor) in the computations but is
  1809. /// not compatible with ordinary Diffie-Hellman.
  1810. INCOMPATIBLE_COFACTOR_MULTIPLICTION};
  1811. typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
  1812. typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
  1813. typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
  1814. /// \brief Diffie-Hellman key agreement algorithm
  1815. template <class ELEMENT, class COFACTOR_OPTION>
  1816. class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT>
  1817. {
  1818. public:
  1819. typedef ELEMENT Element;
  1820. CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName()
  1821. {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
  1822. virtual ~DL_KeyAgreementAlgorithm_DH() {}
  1823. Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
  1824. {
  1825. return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
  1826. COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
  1827. }
  1828. Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
  1829. {
  1830. if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
  1831. {
  1832. const Integer &k = params.GetCofactor();
  1833. return params.ExponentiateElement(publicElement,
  1834. ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
  1835. }
  1836. else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
  1837. return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
  1838. else
  1839. {
  1840. CRYPTOPP_ASSERT(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
  1841. if (!validateOtherPublicKey)
  1842. return params.ExponentiateElement(publicElement, privateExponent);
  1843. if (params.FastSubgroupCheckAvailable())
  1844. {
  1845. if (!params.ValidateElement(2, publicElement, NULLPTR))
  1846. throw DL_BadElement();
  1847. return params.ExponentiateElement(publicElement, privateExponent);
  1848. }
  1849. else
  1850. {
  1851. const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
  1852. Element r[2];
  1853. params.SimultaneousExponentiate(r, publicElement, e, 2);
  1854. if (!params.IsIdentity(r[0]))
  1855. throw DL_BadElement();
  1856. return r[1];
  1857. }
  1858. }
  1859. }
  1860. };
  1861. // ********************************************************
  1862. /// \brief Template implementing constructors for public key algorithm classes
  1863. template <class BASE>
  1864. class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
  1865. {
  1866. public:
  1867. PK_FinalTemplate() {}
  1868. PK_FinalTemplate(const CryptoMaterial &key)
  1869. {this->AccessKey().AssignFrom(key);}
  1870. PK_FinalTemplate(BufferedTransformation &bt)
  1871. {this->AccessKey().BERDecode(bt);}
  1872. PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
  1873. {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
  1874. PK_FinalTemplate(const Integer &v1)
  1875. {this->AccessKey().Initialize(v1);}
  1876. template <class T1, class T2>
  1877. PK_FinalTemplate(const T1 &v1, const T2 &v2)
  1878. {this->AccessKey().Initialize(v1, v2);}
  1879. template <class T1, class T2, class T3>
  1880. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
  1881. {this->AccessKey().Initialize(v1, v2, v3);}
  1882. template <class T1, class T2, class T3, class T4>
  1883. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
  1884. {this->AccessKey().Initialize(v1, v2, v3, v4);}
  1885. template <class T1, class T2, class T3, class T4, class T5>
  1886. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
  1887. {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
  1888. template <class T1, class T2, class T3, class T4, class T5, class T6>
  1889. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
  1890. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
  1891. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
  1892. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
  1893. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
  1894. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
  1895. 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)
  1896. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
  1897. template <class T1, class T2>
  1898. PK_FinalTemplate(T1 &v1, const T2 &v2)
  1899. {this->AccessKey().Initialize(v1, v2);}
  1900. template <class T1, class T2, class T3>
  1901. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
  1902. {this->AccessKey().Initialize(v1, v2, v3);}
  1903. template <class T1, class T2, class T3, class T4>
  1904. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
  1905. {this->AccessKey().Initialize(v1, v2, v3, v4);}
  1906. template <class T1, class T2, class T3, class T4, class T5>
  1907. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
  1908. {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
  1909. template <class T1, class T2, class T3, class T4, class T5, class T6>
  1910. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
  1911. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
  1912. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
  1913. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
  1914. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
  1915. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
  1916. 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)
  1917. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
  1918. };
  1919. /// \brief Base class for public key encryption standard classes.
  1920. /// \details These classes are used to select from variants of algorithms.
  1921. /// Not all standards apply to all algorithms.
  1922. struct EncryptionStandard {};
  1923. /// \brief Base class for public key signature standard classes.
  1924. /// \details These classes are used to select from variants of algorithms.
  1925. /// Not all standards apply to all algorithms.
  1926. struct SignatureStandard {};
  1927. /// \brief Trapdoor Function (TF) encryption scheme
  1928. /// \tparam STANDARD standard
  1929. /// \tparam KEYS keys used in the encryption scheme
  1930. /// \tparam ALG_INFO algorithm information
  1931. template <class KEYS, class STANDARD, class ALG_INFO>
  1932. class TF_ES;
  1933. template <class KEYS, class STANDARD, class ALG_INFO = TF_ES<KEYS, STANDARD, int> >
  1934. class TF_ES : public KEYS
  1935. {
  1936. typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
  1937. public:
  1938. /// see EncryptionStandard for a list of standards
  1939. typedef STANDARD Standard;
  1940. typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
  1941. static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
  1942. /// implements PK_Decryptor interface
  1943. typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor;
  1944. /// implements PK_Encryptor interface
  1945. typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor;
  1946. };
  1947. /// \brief Trapdoor Function (TF) Signature Scheme
  1948. /// \tparam STANDARD standard
  1949. /// \tparam H hash function
  1950. /// \tparam KEYS keys used in the signature scheme
  1951. /// \tparam ALG_INFO algorithm information
  1952. template <class KEYS, class STANDARD, class H, class ALG_INFO>
  1953. class TF_SS;
  1954. template <class KEYS, class STANDARD, class H, class ALG_INFO = TF_SS<KEYS, STANDARD, H, int> >
  1955. class TF_SS : public KEYS
  1956. {
  1957. public:
  1958. /// see SignatureStandard for a list of standards
  1959. typedef STANDARD Standard;
  1960. typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
  1961. typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
  1962. static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
  1963. /// implements PK_Signer interface
  1964. typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
  1965. /// implements PK_Verifier interface
  1966. typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
  1967. };
  1968. /// \brief Discrete Log (DL) signature scheme
  1969. /// \tparam KEYS keys used in the signature scheme
  1970. /// \tparam SA signature algorithm
  1971. /// \tparam MEM message encoding method
  1972. /// \tparam H hash function
  1973. /// \tparam ALG_INFO algorithm information
  1974. template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
  1975. class DL_SS;
  1976. template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
  1977. class DL_SS : public KEYS
  1978. {
  1979. typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
  1980. public:
  1981. static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
  1982. /// implements PK_Signer interface
  1983. typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
  1984. /// implements PK_Verifier interface
  1985. typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
  1986. };
  1987. /// \brief Discrete Log (DL) encryption scheme
  1988. /// \tparam KEYS keys used in the encryption scheme
  1989. /// \tparam AA key agreement algorithm
  1990. /// \tparam DA key derivation algorithm
  1991. /// \tparam EA encryption algorithm
  1992. /// \tparam ALG_INFO algorithm information
  1993. template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
  1994. class DL_ES : public KEYS
  1995. {
  1996. typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
  1997. public:
  1998. /// implements PK_Decryptor interface
  1999. typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor;
  2000. /// implements PK_Encryptor interface
  2001. typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor;
  2002. };
  2003. NAMESPACE_END
  2004. #if CRYPTOPP_MSC_VERSION
  2005. # pragma warning(pop)
  2006. #endif
  2007. #endif