Skip to content

Commit

Permalink
feat: add bls key types into keyring management tool (#73)
Browse files Browse the repository at this point in the history
* keyring: add eth bls key types

* fix: keys/codec_test
  • Loading branch information
j75689 authored Dec 23, 2022
1 parent 240adbc commit e235b25
Show file tree
Hide file tree
Showing 16 changed files with 1,032 additions and 19 deletions.
16 changes: 8 additions & 8 deletions client/keys/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ func getTestCases() testCases {
return testCases{
// nolint:govet
[]keyring.KeyOutput{
{"A", "B", "C", "D", "E"},
{"A", "B", "C", "D", ""},
{"", "B", "C", "D", ""},
{"", "", "", "", ""},
{"A", "B", "C", "D", "D", "E"},
{"A", "B", "C", "D", "D", ""},
{"", "B", "C", "D", "D", ""},
{"", "", "", "", "", ""},
},
make([]keyring.KeyOutput, 4),
[][]byte{
[]byte(`{"name":"A","type":"B","address":"C","pubkey":"D","mnemonic":"E"}`),
[]byte(`{"name":"A","type":"B","address":"C","pubkey":"D"}`),
[]byte(`{"name":"","type":"B","address":"C","pubkey":"D"}`),
[]byte(`{"name":"","type":"","address":"","pubkey":""}`),
[]byte(`{"name":"A","type":"B","address":"C","pubkey":"D","pubkey_hex":"D","mnemonic":"E"}`),
[]byte(`{"name":"A","type":"B","address":"C","pubkey":"D","pubkey_hex":"D"}`),
[]byte(`{"name":"","type":"B","address":"C","pubkey":"D","pubkey_hex":"D"}`),
[]byte(`{"name":"","type":"","address":"","pubkey":"","pubkey_hex":""}`),
},
}
}
Expand Down
6 changes: 5 additions & 1 deletion crypto/codec/amino.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/eth/bls"
kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
Expand All @@ -26,7 +27,8 @@ func RegisterCrypto(cdc *codec.LegacyAmino) {
kmultisig.PubKeyAminoRoute, nil)
cdc.RegisterConcrete(&ethsecp256k1.PubKey{},
ethsecp256k1.PubKeyName, nil)

cdc.RegisterConcrete(&bls.PubKey{},
bls.PubKeyName, nil)
cdc.RegisterInterface((*cryptotypes.PrivKey)(nil), &amino.InterfaceOptions{Priority: []string{"ethermint/PrivKeyEthSecp256k1"}})
cdc.RegisterConcrete(sr25519.PrivKey{},
sr25519.PrivKeyName, nil)
Expand All @@ -36,4 +38,6 @@ func RegisterCrypto(cdc *codec.LegacyAmino) {
secp256k1.PrivKeyName, nil)
cdc.RegisterConcrete(&ethsecp256k1.PrivKey{},
ethsecp256k1.PrivKeyName, nil)
cdc.RegisterConcrete(&bls.PrivKey{},
bls.PrivKeyName, nil)
}
3 changes: 3 additions & 0 deletions crypto/codec/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/eth/bls"
"github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256r1"
Expand All @@ -19,11 +20,13 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
registry.RegisterImplementations(pk, &secp256k1.PubKey{})
registry.RegisterImplementations(pk, &multisig.LegacyAminoPubKey{})
registry.RegisterImplementations(pk, &ethsecp256k1.PubKey{})
registry.RegisterImplementations(pk, &bls.PubKey{})

var priv *cryptotypes.PrivKey
registry.RegisterInterface("cosmos.crypto.PrivKey", priv)
registry.RegisterImplementations(priv, &secp256k1.PrivKey{})
registry.RegisterImplementations(priv, &ed25519.PrivKey{}) //nolint
registry.RegisterImplementations(priv, &ethsecp256k1.PrivKey{})
registry.RegisterImplementations(priv, &bls.PrivKey{})
secp256r1.RegisterInterfaces(registry)
}
48 changes: 48 additions & 0 deletions crypto/hd/algo.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package hd

import (
"strings"

"github.com/cosmos/go-bip39"
util "github.com/wealdtech/go-eth2-util"

"github.com/cosmos/cosmos-sdk/crypto/keys/eth/bls"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/crypto/types"
)
Expand Down Expand Up @@ -68,3 +72,47 @@ func (s secp256k1Algo) Generate() GenerateFn {
return &secp256k1.PrivKey{Key: bzArr}
}
}

const (
// BLSType uses the ethereum BLS parameters.
BLSType = PubKeyType(bls.KeyType)
)

// EthBLS uses the Bitcoin eth_bls parameters.
var EthBLS = ethBLSAlgo{}

type ethBLSAlgo struct{}

// Name returns eth_bls
func (s ethBLSAlgo) Name() PubKeyType {
return BLSType
}

// Derive derives and returns the eth_bls private key for the given seed and HD path.
func (s ethBLSAlgo) Derive() DeriveFn {
// Derive derives and returns the eth_bls private key for the given mnemonic and HD path.
return func(mnemonic, bip39Passphrase, path string) ([]byte, error) {
seed, err := bip39.NewSeedWithErrorChecking(mnemonic, bip39Passphrase)
if err != nil {
return nil, err
}

privKey, err := util.PrivateKeyFromSeedAndPath(
seed, strings.ReplaceAll(path, "'", ""),
)
if err != nil {
return nil, err
}

return privKey.Marshal(), nil
}
}

// Generate generates a eth_bls private key from the given bytes.
func (s ethBLSAlgo) Generate() GenerateFn {
return func(bz []byte) types.PrivKey {
return &bls.PrivKey{
Key: bz,
}
}
}
22 changes: 13 additions & 9 deletions crypto/keyring/output.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package keyring

import (
"encoding/hex"

"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
Expand All @@ -13,11 +15,12 @@ import (
// KeyOutput defines a structure wrapping around an Info object used for output
// functionality.
type KeyOutput struct {
Name string `json:"name" yaml:"name"`
Type string `json:"type" yaml:"type"`
Address string `json:"address" yaml:"address"`
PubKey string `json:"pubkey" yaml:"pubkey"`
Mnemonic string `json:"mnemonic,omitempty" yaml:"mnemonic"`
Name string `json:"name" yaml:"name"`
Type string `json:"type" yaml:"type"`
Address string `json:"address" yaml:"address"`
PubKey string `json:"pubkey" yaml:"pubkey"`
PubKeyHex string `json:"pubkey_hex" yaml:"pubkey_hex"`
Mnemonic string `json:"mnemonic,omitempty" yaml:"mnemonic"`
}

// NewKeyOutput creates a default KeyOutput instance without Mnemonic, Threshold and PubKeys
Expand All @@ -31,10 +34,11 @@ func NewKeyOutput(name string, keyType KeyType, a sdk.Address, pk cryptotypes.Pu
return KeyOutput{}, err
}
return KeyOutput{
Name: name,
Type: keyType.String(),
Address: a.String(),
PubKey: string(bz),
Name: name,
Type: keyType.String(),
Address: a.String(),
PubKey: string(bz),
PubKeyHex: hex.EncodeToString(pk.Bytes()),
}, nil
}

Expand Down
2 changes: 1 addition & 1 deletion crypto/keyring/output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ func TestBech32KeysOutput(t *testing.T) {
out, err := MkAccKeyOutput(k)
require.NoError(t, err)
require.Equal(t, expectedOutput, out)
require.Equal(t, "{Name:multisig Type:multi Address:0x9a4fF4eA75776B118b6d13B3aBD8737511CcdAE0 PubKey:{\"@type\":\"/cosmos.crypto.multisig.LegacyAminoPubKey\",\"threshold\":1,\"public_keys\":[{\"@type\":\"/cosmos.crypto.secp256k1.PubKey\",\"key\":\"AurroA7jvfPd1AadmmOvWM2rJSwipXfRf8yD6pLbA2DJ\"}]} Mnemonic:}", fmt.Sprintf("%+v", out))
require.Equal(t, "{Name:multisig Type:multi Address:0x9a4fF4eA75776B118b6d13B3aBD8737511CcdAE0 PubKey:{\"@type\":\"/cosmos.crypto.multisig.LegacyAminoPubKey\",\"threshold\":1,\"public_keys\":[{\"@type\":\"/cosmos.crypto.secp256k1.PubKey\",\"key\":\"AurroA7jvfPd1AadmmOvWM2rJSwipXfRf8yD6pLbA2DJ\"}]} PubKeyHex:22c1f7e208011226eb5ae9872102eaeba00ee3bdf3ddd4069d9a63af58cdab252c22a577d17fcc83ea92db0360c9 Mnemonic:}", fmt.Sprintf("%+v", out))
}
33 changes: 33 additions & 0 deletions crypto/keys/eth/bls/bls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package bls

import (
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
)

const (
// KeyType is the string constant for the BLS algorithm
KeyType = "eth_bls"
)

// Amino encoding names
const (
// PrivKeyName defines the amino encoding name for the EthBLS private key
PrivKeyName = "ethereum/PrivKeyEthBLS"
// PubKeyName defines the amino encoding name for the EthBLS public key
PubKeyName = "ethereum/PubKeyEthBLS"
)

// ----------------------------------------------------------------------------
// secp256k1 Public Key

var (
_ cryptotypes.PubKey = &PubKey{}
_ codec.AminoMarshaler = &PubKey{}
)

// RegisterInterfaces adds BLS PubKey to pubkey registry
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
registry.RegisterImplementations((*cryptotypes.PubKey)(nil), &PubKey{})
}
Loading

0 comments on commit e235b25

Please sign in to comment.