# 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) } ```