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.

196 lines
5.0 KiB

  1. // rw.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "rw.h"
  4. #include "nbtheory.h"
  5. #include "asn.h"
  6. #ifndef CRYPTOPP_IMPORTS
  7. NAMESPACE_BEGIN(CryptoPP)
  8. void RWFunction::BERDecode(BufferedTransformation &bt)
  9. {
  10. BERSequenceDecoder seq(bt);
  11. m_n.BERDecode(seq);
  12. seq.MessageEnd();
  13. }
  14. void RWFunction::DEREncode(BufferedTransformation &bt) const
  15. {
  16. DERSequenceEncoder seq(bt);
  17. m_n.DEREncode(seq);
  18. seq.MessageEnd();
  19. }
  20. Integer RWFunction::ApplyFunction(const Integer &in) const
  21. {
  22. DoQuickSanityCheck();
  23. Integer out = in.Squared()%m_n;
  24. const word r = 12;
  25. // this code was written to handle both r = 6 and r = 12,
  26. // but now only r = 12 is used in P1363
  27. const word r2 = r/2;
  28. const word r3a = (16 + 5 - r) % 16; // n%16 could be 5 or 13
  29. const word r3b = (16 + 13 - r) % 16;
  30. const word r4 = (8 + 5 - r/2) % 8; // n%8 == 5
  31. switch (out % 16)
  32. {
  33. case r:
  34. break;
  35. case r2:
  36. case r2+8:
  37. out <<= 1;
  38. break;
  39. case r3a:
  40. case r3b:
  41. out.Negate();
  42. out += m_n;
  43. break;
  44. case r4:
  45. case r4+8:
  46. out.Negate();
  47. out += m_n;
  48. out <<= 1;
  49. break;
  50. default:
  51. out = Integer::Zero();
  52. }
  53. return out;
  54. }
  55. bool RWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
  56. {
  57. bool pass = true;
  58. pass = pass && m_n > Integer::One() && m_n%8 == 5;
  59. return pass;
  60. }
  61. bool RWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  62. {
  63. return GetValueHelper(this, name, valueType, pValue).Assignable()
  64. CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
  65. ;
  66. }
  67. void RWFunction::AssignFrom(const NameValuePairs &source)
  68. {
  69. AssignFromHelper(this, source)
  70. CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
  71. ;
  72. }
  73. // *****************************************************************************
  74. // private key operations:
  75. // generate a random private key
  76. void InvertibleRWFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
  77. {
  78. int modulusSize = 2048;
  79. alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
  80. if (modulusSize < 16)
  81. throw InvalidArgument("InvertibleRWFunction: specified modulus length is too small");
  82. AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize);
  83. m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 3)("Mod", 8)));
  84. m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 7)("Mod", 8)));
  85. m_n = m_p * m_q;
  86. m_u = m_q.InverseMod(m_p);
  87. }
  88. void InvertibleRWFunction::BERDecode(BufferedTransformation &bt)
  89. {
  90. BERSequenceDecoder seq(bt);
  91. m_n.BERDecode(seq);
  92. m_p.BERDecode(seq);
  93. m_q.BERDecode(seq);
  94. m_u.BERDecode(seq);
  95. seq.MessageEnd();
  96. }
  97. void InvertibleRWFunction::DEREncode(BufferedTransformation &bt) const
  98. {
  99. DERSequenceEncoder seq(bt);
  100. m_n.DEREncode(seq);
  101. m_p.DEREncode(seq);
  102. m_q.DEREncode(seq);
  103. m_u.DEREncode(seq);
  104. seq.MessageEnd();
  105. }
  106. Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const
  107. {
  108. DoQuickSanityCheck();
  109. ModularArithmetic modn(m_n);
  110. Integer r, rInv;
  111. do { // do this in a loop for people using small numbers for testing
  112. r.Randomize(rng, Integer::One(), m_n - Integer::One());
  113. rInv = modn.MultiplicativeInverse(r);
  114. } while (rInv.IsZero());
  115. Integer re = modn.Square(r);
  116. re = modn.Multiply(re, x); // blind
  117. Integer cp=re%m_p, cq=re%m_q;
  118. if (Jacobi(cp, m_p) * Jacobi(cq, m_q) != 1)
  119. {
  120. cp = cp.IsOdd() ? (cp+m_p) >> 1 : cp >> 1;
  121. cq = cq.IsOdd() ? (cq+m_q) >> 1 : cq >> 1;
  122. }
  123. #pragma omp parallel
  124. #pragma omp sections
  125. {
  126. #pragma omp section
  127. cp = ModularSquareRoot(cp, m_p);
  128. #pragma omp section
  129. cq = ModularSquareRoot(cq, m_q);
  130. }
  131. Integer y = CRT(cq, m_q, cp, m_p, m_u);
  132. y = modn.Multiply(y, rInv); // unblind
  133. y = STDMIN(y, m_n-y);
  134. if (ApplyFunction(y) != x) // check
  135. throw Exception(Exception::OTHER_ERROR, "InvertibleRWFunction: computational error during private key operation");
  136. return y;
  137. }
  138. bool InvertibleRWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
  139. {
  140. bool pass = RWFunction::Validate(rng, level);
  141. pass = pass && m_p > Integer::One() && m_p%8 == 3 && m_p < m_n;
  142. pass = pass && m_q > Integer::One() && m_q%8 == 7 && m_q < m_n;
  143. pass = pass && m_u.IsPositive() && m_u < m_p;
  144. if (level >= 1)
  145. {
  146. pass = pass && m_p * m_q == m_n;
  147. pass = pass && m_u * m_q % m_p == 1;
  148. }
  149. if (level >= 2)
  150. pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
  151. return pass;
  152. }
  153. bool InvertibleRWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  154. {
  155. return GetValueHelper<RWFunction>(this, name, valueType, pValue).Assignable()
  156. CRYPTOPP_GET_FUNCTION_ENTRY(Prime1)
  157. CRYPTOPP_GET_FUNCTION_ENTRY(Prime2)
  158. CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
  159. ;
  160. }
  161. void InvertibleRWFunction::AssignFrom(const NameValuePairs &source)
  162. {
  163. AssignFromHelper<RWFunction>(this, source)
  164. CRYPTOPP_SET_FUNCTION_ENTRY(Prime1)
  165. CRYPTOPP_SET_FUNCTION_ENTRY(Prime2)
  166. CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
  167. ;
  168. }
  169. NAMESPACE_END
  170. #endif