<pre class="notranslate">53116ca07207+ tip

This is a bit of a silly example, but the behavior is different on Linux and Windows
nonetheless, and I'm wondering if it might be part of a bigger issue:

package main

import "fmt"

func main() {
        n := uint8(0)    // or uint16, uint32, uint64...                                                                             
        f := float64(-1) // or float32, but not int32/int64                                                                          
        on := uint8(f)   // does not underflow on Windows                                                                            
        // on := uint8(int32(f)) // this works on both platforms                                                                     
        fmt.Printf("on is %d\n", on)
        n += on
        if n != 255 {
                fmt.Printf("n is not 255: %d\n", n)
        }
}

On Linux (x64):

# uintunderflow 
on is 255

On Windows (x64):

# uintunderflow.exe
on is 0
n is not 255: 0</pre>
<p dir="auto">This idea originated in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="124418875" data-permission-text="Title is private" data-url="https://github.com/golang/go/issues/13785" data-hovercard-type="issue" data-hovercard-url="/golang/go/issues/13785/hovercard" href="https://github.com/golang/go/issues/13785">#13785</a> when using OpenBSD's precedent with <a href="http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/arc4random.3" rel="nofollow"><code class="notranslate">arc4random(3)</code></a>.</p>
<p dir="auto">The Go crypto code includes a <a href="https://en.wikipedia.org/wiki/CSPRNG" rel="nofollow">CSPRNG</a> by default (see <code class="notranslate">src/crypto/rand/rand_unix.go:85</code>). However, it is only used on operating systems that Go doesn't determine to have a reliable, non-blocking randomness sources. Examples of reliable non-blocking randomness sources include a modern <code class="notranslate">/dev/urandom</code>, Linux's <code class="notranslate">getrandom(2)</code>, and OpenBSD's <code class="notranslate">getentropy(2)</code>.</p>
<p dir="auto">Many cryptography guides suggest userland CSPRNGs. The possible benefits include:</p>
<ul dir="auto">
<li>improving performance by avoiding the vast majority of randomness-related syscalls
<ul dir="auto">
<li>Go's CSPRNG fetches 16 bytes of seed entropy for every 1 MB of generated randomness</li>
</ul>
</li>
<li>easing up on the kernel, which may expend considerable effort when serving a Go process's randomness-related syscalls
<ul dir="auto">
<li>I remember seeing Poul-Henning Kamp quoted that FreeBSD kernel spends 15% of its time on random number generation</li>
</ul>
</li>
<li>adding some additional mixing to potentially weak OS-supplied randomness
<ul dir="auto">
<li>This would be a minimal stopgap. However, the Go currently uses <a href="http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf" rel="nofollow">ANSI X9.31</a> which mixes via AES and kneads in the current nanosecond time, which is better than nothing.</li>
</ul>
</li>
<li>potentially being able to replace math/rand with crypto/rand, which would simplify the codebase and prevent misuse of math/rand
<ul dir="auto">
<li>code for deterministic pseudo-randomness could be condensed, and the ability to seed it could be removed</li>
</ul>
</li>
</ul>
<p dir="auto">Network applications that use forward secret encryption make the peformance concerns more relevant.</p>
<p dir="auto">The primary risk is that we would then rely on the soundness and safety of Go's CSPRNG logic. I don't know whether timing attacks are a risk, but that's one issue that came to mind. The CSPRNG backs up to Go's AES implementation, though, so any risks unique to the CSPRNG would have to be outside of that. The fact that uses a standard algorithm (<a href="http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf" rel="nofollow">ANSI X9.31</a>) and a strong crypto primitive (AES) gives me confidence. I'm definitely not qualified to rigorously review something like this, though.</p>
<p dir="auto">This ticket could also entail a review of the existing CSPRNG and whether it could be stronger.</p>
<p dir="auto">Thoughts? Also, if anyone knows of relevant profiling techniques and targets, please share. I plan on investigating what kind of performance impact this switch would have.</p>