Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
9.5 KiB

  1. // dsa.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "config.h"
  4. // TODO: fix the C4589 warnings
  5. #if CRYPTOPP_MSC_VERSION
  6. # pragma warning(disable: 4189 4589)
  7. #endif
  8. #ifndef CRYPTOPP_IMPORTS
  9. #include "gfpcrypt.h"
  10. #include "nbtheory.h"
  11. #include "modarith.h"
  12. #include "integer.h"
  13. #include "asn.h"
  14. #include "oids.h"
  15. #include "misc.h"
  16. NAMESPACE_BEGIN(CryptoPP)
  17. #if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
  18. void TestInstantiations_gfpcrypt()
  19. {
  20. GDSA<SHA>::Signer test;
  21. GDSA<SHA>::Verifier test1;
  22. DSA::Signer test5(NullRNG(), 100);
  23. DSA::Signer test2(test5);
  24. NR<SHA>::Signer test3;
  25. NR<SHA>::Verifier test4;
  26. DLIES<>::Encryptor test6;
  27. DLIES<>::Decryptor test7;
  28. }
  29. #endif
  30. void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
  31. {
  32. Integer p, q, g;
  33. if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
  34. {
  35. q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
  36. Initialize(p, q, g);
  37. }
  38. else
  39. {
  40. int modulusSize = 1024, defaultSubgroupOrderSize;
  41. alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
  42. switch (modulusSize)
  43. {
  44. case 1024:
  45. defaultSubgroupOrderSize = 160;
  46. break;
  47. case 2048:
  48. defaultSubgroupOrderSize = 224;
  49. break;
  50. case 3072:
  51. defaultSubgroupOrderSize = 256;
  52. break;
  53. default:
  54. throw InvalidArgument("DSA: not a valid prime length");
  55. }
  56. DL_GroupParameters_GFP::GenerateRandom(rng, CombinedNameValuePairs(alg, MakeParameters(Name::SubgroupOrderSize(), defaultSubgroupOrderSize, false)));
  57. }
  58. }
  59. bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
  60. {
  61. bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level);
  62. int pSize = GetModulus().BitCount(), qSize = GetSubgroupOrder().BitCount();
  63. pass = pass && ((pSize==1024 && qSize==160) || (pSize==2048 && qSize==224) || (pSize==2048 && qSize==256) || (pSize==3072 && qSize==256));
  64. return pass;
  65. }
  66. void DL_SignatureMessageEncodingMethod_DSA::ComputeMessageRepresentative(RandomNumberGenerator &rng,
  67. const byte *recoverableMessage, size_t recoverableMessageLength,
  68. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  69. byte *representative, size_t representativeBitLength) const
  70. {
  71. CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
  72. CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
  73. assert(recoverableMessageLength == 0);
  74. assert(hashIdentifier.second == 0);
  75. const size_t representativeByteLength = BitsToBytes(representativeBitLength);
  76. const size_t digestSize = hash.DigestSize();
  77. const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
  78. memset(representative, 0, paddingLength);
  79. hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
  80. if (digestSize*8 > representativeBitLength)
  81. {
  82. Integer h(representative, representativeByteLength);
  83. h >>= representativeByteLength*8 - representativeBitLength;
  84. h.Encode(representative, representativeByteLength);
  85. }
  86. }
  87. void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNumberGenerator &rng,
  88. const byte *recoverableMessage, size_t recoverableMessageLength,
  89. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  90. byte *representative, size_t representativeBitLength) const
  91. {
  92. CRYPTOPP_UNUSED(rng);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength);
  93. CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty);
  94. CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength);
  95. assert(recoverableMessageLength == 0);
  96. assert(hashIdentifier.second == 0);
  97. const size_t representativeByteLength = BitsToBytes(representativeBitLength);
  98. const size_t digestSize = hash.DigestSize();
  99. const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
  100. memset(representative, 0, paddingLength);
  101. hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
  102. if (digestSize*8 >= representativeBitLength)
  103. {
  104. Integer h(representative, representativeByteLength);
  105. h >>= representativeByteLength*8 - representativeBitLength + 1;
  106. h.Encode(representative, representativeByteLength);
  107. }
  108. }
  109. bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
  110. {
  111. const Integer &p = GetModulus(), &q = GetSubgroupOrder();
  112. bool pass = true;
  113. pass = pass && p > Integer::One() && p.IsOdd();
  114. pass = pass && q > Integer::One() && q.IsOdd();
  115. if (level >= 1)
  116. pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero();
  117. if (level >= 2)
  118. pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2);
  119. return pass;
  120. }
  121. bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
  122. {
  123. const Integer &p = GetModulus(), &q = GetSubgroupOrder();
  124. bool pass = true;
  125. pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
  126. pass = pass && g < p && !IsIdentity(g);
  127. if (level >= 1)
  128. {
  129. if (gpc)
  130. pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g;
  131. }
  132. if (level >= 2)
  133. {
  134. if (GetFieldType() == 2)
  135. pass = pass && Jacobi(g*g-4, p)==-1;
  136. // verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly
  137. // and at most 1 bit is leaked if it's false
  138. bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable();
  139. if (fullValidate && pass)
  140. {
  141. Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q);
  142. pass = pass && IsIdentity(gp);
  143. }
  144. else if (GetFieldType() == 1)
  145. pass = pass && Jacobi(g, p) == 1;
  146. }
  147. return pass;
  148. }
  149. void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
  150. {
  151. Integer p, q, g;
  152. if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
  153. {
  154. q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
  155. }
  156. else
  157. {
  158. int modulusSize, subgroupOrderSize;
  159. if (!alg.GetIntValue("ModulusSize", modulusSize))
  160. modulusSize = alg.GetIntValueWithDefault("KeySize", 2048);
  161. if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize))
  162. subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize);
  163. PrimeAndGenerator pg;
  164. pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize);
  165. p = pg.Prime();
  166. q = pg.SubPrime();
  167. g = pg.Generator();
  168. }
  169. Initialize(p, q, g);
  170. }
  171. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  172. void DL_GroupParameters_IntegerBased::EncodeElement(bool reversible, const Element &element, byte *encoded) const
  173. {
  174. CRYPTOPP_UNUSED(reversible);
  175. element.Encode(encoded, GetModulus().ByteCount());
  176. }
  177. unsigned int DL_GroupParameters_IntegerBased::GetEncodedElementSize(bool reversible) const
  178. {
  179. CRYPTOPP_UNUSED(reversible);
  180. return GetModulus().ByteCount();
  181. }
  182. #endif
  183. Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const
  184. {
  185. CRYPTOPP_UNUSED(checkForGroupMembership);
  186. Integer g(encoded, GetModulus().ByteCount());
  187. if (!ValidateElement(1, g, NULL))
  188. throw DL_BadElement();
  189. return g;
  190. }
  191. void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt)
  192. {
  193. BERSequenceDecoder parameters(bt);
  194. Integer p(parameters);
  195. Integer q(parameters);
  196. Integer g;
  197. if (parameters.EndReached())
  198. {
  199. g = q;
  200. q = ComputeGroupOrder(p) / 2;
  201. }
  202. else
  203. g.BERDecode(parameters);
  204. parameters.MessageEnd();
  205. SetModulusAndSubgroupGenerator(p, g);
  206. SetSubgroupOrder(q);
  207. }
  208. void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const
  209. {
  210. DERSequenceEncoder parameters(bt);
  211. GetModulus().DEREncode(parameters);
  212. m_q.DEREncode(parameters);
  213. GetSubgroupGenerator().DEREncode(parameters);
  214. parameters.MessageEnd();
  215. }
  216. bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  217. {
  218. return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue)
  219. CRYPTOPP_GET_FUNCTION_ENTRY(Modulus);
  220. }
  221. void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source)
  222. {
  223. AssignFromHelper(this, source)
  224. CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator)
  225. CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
  226. ;
  227. }
  228. OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const
  229. {
  230. return ASN1::id_dsa();
  231. }
  232. void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
  233. {
  234. ModularArithmetic ma(GetModulus());
  235. ma.SimultaneousExponentiate(results, base, exponents, exponentsCount);
  236. }
  237. DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const
  238. {
  239. return a_times_b_mod_c(a, b, GetModulus());
  240. }
  241. DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
  242. {
  243. ModularArithmetic ma(GetModulus());
  244. return ma.CascadeExponentiate(element1, exponent1, element2, exponent2);
  245. }
  246. Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const
  247. {
  248. return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount())));
  249. }
  250. unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const
  251. {
  252. return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize);
  253. }
  254. NAMESPACE_END
  255. #endif