dash/src/random.h

71 lines
1.8 KiB
C
Raw Normal View History

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
2014-12-13 05:09:33 +01:00
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_RANDOM_H
#define BITCOIN_RANDOM_H
#include "uint256.h"
#include <stdint.h>
/* Seed OpenSSL PRNG with additional entropy data */
void RandAddSeed();
/**
* Functions to gather random data via the OpenSSL PRNG
*/
void GetRandBytes(unsigned char* buf, int num);
uint64_t GetRand(uint64_t nMax);
int GetRandInt(int nMax);
uint256 GetRandHash();
/**
* Function to gather random data from multiple sources, failing whenever any
* of those source fail to provide a result.
*/
void GetStrongRandBytes(unsigned char* buf, int num);
/**
* Fast randomness source. This is seeded once with secure random data, but
* is completely deterministic and insecure after that.
* This class is not thread-safe.
*/
class FastRandomContext {
public:
explicit FastRandomContext(bool fDeterministic=false);
uint32_t rand32() {
Rz = 36969 * (Rz & 65535) + (Rz >> 16);
Rw = 18000 * (Rw & 65535) + (Rw >> 16);
return (Rw << 16) + Rz;
}
bool randbool() {
return rand32() & 1;
}
uint32_t Rz;
uint32_t Rw;
};
/* Number of random bytes returned by GetOSRand.
* When changing this constant make sure to change all call sites, and make
* sure that the underlying OS APIs for all platforms support the number.
* (many cap out at 256 bytes).
*/
util: Specific GetOSRandom for Linux/FreeBSD/OpenBSD These are available in sandboxes without access to files or devices. Also [they are safer and more straightforward](https://en.wikipedia.org/wiki/Entropy-supplying_system_calls) to use than `/dev/urandom` as reading from a file has quite a few edge cases: - Linux: `getrandom(buf, buflen, 0)`. [getrandom(2)](http://man7.org/linux/man-pages/man2/getrandom.2.html) was introduced in version 3.17 of the Linux kernel. - OpenBSD: `getentropy(buf, buflen)`. The [getentropy(2)](http://man.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2) function appeared in OpenBSD 5.6. - FreeBSD and NetBSD: `sysctl(KERN_ARND)`. Not sure when this was added but it has existed for quite a while. Alternatives: - Linux has sysctl `CTL_KERN` / `KERN_RANDOM` / `RANDOM_UUID` which gives 16 bytes of randomness. This may be available on older kernels, however [sysctl is deprecated on Linux](https://lwn.net/Articles/605392/) and even removed in some distros so we shouldn't use it. Add tests for `GetOSRand()`: - Test that no error happens (otherwise `RandFailure()` which aborts) - Test that all 32 bytes are overwritten (initialize with zeros, try multiple times) Discussion: - When to use these? Currently they are always used when available. Another option would be to use them only when `/dev/urandom` is not available. But this would mean these code paths receive less testing, and I'm not sure there is any reason to prefer `/dev/urandom`. Closes: #9676
2017-02-21 17:36:37 +01:00
static const ssize_t NUM_OS_RANDOM_BYTES = 32;
/** Get 32 bytes of system entropy. Do not use this in application code: use
* GetStrongRandBytes instead.
*/
void GetOSRand(unsigned char *ent32);
/** Check that OS randomness is available and returning the requested number
* of bytes.
*/
bool Random_SanityCheck();
#endif // BITCOIN_RANDOM_H