@@ -1772,11 +1772,51 @@ else
17721772 }
17731773}
17741774
1775+ version (linux )
1776+ {
1777+ // `getrandom()` was introduced in Linux 3.17.
1778+
1779+ // Shim for missing bindings in druntime
1780+ version (none )
1781+ import core.sys.linux.sys.random : getrandom;
1782+ else
1783+ {
1784+ import core.sys.posix.sys.types ;
1785+ extern extern (C) ssize_t getrandom(
1786+ void * buf,
1787+ size_t buflen,
1788+ uint flags,
1789+ ) @system nothrow @nogc ;
1790+ }
1791+ }
1792+
17751793/**
17761794A "good" seed for initializing random number engines. Initializing
17771795with $(D_PARAM unpredictableSeed) makes engines generate different
17781796random number sequences every run.
17791797
1798+ This function utilizes the system (CS-)PRNG where available and implemented
1799+ (currently `arc4random` on applicable BSD systems or `getrandom` on Linux) to
1800+ generate “high quality” pseudo-random numbers – if possible.
1801+ As a consequence, calling it may block under certain circumstances (typically
1802+ during early boot when the system's entropy pool has not yet been
1803+ initialized).
1804+
1805+ On x86 CPU models which support the `RDRAND` instruction, that will be used
1806+ when no more specialized randomness source is implemented.
1807+
1808+ In the future, further platform-specific PRNGs may be incorporated.
1809+
1810+ Warning:
1811+ $(B This function must not be used for cryptographic purposes.)
1812+ Despite being implemented for certain targets, there are no guarantees
1813+ that it sources its randomness from a cryptographically-secure PRNG.
1814+ The implementation also includes a fallback option that provides very little
1815+ randomness and is used when no better source of randomness is available or
1816+ integrated on the target system.
1817+ As written earlier, this function only aims to provide randomness for seeding
1818+ ordinary (non-cryptographic) RNG engines.
1819+
17801820Returns:
17811821A single unsigned integer seed value, different on each successive call
17821822Note:
@@ -1788,7 +1828,25 @@ how excellent the source of entropy is.
17881828*/
17891829@property uint unpredictableSeed() @trusted nothrow @nogc
17901830{
1791- version (AnyARC4Random)
1831+ version (linux )
1832+ {
1833+ uint buffer;
1834+
1835+ /*
1836+ getrandom(2):
1837+ If the _urandom_ source has been initialized, reads of up to
1838+ 256 bytes will always return as many bytes as requested and
1839+ will not be interrupted by signals. No such guarantees apply
1840+ for larger buffer sizes.
1841+ */
1842+ static assert (buffer.sizeof <= 256 );
1843+
1844+ const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0 ))();
1845+ assert (status == buffer.sizeof);
1846+
1847+ return buffer;
1848+ }
1849+ else version (AnyARC4Random)
17921850 {
17931851 return arc4random ();
17941852 }
@@ -1837,7 +1895,25 @@ if (isUnsigned!UIntType)
18371895 // / ditto
18381896 @property UIntType unpredictableSeed() @nogc nothrow @trusted
18391897 {
1840- version (AnyARC4Random)
1898+ version (linux )
1899+ {
1900+ UIntType buffer;
1901+
1902+ /*
1903+ getrandom(2):
1904+ If the _urandom_ source has been initialized, reads of up to
1905+ 256 bytes will always return as many bytes as requested and
1906+ will not be interrupted by signals. No such guarantees apply
1907+ for larger buffer sizes.
1908+ */
1909+ static assert (buffer.sizeof <= 256 );
1910+
1911+ const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0 ))();
1912+ assert (status == buffer.sizeof);
1913+
1914+ return buffer;
1915+ }
1916+ else version (AnyARC4Random)
18411917 {
18421918 static if (UIntType.sizeof <= uint .sizeof)
18431919 {
0 commit comments