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.

155 lines
3.7 KiB

  1. // rng.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "rng.h"
  4. #include "fips140.h"
  5. #include <time.h>
  6. #include <math.h>
  7. NAMESPACE_BEGIN(CryptoPP)
  8. // linear congruential generator
  9. // originally by William S. England
  10. // do not use for cryptographic purposes
  11. /*
  12. ** Original_numbers are the original published m and q in the
  13. ** ACM article above. John Burton has furnished numbers for
  14. ** a reportedly better generator. The new numbers are now
  15. ** used in this program by default.
  16. */
  17. #ifndef LCRNG_ORIGINAL_NUMBERS
  18. const word32 LC_RNG::m=2147483647L;
  19. const word32 LC_RNG::q=44488L;
  20. const word16 LC_RNG::a=(unsigned int)48271L;
  21. const word16 LC_RNG::r=3399;
  22. #else
  23. const word32 LC_RNG::m=2147483647L;
  24. const word32 LC_RNG::q=127773L;
  25. const word16 LC_RNG::a=16807;
  26. const word16 LC_RNG::r=2836;
  27. #endif
  28. void LC_RNG::GenerateBlock(byte *output, size_t size)
  29. {
  30. while (size--)
  31. {
  32. word32 hi = seed/q;
  33. word32 lo = seed%q;
  34. long test = a*lo - r*hi;
  35. if (test > 0)
  36. seed = test;
  37. else
  38. seed = test+ m;
  39. *output++ = (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3));
  40. }
  41. }
  42. // ********************************************************
  43. #ifndef CRYPTOPP_IMPORTS
  44. X917RNG::X917RNG(BlockTransformation *c, const byte *seed, const byte *deterministicTimeVector)
  45. : cipher(c),
  46. S(cipher->BlockSize()),
  47. dtbuf(S),
  48. randseed(seed, S),
  49. m_lastBlock(S),
  50. m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? S : 0)
  51. {
  52. if (!deterministicTimeVector)
  53. {
  54. time_t tstamp1 = time(0);
  55. xorbuf(dtbuf, (byte *)&tstamp1, UnsignedMin(sizeof(tstamp1), S));
  56. cipher->ProcessBlock(dtbuf);
  57. clock_t tstamp2 = clock();
  58. xorbuf(dtbuf, (byte *)&tstamp2, UnsignedMin(sizeof(tstamp2), S));
  59. cipher->ProcessBlock(dtbuf);
  60. }
  61. // for FIPS 140-2
  62. GenerateBlock(m_lastBlock, S);
  63. }
  64. void X917RNG::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size)
  65. {
  66. while (size > 0)
  67. {
  68. // calculate new enciphered timestamp
  69. if (m_deterministicTimeVector.size())
  70. {
  71. cipher->ProcessBlock(m_deterministicTimeVector, dtbuf);
  72. IncrementCounterByOne(m_deterministicTimeVector, S);
  73. }
  74. else
  75. {
  76. clock_t c = clock();
  77. xorbuf(dtbuf, (byte *)&c, UnsignedMin(sizeof(c), S));
  78. time_t t = time(NULL);
  79. xorbuf(dtbuf+S-UnsignedMin(sizeof(t), S), (byte *)&t, UnsignedMin(sizeof(t), S));
  80. cipher->ProcessBlock(dtbuf);
  81. }
  82. // combine enciphered timestamp with seed
  83. xorbuf(randseed, dtbuf, S);
  84. // generate a new block of random bytes
  85. cipher->ProcessBlock(randseed);
  86. if (memcmp(m_lastBlock, randseed, S) == 0)
  87. throw SelfTestFailure("X917RNG: Continuous random number generator test failed.");
  88. // output random bytes
  89. size_t len = UnsignedMin(S, size);
  90. target.ChannelPut(channel, randseed, len);
  91. size -= len;
  92. // compute new seed vector
  93. memcpy(m_lastBlock, randseed, S);
  94. xorbuf(randseed, dtbuf, S);
  95. cipher->ProcessBlock(randseed);
  96. }
  97. }
  98. #endif
  99. MaurerRandomnessTest::MaurerRandomnessTest()
  100. : sum(0.0), n(0)
  101. {
  102. for (unsigned i=0; i<V; i++)
  103. tab[i] = 0;
  104. }
  105. size_t MaurerRandomnessTest::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
  106. {
  107. while (length--)
  108. {
  109. byte inByte = *inString++;
  110. if (n >= Q)
  111. sum += log(double(n - tab[inByte]));
  112. tab[inByte] = n;
  113. n++;
  114. }
  115. return 0;
  116. }
  117. double MaurerRandomnessTest::GetTestValue() const
  118. {
  119. if (BytesNeeded() > 0)
  120. throw Exception(Exception::OTHER_ERROR, "MaurerRandomnessTest: " + IntToString(BytesNeeded()) + " more bytes of input needed");
  121. double fTu = (sum/(n-Q))/log(2.0); // this is the test value defined by Maurer
  122. double value = fTu * 0.1392; // arbitrarily normalize it to
  123. return value > 1.0 ? 1.0 : value; // a number between 0 and 1
  124. }
  125. NAMESPACE_END