2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-27 15:18:06 +00:00
Files
openvswitch/lib/random.c
Ben Pfaff 78f3f31640 random: Add entropy test.
This test would have made the bug fixed in the previous commit obvious.  It
would have printed the following:

average=0007c220

bit      0     1
  0  5012  4988
  1  5019  4981
  2  5154  4846
  3  4909  5091
  4  5011  4989
  5  5021  4979
  6  4911  5089
  7  4910  5090
  8  5011  4989
  9  5020  4980
 10  5154  4846
 11  5021  4979
 12  5155  4845
 13  5019  4981
 14  5153  4847
 15  5153  4847
 16  5153  4847
 17  5153  4847
 18  5153  4847
 19  5152  4848
 20 10000     0
 21 10000     0
 22 10000     0
 23 10000     0
 24 10000     0
 25 10000     0
 26 10000     0
 27 10000     0
 28 10000     0
 29 10000     0
 30 10000     0
 31 10000     0
(expected values are 5000)

nibble   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
     0 696 646 564 693 542 545 612 611 687 663 645 560 674 566 592 704
     1 625 589 597 571 638 623 604 663 670 652 650 557 541 683 686 651
     2 628 644 659 672 648 569 585 616 623 647 681 600 586 675 601 566
     3 683 665 717 549 633 613 701 592 663 531 545 800 623 608 590 487
     4 622 657 777 557 720 608 613 598 657 678 551 654 615 596 598 499
     5 10000   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
     6 10000   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
     7 10000   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
(expected values are 625)
2010-11-15 09:34:18 -08:00

119 lines
2.4 KiB
C

/*
* Copyright (c) 2008, 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <config.h>
#include "random.h"
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>
#include "entropy.h"
#include "util.h"
/* This is the 32-bit PRNG recommended in G. Marsaglia, "Xorshift RNGs",
* _Journal of Statistical Software_ 8:14 (July 2003). According to the paper,
* it has a period of 2**32 - 1 and passes almost all tests of randomness.
*
* We use this PRNG instead of libc's rand() because rand() varies in quality
* and because its maximum value also varies between 32767 and INT_MAX, whereas
* we often want random numbers in the full range of uint32_t.
*
* This random number generator is intended for purposes that do not require
* cryptographic-quality randomness. */
/* Current random state. */
static uint32_t seed;
static uint32_t random_next(void);
void
random_init(void)
{
while (!seed) {
struct timeval tv;
uint32_t entropy;
if (gettimeofday(&tv, NULL) < 0) {
ovs_fatal(errno, "gettimeofday");
}
get_entropy_or_die(&entropy, 4);
seed = tv.tv_sec ^ tv.tv_usec ^ entropy;
}
}
void
random_set_seed(uint32_t seed_)
{
assert(seed_);
seed = seed_;
}
void
random_bytes(void *p_, size_t n)
{
uint8_t *p = p_;
random_init();
for (; n > 4; p += 4, n -= 4) {
uint32_t x = random_next();
memcpy(p, &x, 4);
}
if (n) {
uint32_t x = random_next();
memcpy(p, &x, n);
}
}
uint8_t
random_uint8(void)
{
return random_uint32();
}
uint16_t
random_uint16(void)
{
return random_uint32();
}
uint32_t
random_uint32(void)
{
random_init();
return random_next();
}
int
random_range(int max)
{
return random_uint32() % max;
}
static uint32_t
random_next(void)
{
seed ^= seed << 13;
seed ^= seed >> 17;
seed ^= seed << 5;
return seed;
}