コード例 #1
0
      RandomDeviceCombined (string path)
        : fd(0),
          pos(0),
          rseed(0) {
        fd = TRI_OPEN(path.c_str(), O_RDONLY);

        if (fd < 0) {
          THROW_INTERNAL_ERROR("cannot open random source '" + path + "'");
        }

        // ..............................................................................
        // Set the random number generator file to be non-blocking (not for windows)
        // ..............................................................................
        {    
          #ifdef _WIN32
            abort();
          #else               
            long flags = fcntl(fd, F_GETFL, 0);
            bool ok = (flags >= 0);
            if (ok) {
              flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
              ok = (flags >= 0);
            }
            if (! ok) {

              THROW_INTERNAL_ERROR("cannot switch random source '" + path + "' to non-blocking");
            }
          #endif
        }  
        fillBuffer();
      }
コード例 #2
0
    void fillBuffer () {
        size_t n = sizeof(buffer);
        char* ptr = reinterpret_cast<char*>(&buffer);

        while (0 < n) {
            ssize_t r = TRI_READ(fd, ptr, n);

            if (r == 0) {
                LOGGER_FATAL << "read on random device failed: nothing read";
                THROW_INTERNAL_ERROR("read on random device failed");
            }
            else if (errno == EWOULDBLOCK) {
                LOGGER_INFO << "not enough entropy (got " << (sizeof(buffer) - n) << " bytes), switching to pseudo-random";
                break;
            }
            else if (r < 0) {
                LOGGER_FATAL << "read on random device failed: " << strerror(errno);
                THROW_INTERNAL_ERROR("read on random device failed");
            }

            ptr += r;
            n -= r;

            rseed = buffer[0];

            LOGGER_TRACE << "using seed " << rseed;
        }

        if (0 < n) {
            unsigned long seed = (unsigned long) time(0);

#ifdef TRI_HAVE_GETTIMEOFDAY
            struct timeval tv;
            int result = gettimeofday(&tv, 0);

            seed ^= static_cast<unsigned long>(tv.tv_sec);
            seed ^= static_cast<unsigned long>(tv.tv_usec);
            seed ^= static_cast<unsigned long>(result);
#endif

            seed ^= static_cast<unsigned long>(Thread::currentProcessId());

            mersenneDevice.seed(rseed ^ (uint32_t) seed);

            while (0 < n) {
                *ptr++ = randomGenerator();
                --n;
            }
        }

        pos = 0;
    }
コード例 #3
0
 RandomDeviceWin32 () : cryptoHandle(0), pos(0)  {
   BOOL result;
   result = CryptAcquireContext(&cryptoHandle, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT); 
   if (cryptoHandle == 0 || result == FALSE) {
     THROW_INTERNAL_ERROR("cannot create cryptographic windows handle");
   }
   fillBuffer();
 }
コード例 #4
0
      int32_t interval (int32_t left, int32_t right) {
        MUTEX_LOCKER(RandomLock);

        if (uniformInteger == 0) {
          THROW_INTERNAL_ERROR("unknown random generator");
        }

        return uniformInteger->random(left, right);
      }
コード例 #5
0
    RandomDeviceCombined (string path)
        : interval(0, UINT32_MAX),
          randomGenerator(mersenneDevice, interval),
          fd(0),
          pos(0),
          rseed(0) {
        fd = TRI_OPEN(path.c_str(), O_RDONLY);

        if (fd < 0) {
            THROW_INTERNAL_ERROR("cannot open random source '" + path + "'");
        }

        if (! TRI_SetNonBlockingSocket(fd)) {
            THROW_INTERNAL_ERROR("cannot switch random source '" + path + "' to non-blocking");
        }

        fillBuffer();
    }
コード例 #6
0
      RandomDeviceDirect (string path)
        : fd(1), pos(0)  {
        fd = TRI_OPEN(path.c_str(), O_RDONLY);

        if (fd < 0) {
          THROW_INTERNAL_ERROR("cannot open random source '" + path + "'");
        }

        fillBuffer();
      }
コード例 #7
0
      uint32_t interval (uint32_t left, uint32_t right) {
        MUTEX_LOCKER(RandomLock);

        if (uniformInteger == 0) {
          THROW_INTERNAL_ERROR("unknown random generator");
        }

        int32_t l = left + INT32_MIN;
        int32_t r = right + INT32_MIN;

        return uniformInteger->random(l, r) - INT32_MIN;
      }
コード例 #8
0
    void fillBuffer () {
        size_t n = sizeof(buffer);
        char* ptr = reinterpret_cast<char*>(&buffer);

        while (0 < n) {
            ssize_t r = TRI_READ(fd, ptr, n);

            if (r == 0) {
                LOGGER_FATAL << "read on random device failed: nothing read";
                THROW_INTERNAL_ERROR("read on random device failed");
            }
            else if (r < 0) {
                LOGGER_FATAL << "read on random device failed: " << strerror(errno);
                THROW_INTERNAL_ERROR("read on random device failed");
            }

            ptr += r;
            n -= r;
        }

        pos = 0;
    }
コード例 #9
0
random_e selectVersion (random_e newVersion) {
    MUTEX_LOCKER(RandomLock);

    random_e oldVersion = version;
    version = newVersion;

    if (uniformInteger != 0) {
        delete uniformInteger;
        uniformInteger = 0;
    }

    switch (version) {
    case RAND_MERSENNE:
        uniformInteger = new UniformIntegerMersenne;
        break;

    case RAND_RANDOM:
        if (RandomHelper::randomDevice == 0) {
            RandomHelper::randomDevice = new RandomHelper::RandomDeviceDirect<1024>("/dev/random");
        }

        uniformInteger = new UniformIntegerRandom(RandomHelper::randomDevice);

        break;

    case RAND_URANDOM:
        if (RandomHelper::urandomDevice == 0) {
            RandomHelper::urandomDevice = new RandomHelper::RandomDeviceDirect<1024>("/dev/urandom");
        }

        uniformInteger = new UniformIntegerRandom(RandomHelper::urandomDevice);

        break;

    case RAND_COMBINED:
        if (RandomHelper::combinedDevice == 0) {
            RandomHelper::combinedDevice = new RandomHelper::RandomDeviceCombined<600>("/dev/random");
        }

        uniformInteger = new UniformIntegerRandom(RandomHelper::combinedDevice);

        break;

    default:
        THROW_INTERNAL_ERROR("unknown random generator");
    }

    return oldVersion;
}