go-libp2p-examples
go-libp2p-examples copied to clipboard
Chat example cannot have predictable RSA keys
The code below is in chat.go:
// If debug is enabled, use a constant random source to generate the peer ID. Only useful for debugging,
// off by default. Otherwise, it uses rand.Reader.
var r io.Reader
if *debug {
// Use the port number as the randomness source.
// This will always generate the same host ID on multiple executions, if the same port number is used.
// Never do this in production code.
r = mrand.New(mrand.NewSource(int64(*sourcePort)))
} else {
r = rand.Reader
}
// Creates a new RSA key pair for this host.
prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r)
if err != nil {
panic(err)
}
While this seems reasonable, in fact crypto.GenerateKeyPairWithReader calls the default go RSA implementation which went out of its way to make doing this basically disallowed. The first line of the RSA implementation in Go is randutil.MaybeReadByte(random)
, which has the following comment:
// MaybeReadByte reads a single byte from r with ~50% probability. This is used
// to ensure that callers do not depend on non-guaranteed behaviour, e.g.
// assuming that rsa.GenerateKey is deterministic w.r.t. a given random stream.
//
// This does not affect tests that pass a stream of fixed bytes as the random
// source (e.g. a zeroReader).
Two questions:
- How should we best change the demo (i.e. should we just say if you want to use encryption then you are stuck with non-deterministic keys/loading your own, and for non-determinism use other types of Peer IDs)?
- Should we submit an issue to the ed25519.go implementation that does not have this same semantics regarding seeded random streams?
- We can probably just switch to ed25519
- Meh? I'd rather just abuse that bug :).