Counter Strike : Global Offensive Source Code
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.

275 lines
8.2 KiB

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