package ecdsa import ( "crypto/ecdsa" "math/big" "github.com/btcsuite/btcd/btcec/v2" gcrypto "github.com/ethereum/go-ethereum/crypto" "github.com/libp2p/go-libp2p/core/crypto" "github.com/pkg/errors" ) func ConvertFromInterfacePrivKey(privkey crypto.PrivKey) (*ecdsa.PrivateKey, error) { secpKey, ok := privkey.(*crypto.Secp256k1PrivateKey) if !ok { return nil, errors.New("could not cast to Secp256k1PrivateKey") } rawKey, err := secpKey.Raw() if err != nil { return nil, err } privKey := new(ecdsa.PrivateKey) k := new(big.Int).SetBytes(rawKey) privKey.D = k privKey.Curve = gcrypto.S256() // Temporary hack, so libp2p Secp256k1 is recognized as geth Secp256k1 in disc v5.1. privKey.X, privKey.Y = gcrypto.S256().ScalarBaseMult(rawKey) return privKey, nil } func ConvertToInterfacePrivkey(privkey *ecdsa.PrivateKey) (crypto.PrivKey, error) { privBytes := privkey.D.Bytes() // In the event the number of bytes outputted by the big-int are less than 32, // we append bytes to the start of the sequence for the missing most significant // bytes. if len(privBytes) < 32 { privBytes = append(make([]byte, 32-len(privBytes)), privBytes...) } return crypto.UnmarshalSecp256k1PrivateKey(privBytes) } func ConvertToInterfacePubkey(pubkey *ecdsa.PublicKey) (crypto.PubKey, error) { xVal, yVal := new(btcec.FieldVal), new(btcec.FieldVal) if xVal.SetByteSlice(pubkey.X.Bytes()) { return nil, errors.Errorf("X value overflows") } if yVal.SetByteSlice(pubkey.Y.Bytes()) { return nil, errors.Errorf("Y value overflows") } newKey := crypto.PubKey((*crypto.Secp256k1PublicKey)(btcec.NewPublicKey(xVal, yVal))) // Zero out temporary values. xVal.Zero() yVal.Zero() return newKey, nil }