# User randomness source in DKG
### Goals
1. being able to inject a user-provided source of randomness
2. being able to reproduce tests
3. being able to detect and return errors from user-provided source of randomness
4. being able to mix both user-provided and /dev/urandom sources of randomness
## Proposition 1
In dkg.go:
```golang
type Config struct {
...
Reader io.Reader // user-provided randomness
UseOnlyReader bool // if we want to only use the Reader
}
func NewDistKeyGenerator(c *Config, ...) {
...
if c.Reader == nil { // user did nothing - we take /dev/urandom
secret = suite.Scalar().Pick(random.New())
} else {
// we want to test only user source - by default it is FALSE
// so by default we create a "good" source.
if c.UseOnlyReader {
secret = suite.Scalar().Pick(random.New(c.Reader))
} else {
// we combine both sources
secret = suite.Scalar().Pick(random.New(rand.Reader,c.Reader))
}
}
...
}
```
In `util/random/random.go`:
```golang
// Creates a kyber.Random from the output of the hash of the
// concatenation of the given reader's bytes. It panics only if
// ALL sources fail.
func New(readers ...io.Reader) kyber.Random {
if len(readers) == 0 {
readers = [1]io.Reader{rand.Reader}
}
return &rand{readers}
}
type rand {
readers []io.Reader
}
const READER_BYTES = 32;
func (r *rand) XORKeyStream(dst, src []byte) {
// prelude checks ommitted ...
...
// take READER_BYTES bytes from the readers
var b bytes.Buffer
var buff [READER_BYTES]byte
var nerr int
for _,r := range r.readers {
if _,err := io.ReadFull(r,buff[0:]); err != nil {
nerr++
}
b.Write(buff[0:])
}
if nerr == len(r.Readers) {
panic("all readers failed")
}
// create the XOF hash output
hash := blake2xb.New(b.Bytes()) // from blake2xb package from kyber
return hash.XORKeyStream(dst,src)
}
```