@@ -1772,11 +1772,53 @@ 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 : ssize_t ;
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 $(I cryptographically-secure pseudo-random
1799+ number generator (CSPRNG)) or $(I pseudo-random number generator (PRNG))
1800+ where available and implemented (currently `arc4random` on applicable BSD
1801+ systems or `getrandom` on Linux) to generate “high quality” pseudo-random
1802+ numbers – if possible.
1803+ As a consequence, calling it may block under certain circumstances (typically
1804+ during early boot when the system's entropy pool has not yet been
1805+ initialized).
1806+
1807+ On x86 CPU models which support the `RDRAND` instruction, that will be used
1808+ when no more specialized randomness source is implemented.
1809+
1810+ In the future, further platform-specific PRNGs may be incorporated.
1811+
1812+ Warning:
1813+ $(B This function must not be used for cryptographic purposes.)
1814+ Despite being implemented for certain targets, there are no guarantees
1815+ that it sources its randomness from a CSPRNG.
1816+ The implementation also includes a fallback option that provides very little
1817+ randomness and is used when no better source of randomness is available or
1818+ integrated on the target system.
1819+ As written earlier, this function only aims to provide randomness for seeding
1820+ ordinary (non-cryptographic) PRNG engines.
1821+
17801822Returns:
17811823A single unsigned integer seed value, different on each successive call
17821824Note:
@@ -1788,7 +1830,25 @@ how excellent the source of entropy is.
17881830*/
17891831@property uint unpredictableSeed() @trusted nothrow @nogc
17901832{
1791- version (AnyARC4Random)
1833+ version (linux )
1834+ {
1835+ uint buffer;
1836+
1837+ /*
1838+ getrandom(2):
1839+ If the _urandom_ source has been initialized, reads of up to
1840+ 256 bytes will always return as many bytes as requested and
1841+ will not be interrupted by signals. No such guarantees apply
1842+ for larger buffer sizes.
1843+ */
1844+ static assert (buffer.sizeof <= 256 );
1845+
1846+ const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0 ))();
1847+ assert (status == buffer.sizeof);
1848+
1849+ return buffer;
1850+ }
1851+ else version (AnyARC4Random)
17921852 {
17931853 return arc4random ();
17941854 }
@@ -1837,7 +1897,25 @@ if (isUnsigned!UIntType)
18371897 // / ditto
18381898 @property UIntType unpredictableSeed() @nogc nothrow @trusted
18391899 {
1840- version (AnyARC4Random)
1900+ version (linux )
1901+ {
1902+ UIntType buffer;
1903+
1904+ /*
1905+ getrandom(2):
1906+ If the _urandom_ source has been initialized, reads of up to
1907+ 256 bytes will always return as many bytes as requested and
1908+ will not be interrupted by signals. No such guarantees apply
1909+ for larger buffer sizes.
1910+ */
1911+ static assert (buffer.sizeof <= 256 );
1912+
1913+ const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0 ))();
1914+ assert (status == buffer.sizeof);
1915+
1916+ return buffer;
1917+ }
1918+ else version (AnyARC4Random)
18411919 {
18421920 static if (UIntType.sizeof <= uint .sizeof)
18431921 {
0 commit comments