package p2p import ( "crypto/ecdsa" "crypto/rand" "encoding/hex" "io/ioutil" "net" "os" "path" "github.com/btcsuite/btcd/btcec" "github.com/libp2p/go-libp2p-core/crypto" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/shared/iputils" ) const keyPath = "network-keys" func convertFromInterfacePrivKey(privkey crypto.PrivKey) *ecdsa.PrivateKey { typeAssertedKey := (*ecdsa.PrivateKey)((*btcec.PrivateKey)(privkey.(*crypto.Secp256k1PrivateKey))) return typeAssertedKey } func convertToInterfacePrivkey(privkey *ecdsa.PrivateKey) crypto.PrivKey { typeAssertedKey := crypto.PrivKey((*crypto.Secp256k1PrivateKey)((*btcec.PrivateKey)(privkey))) return typeAssertedKey } func convertToInterfacePubkey(pubkey *ecdsa.PublicKey) crypto.PubKey { typeAssertedKey := crypto.PubKey((*crypto.Secp256k1PublicKey)((*btcec.PublicKey)(pubkey))) return typeAssertedKey } func privKey(cfg *Config) (*ecdsa.PrivateKey, error) { defaultKeyPath := path.Join(cfg.DataDir, keyPath) privateKeyPath := cfg.PrivateKey _, err := os.Stat(defaultKeyPath) defaultKeysExist := !os.IsNotExist(err) if err != nil && defaultKeysExist { return nil, err } if privateKeyPath == "" && !defaultKeysExist { priv, _, err := crypto.GenerateSecp256k1Key(rand.Reader) if err != nil { return nil, err } rawbytes, err := priv.Raw() if err != nil { return nil, err } dst := make([]byte, hex.EncodedLen(len(rawbytes))) hex.Encode(dst, rawbytes) if err = ioutil.WriteFile(defaultKeyPath, dst, 0600); err != nil { return nil, err } convertedKey := convertFromInterfacePrivKey(priv) return convertedKey, nil } if defaultKeysExist && privateKeyPath == "" { privateKeyPath = defaultKeyPath } return retrievePrivKeyFromFile(privateKeyPath) } func retrievePrivKeyFromFile(path string) (*ecdsa.PrivateKey, error) { src, err := ioutil.ReadFile(path) if err != nil { log.WithError(err).Error("Error reading private key from file") return nil, err } dst := make([]byte, hex.DecodedLen(len(src))) _, err = hex.Decode(dst, src) if err != nil { return nil, errors.Wrap(err, "failed to decode hex string") } unmarshalledKey, err := crypto.UnmarshalSecp256k1PrivateKey(dst) if err != nil { return nil, err } return convertFromInterfacePrivKey(unmarshalledKey), nil } func ipAddr() net.IP { ip, err := iputils.ExternalIPv4() if err != nil { log.Fatalf("Could not get IPv4 address: %v", err) } return net.ParseIP(ip) }