ah oops i need to set tmp at nonzero to start
Discussion
```go
func Zero(sk *SecKey) {
b := (*[96]byte)(unsafe.Pointer(sk))[:96]
tmp := byte(1)
for i := range b {
for tmp != 0 {
b[i] = 0
tmp = b[i]
}
}
}
```
i have an idea
forget zero, scramble
```go
func Zero(sk *SecKey) {
b := (*[96]byte)(unsafe.Pointer(sk))[:96]
for i := range 8 {
rand.Read(b)
}
// reverse the order and negate
for i := range b {
b[i] = ^b[len(b)-1-i]
}
}
```
this should rewrite the bits 8 times with secure random bits and then reverse and negate them, i can't see how it could optimize that out
and yeah, i sorta have an idea about this... in Go, it caches tests with deterministic results, but tests that read from the crypto/rand library never do, neither do the ones even from pseudorandom generators like luke champine's frand, which uses chacha12/20 hash chains and seeds
Yeah many people write CSRNG data instead of zeroing. It's an option. Don't know the results of it's effectiveness. I've considered it in some instances.
it bypasses the problem of optimization
it also mitigates against flash memory shadows
I'm not sure it will do that. Depends on the controller I guess. Some flash controllers can randomize writes and mark an old block as stale for wear leveling
well, really the chances of a key falling into swap are nearly insignificant if the signing is being done frequently
but even stilll, i've put 8 rewrites on it, even if it optimizes out to only one actual write it's still effective
Yes and if it's that important you can always use mlock() or VirtualLock()
oh yeah i am always forgetting... with Go there is always cgo for this kind of thing or maybe it can be done with assembler, assembler is preferable because it doesn't complicate the build workflow
not sure about such kernel specific calls and build workflow but probably it's something you can just dump into the symbol tabel and voila