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.

210 lines
5.7 KiB

  1. // esign.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "esign.h"
  4. #include "asn.h"
  5. #include "modarith.h"
  6. #include "nbtheory.h"
  7. #include "sha.h"
  8. #include "algparam.h"
  9. NAMESPACE_BEGIN(CryptoPP)
  10. void ESIGN_TestInstantiations()
  11. {
  12. ESIGN<SHA>::Verifier x1(1, 1);
  13. ESIGN<SHA>::Signer x2(NullRNG(), 1);
  14. ESIGN<SHA>::Verifier x3(x2);
  15. ESIGN<SHA>::Verifier x4(x2.GetKey());
  16. ESIGN<SHA>::Verifier x5(x3);
  17. ESIGN<SHA>::Signer x6 = x2;
  18. x6 = x2;
  19. x3 = ESIGN<SHA>::Verifier(x2);
  20. x4 = x2.GetKey();
  21. }
  22. void ESIGNFunction::BERDecode(BufferedTransformation &bt)
  23. {
  24. BERSequenceDecoder seq(bt);
  25. m_n.BERDecode(seq);
  26. m_e.BERDecode(seq);
  27. seq.MessageEnd();
  28. }
  29. void ESIGNFunction::DEREncode(BufferedTransformation &bt) const
  30. {
  31. DERSequenceEncoder seq(bt);
  32. m_n.DEREncode(seq);
  33. m_e.DEREncode(seq);
  34. seq.MessageEnd();
  35. }
  36. Integer ESIGNFunction::ApplyFunction(const Integer &x) const
  37. {
  38. DoQuickSanityCheck();
  39. return STDMIN(a_exp_b_mod_c(x, m_e, m_n) >> (2*GetK()+2), MaxImage());
  40. }
  41. bool ESIGNFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
  42. {
  43. bool pass = true;
  44. pass = pass && m_n > Integer::One() && m_n.IsOdd();
  45. pass = pass && m_e >= 8 && m_e < m_n;
  46. return pass;
  47. }
  48. bool ESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  49. {
  50. return GetValueHelper(this, name, valueType, pValue).Assignable()
  51. CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
  52. CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent)
  53. ;
  54. }
  55. void ESIGNFunction::AssignFrom(const NameValuePairs &source)
  56. {
  57. AssignFromHelper(this, source)
  58. CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
  59. CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent)
  60. ;
  61. }
  62. // *****************************************************************************
  63. void InvertibleESIGNFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &param)
  64. {
  65. int modulusSize = 1023*2;
  66. param.GetIntValue("ModulusSize", modulusSize) || param.GetIntValue("KeySize", modulusSize);
  67. if (modulusSize < 24)
  68. throw InvalidArgument("InvertibleESIGNFunction: specified modulus size is too small");
  69. if (modulusSize % 3 != 0)
  70. throw InvalidArgument("InvertibleESIGNFunction: modulus size must be divisible by 3");
  71. m_e = param.GetValueWithDefault("PublicExponent", Integer(32));
  72. if (m_e < 8)
  73. throw InvalidArgument("InvertibleESIGNFunction: public exponents less than 8 may not be secure");
  74. // VC70 workaround: putting these after primeParam causes overlapped stack allocation
  75. ConstByteArrayParameter seedParam;
  76. SecByteBlock seed;
  77. const Integer minP = Integer(204) << (modulusSize/3-8);
  78. const Integer maxP = Integer::Power2(modulusSize/3)-1;
  79. AlgorithmParameters primeParam = MakeParameters("Min", minP)("Max", maxP)("RandomNumberType", Integer::PRIME);
  80. if (param.GetValue("Seed", seedParam))
  81. {
  82. seed.resize(seedParam.size() + 4);
  83. memcpy(seed + 4, seedParam.begin(), seedParam.size());
  84. PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)0);
  85. m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed))));
  86. PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)1);
  87. m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed))));
  88. }
  89. else
  90. {
  91. m_p.GenerateRandom(rng, primeParam);
  92. m_q.GenerateRandom(rng, primeParam);
  93. }
  94. m_n = m_p * m_p * m_q;
  95. assert(m_n.BitCount() == modulusSize);
  96. }
  97. void InvertibleESIGNFunction::BERDecode(BufferedTransformation &bt)
  98. {
  99. BERSequenceDecoder privateKey(bt);
  100. m_n.BERDecode(privateKey);
  101. m_e.BERDecode(privateKey);
  102. m_p.BERDecode(privateKey);
  103. m_q.BERDecode(privateKey);
  104. privateKey.MessageEnd();
  105. }
  106. void InvertibleESIGNFunction::DEREncode(BufferedTransformation &bt) const
  107. {
  108. DERSequenceEncoder privateKey(bt);
  109. m_n.DEREncode(privateKey);
  110. m_e.DEREncode(privateKey);
  111. m_p.DEREncode(privateKey);
  112. m_q.DEREncode(privateKey);
  113. privateKey.MessageEnd();
  114. }
  115. Integer InvertibleESIGNFunction::CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
  116. {
  117. DoQuickSanityCheck();
  118. Integer pq = m_p * m_q;
  119. Integer p2 = m_p * m_p;
  120. Integer r, z, re, a, w0, w1;
  121. do
  122. {
  123. r.Randomize(rng, Integer::Zero(), pq);
  124. z = x << (2*GetK()+2);
  125. re = a_exp_b_mod_c(r, m_e, m_n);
  126. a = (z - re) % m_n;
  127. Integer::Divide(w1, w0, a, pq);
  128. if (w1.NotZero())
  129. {
  130. ++w0;
  131. w1 = pq - w1;
  132. }
  133. }
  134. while ((w1 >> 2*GetK()+1).IsPositive());
  135. ModularArithmetic modp(m_p);
  136. Integer t = modp.Divide(w0 * r % m_p, m_e * re % m_p);
  137. Integer s = r + t*pq;
  138. assert(s < m_n);
  139. /*
  140. using namespace std;
  141. cout << "f = " << x << endl;
  142. cout << "r = " << r << endl;
  143. cout << "z = " << z << endl;
  144. cout << "a = " << a << endl;
  145. cout << "w0 = " << w0 << endl;
  146. cout << "w1 = " << w1 << endl;
  147. cout << "t = " << t << endl;
  148. cout << "s = " << s << endl;
  149. */
  150. return s;
  151. }
  152. bool InvertibleESIGNFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
  153. {
  154. bool pass = ESIGNFunction::Validate(rng, level);
  155. pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n;
  156. pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n;
  157. pass = pass && m_p.BitCount() == m_q.BitCount();
  158. if (level >= 1)
  159. pass = pass && m_p * m_p * m_q == m_n;
  160. if (level >= 2)
  161. pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
  162. return pass;
  163. }
  164. bool InvertibleESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  165. {
  166. return GetValueHelper<ESIGNFunction>(this, name, valueType, pValue).Assignable()
  167. CRYPTOPP_GET_FUNCTION_ENTRY(Prime1)
  168. CRYPTOPP_GET_FUNCTION_ENTRY(Prime2)
  169. ;
  170. }
  171. void InvertibleESIGNFunction::AssignFrom(const NameValuePairs &source)
  172. {
  173. AssignFromHelper<ESIGNFunction>(this, source)
  174. CRYPTOPP_SET_FUNCTION_ENTRY(Prime1)
  175. CRYPTOPP_SET_FUNCTION_ENTRY(Prime2)
  176. ;
  177. }
  178. NAMESPACE_END