Skip to content

Commit

Permalink
Make unpredictableSeed use getrandom (syscall) on Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
0xEAB committed Jan 19, 2025
1 parent 1b24204 commit 6fc083d
Showing 1 changed file with 56 additions and 2 deletions.
58 changes: 56 additions & 2 deletions std/random.d
Original file line number Diff line number Diff line change
Expand Up @@ -1772,6 +1772,24 @@ else
}
}

version (linux)
{
// `getrandom()` was introduced in Linux 3.17.

// Shim for missing bindings in druntime
version (none)
import core.sys.linux.sys.random : getrandom;
else
{
import core.sys.posix.sys.types;
extern extern(C) ssize_t getrandom(
void* buf,
size_t buflen,
uint flags,
) @system nothrow @nogc;
}
}

/**
A "good" seed for initializing random number engines. Initializing
with $(D_PARAM unpredictableSeed) makes engines generate different
Expand All @@ -1788,7 +1806,25 @@ how excellent the source of entropy is.
*/
@property uint unpredictableSeed() @trusted nothrow @nogc
{
version (AnyARC4Random)
version (linux)
{
uint buffer;

/*
getrandom(2):
If the _urandom_ source has been initialized, reads of up to
256 bytes will always return as many bytes as requested and
will not be interrupted by signals. No such guarantees apply
for larger buffer sizes.
*/
static assert(buffer.sizeof <= 256);

const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0))();
assert(status == buffer.sizeof);

return buffer;
}
else version (AnyARC4Random)
{
return arc4random();
}
Expand Down Expand Up @@ -1837,7 +1873,25 @@ if (isUnsigned!UIntType)
/// ditto
@property UIntType unpredictableSeed() @nogc nothrow @trusted
{
version (AnyARC4Random)
version (linux)
{
UIntType buffer;

/*
getrandom(2):
If the _urandom_ source has been initialized, reads of up to
256 bytes will always return as many bytes as requested and
will not be interrupted by signals. No such guarantees apply
for larger buffer sizes.
*/
static assert(buffer.sizeof <= 256);

const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0))();
assert(status == buffer.sizeof);

return buffer;
}
else version (AnyARC4Random)
{
static if (UIntType.sizeof <= uint.sizeof)
{
Expand Down

0 comments on commit 6fc083d

Please sign in to comment.