Back to index

lightning-sunbird  0.9+nobinonly
Functions
nsEntropyCollector.cpp File Reference
#include "prlog.h"
#include "nsEntropyCollector.h"
#include "nsMemory.h"

Go to the source code of this file.

Functions

 NS_IMPL_THREADSAFE_ISUPPORTS2 (nsEntropyCollector, nsIEntropyCollector, nsIBufEntropyCollector) NS_IMETHODIMP nsEntropyCollector

Function Documentation

Definition at line 53 of file nsEntropyCollector.cpp.

{
  if (bufLen > 0) {
    if (mForwardTarget) {
      return mForwardTarget->RandomUpdate(new_entropy, bufLen);
    }
    else {
      const unsigned char *InputPointer = (const unsigned char *)new_entropy;
      const unsigned char *PastEndPointer = mEntropyCache + entropy_buffer_size;

      // if the input is large, we only take as much as we can store
      PRInt32 bytes_wanted = PR_MIN(bufLen, entropy_buffer_size);

      // remember the number of bytes we will have after storing new_entropy
      mBytesCollected = PR_MIN(entropy_buffer_size, mBytesCollected + bytes_wanted);

      // as the above statements limit bytes_wanted to the entropy_buffer_size,
      // this loop will iterate at most twice.
      while (bytes_wanted > 0) {

        // how many bytes to end of cyclic buffer?
        const PRInt32 space_to_end = PastEndPointer - mWritePointer;

        // how many bytes can we copy, not reaching the end of the buffer?
        const PRInt32 this_time = PR_MIN(space_to_end, bytes_wanted);

        // copy at most to the end of the cyclic buffer
        for (PRInt32 i = 0; i < this_time; ++i) {

          // accept the fact that we use our buffer's random uninitialized content
          unsigned int old = *mWritePointer;

          // combine new and old value already stored in buffer
          // this logic comes from PSM 1
          *mWritePointer++ = ((old << 1) | (old >> 7)) ^ *InputPointer++;
        }

        PR_ASSERT(mWritePointer <= PastEndPointer);
        PR_ASSERT(mWritePointer >= mEntropyCache);

        // have we arrived at the end of the buffer?
        if (PastEndPointer == mWritePointer) {
          // reset write pointer back to begining of our buffer
          mWritePointer = mEntropyCache;
        }

        // subtract the number of bytes we have already copied
        bytes_wanted -= this_time;
      }
    }
  }

  return NS_OK;
}