Well,  I took Bardur&#39;s suggestion and avoided all the complexities of GHC&#39;s IO stack and simply used <a href="http://System.Posix.IO">System.Posix.IO</a> and Foreign.    This appears to work,  but for better or worse,   it is using blocking calls to the &quot;read&quot; system call and is not integrated with GHC&#39;s IO manager.   This shouldn&#39;t be an issue for my purposes,  but I suppose it&#39;s worth pointing out.  <div>
<br></div><div><div><div>{-# LANGUAGE BangPatterns, ViewPatterns #-}</div><div><br></div><div>import           Control.Applicative</div><div>import           Data.Bits</div><div>import           Data.Word(Word64)</div><div>
import qualified Data.ByteString as S</div><div>import qualified Data.ByteString.Lazy as L</div><div>import           Data.ByteString.Internal (c2w)</div><div>import           Control.Exception</div><div>import           <a href="http://System.Posix.IO">System.Posix.IO</a></div>
<div>import           Foreign</div><div>import qualified System.IO              as IO</div><div>import qualified Data.Binary.Get        as Get</div><div><br></div><div>showHex :: Word64 -&gt; S.ByteString</div><div>showHex n = s</div>
<div>  where</div><div>    (!s,_) = S.unfoldrN 16 f n</div><div><br></div><div>    f n = Just (char (n `shiftR` 60), n `shiftL` 4)</div><div><br></div><div>    char (fromIntegral -&gt; i)</div><div>      | i &lt; 10    = (c2w &#39;0&#39; -  0) + i</div>
<div>      | otherwise = (c2w &#39;a&#39; - 10) + i</div><div><br></div><div>twoRandomWord64s :: IO (Word64,Word64)</div><div>twoRandomWord64s = bracket openRd closeRd readRd</div><div>  where</div><div>    openRd = openFd &quot;/dev/urandom&quot; ReadOnly Nothing defaultFileFlags { noctty = True }</div>
<div>    readRd = \fd -&gt; allocaBytes 16 $ \ptr -&gt; do</div><div>                fdReadAll fd ptr 16</div><div>                x &lt;- peek (castPtr ptr)</div><div>                y &lt;- peek (castPtr ptr `plusPtr` 8)</div>
<div>                return (x,y)</div><div>    closeRd = closeFd</div><div>    fdReadAll fd ptr n = do</div><div>      n&#39; &lt;- fdReadBuf fd ptr n</div><div>      if n /= n&#39;</div><div>      then fdReadAll fd (ptr `plusPtr` n&#39;) (n - n&#39;)</div>
<div>      else return ()</div><div><br></div><div>main = do</div><div>   (x,y) &lt;- twoRandomWord64s</div><div>   S.hPutStrLn IO.stdout (S.append (showHex x) (showHex y))</div></div><div><br></div><div><br><div class="gmail_quote">
On Wed, Nov 28, 2012 at 6:05 PM, Leon Smith <span dir="ltr">&lt;<a href="mailto:leon.p.smith@gmail.com" target="_blank">leon.p.smith@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If you have rdrand,  there is no need to build your own PRNG on top of rdrand.   RdRand already incorporates one so that it can produce random numbers as fast as they can be requested,  and this number is continuously re-seeded with the on-chip entropy source.<div>

<br></div><div>It would be nice to have a little more information about /dev/urandom and how it varies by OS and hardware,   but on Linux and FreeBSD at least it&#39;s supposed to be a cryptographically secure RNG that incorporates a PRNG to produce numbers in case you exhaust the entropy pool.</div>
<div class="HOEnZb"><div class="h5">
<div><br><div class="gmail_quote">On Wed, Nov 28, 2012 at 5:00 PM, Vincent Hanquez <span dir="ltr">&lt;<a href="mailto:tab@snarc.org" target="_blank">tab@snarc.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div>On 11/28/2012 09:31 PM, Leon Smith wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Quite possibly,  entropy does seem to be a pretty lightweight dependency...<br>
<br>
Though doesn&#39;t recent kernels use rdrand to seed /dev/urandom if it&#39;s available?   So /dev/urandom is the most portable source of random numbers on unix systems,  though rdrand does have the advantage of avoiding system calls,  so it certainly would be preferable, especially if you need large numbers of random numbers.<br>


</blockquote></div>
There&#39;s no much information on this i think, but if you need large number of random numbers you should build a PRNG yourself on top of the best random seed you can get, and make sure you reseed your prng casually with more entropy bytes. Also if<br>


you don&#39;t have enough initial entropy, you should block.<br>
<br>
/dev/urandom is not the same thing on every unix system. leading to various assumptions broken when varying the unixes. It also varies with the hardware context: for example on an embedded or some virtualized platform, giving you really terrible entropy.<span><font color="#888888"><br>


<br>
-- <br>
Vincent<br>
</font></span></blockquote></div><br></div>
</div></div></blockquote></div><br></div></div>