Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add bls verification #239

Merged
merged 7 commits into from
Jul 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
567 changes: 357 additions & 210 deletions api/cosmos/staking/v1beta1/tx.pulsar.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions client/keys/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ The pass backend requires GnuPG: https://gnupg.org/
RenameKeyCommand(),
ParseKeyStringCommand(),
MigrateCommand(),
SignMsgKeysCmd(),
VerifySignatureCmd(),
)

cmd.PersistentFlags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
Expand Down
2 changes: 1 addition & 1 deletion client/keys/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ func TestCommands(t *testing.T) {
assert.Assert(t, rootCommands != nil)

// Commands are registered
assert.Equal(t, 11, len(rootCommands.Commands()))
assert.Equal(t, 13, len(rootCommands.Commands()))
}
117 changes: 117 additions & 0 deletions client/keys/sign.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package keys

import (
"encoding/hex"
"errors"

"github.com/cometbft/cometbft/crypto/tmhash"
"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
)

// SignMsgKeysCmd returns the Cobra Command for signing messages with the private key of a given name.
func SignMsgKeysCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "sign [message]",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a dangerous action, please note user to take care.

And give an example, it can be used to do possesion of proof..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Short: "Sign message",
Long: `Return a signature from their associated name and address private key.
!!!NOTE!!!
This is not a secure way to sign messages.
This command is allowed to sign any message from your private key.
Please *DO NOT* use this command unless you know what you are doing.

Example For Signing BLS PoP Message:
$ gnfd keys add bls --keyring-backend test --algo eth_bls
$ BLS=$(./build/bin/gnfd keys show bls --keyring-backend test --output json | jq -r .pubkey_hex)
$ gnfd keys sign $BLS --from bls

`,
RunE: runSignMsgCmd,
}

cmd.Flags().String(flags.FlagFrom, "", "Name or address of private key with which to sign")
return cmd
}

func runSignMsgCmd(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return errors.New("invalid number of arguments")
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

_, name, _, err := client.GetFromFields(clientCtx, clientCtx.Keyring, clientCtx.From)
if err != nil {
return err
}

msg, err := hex.DecodeString(args[0])
if err != nil {
return err
}
sig, _, err := clientCtx.Keyring.Sign(name, tmhash.Sum(msg))
if err != nil {
return err
}

cmd.Println(hex.EncodeToString(sig))
return nil
}

// VerifySignatureCmd returns the Cobra Command for verifying signatures with a given public key and message.
func VerifySignatureCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "verify [message] [signature]",
Short: "Verify signature",
Long: "Verify signature with public key and message",
RunE: runVerifySignatureCmd,
}

cmd.Flags().String(flags.FlagFrom, "", "Name or address of private key with which to sign")
return cmd
}

func runVerifySignatureCmd(cmd *cobra.Command, args []string) error {
if len(args) != 2 {
return errors.New("invalid number of arguments")
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

_, name, _, err := client.GetFromFields(clientCtx, clientCtx.Keyring, clientCtx.From)
if err != nil {
return err
}
record, err := clientCtx.Keyring.Key(name)
if err != nil {
return err
}

priv, err := record.ExtractPrivKey()
if err != nil {
return nil
}

msg, err := hex.DecodeString(args[0])
if err != nil {
return nil
}
signature, err := hex.DecodeString(args[1])
if err != nil {
return nil
}
if priv.PubKey().VerifySignature(tmhash.Sum(msg), signature) {
cmd.Println("Signature verify successfully")
} else {
cmd.Println("Signature verify failed")
}
return nil
}
5 changes: 5 additions & 0 deletions crypto/keyring/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ func (k *Record) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
return nil
}

// ExtractPrivKey returns the priv key
func (k *Record) ExtractPrivKey() (cryptotypes.PrivKey, error) {
return extractPrivKeyFromRecord(k)
}

func extractPrivKeyFromRecord(k *Record) (cryptotypes.PrivKey, error) {
rl := k.GetLocal()
if rl == nil {
Expand Down
4 changes: 3 additions & 1 deletion proto/cosmos/staking/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ message MsgCreateValidator {
string relayer_address = 9 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string challenger_address = 10 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string bls_key = 11;
string bls_proof = 12;
}

// MsgCreateValidatorResponse defines the Msg/CreateValidator response type.
Expand Down Expand Up @@ -98,7 +99,8 @@ message MsgEditValidator {

string relayer_address = 5 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string challenger_address = 6 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string bls_key = 7; // The BLS pubkey for the authorized relayer/challenger
string bls_key = 7; // The BLS pubkey for the authorized relayer/challenger
string bls_proof = 8;
}

// MsgEditValidatorResponse defines the Msg/EditValidator response type.
Expand Down
5 changes: 4 additions & 1 deletion simapp/simd/cmd/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"path/filepath"

tmconfig "github.com/cometbft/cometbft/config"
"github.com/cometbft/cometbft/crypto/tmhash"
"github.com/cometbft/cometbft/types"
tmtime "github.com/cometbft/cometbft/types/time"
"github.com/prysmaticlabs/prysm/crypto/bls"
Expand Down Expand Up @@ -302,14 +303,16 @@ func initTestnetFiles(
valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction)
blsSecretKey, _ := bls.RandKey()
blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal())
blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal()))
blsProof := hex.EncodeToString(blsProofBuf.Marshal())
createValMsg, err := stakingtypes.NewMsgCreateValidator(
sdk.AccAddress(addr),
valPubKeys[i],
sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()),
sdk.OneInt(),
addr, addr, addr, addr, blsPk,
addr, addr, addr, addr, blsPk, blsProof,
)
if err != nil {
return err
Expand Down
6 changes: 6 additions & 0 deletions tests/e2e/genutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"path/filepath"

"github.com/cometbft/cometbft/crypto/tmhash"
"github.com/prysmaticlabs/prysm/crypto/bls"
"github.com/stretchr/testify/suite"

Expand Down Expand Up @@ -53,6 +54,8 @@ func (s *E2ETestSuite) TestGenTxCmd() {
amount := sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(12))
blsSecretKey, _ := bls.RandKey()
blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal())
blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal()))
blsProof := hex.EncodeToString(blsProofBuf.Marshal())

tests := []struct {
name string
Expand Down Expand Up @@ -83,6 +86,7 @@ func (s *E2ETestSuite) TestGenTxCmd() {
val.Address.String(),
val.Address.String(),
blsPk,
blsProof,
},
expError: false,
},
Expand All @@ -97,6 +101,7 @@ func (s *E2ETestSuite) TestGenTxCmd() {
val.Address.String(),
val.Address.String(),
blsPk,
blsProof,
},
expError: true,
},
Expand All @@ -111,6 +116,7 @@ func (s *E2ETestSuite) TestGenTxCmd() {
val.Address.String(),
val.Address.String(),
blsPk,
blsProof,
},
expError: false,
},
Expand Down
9 changes: 7 additions & 2 deletions tests/integration/genutil/gentx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"cosmossdk.io/math"
"github.com/cometbft/cometbft/crypto/tmhash"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1"
Expand Down Expand Up @@ -86,17 +87,21 @@ func (suite *GenTxTestSuite) SetupTest() {
amount := sdk.NewInt64Coin(sdk.DefaultBondDenom, 50)
one := math.OneInt()
blsSecretKey1, _ := bls.RandKey()
blsProofBuf := blsSecretKey1.Sign(tmhash.Sum(blsSecretKey1.PublicKey().Marshal()))
blsProof1 := hex.EncodeToString(blsProofBuf.Marshal())
blsPk1 := hex.EncodeToString(blsSecretKey1.PublicKey().Marshal())

suite.msg1, err = stakingtypes.NewMsgCreateValidator(
sdk.AccAddress(pk1.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1)
sdk.AccAddress(pk1.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1, blsProof1)
suite.NoError(err)

blsSecretKey2, _ := bls.RandKey()
blsPk2 := hex.EncodeToString(blsSecretKey2.PublicKey().Marshal())
blsProofBuf = blsSecretKey2.Sign(tmhash.Sum(blsSecretKey2.PublicKey().Marshal()))
blsProof2 := hex.EncodeToString(blsProofBuf.Marshal())

suite.msg2, err = stakingtypes.NewMsgCreateValidator(
sdk.AccAddress(pk2.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), blsPk2)
sdk.AccAddress(pk2.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), blsPk2, blsProof2)
suite.NoError(err)
}

Expand Down
6 changes: 4 additions & 2 deletions testutil/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"time"

dbm "github.com/cometbft/cometbft-db"
"github.com/cometbft/cometbft/crypto/tmhash"
"github.com/cometbft/cometbft/node"
tmclient "github.com/cometbft/cometbft/rpc/client"
"github.com/prysmaticlabs/prysm/crypto/bls"
Expand Down Expand Up @@ -498,15 +499,16 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) {
return nil, err
}
blsPubKey := hex.EncodeToString(blsSecretKey.PublicKey().Marshal())

blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal()))
blsProof := hex.EncodeToString(blsProofBuf.Marshal())
createValMsg, err := stakingtypes.NewMsgCreateValidator(
addr,
valPubKeys[i],
sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens),
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
stakingtypes.NewCommissionRates(commission, math.LegacyOneDec(), math.LegacyOneDec()),
math.OneInt(),
addr, addr, addr, addr, blsPubKey,
addr, addr, addr, addr, blsPubKey, blsProof,
)
if err != nil {
return nil, err
Expand Down
5 changes: 3 additions & 2 deletions types/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ const (
EthAddressLength = 20

// BLSPubKeyLength defines a valid BLS Public key length
BLSPubKeyLength = 48
BLSEmptyPubKey = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dead"
BLSPubKeyLength = 48
BLSSignatureLength = 96
BLSEmptyPubKey = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dead"
)

// cache variables
Expand Down
10 changes: 8 additions & 2 deletions x/genutil/client/cli/gentx.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ func GenTxCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfig, genBalI
fsCreateValidator, defaultsDesc := cli.CreateValidatorMsgFlagSet(ipDefault)

cmd := &cobra.Command{
Use: "gentx [key_name] [amount] [validator] [relayer] [challenger] [blskey]",
Use: "gentx [key_name] [amount] [validator] [relayer] [challenger] [blskey] [blsProof]",
Short: "Generate a genesis tx carrying a self delegation",
Args: cobra.ExactArgs(6),
Args: cobra.ExactArgs(7),
Long: fmt.Sprintf(`Generate a genesis transaction that creates a validator with a self-delegation,
that is signed by the key in the Keyring referenced by a given name. A node ID and Bech32 consensus
pubkey may optionally be provided. If they are omitted, they will be retrieved from the priv_validator.json
Expand All @@ -47,6 +47,7 @@ $ %s gentx my-key-name 1000000stake \
0x6D967dc83b625603c963713eABd5B43A281E595e \
0xcdd393723f1Af81faa3F3c87B51dAB72B6c68154 \
ac1e598ae0ccbeeaafa31bc6faefa85c2ae3138699cac79169cd718f1a38445201454ec092a86f200e08a15266bdc6e9 \
b68b819c2d431bd8ea800326bbcd91bbbbec5404b8f456b23c87de368c7f48507e7be120f32354ebf3df38c2b5808cebd4c07254f0b4626007c6d46fc05b260901 \
--home=/path/to/home/dir --keyring-backend=os --chain-id=greenfield_9000-1 \
--moniker="myvalidator" \
--commission-max-change-rate=0.01 \
Expand Down Expand Up @@ -172,12 +173,17 @@ $ %s gentx my-key-name 1000000stake \
if len(blsPk) != 2*sdk.BLSPubKeyLength {
return fmt.Errorf("invalid bls pubkey")
}
blsProof := args[6]
if len(blsProof) != 2*sdk.BLSSignatureLength {
return fmt.Errorf("invalid bls proof, len: %d", len(blsProof))
}

createValCfg.Validator = validator
createValCfg.Delegator = addr
createValCfg.Relayer = relayer
createValCfg.Challenger = challenger
createValCfg.BlsKey = blsPk
createValCfg.BLSProof = blsProof

// create a 'create-validator' message
txBldr, msg, err := cli.BuildCreateValidatorMsg(clientCtx, createValCfg, txFactory, true)
Expand Down
7 changes: 5 additions & 2 deletions x/genutil/gentx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"

abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/crypto/tmhash"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltestutil "github.com/cosmos/cosmos-sdk/x/genutil/testutil"
Expand Down Expand Up @@ -67,17 +68,19 @@ func (suite *GenTxTestSuite) SetupTest() {
one := math.OneInt()
blsSecretKey, _ := bls.RandKey()
blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal())
blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal()))
blsProof := hex.EncodeToString(blsProofBuf.Marshal())
suite.msg1, err = stakingtypes.NewMsgCreateValidator(
sdk.AccAddress(pk1.Address()), pk1,
amount, desc, comm, one,
sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()),
sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk)
sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk, blsProof)
suite.NoError(err)
suite.msg2, err = stakingtypes.NewMsgCreateValidator(
sdk.AccAddress(pk2.Address()), pk1,
amount, desc, comm, one,
sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()),
sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk1.Address()), blsPk)
sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk1.Address()), blsPk, blsProof)
suite.NoError(err)
}

Expand Down
Loading