From 4072bc60b85d2d52662b081023c7638386ce15ec Mon Sep 17 00:00:00 2001 From: Oleg Grenrus Date: Wed, 11 Jun 2025 13:48:09 +0300 Subject: [PATCH] Always #include sys/random.h ... because apparently some systems don't expose getentropy via unistd.h (as POSIX suggests since recently). (Some systems include Android). While we are on it: - Use `RtlGenRandom` on Windows instead of time - Use `SecRandomCopyBytes` on macos and ios I have no access to ios devices, but if SecRandomCopyBytes approach works on macos, I hope it works on ios. `getentropy` is reported to not work on `ios` elsewhere. --- cbits-apple/init.c | 8 +++++ cbits-unix/init.c | 4 --- cbits-win/init.c | 27 +++------------ splitmix.cabal | 83 ++++++++++++++++++++++++---------------------- 4 files changed, 56 insertions(+), 66 deletions(-) create mode 100644 cbits-apple/init.c diff --git a/cbits-apple/init.c b/cbits-apple/init.c new file mode 100644 index 0000000..4ad2e83 --- /dev/null +++ b/cbits-apple/init.c @@ -0,0 +1,8 @@ +#include +#include + +uint64_t splitmix_init() { + uint64_t result; + int r = SecRandomCopyBytes(kSecRandomDefault, sizeof(uint64_t), &result); + return r == errSecSuccess ? result : 0xfeed1000; +} diff --git a/cbits-unix/init.c b/cbits-unix/init.c index 255b667..05fb84c 100644 --- a/cbits-unix/init.c +++ b/cbits-unix/init.c @@ -1,10 +1,6 @@ #include #include - -/* for macos */ -#ifdef __APPLE__ #include -#endif uint64_t splitmix_init() { uint64_t result; diff --git a/cbits-win/init.c b/cbits-win/init.c index a6feb59..938fa5b 100644 --- a/cbits-win/init.c +++ b/cbits-win/init.c @@ -1,28 +1,9 @@ #include - #include +#include uint64_t splitmix_init() { - /* Handy list at https://stackoverflow.com/a/3487338/1308058 */ - - uint64_t a = GetCurrentProcessId(); /* DWORD */ - uint64_t b = GetCurrentThreadId(); /* DWORD */ - uint64_t c = GetTickCount(); /* DWORD */ - - SYSTEMTIME t = {0,0,0,0,0,0,0,0}; - GetSystemTime(&t); - - LARGE_INTEGER i; - QueryPerformanceCounter(&i); - - return a ^ (b << 32) ^ (c << 16) - ^ ((uint64_t) t.wYear << 56) - ^ ((uint64_t) t.wMonth << 48) - ^ ((uint64_t) t.wDayOfWeek << 40) - ^ ((uint64_t) t.wDay << 32) - ^ ((uint64_t) t.wHour << 24) - ^ ((uint64_t) t.wMinute << 16) - ^ ((uint64_t) t.wSecond << 8) - ^ ((uint64_t) t.wMilliseconds << 0) - ^ ((uint64_t) i.QuadPart); + uint64_t result; + int r = RtlGenRandom(&result, sizeof(uint64_t)); + return r ? result : 0xfeed1000; } diff --git a/splitmix.cabal b/splitmix.cabal index 9dfcbb1..e0c78a1 100644 --- a/splitmix.cabal +++ b/splitmix.cabal @@ -1,6 +1,6 @@ -cabal-version: >=1.10 +cabal-version: 2.4 name: splitmix -version: 0.1.2 +version: 0.1.3 synopsis: Fast Splittable PRNG description: Pure Haskell implementation of SplitMix described in @@ -26,28 +26,30 @@ description: (the mixing functions are easily inverted, and two successive outputs suffice to reconstruct the internal state). -license: BSD3 +license: BSD-3-Clause license-file: LICENSE maintainer: Oleg Grenrus bug-reports: https://github.com/haskellari/splitmix/issues category: System, Random build-type: Simple tested-with: - GHC ==8.6.5 - || ==8.8.4 - || ==8.10.4 - || ==9.0.2 - || ==9.2.8 - || ==9.4.8 - || ==9.6.7 - || ==9.8.4 - || ==9.10.2 - || ==9.12.2 + GHC ==8.6.5 + || ==8.8.4 + || ==8.10.4 + || ==9.0.2 + || ==9.2.8 + || ==9.4.8 + || ==9.6.7 + || ==9.8.4 + || ==9.10.2 + || ==9.12.2 + +extra-doc-files: + Changelog.md + README.md extra-source-files: - Changelog.md make-hugs.sh - README.md test-hugs.sh flag optimised-mixer @@ -72,7 +74,7 @@ library -- ghc-options: -fplugin=DumpCore -fplugin-opt DumpCore:core-html build-depends: - base >=4.12.0.0 && <4.22 + , base >=4.12.0.0 && <4.22 , deepseq >=1.4.4.0 && <1.6 if flag(optimised-mixer) @@ -85,19 +87,22 @@ library if impl(ghcjs) cpp-options: -DSPLITMIX_INIT_GHCJS=1 - else - if impl(ghc) - cpp-options: -DSPLITMIX_INIT_C=1 + elif impl(ghc) + cpp-options: -DSPLITMIX_INIT_C=1 - if os(windows) - c-sources: cbits-win/init.c + if os(windows) + c-sources: cbits-win/init.c - else - c-sources: cbits-unix/init.c + elif (os(osx) || os(ios)) + c-sources: cbits-apple/init.c + ld-options: -framework Security else - cpp-options: -DSPLITMIX_INIT_COMPAT=1 - build-depends: time >=1.2.0.3 && <1.15 + c-sources: cbits-unix/init.c + + else + cpp-options: -DSPLITMIX_INIT_COMPAT=1 + build-depends: time >=1.2.0.3 && <1.15 source-repository head type: git @@ -110,7 +115,7 @@ benchmark comparison hs-source-dirs: bench main-is: Bench.hs build-depends: - base + , base , containers >=0.6.0.1 && <0.8 , criterion >=1.6.0.0 && <1.7 , random @@ -124,7 +129,7 @@ benchmark simple-sum hs-source-dirs: bench main-is: SimpleSum.hs build-depends: - base + , base , random , splitmix @@ -136,7 +141,7 @@ benchmark range main-is: Range.hs other-modules: Data.Bits.Compat build-depends: - base + , base , random , splitmix @@ -147,7 +152,7 @@ test-suite examples hs-source-dirs: tests main-is: Examples.hs build-depends: - base + , base , HUnit >=1.6.0.0 && <1.7 , splitmix @@ -162,7 +167,7 @@ test-suite splitmix-tests Uniformity build-depends: - base + , base , containers >=0.4.0.0 && <0.8 , HUnit >=1.6.0.0 && <1.7 , math-functions >=0.3.3.0 && <0.4 @@ -177,7 +182,7 @@ test-suite montecarlo-pi hs-source-dirs: tests main-is: SplitMixPi.hs build-depends: - base + , base , splitmix test-suite montecarlo-pi-32 @@ -187,7 +192,7 @@ test-suite montecarlo-pi-32 hs-source-dirs: tests main-is: SplitMixPi32.hs build-depends: - base + , base , splitmix test-suite splitmix-dieharder @@ -197,15 +202,15 @@ test-suite splitmix-dieharder hs-source-dirs: tests main-is: Dieharder.hs build-depends: - async >=2.2.1 && <2.3 + , async >=2.2.1 && <2.3 , base - , bytestring >=0.10.8.2 && <0.13 + , bytestring >=0.10.8.2 && <0.13 , deepseq - , process >=1.6.0.0 && <1.7 + , process >=1.6.0.0 && <1.7 , random , splitmix - , tf-random >=0.5 && <0.6 - , vector >=0.13.0.0 && <0.14 + , tf-random >=0.5 && <0.6 + , vector >=0.13.0.0 && <0.14 test-suite splitmix-testu01 if !os(linux) @@ -219,7 +224,7 @@ test-suite splitmix-testu01 c-sources: tests/cbits/testu01.c extra-libraries: testu01 build-depends: - base + , base , base-compat-batteries >=0.10.5 && <0.15 , splitmix @@ -230,6 +235,6 @@ test-suite initialization hs-source-dirs: tests main-is: Initialization.hs build-depends: - base + , base , HUnit >=1.6.0.0 && <1.7 , splitmix