rand.cpp revision 166d15723bdbf3eeec7d9d420de92c65cf9daf9f
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * IPRT - Random Number
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * available from http://www.virtualbox.org. This file is free software;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * you can redistribute it and/or modify it under the terms of the GNU
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * General Public License (GPL) as published by the Free Software
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * The contents of this file may alternatively be used under the terms
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * of the Common Development and Distribution License Version 1.0
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * VirtualBox OSE distribution, in which case the provisions of the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * CDDL are applicable instead of those of the GPL.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * You may elect to license modified versions of this file under the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * terms and conditions of either the GPL or the CDDL or both.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * additional information or have any questions.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Header Files *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Global Variables *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Lazy init. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic volatile bool g_fInitialized = false;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** The context variable for the fallback path. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Internal Functions *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic uint32_t rtRandGenBytesFallbackU31(uint32_t *pCtx);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Lazy initialization of the native and fallback random byte sources.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic void rtRandLazyInit(void)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Seed the fallback random code.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Call host specific init.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Internal wrapper for the native and generic random byte methods.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pv Where to store the random bytes.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param cb Number of bytes to generate.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Fills a buffer with random bytes.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pv Where to store the random bytes.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param cb Number of bytes to generate.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncRTDECL(void) RTRandBytes(void *pv, size_t cb) RT_NO_THROW
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Generate a 32-bit unsigned random number in the set [u32First..u32Last].
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @returns The random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param u32First First number in the set.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param u32Last Last number in the set.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncRTDECL(uint32_t) RTRandU32Ex(uint32_t u32First, uint32_t u32Last) RT_NO_THROW
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* get 4 random bytes and return them raw. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* get 4 random bytes and do simple squeeze. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* get 5 random bytes and do shifted squeeze. (this ain't perfect) */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Generate a 32-bit unsigned random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @returns The random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Generate a 32-bit signed random number in the set [i32First..i32Last].
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @returns The random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param i32First First number in the set.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param i32Last Last number in the set.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncRTDECL(int32_t) RTRandS32Ex(int32_t i32First, int32_t i32Last) RT_NO_THROW
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync return RTRandU32Ex(0, i32Last - i32First) + i32First;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Generate a 32-bit signed random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @returns The random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Generate a 64-bit unsigned random number in the set [u64First..u64Last].
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @returns The random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param u64First First number in the set.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param u64Last Last number in the set.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncRTDECL(uint64_t) RTRandU64Ex(uint64_t u64First, uint64_t u64Last) RT_NO_THROW
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* get 8 random bytes and return them raw. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync else if (!(offLast & UINT64_C(0xf000000000000000)))
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* get 8 random bytes and do simple squeeze. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* get 9 random bytes and do shifted squeeze. (this ain't perfect) */
50f998bb47f333d10515d4c12ad01a4e92a0747bvboxsync * Generate a 64-bit unsigned random number.
50f998bb47f333d10515d4c12ad01a4e92a0747bvboxsync * @returns The random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Generate a 64-bit signed random number in the set [i64First..i64Last].
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @returns The random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param i64First First number in the set.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param i64Last Last number in the set.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncRTDECL(int64_t) RTRandS64Ex(int64_t i64First, int64_t i64Last) RT_NO_THROW
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync return (int64_t)RTRandU64Ex(0, i64Last - i64First) + i64First;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Generate a 64-bit signed random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @returns The random number.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Fallback random byte source.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pv Where to store the random bytes.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param cb Number of bytes to generate.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncvoid rtRandGenBytesFallback(void *pv, size_t cb) RT_NO_THROW
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync for (unsigned i = 0;; i++)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t u32 = rtRandGenBytesFallbackU31(&g_u32Ctx);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Is this really a good idea? Looks like we cannot
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * quite trust the lower bits here for instance...
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync if (!(i % 3))
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Copyright (c) 1990, 1993
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * The Regents of the University of California. All rights reserved.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Redistribution and use in source and binary forms, with or without
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * modification, are permitted provided that the following conditions
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * 1. Redistributions of source code must retain the above copyright
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * notice, this list of conditions and the following disclaimer.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * 2. Redistributions in binary form must reproduce the above copyright
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * notice, this list of conditions and the following disclaimer in the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * documentation and/or other materials provided with the distribution.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * 4. Neither the name of the University nor the names of its contributors
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * may be used to endorse or promote products derived from this software
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * without specific prior written permission.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * SUCH DAMAGE.
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync/* The core of:
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdlib/rand.c,v 1.16 2007/01/09 00:28:10 imp Exp $");
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * Generates an unsigned 31 bit pseudo random number.
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * @returns pseudo random number.
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * @param pCtx The context.
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsyncstatic uint32_t rtRandGenBytesFallbackU31(uint32_t *pCtx)
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * Compute x = (7^5 * x) mod (2^31 - 1)
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * without overflowing 31 bits:
021c939a9e3f688c0c3bbd759354be906bb2dcabvboxsync * (2^31 - 1) = 127773 * (7^5) + 2836
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * From "Random number generators: good ones are hard to find", Park and
d1d4bf58f99da14d0aaa7bcc728a359c8a7eb7bdvboxsync * Miller, Communications of the ACM, vol. 31, no. 10, October 1988, p. 1195.